Compare commits

..
Author SHA1 Message Date
Alug 3fdc829686 add g_localplayers similar to displayplayers
but this keeps track of actual local players and will never change during runtime
2024-12-30 17:27:04 +01:00
Alug f2b9077f5a no need to check for all this crap 2024-12-29 20:00:42 +01:00
Alug cd4bdde67c remove this turning off director
director will only work when in spec anyways
2024-12-29 19:46:54 +01:00
Alug de94ad24a5 Merge branch 'freecamstuffs' into splitscreendirector 2024-12-29 19:46:49 +01:00
Alug bb3f9b5882 fix wrong cam default controls 2024-12-29 16:51:24 +01:00
Alug 20044fa6a7 Merge branch 'freecamstuffs' into splitscreendirector 2024-12-29 16:47:25 +01:00
Alug b9428360c0 Merge branch 'Saturn-Next' into splitscreendirector 2024-12-29 16:16:59 +01:00
Alug 649373ff51 Merge branch 'freecamstuffs' into splitscreendirector 2024-12-29 06:41:40 +01:00
Alug 97e6222176 make function to return button names
to use with new rebindable cam controls
2024-12-29 06:03:20 +01:00
Alug eef56a7c82 make debugdirector show stuff for p1 atleast 2024-12-29 05:51:13 +01:00
Alug 8853666645 track views in directorinfo structs
should hopefully fix any potential remaining issues
2024-12-29 05:45:04 +01:00
Alug a379764076 fix director toggling + smol cleanup 2024-12-29 05:45:01 +01:00
Alug edd1cc6059 Merge branch 'freecamstuffs' into splitscreendirector 2024-12-29 05:44:53 +01:00
Alug 03280db377 missing inlucde 2024-12-28 18:52:57 +01:00
Alug 86aeff5547 cleanup K_DirectorIsAvailable 2024-12-28 18:25:23 +01:00
Alug b5b2062efa add K_DirectorIsAvailable 2024-12-28 18:25:05 +01:00
Alug b51731d675 cleanup director splitscreen stuff 2024-12-28 17:48:02 +01:00
Alug 229e8d9592 WIP splitscreen director lel 2024-12-28 17:47:58 +01:00
144 changed files with 12438 additions and 7971 deletions

No files matched your search

-4
View File
@@ -28,10 +28,6 @@ exist.
Returns the values of the given HUD item's `xoffset`/`yoffset` cvars.
Available for any HUD item with offset cvars.
## patch = v.cachePatchRotated(name, rollangle)
Like v.cachePatch, it caches a new patch with the corresponding name. Unlike v.cachePatch, however,
a rollangle can be supplied to the function so that it returns a rotated patch instead.
## x, y, flags = v.getDrawInfo(item)
Returns the X, Y and flags where the given HUD item will be drawn for the current displayplayer.
-8
View File
@@ -1,8 +0,0 @@
ifdef SILENT
MAKEFLAGS+=--no-print-directory
endif
all :
% ::
@$(MAKE) -C src $(MAKECMDGOALS)
+1 -1
View File
@@ -76,7 +76,7 @@ Crashlogs now contain alot more informations. and even more if your build has de
Also allows 64bit Windows builds to produce Crashlogs!
## MISC
- Bird's Camera Tilting feature is no longer turned on by default
- Bird's Camara Tilting feature is no longer turned on by default
- Bird's warning on the title screen has been removed
## Bugs
+72 -1
View File
@@ -31,6 +31,18 @@
# compile all HW render and 3D sound DLLs for the set
# opengl_dll
# Pure Mingw only, compile OpenGL HW render DLL
# minigl_dll
# Pure Mingw only, compile MiniGL HW render DLL
# ds3d_dll
# Pure Mingw only, compile DirectX DirectSound HW sound DLL
# fmod_dll
# Pure Mingw only, compile FMOD HW sound DLL
# openal_dll
# Pure Mingw only, compile OpenAL HW sound DLL
# fmod_so
# Non-Mingw, compile FMOD HW sound SO
# openal_so
# Non-Mingw, compile OpenAL HW sound SO
#
#
# Addon:
@@ -57,7 +69,10 @@
# Compile without SDL_Mixer, add 'NOMIXER=1'
# Compile without BSD API, add 'NONET=1'
# Compile without IPX/SPX, add 'NOIPX=1'
# Compile Mingw/SDL with S_DS3S, add 'DS3D=1'
# Compile without libopenmpt, add 'NOOPENMPT=1'
# Compile with S_FMOD3D, add 'FMOD=1' (WIP)
# Compile with S_OPENAL, add 'OPENAL=1' (WIP)
# To link with the whole SDL_Image lib to load Icons, add 'SDL_IMAGE=1' but it isn't not realy needed
# To link with SDLMain to hide console or make on a console-less binary, add 'SDLMAIN=1'
#
@@ -676,7 +691,7 @@ else
dll : opengl_dll
endif
ifdef MINGW
all_dll: opengl_dll
all_dll: opengl_dll ds3d_dll fmod_dll openal_dll
opengl_dll: $(BIN)/r_opengl.dll
$(BIN)/r_opengl.dll: $(OBJDIR)/ogl_win.o $(OBJDIR)/r_opengl.o
@@ -686,6 +701,37 @@ $(BIN)/r_opengl.dll: $(OBJDIR)/ogl_win.o $(OBJDIR)/r_opengl.o
ifndef NOUPX
-$(UPX) $(UPX_OPTS) $@
endif
ds3d_dll: $(BIN)/s_ds3d.dll
$(BIN)/s_ds3d.dll: $(OBJDIR)/s_ds3d.o
@echo Linking S_DS3d.dll...
$(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -ldsound -luuid
fmod_dll: $(BIN)/s_fmod.dll
$(BIN)/s_fmod.dll: $(OBJDIR)/s_fmod.o
-$(MKDIR) $(BIN)
@echo Linking S_FMOD.dll...
$(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -lfmod
openal_dll: $(BIN)/s_openal.dll
$(BIN)/s_openal.dll: $(OBJDIR)/s_openal.o
-$(MKDIR) $(BIN)
@echo Linking S_OpenAL.dll...
$(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -lopenal32
else
all_dll: fmod_so openal_so
fmod_so: $(BIN)/s_fmod.so
$(BIN)/s_fmod.so: $(OBJDIR)/s_fmod.o
-$(MKDIR) $(BIN)
@echo Linking S_FMOD.so...
$(CC) --shared $^ -o $@ -g --nostartfiles -lm -lfmod
openal_so: $(BIN)/s_openal.so
$(BIN)/s_openal.so: $(OBJDIR)/s_openal.o
-$(MKDIR) $(BIN)
@echo Linking S_OpenAL.so...
$(CC) --shared $^ -o $@ -g --nostartfiles -lm -lopenal
endif
else
@@ -777,6 +823,31 @@ $(OBJDIR)/win_dbg.o: win32/win_dbg.c
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
endif
ifdef STATICHS
$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \
hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \
hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
ifdef MINGW
$(OBJDIR)/s_ds3d.o: hardware/s_ds3d/s_ds3d.c hardware/hw3dsdrv.h \
hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
endif
else
$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \
hardware/hw_dll.h
$(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_fmod.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_fmod/s_fmod.c
$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \
hardware/hw_dll.h
$(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_openal.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_openal/s_openal.c
endif
ifdef FILTERS
$(OBJDIR)/%.o: $(INTERFACE)/filter/%.c
@echo $< needs deps
+4
View File
@@ -184,6 +184,8 @@ void I_OutputMsg(const char *fmt, ...)
void I_StartupMouse(void){}
void I_StartupMouse2(void){}
void I_StartupKeyboard(void){}
INT32 I_GetKey(void)
@@ -240,6 +242,8 @@ void I_GetJoystickEvents(void){}
void I_GetJoystick2Events(void){}
void I_GetMouseEvents(void){}
char *I_GetEnv(const char *name)
{
LOGW("I_GetEnv() called?!");
+1 -7
View File
@@ -608,7 +608,7 @@ static void CON_MoveConsole(void)
}
// Not instant - Increment fracmovement fractionally
fracmovement += FixedMul(cons_speed.value*vid.fdupy, (cv_uncappedhud.value ? renderdeltatics : FRACUNIT));
fracmovement += FixedMul(cons_speed.value*vid.fdupy, renderdeltatics);
if (con_curlines < con_destlines) // Move the console downwards
{
@@ -1466,10 +1466,7 @@ static void CON_DrawHudlines(void)
{
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++;
c++;
}
if (c >= con_width)
break;
if (*p < HU_FONTSTART)
;//charwidth = 4 * con_scalefactor;
else
@@ -1549,10 +1546,7 @@ static void CON_DrawConsole(void)
{
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++;
c++;
}
if (c >= con_width)
break;
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
}
}
+61 -255
View File
@@ -103,30 +103,6 @@ static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the
UINT16 pingmeasurecount = 1;
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
#define GENTLEMANSMOOTHING (TICRATE)
static tic_t reference_lag;
static UINT8 spike_time;
tic_t lowest_lag;
tic_t simulated_lag;
boolean server_lagless;
static void Lagless_OnChange(void)
{
/* don't back out of dishonesty, or go lagless after playing honestly */
if (cv_lagless.value && gamestate == GS_LEVEL)
server_lagless = true;
/*if (cv_lagless.value)
HU_AddChatText(M_GetText("\x82*Gentlemans Delay has been disabled for Serverplayer."), false);
else
HU_AddChatText(M_GetText("\x82*Gentlemans Delay will be enabled for Serverplayer."), false);*/
}
static CV_PossibleValue_t mindelay_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
consvar_t cv_mindelay = {"mindelay", "0", CV_SAVE, mindelay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_lagless = {"serverlagless", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, Lagless_OnChange, 0, NULL, NULL, 0, 0, NULL}; // this should be a netvar Zzz...
SINT8 nodetoplayer[MAXNETNODES];
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen)
SINT8 nodetoplayer3[MAXNETNODES]; // say the numplayer for this node if any (splitscreen == 2)
@@ -164,7 +140,7 @@ static UINT8 gamestate_resend_counter[MAXNETNODES];
boolean hu_stopped = false;
// Client specific
static ticcmd_t localcmds[MAXSPLITSCREENPLAYERS][MAXGENTLEMENDELAY];
static ticcmd_t localcmds[MAXSPLITSCREENPLAYERS];
static boolean cl_packetmissed;
// here it is for the secondary local player (splitscreen)
static UINT8 mynode; // my address pointofview server
@@ -211,16 +187,6 @@ typedef struct textcmdtic_s
struct textcmdtic_s *next;
} textcmdtic_t;
typedef struct textcmdbuf_s textcmdbuf_t;
struct textcmdbuf_s
{
textcmdbuf_t *next;
UINT8 cmd[MAXTEXTCMD];
};
static textcmdbuf_t *textcmdbuf[MAXSPLITSCREENPLAYERS] = {NULL};
ticcmd_t netcmds[TICQUEUE][MAXPLAYERS];
static textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL};
@@ -305,57 +271,23 @@ void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum))
listnetxcmd[id] = cmd_f;
}
static void WriteNetXCmd(UINT8 *cmd, netxcmd_t id, const void *param, size_t nparam)
{
cmd[0]++;
cmd[cmd[0]] = (UINT8)id;
if (param && nparam)
{
M_Memcpy(&cmd[cmd[0]+1], param, nparam);
cmd[0] = (UINT8)(cmd[0] + (UINT8)nparam);
}
}
void SendNetXCmdForPlayer(UINT8 playerid, netxcmd_t id, const void *param, size_t nparam)
{
if (localtextcmd[playerid][0]+2+nparam > MAXTEXTCMD)
if ((localtextcmd[playerid])[0]+2+nparam > MAXTEXTCMD)
{
textcmdbuf_t *buf = textcmdbuf[playerid];
if (2+nparam > MAXTEXTCMD)
{
CONS_Alert(CONS_ERROR, M_GetText("packet too large to fit NetXCmd, cannot add netcmd %d! (size: %s, max: %d)\n"), id, sizeu1(2+nparam), MAXTEXTCMD);
return;
}
// for future reference: if (cv_debug) != debug disabled.
CONS_Alert(CONS_NOTICE, M_GetText("NetXCmd buffer full, delaying netcmd %d... (size: %d, needed: %s)\n"), id, localtextcmd[playerid][0], sizeu1(nparam));
if (buf == NULL)
{
textcmdbuf[playerid] = Z_Malloc(sizeof(textcmdbuf_t), PU_STATIC, NULL);
textcmdbuf[playerid]->cmd[0] = 0;
textcmdbuf[playerid]->next = NULL;
WriteNetXCmd(textcmdbuf[playerid]->cmd, id, param, nparam);
return;
}
while (buf->next != NULL)
buf = buf->next;
if (buf->cmd[0]+2+nparam > MAXTEXTCMD)
{
buf->next = Z_Malloc(sizeof(textcmdbuf_t), PU_STATIC, NULL);
buf->next->cmd[0] = 0;
buf->next->next = NULL;
WriteNetXCmd(buf->next->cmd, id, param, nparam);
}
else
{
WriteNetXCmd(buf->cmd, id, param, nparam);
}
// for future reference: if (cht_debug) != debug disabled.
CONS_Alert(CONS_ERROR, M_GetText("NetXCmd buffer full, cannot add netcmd %d! (size: %d, needed: %s)\n"), id, localtextcmd[playerid][0], sizeu1(nparam));
return;
}
WriteNetXCmd(localtextcmd[playerid], id, param, nparam);
localtextcmd[playerid][0]++;
localtextcmd[playerid][localtextcmd[playerid][0]] = (UINT8)id;
if (param && nparam)
{
M_Memcpy(&localtextcmd[playerid][localtextcmd[playerid][0] + 1], param, nparam);
localtextcmd[playerid][0] = (UINT8)(localtextcmd[playerid][0] + (UINT8)nparam);
}
}
/*UINT8 GetFreeXCmdSize(UINT8 playerid)
@@ -524,15 +456,10 @@ static void D_Clearticcmd(tic_t tic)
void D_ResetTiccmds(void)
{
INT32 i, j;
INT32 i;
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
for (j = 0; j < MAXGENTLEMENDELAY; j++)
{
memset(&localcmds[i][j], 0, sizeof(ticcmd_t));
}
}
memset(&localcmds[i], 0, sizeof(ticcmd_t));
// Reset the net command list
for (i = 0; i < TEXTCMD_HASH_SIZE; i++)
@@ -540,6 +467,11 @@ void D_ResetTiccmds(void)
D_Clearticcmd(textcmds[i]->tic);
}
ticcmd_t *D_LocalTiccmd(UINT8 ss)
{
return &localcmds[ss];
}
// -----------------------------------------------------------------
// end of extra data function
// -----------------------------------------------------------------
@@ -1232,8 +1164,7 @@ static inline void CL_DrawConnectionStatus(void)
INT32 ccstime = I_GetTime();
// Draw background fade
if (!menuactive) // menu already draws its own fade
V_DrawFadeScreen(0xFF00, 16); // force default
V_DrawFadeScreen(0xFF00, 16);
if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_LOADFILES && cl_mode != CL_CHECKFILES
#ifdef HAVE_CURL
@@ -1259,22 +1190,10 @@ static inline void CL_DrawConnectionStatus(void)
case CL_DOWNLOADSAVEGAME:
if (lastfilenum != -1)
{
UINT32 currentsize = fileneeded[lastfilenum].currentsize;
UINT32 totalsize = fileneeded[lastfilenum].totalsize;
INT32 dldlength;
cltext = M_GetText("Downloading game state...");
Net_GetNetStat();
dldlength = (INT32)((currentsize/(double)totalsize) * 256);
if (dldlength > 256)
dldlength = 256;
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 111);
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 96);
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
va(" %4uK/%4uK",currentsize>>10,totalsize>>10));
va(" %4uK",fileneeded[lastfilenum].currentsize>>10));
V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE,
va("%3.1fK/s ", ((double)getbps)/1024));
}
@@ -2045,7 +1964,7 @@ static void CL_ReloadReceivedSavegame(void)
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
camera[i].subsector = R_PointInSubsector(camera[i].x, camera[i].y);
camera[i].subsector = R_PointInSubsectorFast(camera[i].x, camera[i].y);
}
cl_redownloadinggamestate = false;
@@ -2769,12 +2688,12 @@ static void CL_ConnectToServer(void)
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
#endif
cl_mode = CL_SEARCHING;
#ifdef CLIENT_LOADINGSCREEN
lastfilenum = -1;
#endif
cl_mode = CL_SEARCHING;
#ifdef JOININGAME
// Don't get a corrupt savegame error because tmpsave already exists
if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1)
@@ -3155,10 +3074,9 @@ static void Command_connect(void)
return;
}
M_ClearMenus(true);
if (Playing() || demo.title)
{
M_ClearMenus(true);
if (demo.title)
G_CheckDemoStatus();
@@ -3218,8 +3136,6 @@ static void Command_connect(void)
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
}
CV_Set(&cv_lastserver, I_GetNodeAddress(servernode));
if (splitscreen != cv_splitplayers.value-1)
{
splitscreen = cv_splitplayers.value-1;
@@ -4458,6 +4374,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (splitscreenplayer)
{
displayplayers[splitscreenplayer] = newplayernum;
g_localplayers[splitscreenplayer] = newplayernum;
DEBFILE(va("spawning one of my sister number %d\n", splitscreenplayer));
if (splitscreenplayer == 1 && botingame)
players[newplayernum].bot = 1;
@@ -4466,7 +4383,10 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
{
consoleplayer = newplayernum;
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
displayplayers[i] = newplayernum;
g_localplayers[i] = newplayernum;
}
DEBFILE("spawning me\n");
}
D_SendPlayerConfig();
@@ -5356,12 +5276,6 @@ static void HandlePacketFromPlayer(SINT8 node)
/// \todo Use a separate cvar for that kind of timeout?
freezetimeout[node] = I_GetTime() + connectiontimeout;
// If we've alredy received a ticcmd for this tic, just submit it for the next one.
tic_t faketic = maketic;
if ((!!(netcmds[maketic % TICQUEUE][netconsole].angleturn & TICCMD_RECEIVED))
&& (maketic - firstticstosend < TICQUEUE - 1))
faketic++;
// Don't do anything for packets of type NODEKEEPALIVE?
// Sryder 2018/07/01: Update the freezetimeout still!
if (netbuffer->packettype == PT_NODEKEEPALIVE
@@ -5369,7 +5283,7 @@ static void HandlePacketFromPlayer(SINT8 node)
break;
// Copy ticcmd
G_MoveTiccmd(&netcmds[faketic%TICQUEUE][netconsole], &netbuffer->u.clientpak.cmd, 1);
G_MoveTiccmd(&netcmds[maketic%TICQUEUE][netconsole], &netbuffer->u.clientpak.cmd, 1);
// Check ticcmd for "speed hacks"
if (CheckForSpeedHacks((UINT8)netconsole))
@@ -5381,7 +5295,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|| (netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS))
&& (nodetoplayer2[node] >= 0))
{
G_MoveTiccmd(&netcmds[faketic%TICQUEUE][(UINT8)nodetoplayer2[node]],
G_MoveTiccmd(&netcmds[maketic%TICQUEUE][(UINT8)nodetoplayer2[node]],
&netbuffer->u.client2pak.cmd2, 1);
if (CheckForSpeedHacks((UINT8)nodetoplayer2[node]))
@@ -5392,7 +5306,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|| (netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS))
&& (nodetoplayer3[node] >= 0))
{
G_MoveTiccmd(&netcmds[faketic%TICQUEUE][(UINT8)nodetoplayer3[node]],
G_MoveTiccmd(&netcmds[maketic%TICQUEUE][(UINT8)nodetoplayer3[node]],
&netbuffer->u.client3pak.cmd3, 1);
if (CheckForSpeedHacks((UINT8)nodetoplayer3[node]))
@@ -5402,7 +5316,7 @@ static void HandlePacketFromPlayer(SINT8 node)
if ((netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS)
&& (nodetoplayer4[node] >= 0))
{
G_MoveTiccmd(&netcmds[faketic%TICQUEUE][(UINT8)nodetoplayer4[node]],
G_MoveTiccmd(&netcmds[maketic%TICQUEUE][(UINT8)nodetoplayer4[node]],
&netbuffer->u.client4pak.cmd4, 1);
if (CheckForSpeedHacks((UINT8)nodetoplayer4[node]))
@@ -6099,78 +6013,27 @@ static void CL_SendClientCmd(void)
}
else if (gamestate != GS_NULL)
{
UINT8 lagDelay = 0;
if (lowest_lag > 0)
{
// Gentlemens' ping.
lagDelay = min(lowest_lag, MAXGENTLEMENDELAY);
// Is our connection worse than our current gentleman point?
// Make sure it stays that way for a bit before increasing delay levels.
if (lagDelay > reference_lag)
{
spike_time++;
if (spike_time >= GENTLEMANSMOOTHING)
{
// Okay, this is genuinely the new baseline delay.
reference_lag = lagDelay;
spike_time = 0;
}
else
{
// Just a temporary fluctuation, ignore it.
lagDelay = reference_lag;
}
}
else
{
reference_lag = lagDelay; // Adjust quickly if the connection improves.
spike_time = 0;
}
/*
if (server) // Clients have to wait for the gamestate to make it back. Servers don't!
lagDelay *= 2; // Simulate the HELLFUCK NIGHTMARE of a complete round trip.
*/
// [deep breath in]
// Plausible, elegant explanation that is WRONG AND SUPER HARMFUL.
// Clients with stable connections were adding their mindelay to network delay,
// even when their mindelay was as high or higher than network delay—which made
// client delay APPEAR slower than host mindelay, by the exact value that made
// "lmao just double it" make sense at the time.
//
// While this fix made client connections match server mindelay in our most common
// test environment, it also masked an issue that seriously affected online handling
// responsiveness, completely ruining our opportunity to further investigate it!
//
// See UpdatePingTable.
// I am taking this shitty code to my grave as an example of "never trust your brain".
// -Tyron 2024-05-15
}
packetsize = sizeof (clientcmd_pak);
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds[0][lagDelay], 1);
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic % TICQUEUE]);
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds[0], 1);
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%TICQUEUE]);
if (splitscreen || botingame) // Send a special packet with 2 cmd for splitscreen
{
netbuffer->packettype = (mis ? PT_CLIENT2MIS : PT_CLIENT2CMD);
packetsize = sizeof (client2cmd_pak);
G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds[1][lagDelay], 1);
G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds[1], 1);
if (splitscreen > 1)
{
netbuffer->packettype = (mis ? PT_CLIENT3MIS : PT_CLIENT3CMD);
packetsize = sizeof (client3cmd_pak);
G_MoveTiccmd(&netbuffer->u.client3pak.cmd3, &localcmds[2][lagDelay], 1);
G_MoveTiccmd(&netbuffer->u.client3pak.cmd3, &localcmds[2], 1);
if (splitscreen > 2)
{
netbuffer->packettype = (mis ? PT_CLIENT4MIS : PT_CLIENT4CMD);
packetsize = sizeof (client4cmd_pak);
G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds[3][lagDelay], 1);
G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds[3], 1);
}
}
}
@@ -6205,16 +6068,7 @@ static void CL_SendClientCmd(void)
M_Memcpy(netbuffer->u.textcmd, localtextcmd[i], localtextcmd[i][0]+1);
// All extra data have been sent
if (HSendPacket(servernode, true, 0, localtextcmd[i][0]+1)) // Send can fail...
{
localtextcmd[i][0] = 0;
if (textcmdbuf[i] != NULL)
{
textcmdbuf_t *buf = textcmdbuf[i];
M_Memcpy(localtextcmd[i], textcmdbuf[i]->cmd, textcmdbuf[i]->cmd[0]+1);
textcmdbuf[i] = textcmdbuf[i]->next;
Z_Free(buf);
}
}
}
}
}
@@ -6346,15 +6200,8 @@ static void SV_SendTics(void)
//
static inline void CreateNewLocalCMD(UINT8 p, INT32 realtics)
{
INT32 i;
for (i = MAXGENTLEMENDELAY-1; i > 0; i--)
{
G_MoveTiccmd(&localcmds[p][i], &localcmds[p][i-1], 1);
}
G_BuildTiccmd(&localcmds[p][0], realtics, p+1);
localcmds[p][0].angleturn |= TICCMD_RECEIVED;
G_BuildTiccmd(&localcmds[p], realtics, p+1);
localcmds[p].angleturn |= TICCMD_RECEIVED;
}
static void Local_Maketic(INT32 realtics)
@@ -6366,8 +6213,8 @@ static void Local_Maketic(INT32 realtics)
// game responder calls HU_Responder, AM_Responder, F_Responder,
// and G_MapEventsToControls
if (!dedicated) rendergametic = gametic;
// translate inputs (keyboard/mouse/joystick) into game controls
for (i = 0; i <= splitscreen; i++)
{
CreateNewLocalCMD(i, realtics);
@@ -6487,19 +6334,21 @@ boolean TryRunTics(tic_t realtics)
}
#endif
if (neededtic > gametic)
ticking = neededtic > gametic;
if (ticking)
{
hu_stopped = false;
if (realtics)
hu_stopped = false;
}
if (player_joining)
{
hu_stopped = true;
if (realtics)
hu_stopped = true;
return false;
}
ticking = neededtic > gametic;
if (ticking)
{
// run the count * tics
@@ -6654,62 +6503,17 @@ static tic_t gametime = 0;
static void UpdatePingTable(void)
{
tic_t fastest;
tic_t lag;
INT32 i;
if (server)
{
if (Playing() && !(gametime % 8)) // Value chosen based on _my vibes man_
if (netgame && !(gametime % 35)) // update once per second.
PingUpdate();
fastest = 0;
// update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && playernode[i] > 0 && playernode[i] != UINT8_MAX)
{
if (playeringame[i] && playernode[i] != UINT8_MAX)
realpingtable[i] += GetLag(playernode[i]);
if (!server_lagless && !players[i].spectator)
{
lag = playerpingtable[i];
if (! fastest || lag < fastest)
fastest = lag;
}
}
}
if (server_lagless)
lowest_lag = 0;
else
lowest_lag = fastest;
// Don't gentleman below your mindelay
if (lowest_lag < (tic_t)cv_mindelay.value)
lowest_lag = (tic_t)cv_mindelay.value;
simulated_lag = lowest_lag;
pingmeasurecount++;
}
else // We're a client, handle mindelay on the way out.
{
// Previously (neededtic - gametic) - WRONG VALUE!
// Pretty sure that's measuring jitter, not RTT.
// Stable connections would be punished by adding their mindelay to network delay!
tic_t mydelay = playerpingtable[consoleplayer];
if (mydelay < (tic_t)cv_mindelay.value)
{
lowest_lag = ((tic_t)cv_mindelay.value - mydelay);
simulated_lag = (tic_t)cv_mindelay.value;
}
else
lowest_lag = simulated_lag = 0;
}
}
#ifdef HOLEPUNCH
@@ -6804,6 +6608,14 @@ void NetUpdate(void)
if (realtics <= 0) // nothing new to update
return;
if (realtics > 5)
{
if (server)
realtics = 1;
else
realtics = 5;
}
#ifdef DEDICATEDIDLETIME
if (server && dedicated && gamestate == GS_LEVEL)
{
@@ -6852,14 +6664,6 @@ void NetUpdate(void)
}
#endif
if (realtics > 5)
{
if (server)
realtics = 1;
else
realtics = 5;
}
gametime = nowtime;
UpdatePingTable();
@@ -6953,6 +6757,8 @@ void NetUpdate(void)
Net_AckTicker();
HandleNodeTimeouts();
nowtime /= NEWTICRATERATIO;
if (nowtime > resptime)
{
resptime = nowtime;
+1 -14
View File
@@ -41,15 +41,6 @@ applications may follow different packet versions.
#define BACKUPTICS 32
#define TICQUEUE 512 // more than enough for most timeouts....
#define MAXTEXTCMD 256
// No. of tics your controls can be delayed by.
// TODO: Instead of storing a ton of extra cmds for gentlemens' delay,
// keep them in a linked-list, with timestamps to discard everything that's older than already sent.
// That will support any amount of lag, and be less wasteful for clients who don't use it.
// This just works as a quick implementation.
#define MAXGENTLEMENDELAY TICRATE
//
// Packet structure
//
@@ -585,11 +576,6 @@ extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
extern boolean server_lagless;
extern tic_t simulated_lag;
extern tic_t lowest_lag;
extern consvar_t cv_mindelay, cv_lagless;
extern consvar_t
#ifdef VANILLAJOINNEXTROUND
cv_joinnextround,
@@ -661,6 +647,7 @@ extern UINT8 playernode[MAXPLAYERS];
INT32 D_NumPlayers(void);
void D_ResetTiccmds(void);
ticcmd_t *D_LocalTiccmd(UINT8 ss);
tic_t GetLag(INT32 node);
//UINT8 GetFreeXCmdSize(UINT8 playerid);
+1
View File
@@ -25,6 +25,7 @@ typedef enum
ev_console,
ev_mouse,
ev_joystick,
ev_mouse2,
ev_joystick2,
ev_joystick3,
ev_joystick4,
+94 -107
View File
@@ -85,6 +85,10 @@
#include "hardware/hw_main.h" // 3D View Rendering
#endif
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
#endif
#ifdef HAVE_DISCORDRPC
#include "discord.h"
#endif
@@ -133,7 +137,6 @@ char srb2home[256] = ".";
char srb2path[256] = ".";
boolean usehome = true;
const char *pandf = "%s" PATHSEP "%s";
static char addonsdir[MAX_WADPATH];
//
// EVENT HANDLING
@@ -166,65 +169,20 @@ UINT8 ctrldown = 0; // 0x1 left, 0x2 right
UINT8 altdown = 0; // 0x1 left, 0x2 right
boolean capslock = 0; // gee i wonder what this does.
static void D_PadMenuScrollInput(int input)
{
event_t myev = {0, 0, 0, 0};
myev.type = ev_keydown;
myev.data1 = input;
D_PostEvent(&myev); // put into eventlist
}
#define SCROLLDELAY 19 // TICRATE * ( (k+2) (1 - [wz + h + j - q]^2 - [(gk + 2g + k + 1)(h + j) + h - z]^2 - [16(k + 1)^3(k + 2)(n + 1)^2 + 1 - f^2]^2 calculated by my butt
// this is absolutely awful and i hate it lmao
// but le hAx0r to make dpad also be able to scroll in the menu
static void D_GamePadMenuScrollTicker(void)
{
static SINT8 menuInputDelayTimer = 0;
int key = 0; // butt-on output
if (dedicated)
return;
// wish i had a switch ono
if (DPADUPSCROLL)
key = KEY_UPARROW;
else if (DPADDOWNSCROLL)
key = KEY_DOWNARROW;
else if (DPADLEFTSCROLL)
key = KEY_LEFTARROW;
else if (DPADRIGHTSCROLL)
key = KEY_RIGHTARROW;
if (key)
{
if (menuInputDelayTimer < SCROLLDELAY)
menuInputDelayTimer++;
if (menuInputDelayTimer == SCROLLDELAY)
D_PadMenuScrollInput(key);
}
else
{
menuInputDelayTimer = 0;
}
}
#undef SCROLLDELAY
static void D_DeviceLEDTick(void)
static inline void D_DeviceLEDTick(void)
{
UINT8 i;
static UINT16 color[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0};
static UINT16 curcolor[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0};
UINT16 color[MAXSPLITSCREENPLAYERS];
UINT16 curcolor[MAXSPLITSCREENPLAYERS];
if (dedicated || numcontrollers == 0)
if (I_NumJoys() == 0 || (cv_gamepadled[0].value == 0 && cv_gamepadled[1].value == 0 && cv_gamepadled[2].value == 0 && cv_gamepadled[3].value == 0))
{
return;
}
for (i = 0; i <= splitscreen; i++)
{
if (!cv_usejoystick[i].value || !cv_gamepadled[i].value)
if (cv_usejoystick[i].value == 0)
continue;
color[i] = G_GetSkinColor(i);
@@ -335,7 +293,7 @@ static boolean D_Display(void)
if (rendermode == render_soft && !splitscreen)
{
R_InterpolateViewRollAngle(rendertimefrac_unpaused);
R_InterpolateViewRollAngle(rendertimefrac);
R_CheckViewMorph();
}
@@ -353,7 +311,6 @@ static boolean D_Display(void)
// save the current screen if about to wipe
wipe = (gamestate != wipegamestate);
if (wipe)
{
// set for all later
@@ -487,11 +444,11 @@ static boolean D_Display(void)
{
PS_START_TIMING(ps_rendercalltime);
R_ApplyLevelInterpolators(rendertimefrac);
R_ApplyLevelInterpolators(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
for (i = 0; i <= splitscreen; i++)
{
if (!P_MobjWasRemoved(players[displayplayers[i]].mo) || players[displayplayers[i]].playerstate == PST_DEAD)
if (players[displayplayers[i]].mo || players[displayplayers[i]].playerstate == PST_DEAD)
{
viewssnum = i;
@@ -506,7 +463,7 @@ static boolean D_Display(void)
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_RenderPlayerView();
HWR_RenderPlayerView(i, &players[displayplayers[i]]);
else
#endif
if (rendermode != render_none)
@@ -560,7 +517,7 @@ static boolean D_Display(void)
for (i = 0; i <= splitscreen; i++)
{
V_DoPostProcessor(i, postimgparam[i]);
V_DoPostProcessor(i, &players[displayplayers[i]], postimgparam[i]);
}
}
@@ -581,6 +538,8 @@ static boolean D_Display(void)
PS_START_TIMING(ps_uitime);
ST_Drawer();
HU_Drawer();
NetUpdate(); // TEST: run this EVERY frame
}
else
{
@@ -693,6 +652,7 @@ static boolean D_Display(void)
// =========================================================================
tic_t rendergametic;
static SINT8 menuInputDelayTimer = 0;
void D_SRB2Loop(void)
{
@@ -741,9 +701,11 @@ void D_SRB2Loop(void)
precise_t enterprecise = I_GetPreciseTime();
precise_t finishprecise = enterprecise;
// Casting the return value of a function is bad practice (apparently)
double budget = ((R_GetFramerateCap() == 0) ? 0.0 : round((1.0 / R_GetFramerateCap()) * I_GetPrecisePrecision()));
capbudget = (precise_t) budget;
{
// Casting the return value of a function is bad practice (apparently)
double budget = round((1.0 / R_GetFramerateCap()) * I_GetPrecisePrecision());
capbudget = (precise_t) budget;
}
boolean ranwipe = false;
@@ -772,15 +734,19 @@ void D_SRB2Loop(void)
debugload--;
#endif
interp = (R_UsingFrameInterpolation() && !dedicated);
interp = R_UsingFrameInterpolation() && !dedicated;
doDisplay = false;
#ifdef HW3SOUND
HW3S_BeginFrameUpdate();
#endif
renderisnewtic = (realtics > 0 || singletics);
refreshdirmenu = 0; // not sure where to put this, here as good as any?
if (renderisnewtic)
{
refreshdirmenu = 0; // not sure where to put this, here as good as any?
// don't skip more than 10 frames at a time
// (fadein / fadeout cause massive frame skip!)
if (realtics > 8)
@@ -789,7 +755,7 @@ void D_SRB2Loop(void)
// process tics (but maybe not if realtic == 0)
TryRunTics(realtics);
if (lastdraw || singletics || (gametic > rendergametic))
if (lastdraw || singletics || gametic > rendergametic)
{
rendergametic = gametic;
rendertimeout = entertic + TICRATE/17;
@@ -803,7 +769,7 @@ void D_SRB2Loop(void)
{
// Evaluate the chase cam once for every local realtic
// This might actually be better suited inside G_Ticker or TryRunTics
for (tic_t chasecamtics = 0; (chasecamtics < realtics); chasecamtics++)
for (tic_t chasecamtics = 0; chasecamtics < realtics; chasecamtics++)
{
P_RunChaseCameras();
}
@@ -813,10 +779,35 @@ void D_SRB2Loop(void)
doDisplay = true;
}
if (menuactive)
#define DPADSCROLLINPUT(INPUT)\
{\
myev.data1 = INPUT;\
M_Responder(&myev);\
}
// this is absolutely awful and i hate it lmao
if (menuactive && (DPADUPSCROLL || DPADDOWNSCROLL || DPADLEFTSCROLL || DPADRIGHTSCROLL))
{
D_GamePadMenuScrollTicker();
event_t myev;
myev.type = ev_keydown;
if (menuInputDelayTimer < 19)
menuInputDelayTimer++;
if (menuInputDelayTimer == 19) // TICRATE * ( (k+2) (1 - [wz + h + j - q]^2 - [(gk + 2g + k + 1)(h + j) + h - z]^2 - [16(k + 1)^3(k + 2)(n + 1)^2 + 1 - f^2]^2 calculated by my butt
{
if (DPADUPSCROLL)
DPADSCROLLINPUT(KEY_UPARROW)
else if (DPADDOWNSCROLL)
DPADSCROLLINPUT(KEY_DOWNARROW)
else if (DPADLEFTSCROLL)
DPADSCROLLINPUT(KEY_LEFTARROW)
else if (DPADRIGHTSCROLL)
DPADSCROLLINPUT(KEY_RIGHTARROW)
}
}
else
menuInputDelayTimer = 0;
#undef DPADSCROLLINPUT
D_DeviceLEDTick();
}
@@ -825,7 +816,7 @@ void D_SRB2Loop(void)
{
renderdeltatics = FLOAT_TO_FIXED(deltatics);
if (!(paused || P_AutoPause()) && deltatics < 1.0 && !hu_stopped)
if (!(paused || P_AutoPause()) && !hu_stopped)
{
rendertimefrac = g_time.timefrac;
}
@@ -834,7 +825,7 @@ void D_SRB2Loop(void)
rendertimefrac = FRACUNIT;
}
if ((deltatics < 1.0) && !hu_stopped)
if (!hu_stopped)
{
rendertimefrac_unpaused = g_time.timefrac;
}
@@ -864,6 +855,10 @@ void D_SRB2Loop(void)
// consoleplayer -> displayplayers (hear sounds from viewpoint)
S_UpdateSounds(); // move positional sounds
#ifdef HW3SOUND
HW3S_EndFrameUpdate();
#endif
LUA_Step();
#ifdef HAVE_DISCORDRPC
@@ -889,7 +884,7 @@ void D_SRB2Loop(void)
//
// Wipes run an inner loop and artificially increase
// the measured time.
if (!ranwipe && (frameskip < 3) && (deltatics > 1.0))
if (!ranwipe && frameskip < 3 && deltatics > 1.0)
{
frameskip++;
}
@@ -905,7 +900,7 @@ void D_SRB2Loop(void)
// in the case of "match refresh rate" + vsync, don't sleep at all
const boolean vsync_with_match_refresh = cv_vidwait.value && cv_fpscap.value == 0;
if ((elapsed > 0) && ((INT64)capbudget > elapsed) && !vsync_with_match_refresh)
if (elapsed > 0 && (INT64)capbudget > elapsed && !vsync_with_match_refresh)
{
I_SleepDuration(capbudget - (finishprecise - enterprecise));
}
@@ -972,6 +967,7 @@ void D_StartTitle(void)
gameaction = ga_nothing;
memset(displayplayers, 0, sizeof(displayplayers));
memset(g_localplayers, 0, sizeof g_localplayers);
consoleplayer = 0;
//demosequence = -1;
gametype = GT_RACE; // SRB2kart
@@ -980,6 +976,10 @@ void D_StartTitle(void)
S_ResetKeepAndSpecialMus(); // just in case
F_StartTitleScreen();
// Reset the palette -- SRB2Kart: actually never mind let's do this in the middle of every fade
/*if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL");*/
}
//
@@ -1197,22 +1197,19 @@ boolean found_extra_kart;
boolean found_extra2_kart;
boolean found_extra3_kart;
boolean xtra_speedo; // extra speedometer check
boolean xtra_speedo_clr; // extra speedometer colour check
boolean xtra_speedo3; // 80x 11 extra speedometer check
boolean xtra_speedo_clr3; // 80x 11 extra speedometer colour check
boolean achi_speedo; // achiiro speedometer check
boolean achi_speedo_clr; // extra speedometer colour check
boolean kartz_speedo; // kartZ speedo
boolean clr_hud; // colour hud check
boolean big_lap; // bigger lap counter
boolean big_lap_color; // bigger lap counter but colour
boolean statdp; // stat display for extended player setup
boolean nametaggfx; // Nametag stuffs
boolean driftgaugegfx; // Driftgauge stuffs
boolean multiitem_icon; // Extra icons for Sneakers, Banana and Jawz
//
boolean xtra_speedo; // extra speedometer check
boolean xtra_speedo_clr; // extra speedometer colour check
boolean xtra_speedo3; // 80x 11 extra speedometer check
boolean xtra_speedo_clr3; // 80x 11 extra speedometer colour check
boolean achi_speedo; // achiiro speedometer check
boolean achi_speedo_clr; // extra speedometer colour check
boolean clr_hud; // colour hud check
boolean big_lap; // bigger lap counter
boolean big_lap_color; // bigger lap counter but colour
boolean kartzspeedo; // kartZ speedo
boolean statdp; // stat display for extended player setup
boolean nametaggfx; // Nametag stuffs
boolean driftgaugegfx;
static void IdentifyVersion(void)
{
@@ -1438,6 +1435,8 @@ void D_SRB2Main(void)
// can't use sprintf since there is %u in savegamename
strcatbf(savegamename, srb2home, PATHSEP);
I_mkdir(srb2home, 0700);
#else
snprintf(srb2home, sizeof srb2home, "%s", userhome);
snprintf(downloaddir, sizeof downloaddir, "%s", userhome);
@@ -1474,10 +1473,6 @@ void D_SRB2Main(void)
}
}
// Create addons dir
snprintf(addonsdir, sizeof addonsdir, "%s%s%s", srb2home, PATHSEP, "addons");
I_mkdir(addonsdir, 0755);
D_SetupProtocol();
// rand() needs seeded regardless of password
@@ -1576,10 +1571,8 @@ void D_SRB2Main(void)
// Possible value that changes depending on whether required files for speedometer are found or not
CV_PossibleValue_t speedo_cons_temp[NUMSPEEDOSTUFF] = {{1, "Default"}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}};
CV_PossibleValue_t driftgaugestyle_cons_temp[NUMSPEEDOSTUFF] = {{1, "Default"}, {2, "Small"}, {3, "Big Numbers"}, {4, "Numbers Only"}, {0, NULL}, {0, NULL}}; // ugh i dont want this but bleh
unsigned last_speedo_i = 0;
unsigned last_driftgauge_i = 0;
#define PUSHCONS(cons, i, id, name) { ++i; cons[i].value = id; cons[i].strvalue = name; }
#define PUSHSPEEDO(id, name) { ++last_speedo_i; speedo_cons_temp[last_speedo_i].value = id; speedo_cons_temp[last_speedo_i].strvalue = name; }
if (found_extra_kart || found_extra2_kart || found_extra3_kart) // found the funny, add it in!
{
@@ -1595,7 +1588,7 @@ void D_SRB2Main(void)
if (W_CheckMultipleLumps("SP_SMSTC", "K_TRNULL", "SP_MKMH", "SP_MMPH", "SP_MFRAC", "SP_MPERC", NULL))
{
xtra_speedo = true;
PUSHCONS(speedo_cons_temp, last_speedo_i, 2, "Small");
PUSHSPEEDO(2, "Small");
}
if (W_LumpExists("SC_SMSTC"))
@@ -1605,7 +1598,7 @@ void D_SRB2Main(void)
if (W_CheckMultipleLumps("SP_AMSTC", "K_TRNULL", "SP_AKMH", "SP_AMPH", "SP_AFRAC", "SP_APERC", NULL))
{
achi_speedo = true;
PUSHCONS(speedo_cons_temp, last_speedo_i, 3, "Achii");
PUSHSPEEDO(3, "Achii");
}
if (W_CheckMultipleLumps("SC_AMSTC", "K_TRNULL", "SC_AKMH", "SC_AMPH", "SC_AFRAC", "SC_APERC", NULL))
@@ -1630,8 +1623,8 @@ void D_SRB2Main(void)
"K_KZSP13", "K_KZSP14", "K_KZSP15", "K_KZSP16", "K_KZSP17", "K_KZSP18", "K_KZSP19", \
"K_KZSP20", "K_KZSP21", "K_KZSP22", "K_KZSP23", "K_KZSP24", "K_KZSP25", NULL))
{
kartz_speedo = true;
PUSHCONS(speedo_cons_temp, last_speedo_i, 4, "P-Meter");
kartzspeedo = true;
PUSHSPEEDO(4, "P-Meter");
}
// stat display for extended player setup
@@ -1646,18 +1639,13 @@ void D_SRB2Main(void)
if (W_CheckMultipleLumps("K_DGAU","K_DCAU","K_DGSU","K_DCSU", NULL))
driftgaugegfx = true;
// extra item icons
if (W_CheckMultipleLumps("K_ITSHO2", "K_ITSHO3", "K_ITBAN2", "K_ITBAN3", "K_ITBAN4", "K_ITJAW2", NULL))
multiitem_icon = true;
if (found_extra3_kart)
{
// 80x11 speedometer crap
if (W_LumpExists("SP_SM3TC"))
{
xtra_speedo3 = true;
PUSHCONS(speedo_cons_temp, last_speedo_i, 5, "Extra");
PUSHCONS(driftgaugestyle_cons_temp, last_driftgauge_i, 5, "Extra");
PUSHSPEEDO(5, "Extra");
}
if (W_LumpExists("SC_SM3TC"))
@@ -1665,9 +1653,8 @@ void D_SRB2Main(void)
}
}
#undef PUSHCONS
#undef PUSHSPEEDO
memcpy(speedo_cons_t, speedo_cons_temp, sizeof(speedo_cons_t));
memcpy(driftgaugestyle_cons_t, driftgaugestyle_cons_temp, sizeof(driftgaugestyle_cons_t));
// Do it before P_InitMapData because PNG patch
// conversion sometimes needs the palette
@@ -2077,7 +2064,7 @@ void D_SRB2Main(void)
}
#ifdef HAVE_DISCORDRPC
if (!dedicated)
if (! dedicated)
{
DRPC_Init();
}
+13 -17
View File
@@ -27,27 +27,23 @@ extern boolean usehome; //Alam: which path?
extern const char *pandf; //Alam: how to path?
extern char srb2path[256]; //Alam: SRB2's Home
// extra graphic patches for saturn specific thingies
extern boolean found_extra_kart; // for use in k_kart.c
extern boolean found_extra2_kart; // for use in k_kart.c
extern boolean found_extra3_kart; // for use in k_kart.c
extern boolean xtra_speedo; // extra speedometer check
extern boolean xtra_speedo_clr; // extra speedometer colour check
extern boolean xtra_speedo3; // 80x11 extra speedometer check
extern boolean xtra_speedo_clr3; // 80x11 extra speedometer colour check
extern boolean achi_speedo; // achiiro speedometer check
extern boolean achi_speedo_clr; // extra speedometer colour check
extern boolean kartz_speedo; // kartZ speedo
extern boolean clr_hud; // colour hud check
extern boolean big_lap; // bigger lap counter
extern boolean big_lap_color; // bigger lap counter but colour
extern boolean statdp; // stat display for extended player setup
extern boolean nametaggfx; // Nametag stuffs
extern boolean driftgaugegfx; // Driftgauge stuffs
extern boolean multiitem_icon; // Extra icons for Sneakers, Banana and Jawz
//
extern boolean xtra_speedo; // extra speedometer check
extern boolean xtra_speedo_clr; // extra speedometer colour check
extern boolean xtra_speedo3; // 80x11 extra speedometer check
extern boolean xtra_speedo_clr3; // 80x11 extra speedometer colour check
extern boolean achi_speedo; // achiiro speedometer check
extern boolean achi_speedo_clr; // extra speedometer colour check
extern boolean clr_hud; // colour hud check
extern boolean big_lap; // bigger lap counter
extern boolean big_lap_color; // bigger lap counter but colour
extern boolean kartzspeedo; // kartZ speedo
extern boolean statdp; // stat display for extended player setup
extern boolean nametaggfx; // Nametag stuffs
extern boolean driftgaugegfx;
// autoload stuff
extern boolean autoloading;
+2 -3
View File
@@ -638,7 +638,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
static void InitNode(node_t *node)
{
node->acktosend_head = node->acktosend_tail = 0;
memset(node->acktosend, 0, sizeof(node->acktosend));
node->firstacktosend = 0;
node->nextacknum = 1;
node->remotefirstack = 0;
@@ -1340,9 +1339,9 @@ boolean D_CheckNetGame(void)
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES);
netbuffer = (doomdata_t *)(void *)&doomcom->data;
#ifdef HOLEPUNCH
#ifdef HOLEPUNCH
holepunchpacket = (holepunch_t *)(void *)&doomcom->data;
#endif
#endif
#ifdef DEBUGFILE
if (M_CheckParm("-debugfile"))
+127 -34
View File
@@ -209,6 +209,13 @@ void SendWeaponPref3(void);
void SendWeaponPref4(void);
static CV_PossibleValue_t usemouse_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Force"}, {0, NULL}};
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
static CV_PossibleValue_t mouse2port_cons_t[] = {{0, "/dev/gpmdata"}, {1, "/dev/ttyS0"},
{2, "/dev/ttyS1"}, {3, "/dev/ttyS2"}, {4, "/dev/ttyS3"}, {0, NULL}};
#else
static CV_PossibleValue_t mouse2port_cons_t[] = {{1, "COM1"}, {2, "COM2"}, {3, "COM3"}, {4, "COM4"},
{0, NULL}};
#endif
#ifdef LJOYSTICK
static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"}, {3, "/dev/js2"},
@@ -291,15 +298,13 @@ consvar_t cv_skipmapcheck = {"skipmapcheck", "Off", CV_SAVE, CV_OnOff, NULL, 0,
INT32 cv_debug;
consvar_t cv_usemouse = {"use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2, 0, NULL, NULL, 0, 0, NULL};
//WTF
consvar_t cv_mouseturn = {"mouseturn", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
// Lagless camera! Yay!
consvar_t cv_laglesscam = {"laglesscamera", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_verticallook = {"verticallook", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#if defined(HAVE_SDL) || defined(_WINDOWS) //joystick 1 and 2
consvar_t cv_usejoystick[MAXSPLITSCREENPLAYERS] = {
{"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick1, 0, NULL, NULL, 0, 0, NULL},
@@ -326,6 +331,12 @@ consvar_t cv_joyscale[2] = { //Alam: Dummy for save
{"joyscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}
};
#endif
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
consvar_t cv_mouse2port = {"mouse2port", "/dev/gpmdata", CV_SAVE, mouse2port_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mouse2opt = {"mouse2opt", "0", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
#else
consvar_t cv_mouse2port = {"mouse2port", "COM2", CV_SAVE, mouse2port_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
consvar_t cv_matchboxes = {"matchboxes", "Normal", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, matchboxes_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_specialrings = {"specialrings", "On", CV_NETVAR|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -393,18 +404,18 @@ static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"},
consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_karthitemdialog = {"karthitemdialog", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOSHOWHELP, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t kartdebugitem_cons_t[] = {{-1, "MIN"}, {NUMKARTITEMS-1, "MAX"}, {0, NULL}};
consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
consvar_t cv_kartdebugamount = {"kartdebugamount", "1", CV_NETVAR|CV_CHEAT, kartdebugamount_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugshrink = {"kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugdistribution = {"kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugamount = {"kartdebugamount", "1", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugamount_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugshrink = {"kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugdistribution = {"kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugnodes = {"kartdebugnodes", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugnodes = {"kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugcolorize = {"kartdebugcolorize", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t votetime_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, NULL}};
@@ -479,6 +490,12 @@ consvar_t cv_pingstyle = {"pingstyle", "New", CV_SAVE, cv_pingstyle_cons_t, 0, 0
consvar_t cv_luaimmersion = {"luaimmersion", "On", CV_SAVE, CV_OnOff, 0, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_minihead = {"smallminimapplayers", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showminimapnames = {"showminimapnames", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showlapemblem = {"showlapemblem", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showviewpointtext = {"showviewpointtext", "On", CV_SAVE, CV_OnOff, 0, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showdownloadprompt = {"showdownloadprompt", "On", CV_SAVE, CV_OnOff, 0, 0, NULL, NULL, 0, 0, NULL};
@@ -499,6 +516,45 @@ consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange,
consvar_t cv_sleep = {"cpusleep", "1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t nametagtrans_cons_t[] = {
{0, "Never"}, {1, "Far only"}, {2, "Dynamic"}, {3, "Always"}, {4, "HUD Trans."}, {0, NULL}};
/*static CV_PossibleValue_t nametagscaling_cons_t[] = {
{0, "MIN"}, {320, "MAX"}, {0, NULL}};*/
static CV_PossibleValue_t nametagdistance_cons_t[] = {
{0, "MIN"}, {640, "MAX"}, {0, NULL}};
static CV_PossibleValue_t nametagmaxplayer_cons_t[] = {
{1, "MIN"}, {MAXPLAYERS, "MAX"}, {0, NULL}};
static CV_PossibleValue_t nametagsize_cons_t[] = {
{0, "Off"}, {1, "Small"}, {2, "Minimal"}, {0, NULL}};
static CV_PossibleValue_t nametagrestat_cons_t[] = {
{0, "Off"}, {1, "Restat"}, {2, "Always"}, {0, NULL}};
consvar_t cv_nametag = {"kartnametag", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_nametagtrans = {"kartnametagtransparency", "Dynamic", CV_SAVE, nametagtrans_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_nametagfacerank = {"kartnametagfacerank", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_nametagrestat = {"kartnametagrestat", "Restat", CV_SAVE, nametagrestat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_nametagdist = {"kartnametagdist", "320", CV_SAVE, nametagdistance_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_nametagmaxplayers = {"kartnametagmaxplayers", "3", CV_SAVE, nametagmaxplayer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_nametagmaxlenght = {"kartnametagmaxlenght", "12", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_nametagscaling = {"nametagscaling", "160", CV_SAVE, nametagscaling_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showownnametag = {"kartnametagshowown", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_smallnametags = {"kartnametagsmall", "Off", CV_SAVE, nametagsize_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_nametaghop = {"kartnametaghop", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_nametagscore = {"kartnametagscore", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_shownametagfinish = {"kartshownametagfinished", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_shownametagspectator = {"kartshownametagspectator", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t driftgaugeoffset_cons_t[] = {
{-FRACUNIT*128, "MIN"}, {FRACUNIT*128, "MAX"}, {0, NULL}};
static CV_PossibleValue_t driftgaugestyle_cons_t[] = {
{1, "Default"}, {2, "Small"}, {3, "Big Numbers"}, {4, "Numbers Only"}, {0, NULL}};
consvar_t cv_driftgauge = {"kartdriftgauge", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_driftgaugeofs = {"kartdriftgaugeoffset", "-20", CV_FLOAT|CV_SAVE, driftgaugeoffset_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_driftgaugetrans = {"kartdriftgaugetransparency", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_driftgaugestyle = {"kartdriftgaugestyle", "1", CV_SAVE, driftgaugestyle_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t skinselectspin_cons_t[] = {
{0, "Off"}, {1, "Slow"}, {2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"}, {8, "8"}, {9, "9"}, {10, "Fast"}, {SKINSELECTSPIN_PAIN, "Pain"}, {0, NULL}};
consvar_t cv_skinselectspin = {"skinselectspin", "5", CV_SAVE, skinselectspin_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -516,8 +572,14 @@ static CV_PossibleValue_t ps_descriptor_cons_t[] = {
{1, "Average"}, {2, "SD"}, {3, "Minimum"}, {4, "Maximum"}, {0, NULL}};
consvar_t cv_ps_descriptor = {"ps_descriptor", "Average", 0, ps_descriptor_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// only there to better keep track of it globally
consvar_t cv_director = {"director", "Off", CV_HIDEN, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_director = {"director", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_director[MAXSPLITSCREENPLAYERS] = {
{"director", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"director2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"director3", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"director4", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}
};
consvar_t cv_kartdebugdirector = {"debugdirector", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showdirectorhud = {"showdirectorhud", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -858,8 +920,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_screenshot_option);
CV_RegisterVar(&cv_screenshot_folder);
CV_RegisterVar(&cv_moviemode);
CV_RegisterVar(&cv_movie_option);
CV_RegisterVar(&cv_movie_folder);
// PNG variables
CV_RegisterVar(&cv_zlib_level);
CV_RegisterVar(&cv_zlib_memory);
@@ -908,8 +968,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_rollingdemos);
CV_RegisterVar(&cv_netstat);
CV_RegisterVar(&cv_netticbuffer);
CV_RegisterVar(&cv_mindelay);
CV_RegisterVar(&cv_lagless);
#ifdef NETGAME_DEVMODE
CV_RegisterVar(&cv_fishcake);
@@ -955,7 +1013,11 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_showviewpointtext);
CV_RegisterVar(&cv_showdownloadprompt);
CV_RegisterVar(&cv_director);
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
CV_RegisterVar(&cv_director[i]);
}
CV_RegisterVar(&cv_kartdebugdirector);
CV_RegisterVar(&cv_showdirectorhud);
@@ -964,6 +1026,14 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_showlocalskinmenus);
//CV_RegisterVar(&cv_crosshair);
//CV_RegisterVar(&cv_crosshair2);
//CV_RegisterVar(&cv_crosshair3);
//CV_RegisterVar(&cv_crosshair4);
//CV_RegisterVar(&cv_alwaysfreelook);
//CV_RegisterVar(&cv_alwaysfreelook2);
//CV_RegisterVar(&cv_chasefreelook);
//CV_RegisterVar(&cv_chasefreelook2);
CV_RegisterVar(&cv_replaysearchrate);
CV_RegisterVar(&cv_showfocuslost);
CV_RegisterVar(&cv_pauseifunfocused);
@@ -973,8 +1043,6 @@ void D_RegisterClientCommands(void)
{
CV_RegisterVar(&cv_turnaxis[i]);
CV_RegisterVar(&cv_moveaxis[i]);
CV_RegisterVar(&cv_camturnaxis[i]);
CV_RegisterVar(&cv_camstrafeaxis[i]);
CV_RegisterVar(&cv_brakeaxis[i]);
CV_RegisterVar(&cv_aimaxis[i]);
CV_RegisterVar(&cv_lookaxis[i]);
@@ -996,6 +1064,12 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_addons_search_type);
CV_RegisterVar(&cv_addons_search_case);
// WARNING: the order is important when initialising mouse2
// we need the mouse2port
CV_RegisterVar(&cv_mouse2port);
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
CV_RegisterVar(&cv_mouse2opt);
#endif
CV_RegisterVar(&cv_controlperkey);
CV_RegisterVar(&cv_turnsmooth);
@@ -1007,10 +1081,15 @@ void D_RegisterClientCommands(void)
}
CV_RegisterVar(&cv_usemouse);
CV_RegisterVar(&cv_usemouse2);
CV_RegisterVar(&cv_invertmouse);
CV_RegisterVar(&cv_invertmouse2);
CV_RegisterVar(&cv_mousesens);
CV_RegisterVar(&cv_mousesens2);
CV_RegisterVar(&cv_mouseysens);
CV_RegisterVar(&cv_mouseysens2);
//CV_RegisterVar(&cv_mousemove);
//CV_RegisterVar(&cv_mousemove2);
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
@@ -1054,6 +1133,26 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_soundtest);
CV_RegisterVar(&cv_nametag);
CV_RegisterVar(&cv_nametagtrans);
CV_RegisterVar(&cv_nametagfacerank);
CV_RegisterVar(&cv_nametagmaxplayers);
CV_RegisterVar(&cv_nametagmaxlenght);
//CV_RegisterVar(&cv_nametagscaling);
CV_RegisterVar(&cv_nametagdist);
CV_RegisterVar(&cv_showownnametag);
CV_RegisterVar(&cv_smallnametags);
CV_RegisterVar(&cv_nametagrestat);
CV_RegisterVar(&cv_nametaghop);
CV_RegisterVar(&cv_nametagscore);
CV_RegisterVar(&cv_shownametagfinish);
CV_RegisterVar(&cv_shownametagspectator);
CV_RegisterVar(&cv_driftgauge);
CV_RegisterVar(&cv_driftgaugeofs);
CV_RegisterVar(&cv_driftgaugetrans);
CV_RegisterVar(&cv_driftgaugestyle);
CV_RegisterVar(&cv_perfstats);
CV_RegisterVar(&cv_ps_thinkframe_page);
CV_RegisterVar(&cv_ps_samplesize);
@@ -1068,8 +1167,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_laglesscam);
CV_RegisterVar(&cv_verticallook);
// ingame object placing
COM_AddCommand("objectplace", Command_ObjectPlace_f);
COM_AddCommand("writethings", Command_Writethings_f);
@@ -2345,13 +2442,10 @@ static void Command_Playdemo_f(void)
if (!demo.playback && gamestate == GS_LEVEL) // special case: allow starting another demo while watching a demo
{
CONS_Printf(M_GetText("You can't play a demo while in a game.\n"));
CONS_Printf(M_GetText("You can't time a demo while in a game.\n"));
return;
}
// turn off any open menus
M_ClearMenus(true);
// disconnect from server here?
if (demo.playback)
G_StopDemo();
@@ -2397,9 +2491,6 @@ static void Command_Timedemo_f(void)
return;
}
// turn off any open menus
M_ClearMenus(true);
// disconnect from server here?
if (demo.playback)
G_StopDemo();
@@ -2434,6 +2525,8 @@ static void Command_StopMovie_f(void)
INT32 mapchangepending = 0;
tic_t driftsparkGrowTimer[MAXPLAYERS];
/** Runs a map change.
* The supplied data are assumed to be good. If provided by a user, they will
* have already been checked in Command_Map_f().
@@ -2467,6 +2560,9 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d encoremode=%d resetplayers=%d delay=%d skipprecutscene=%d\n",
mapnum, newgametype, pencoremode, resetplayers, delay, skipprecutscene);
// just gonna hack in a timer reset here...
memset(driftsparkGrowTimer, 0, sizeof(driftsparkGrowTimer));
if (netgame || multiplayer)
FLS = false;
@@ -2676,8 +2772,6 @@ static void Command_Map_f(void)
return;
}
M_ClearMenus(true);
last_map_cmd = I_GetTime();
size_t first_option;
@@ -2870,7 +2964,6 @@ static void Command_Map_f(void)
}
fromlevelselect = false;
D_MapChange(newmapnum, newgametype, newencoremode, newresetplayers, 0, false, false);
Z_Free(realmapname);
@@ -3154,7 +3247,7 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum)
return;
if (players[respawnplayer].mo)
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, DMG_INSTAKILL);
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 10000);
demo_extradata[playernum] |= DXD_RESPAWN;
}
@@ -3856,7 +3949,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
if (!players[playernum].spectator)
{
if (players[playernum].mo)
P_DamageMobj(players[playernum].mo, NULL, NULL, DMG_INSTAKILL);
P_DamageMobj(players[playernum].mo, NULL, NULL, 10000);
else
players[playernum].playerstate = PST_REBORN;
}
+13 -3
View File
@@ -50,6 +50,13 @@ extern consvar_t cv_joyport2;
#endif
extern consvar_t cv_joyscale[4]; //MAXSPLITSCREENPLAYERS
// splitscreen with second mouse
extern consvar_t cv_mouse2port;
extern consvar_t cv_usemouse2;
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
extern consvar_t cv_mouse2opt;
#endif
// normally in p_mobj but the .h is not read
extern consvar_t cv_itemrespawntime;
extern consvar_t cv_itemrespawn;
@@ -172,7 +179,9 @@ extern consvar_t cv_nametagdist;
extern consvar_t cv_showownnametag;
extern consvar_t cv_smallnametags;
extern consvar_t cv_nametagrestat;
extern consvar_t cv_nametaghop;
extern consvar_t cv_nametagscore;
extern consvar_t cv_shownametagfinish;
extern consvar_t cv_shownametagspectator;
#define SKINSELECTSPIN_PAIN 25
@@ -188,7 +197,8 @@ extern consvar_t cv_ps_thinkframe_page;
extern consvar_t cv_ps_samplesize;
extern consvar_t cv_ps_descriptor;
extern consvar_t cv_director, cv_kartdebugdirector, cv_showdirectorhud;
extern consvar_t cv_director[4]; // screw you includes
extern consvar_t cv_kartdebugdirector, cv_showdirectorhud;
extern consvar_t cv_showtrackaddon;
@@ -198,8 +208,6 @@ extern consvar_t cv_betainterscreen;
extern consvar_t cv_laglesscam;
extern consvar_t cv_verticallook;
typedef enum
{
SKINMENUTYPE_SCROLL = 0,
@@ -297,6 +305,8 @@ typedef union {
#pragma pack()
#endif
extern tic_t driftsparkGrowTimer[16];
// add game commands, needs cleanup
void D_RegisterServerCommands(void);
void D_RegisterClientCommands(void);
-11
View File
@@ -111,7 +111,6 @@ static fileused_t transferFiles[UINT8_MAX + 1];
// Receiver structure
INT32 fileneedednum; // Number of files needed to join the server
fileneeded_t fileneeded[MAX_WADFILES]; // List of needed files
static I_mutex downloadmutex;
char downloaddir[512] = "DOWNLOAD";
#ifdef CLIENT_LOADINGSCREEN
@@ -233,9 +232,6 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
void CL_PrepareDownloadSaveGame(const char *tmpsave)
{
#ifdef CLIENT_LOADINGSCREEN
lastfilenum = -1;
#endif
fileneedednum = 1;
fileneeded[0].status = FS_REQUESTED;
fileneeded[0].totalsize = UINT32_MAX;
@@ -1331,7 +1327,6 @@ void CURLPrepareFile(const char* url, int dfilenum)
curl_starttime = time(NULL);
curl_running = true;
#ifdef HAVE_THREADS
I_spawn_thread("http-download", (I_thread_fn)CURLGetFile, NULL);
#endif
@@ -1341,15 +1336,10 @@ void CURLPrepareFile(const char* url, int dfilenum)
void CURLAbortFile(void)
{
curl_running = false;
// lock and unlock to wait for the download thread to exit
I_lock_mutex(&downloadmutex);
I_unlock_mutex(downloadmutex);
}
void CURLGetFile(void)
{
I_lock_mutex(&downloadmutex);
CURLMcode mc; /* return code used by curl_multi_wait() */
CURLcode easyres; /* Return from easy interface */
CURLMsg *m; /* for picking up messages with the transfer status */
@@ -1442,7 +1432,6 @@ void CURLGetFile(void)
multi_handle = NULL;
}
curl_running = false;
I_unlock_mutex(downloadmutex);
}
HTTP_login *
+4 -6
View File
@@ -351,7 +351,6 @@ typedef enum
typedef enum
{
LAP_CUR,
LAP_BEST,
LAP_LAST,
LAP__MAX
} laptime_e;
@@ -413,6 +412,8 @@ typedef struct player_s
// See pflags_t, above.
pflags_t pflags;
UINT16 postimgflags;
// playing animation.
panim_t panim;
@@ -550,12 +551,9 @@ typedef struct player_s
UINT8 hitemvictim;
UINT8 splitscreenindex;
tic_t driftsparkGrowTimer;
fixed_t spinoutrot; // When a player spins out, this value increments modulus 360.
#ifdef HWRENDER
fixed_t fovadd; // adjust FOV for hw rendering
#endif
} player_t;
#endif
+3 -82
View File
@@ -690,20 +690,6 @@ static const struct {
{NULL, 0}
};
static mapheader_lighting_t *usemaplighting(INT32 mapnum, const char *word)
{
if (fastncmp(word, "ENCORE", 6))
{
mapheaderinfo[mapnum]->use_encore_lighting = true;
return &mapheaderinfo[mapnum]->lighting_encore;
}
else
{
return &mapheaderinfo[mapnum]->lighting;
}
}
static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
@@ -997,35 +983,6 @@ static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
}*/
else if (fastcmp(word, "MOBJSCALE"))
mapheaderinfo[num-1]->mobj_scale = get_number(word2);
else if (fastcmp(word, "LIGHTCONTRAST") || fastcmp(word, "ENCORELIGHTCONTRAST"))
{
mapheader_lighting_t *lighting = usemaplighting(num-1, word);
lighting->light_contrast = (UINT8)i;
lighting->use_custom_light = true;
}
else if (fastcmp(word, "SPRITEBACKLIGHT") || fastcmp(word, "ENCORESPRITEBACKLIGHT"))
{
mapheader_lighting_t *lighting = usemaplighting(num-1, word);
lighting->sprite_backlight = (SINT8)i;
lighting->use_custom_light = true;
}
else if (fastcmp(word, "LIGHTANGLE") || fastcmp(word, "ENCORELIGHTANGLE"))
{
mapheader_lighting_t *lighting = usemaplighting(num-1, word);
if (fastcmp(word2, "EVEN"))
{
lighting->use_light_angle = false;
lighting->light_angle = 0;
}
else
{
lighting->use_light_angle = true;
lighting->light_angle = FixedAngle(FloatToFixed(atof(word2)));
}
lighting->use_custom_light = true;
}
// Individual triggers for level flags, for ease of use (and 2.0 compatibility)
else if (fastcmp(word, "SCRIPTISFILE"))
@@ -7761,18 +7718,7 @@ struct {
{"FF_HORIZONTALFLIP",FF_HORIZONTALFLIP},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_ANIMATE",FF_ANIMATE},
// brightness
{"FF_BRIGHTMASK",FF_BRIGHTMASK},
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_SEMIBRIGHT",FF_SEMIBRIGHT},
{"FF_FULLDARK",FF_FULLDARK},
// blending
{"FF_BLENDMASK",FF_BLENDMASK},
{"FF_BLENDSHIFT",FF_BRIGHTMASK},
{"FF_ADD",FF_ADD},
{"FF_SUBTRACT",FF_SUBTRACT},
{"FF_REVERSESUBTRACT",FF_REVERSESUBTRACT},
{"FF_MODULATE",FF_MODULATE},
{"FF_TRANSMASK",FF_TRANSMASK},
{"FF_TRANSSHIFT",FF_TRANSSHIFT},
// new preshifted translucency (used in source)
@@ -7808,15 +7754,6 @@ struct {
{"tr_trans90",tr_trans90},
{"NUMTRANSMAPS",NUMTRANSMAPS},
// Alpha styles (blend modes)
{"AST_COPY",AST_COPY},
{"AST_TRANSLUCENT",AST_TRANSLUCENT},
{"AST_ADD",AST_ADD},
{"AST_SUBTRACT",AST_SUBTRACT},
{"AST_REVERSESUBTRACT",AST_REVERSESUBTRACT},
{"AST_MODULATE",AST_MODULATE},
{"AST_OVERLAY",AST_OVERLAY},
// Type of levels
{"TOL_SP",TOL_SP},
{"TOL_COOP",TOL_COOP},
@@ -8181,14 +8118,6 @@ struct {
{"V_CHARCOLORSHIFT",V_CHARCOLORSHIFT},
{"V_ALPHASHIFT",V_ALPHASHIFT},
// Blending
{"V_BLENDSHIFT",V_BLENDSHIFT},
{"V_BLENDMASK",V_BLENDMASK},
{"B_ADD",B_ADD},
{"B_SUBTRACT",B_SUBTRACT},
{"B_REVERSESUBTRACT",B_REVERSESUBTRACT},
{"B_MODULATE",B_MODULATE},
//Kick Reasons
{"KR_KICK",KR_KICK},
{"KR_PINGLIMIT",KR_PINGLIMIT},
@@ -9227,6 +9156,8 @@ int LUA_EnumLib(lua_State *L)
PUSHGETTER(globalweather, u8);
PUSHGETTER(levelskynum, i32);
PUSHGETTER(globallevelskynum, i32);
PUSHGETTER(mapmusflags, u16);
PUSHGETTER(mapmusposition, u32);
PUSHGETTER(gravity, fxp);
PUSHGETTER(gamespeed, u8);
PUSHGETTER(encoremode, bool);
@@ -9241,19 +9172,9 @@ int LUA_EnumLib(lua_State *L)
PUSHGETTER(racecountdown, u32);
PUSHGETTER(exitcountdown, u32);
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "mapmusflags");
lua_glib_push_u16_getter(L, &mapmusic.flags);
lua_call(L, 2, 0);
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "mapmusposition");
lua_glib_push_u32_getter(L, &mapmusic.position);
lua_call(L, 2, 0);
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "mapmusname");
lua_glib_push_str_getter(L, mapmusic.name);
lua_glib_push_str_getter(L, mapmusname);
lua_call(L, 2, 0);
lua_pushcfunction(L, lua_glib_new_getter);
+18 -3
View File
@@ -21,6 +21,7 @@
#define SOUND_DUMMY 0
#define SOUND_SDL 1
#define SOUND_MIXER 2
#define SOUND_FMOD 3
#ifndef SOUND
#ifdef HAVE_SDL
@@ -28,6 +29,9 @@
// Use Mixer interface?
#ifdef HAVE_MIXER
#define SOUND SOUND_MIXER
#ifdef HW3SOUND
#undef HW3SOUND
#endif
#endif
// Use generic SDL interface.
@@ -36,8 +40,18 @@
#endif
#else // No SDL.
// No more interfaces. :(
#define SOUND SOUND_DUMMY
// Use FMOD?
#ifdef HAVE_FMOD
#define SOUND SOUND_FMOD
#ifdef HW3SOUND
#undef HW3SOUND
#endif
#else
// No more interfaces. :(
#define SOUND SOUND_DUMMY
#endif
#endif
#endif
@@ -530,8 +544,9 @@ UINT32 quickncasehash (const char *p, size_t n)
#ifndef max // Double-Check with WATTCP-32's cdefs.h
#define max(x, y) (((x) > (y)) ? (x) : (y))
#endif
#ifndef CLAMP
#define CLAMP(x, y, z) ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x)))
#define CLAMP(x, min_val, max_val) ((x) < (min_val) ? (min_val) : ((x) > (max_val) ? (max_val) : (x)))
#endif
#ifndef M_PIl
+7 -36
View File
@@ -30,26 +30,16 @@
// =============================
// Selected by user.
typedef struct
{
char name[7]; // Music name, up to 6-character name
void *data; // Music lump
UINT16 flags; // Track and reset bit
boolean looping; // Is this music looping?
UINT32 position; // Position to jump to
UINT32 resume; // Saved Position when music was stopped
UINT32 fadeinms; // Fade in time in ms (used for queue)
} music_t;
extern music_t mapmusic;
extern INT16 gamemap;
extern char mapmusname[7];
extern UINT16 mapmusflags;
extern UINT32 mapmusposition;
extern UINT32 mapmusresume;
#define MUSIC_TRACKMASK 0x0FFF // ----************
#define MUSIC_RELOADRESET 0x8000 // *---------------
#define MUSIC_FORCERESET 0x4000 // -*--------------
// Use other bits if necessary.
extern INT16 gamemap;
extern INT16 maptol;
extern UINT8 globalweather;
extern INT32 curWeather;
@@ -132,6 +122,7 @@ extern boolean gamedataloaded;
// Player taking events, and displaying.
extern INT32 consoleplayer;
extern INT32 displayplayers[MAXSPLITSCREENPLAYERS];
extern INT32 g_localplayers[MAXSPLITSCREENPLAYERS];
// Maps of special importance
extern INT16 spstage_start;
@@ -222,15 +213,6 @@ typedef struct
char value[256]; // 255 usable characters. If this seriously isn't enough then wtf.
} customoption_t;
typedef struct
{
boolean use_custom_light;
UINT8 light_contrast; ///< Range of wall lighting. 0 is no lighting.
SINT8 sprite_backlight; ///< Subtract from wall lighting for sprites only.
boolean use_light_angle; ///< When false, wall lighting is evenly distributed. When true, wall lighting is directional.
angle_t light_angle; ///< Angle of directional wall lighting.
} mapheader_lighting_t;
/** Map header information.
*/
typedef struct
@@ -278,10 +260,6 @@ typedef struct
//boolean automap; ///< Displays a level's white map outline in modified games
fixed_t mobj_scale; ///< Replacement for TOL_ERZ3
mapheader_lighting_t lighting; ///< Wall and sprite lighting
mapheader_lighting_t lighting_encore; ///< Alternative lighting for Encore mode
boolean use_encore_lighting; ///< Whether to use separate Encore lighting
// Music stuff.
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
char musintername[7]; ///< Intermission screen music.
@@ -477,14 +455,6 @@ extern tic_t racecountdown, exitcountdown;
extern fixed_t gravity;
extern fixed_t mapobjectscale;
extern struct maplighting
{
UINT8 contrast;
SINT8 backlight;
boolean directional;
angle_t angle;
} maplighting;
//for CTF balancing
extern INT16 autobalance;
extern INT16 teamscramble;
@@ -513,6 +483,7 @@ extern boolean startedInFreePlay;
extern boolean legitimateexit;
extern boolean comebackshowninfo;
extern tic_t curlap, bestlap;
extern INT16 votelevels[4][2];
extern SINT8 votes[MAXPLAYERS];
+9 -3
View File
@@ -342,6 +342,15 @@ union FColorRGBA
} ATTRPACK;
typedef union FColorRGBA RGBA_t;
typedef enum
{
POSTIMG_WATER = 1, // Underwater screen effect.
POSTIMG_MOTION = 1<<1, // Unused motion blur effect.
POSTIMG_FLIP = 1<<2, // Flipcam screen effect.
POSTIMG_HEAT = 1<<3, // Heatwave screen effect.
POSTIMG_MIRROR = 1<<4, // encore screen effect.
} postimgflag_t;
typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
#define LUMPERROR UINT32_MAX
@@ -380,9 +389,6 @@ unset_bit_array (bitarray_t * const array, const int value)
array[value >> 3] &= ~(1<<(value & 7));
}
#define intsign(n) \
((n) < 0 ? -1 : (n) > 0 ? 1 : 0)
typedef UINT64 precise_t;
#endif //__DOOMTYPE__
+4
View File
@@ -92,6 +92,8 @@ void I_OutputMsg(const char *error, ...)
void I_StartupMouse(void){}
void I_StartupMouse2(void){}
void I_StartupKeyboard(void){}
INT32 I_GetKey(void)
@@ -144,6 +146,8 @@ void I_GetJoystickEvents(void){}
void I_GetJoystick2Events(void){}
void I_GetMouseEvents(void){}
char *I_GetEnv(const char *name)
{
(void)name;
+1 -1
View File
@@ -273,7 +273,7 @@ static void F_DoWipe(fademask_t *fademask)
else
{
// pointer to transtable that this mask would use
transtbl = R_GetTranslucencyTable((9 - *mask) + 1);
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
// DRAWING LOOP
while (draw_linestogo--)
+1 -1
View File
@@ -797,7 +797,7 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
}
else if (ext == EXT_TXT)
{
if (!strncmp(dent->d_name, "log-", 4) || !strcmp(dent->d_name, "errorlog.txt"))
if (!strcmp(dent->d_name, "log.txt") || !strcmp(dent->d_name, "errorlog.txt"))
ext |= EXT_LOADED;
}
+287 -234
View File
@@ -84,7 +84,10 @@ static void G_DoStartVote(void);
static void G_ResetDemoPlayback(char *pdemoname);
music_t mapmusic;
char mapmusname[7]; // Music name
UINT16 mapmusflags; // Track and reset bit
UINT32 mapmusposition; // Position to jump to
UINT32 mapmusresume;
INT16 gamemap = 1;
INT16 maptol;
@@ -120,6 +123,7 @@ player_t players[MAXPLAYERS];
INT32 consoleplayer; // player taking events and displaying
INT32 displayplayers[MAXSPLITSCREENPLAYERS]; // view being displayed
INT32 g_localplayers[MAXSPLITSCREENPLAYERS];
tic_t gametic;
tic_t levelstarttic; // gametic at level start
@@ -240,8 +244,6 @@ tic_t racecountdown, exitcountdown; // for racing
fixed_t gravity;
fixed_t mapobjectscale;
struct maplighting maplighting;
INT16 autobalance; //for CTF team balance
INT16 teamscramble; //for CTF team scramble
INT16 scrambleplayers[MAXPLAYERS]; //for CTF team scramble
@@ -278,6 +280,8 @@ boolean startedInFreePlay; // Map was started in free play
// Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players)
boolean legitimateexit; // Did this client actually finish the match?
boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message?
tic_t curlap; // Current lap time
tic_t bestlap; // Best lap time
static INT16 randmapbuffer[NUMMAPS+1]; // Buffer for maps RandMap is allowed to roll
tic_t hidetime;
@@ -331,6 +335,11 @@ boolean precache = true; // if true, load all graphics at start
INT16 prevmap, nextmap;
// save if director is enabled
// so demos can disable it by default and restore it after
static int directorstate[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
tic_t directortoggletimer = 0;
static CV_PossibleValue_t recordmultiplayerdemos_cons_t[] = {{0, "Disabled"}, {1, "Manual Save"}, {2, "Auto Save"}, {0, NULL}};
consvar_t cv_recordmultiplayerdemos = {"netdemo_record", "Manual Save", CV_SAVE, recordmultiplayerdemos_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -350,6 +359,8 @@ void SendWeaponPref2(void);
void SendWeaponPref3(void);
void SendWeaponPref4(void);
static void G_FixCamera(UINT8 view);
// don't mind me putting these here, I was lazy to figure out where else I could put those without blowing up the compiler.
// chat timer thingy
@@ -391,9 +402,20 @@ static CV_PossibleValue_t powermusic_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "SFX
consvar_t cv_growmusic = {"growmusic", "On", CV_SAVE, powermusic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_supermusic = {"supermusic", "On", CV_SAVE, powermusic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
/*consvar_t cv_crosshair = {"crosshair", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_crosshair2 = {"crosshair2", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_crosshair3 = {"crosshair3", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_crosshair4 = {"crosshair4", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};*/
consvar_t cv_invertmouse = {"invertmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_mousemove = {"mousemove", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_invertmouse2 = {"invertmouse2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
/*consvar_t cv_alwaysfreelook = {"alwaysmlook", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_alwaysfreelook2 = {"alwaysmlook2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chasefreelook = {"chasemlook", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chasefreelook2 = {"chasemlook2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mousemove = {"mousemove", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mousemove2 = {"mousemove2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};*/
//static CV_PossibleValue_t crosshair_cons_t[] = {{0, "Off"}, {1, "Cross"}, {2, "Angle"}, {3, "Point"}, {0, NULL}};
static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
{1, "Left X"}, {2, "Left Y"}, {-1, "Left X-"}, {-2, "Left Y-"},
#if JOYAXISSET > 1
@@ -426,20 +448,6 @@ consvar_t cv_moveaxis[MAXSPLITSCREENPLAYERS] = {
{"joyaxis4_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
};
consvar_t cv_camstrafeaxis[MAXSPLITSCREENPLAYERS] = {
{"joyaxis_camstrafe", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"joyaxis2_camstrafe", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"joyaxis3_camstrafe", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"joyaxis4_camstrafe", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
};
consvar_t cv_camturnaxis[MAXSPLITSCREENPLAYERS] = {
{"joyaxis_camturn", "Left X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"joyaxis2_camturn", "Left X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"joyaxis3_camturn", "Left X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"joyaxis4_camturn", "Left X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
};
consvar_t cv_brakeaxis[MAXSPLITSCREENPLAYERS] = {
{"joyaxis_brake", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"joyaxis2_brake", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
@@ -520,6 +528,26 @@ consvar_t cv_ydeadzone[MAXSPLITSCREENPLAYERS] = {
static CV_PossibleValue_t driftsparkpulse_t[] = {{0, "MIN"}, {FRACUNIT*3, "MAX"}, {0, NULL}};
consvar_t cv_driftsparkpulse = {"driftsparkpulse", "1.4", CV_FLOAT | CV_SAVE, driftsparkpulse_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t stretchfactor_t[] = {
{0, "Off"}, {FRACUNIT/8, "0.125"}, {FRACUNIT/4, "0.250"},
{3*FRACUNIT/8, "0.375"}, {FRACUNIT/2, "0.500"}, {5*FRACUNIT/8, "0.625"},
{3*FRACUNIT/4, "0.750"}, {7*FRACUNIT/8, "0.875"}, {FRACUNIT, "Max"}, {0, NULL}};
consvar_t cv_gravstretch = {"gravstretch", "0", CV_SAVE, stretchfactor_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t slamsound_t[] = {{0, "Off"}, {1, "On"}, {0, NULL}};
consvar_t cv_slamsound = {"slamsound", "1", CV_SAVE, slamsound_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t sloperolldist_cons_t[] = {
/*{256, "256"},*/ {512, "512"}, {768, "768"},
{1024, "1024"}, {1536, "1536"}, {2048, "2048"},
{3072, "3072"}, {4096, "4096"}, {6144, "6144"},
{8192, "8192"}, {0, "Infinite"}, {0, NULL}};
consvar_t cv_sloperolldist = {"sloperolldist", "Infinite", CV_SAVE, sloperolldist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t sloperoll_cons_t[] = {{0, "Off"}, {1, "Players"}, {2, "Everything"}, {0, NULL}};
consvar_t cv_sloperoll = {"sloperoll", "Off", CV_SAVE|CV_CALL, sloperoll_cons_t, PDistort_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_sparkroll = {"sparkroll", "Off", CV_SAVE|CV_CALL, CV_OnOff, PDistort_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_sliptideroll = {"sliptideroll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cechotoggle = {"show_cecho", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#if MAXPLAYERS > 16
@@ -674,7 +702,9 @@ const char *G_BuildMapName(INT32 map)
*/
INT16 G_ClipAimingPitch(INT32 *aiming)
{
static const INT32 limitangle = ANGLE_90 - 1;
INT32 limitangle;
limitangle = ANGLE_90 - 1;
if (*aiming > limitangle)
*aiming = limitangle;
@@ -686,8 +716,10 @@ INT16 G_ClipAimingPitch(INT32 *aiming)
INT16 G_SoftwareClipAimingPitch(INT32 *aiming)
{
INT32 limitangle;
// note: the current software mode implementation doesn't have true perspective
static const INT32 limitangle = ANGLE_90 - ANG10; // Some viewing fun, but not too far down...
limitangle = ANGLE_90 - ANG10; // Some viewing fun, but not too far down...
if (*aiming > limitangle)
*aiming = limitangle;
@@ -712,12 +744,6 @@ INT32 JoyAxis(axis_input_e axissel, UINT8 player)
case AXISMOVE:
axisval = cv_moveaxis[player-1].value;
break;
case AXISCAMTURN:
axisval = cv_camturnaxis[player-1].value;
break;
case AXISCAMSTRAFE:
axisval = cv_camstrafeaxis[player-1].value;
break;
case AXISBRAKE:
axisval = cv_brakeaxis[player-1].value;
break;
@@ -811,6 +837,14 @@ boolean InputDown(INT32 gc, UINT8 p)
}
}
//
// G_BuildTiccmd
// Builds a ticcmd from all of the available inputs
// or reads it from the demo buffer.
// If recording a demo, write it out
//
// set secondaryplayer true to build player 2's ticcmd in splitscreen mode
//
INT32 localaiming[MAXSPLITSCREENPLAYERS];
angle_t localangle[MAXSPLITSCREENPLAYERS];
boolean camspin[MAXSPLITSCREENPLAYERS];
@@ -819,94 +853,42 @@ static fixed_t forwardmove[2] = {25<<FRACBITS>>16, 50<<FRACBITS>>16};
static fixed_t sidemove[2] = {2<<FRACBITS>>16, 4<<FRACBITS>>16};
static fixed_t angleturn[3] = {KART_FULLTURN/2, KART_FULLTURN, KART_FULLTURN/4}; // + slow turn
//
// G_BuildLocalTiccmd
// extremely basic cut down ticcmd builder
// for spectator and freecam
// this does not make the player move at all but keeps important things working
//
static void G_BuildLocalTiccmd(ticcmd_t *cmd, UINT8 ssplayer, boolean freecam)
{
boolean moveinput = false;
INT32 axis = 0;
const boolean usejoystick = (cv_usejoystick[(ssplayer-1)].value);
// check for inputs and return button commands
// for stuff like joining with item button, saltyhop, honking, etc.
#define CHECKINPUT(button, AXIS, buttflag) \
axis = JoyAxis(AXIS, ssplayer); \
if (InputDown(button, ssplayer) || (usejoystick && axis > 0)) cmd->buttons |= buttflag;
CHECKINPUT(gc_fire, AXISFIRE, BT_ATTACK);
CHECKINPUT(gc_drift, AXISDRIFT, BT_DRIFT);
CHECKINPUT(gc_custom1, AXISCUSTOM1, BT_CUSTOM1);
CHECKINPUT(gc_custom2, AXISCUSTOM2, BT_CUSTOM2);
CHECKINPUT(gc_custom3, AXISCUSTOM3, BT_CUSTOM3);
// we dont need the rest of this if were in freecam state
if (freecam)
{
return;
}
CHECKINPUT(gc_accelerate, AXISMOVE, BT_ACCELERATE);
CHECKINPUT(gc_brake, AXISBRAKE, BT_BRAKE);
#undef CHECKINPUT
moveinput = (InputDown(gc_turnleft, ssplayer) || InputDown(gc_turnright, ssplayer)
|| InputDown(gc_aimforward, ssplayer) || InputDown(gc_aimbackward, ssplayer) ||
(usejoystick && JoyAxis(AXISAIM, ssplayer) != 0) || (usejoystick && JoyAxis(AXISTURN, ssplayer) != 0));
axis = JoyAxis(AXISLOOKBACK, ssplayer);
camspin[ssplayer-1] = (InputDown(gc_lookback, ssplayer) || (usejoystick && axis > 0));
// Reset to our spec player if we watch someone else.
if ((moveinput || cmd->buttons)
&& displayplayers[0] != consoleplayer && ssplayer == 1)
{
if (cv_director.value)
CV_SetValue(&cv_director, 0);
displayplayers[0] = consoleplayer;
R_ResetViewInterpolation(0);
camera[0].reset_aiming = true;
}
}
//
// G_BuildTiccmd
// Builds a ticcmd from all of the available inputs
// or reads it from the demo buffer.
// If recording a demo, write it out
//
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
{
INT32 laim, th, tspeed, forward, side, axis;
const UINT8 forplayer = ssplayer-1;
INT32 laim, th, tspeed, forward, side, axis; //i
const INT32 speed = 1;
// these ones used for multiple conditions
boolean turnleft, turnright;
boolean usejoystick, rd;
boolean turnleft, turnright, mouseaiming;
boolean invertmouse, usejoystick, kbl, rd;
player_t *player;
camera_t *thiscam;
angle_t lang;
static INT32 turnheld[MAXSPLITSCREENPLAYERS]; // for accelerative turning
static boolean keyboard_look[MAXSPLITSCREENPLAYERS]; // true if lookup/down using keyboard
static boolean resetdown[MAXSPLITSCREENPLAYERS]; // don't cam reset every frame
if (demo.playback)
return;
const UINT8 forplayer = (ssplayer-1);
player_t *player = ((ssplayer == 1) ? &players[consoleplayer] : &players[displayplayers[forplayer]]);
camera_t *thiscam = &camera[forplayer];
const boolean freecam = camera[forplayer].freecam;
const boolean lookaxis = cv_lookaxis[forplayer].value;
const boolean analogjoystickmove = cv_usejoystick[forplayer].value && !Joystick[forplayer].bGamepadStyle;
const boolean gamepadjoystickmove = cv_usejoystick[forplayer].value && Joystick[forplayer].bGamepadStyle;
if (demo.playback) return;
if (ssplayer == 1)
player = &players[consoleplayer];
else
player = &players[displayplayers[forplayer]];
if (ssplayer == 2)
thiscam = (player->bot == 2 ? &camera[0] : &camera[forplayer]);
else
thiscam = &camera[forplayer];
lang = localangle[forplayer];
laim = localaiming[forplayer];
th = turnheld[forplayer];
kbl = keyboard_look[forplayer];
rd = resetdown[forplayer];
switch (ssplayer)
@@ -936,17 +918,25 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
return;
}
// dumbass thing so we can use a few buttons but dont accidentally drive away
if (player->spectator || freecam)
switch (ssplayer)
{
cmd->angleturn = (INT16)(lang >> 16);
G_BuildLocalTiccmd(cmd, ssplayer, freecam);
// let lua override everything
if (gamestate == GS_LEVEL)
LUA_HookTiccmd(player, cmd, HOOK(PlayerCmd));
return;
case 2:
mouseaiming = player->spectator; //(PLAYER2INPUTDOWN(gc_mouseaiming)) ^ cv_alwaysfreelook2.value;
invertmouse = cv_invertmouse2.value;
break;
case 3:
mouseaiming = false;
invertmouse = false;
break;
case 4:
mouseaiming = false;
invertmouse = false;
break;
case 1:
default:
mouseaiming = player->spectator; //(PLAYER1INPUTDOWN(gc_mouseaiming)) ^ cv_alwaysfreelook.value;
invertmouse = cv_invertmouse.value;
break;
}
usejoystick = (analogjoystickmove || gamepadjoystickmove);
@@ -980,7 +970,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
if (th < SLOWTURNTICS)
tspeed = cv_turnsmooth.value == 2 ? 2 : 0; // slow turn
else
tspeed = 1;
tspeed = speed;
cmd->driftturn = 0;
@@ -1006,14 +996,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
side += ((axis * sidemove[0]) >> 10);
}
if (cv_mouseturn.value)
if (player->spectator || cv_mouseturn.value)
{
//THIS WORKS WTF????????
cmd->angleturn = (INT16)(cmd->angleturn - ((mousex*(encoremode ? -1 : 1)*8)));
cmd->driftturn = (INT16)(cmd->driftturn - ((mousex*(encoremode ? -1 : 1)*8)));
}
if (objectplacing) // SRB2Kart: spectators need special controls // not anymore huehuehue
if (player->spectator || objectplacing) // SRB2Kart: spectators need special controls
{
axis = JoyAxis(AXISMOVE, ssplayer);
if (InputDown(gc_accelerate, ssplayer) || (usejoystick && axis > 0))
@@ -1095,7 +1085,54 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
else
rd = false;
cmd->aiming = G_ClipAimingPitch(&laim);
// spectator aiming shit, ahhhh...
{
INT32 player_invert = invertmouse ? -1 : 1;
INT32 screen_invert =
(player->mo && (player->mo->eflags & MFE_VERTICALFLIP)
&& (!thiscam->chase || player->pflags & PF_FLIPCAM)) //because chasecam's not inverted
? -1 : 1; // set to -1 or 1 to multiply
// mouse look stuff (mouse look is not the same as mouse aim)
if (mouseaiming && player->spectator)
{
kbl = false;
// looking up/down
laim += (mlooky<<19)*player_invert*screen_invert;
}
axis = JoyAxis(AXISLOOK, ssplayer);
if (analogjoystickmove && axis != 0 && lookaxis && player->spectator)
laim += (axis<<16) * screen_invert;
// spring back if not using keyboard neither mouselookin'
if (!kbl && !lookaxis && !mouseaiming)
laim = 0;
if (player->spectator)
{
if (InputDown(gc_lookup, ssplayer) || (gamepadjoystickmove && axis < 0))
{
laim += KB_LOOKSPEED * screen_invert;
kbl = true;
}
else if (InputDown(gc_lookdown, ssplayer) || (gamepadjoystickmove && axis > 0))
{
laim -= KB_LOOKSPEED * screen_invert;
kbl = true;
}
}
if (InputDown(gc_centerview, ssplayer)) // No need to put a spectator limit on this one though :V
laim = 0;
// accept no mlook for network games
if (!cv_allowmlook.value)
laim = 0;
cmd->aiming = G_ClipAimingPitch(&laim);
}
mousex = mousey = mlooky = 0;
@@ -1147,6 +1184,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
{
localangle[forplayer] = lang;
localaiming[forplayer] = laim;
keyboard_look[forplayer] = kbl;
turnheld[forplayer] = th;
resetdown[forplayer] = rd;
axis = JoyAxis(AXISLOOKBACK, ssplayer);
@@ -1167,8 +1205,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
LUA_HookTiccmd(player, cmd, HOOK(PlayerCmd));
//Reset away view if a command is given.
if (displayplayers[0] != consoleplayer && ssplayer == 1
&& (cmd->forwardmove || cmd->sidemove || cmd->buttons))
if ((cmd->forwardmove || cmd->sidemove || cmd->buttons)
&& displayplayers[0] != consoleplayer && ssplayer == 1)
{
displayplayers[0] = consoleplayer;
G_FixCamera(1);
@@ -1184,7 +1222,7 @@ static void G_DoLoadLevel(boolean resetplayer)
// Saturn Music Feature stuffs
S_ResetKeepAndSpecialMus();
S_KeepMusic();
S_CheckMap();
// Make sure objectplace is OFF when you first start the level!
OP_ResetObjectplace();
@@ -1247,18 +1285,17 @@ static void G_DoLoadLevel(boolean resetplayer)
joy4xmove[i] = joy4ymove[i] = 0;
}
mousex = mousey = 0;
mouse2x = mouse2y = 0;
// clear hud messages remains (usually from game startup)
CON_ClearHUD();
server_lagless = cv_lagless.value;
G_ResetAllDeviceRumbles();
}
static INT32 pausedelay = 0;
static INT32 camtoggledelay[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
static INT32 spectatedelay[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
static INT32 camtoggledelay, camtoggledelay2, camtoggledelay3, camtoggledelay4 = 0;
static INT32 spectatedelay, spectatedelay2, spectatedelay3, spectatedelay4 = 0;
//
// G_Responder
@@ -1439,79 +1476,91 @@ boolean G_Responder(event_t *ev)
if (ev->data1 == gamecontrol[gc_camtoggle][0]
|| ev->data1 == gamecontrol[gc_camtoggle][1])
{
if (!camtoggledelay[0])
if (!camtoggledelay)
{
camtoggledelay[0] = NEWTICRATE / 7;
camtoggledelay = NEWTICRATE / 7;
CV_SetValue(&cv_chasecam[0], cv_chasecam[0].value ? 0 : 1);
}
}
if (ev->data1 == gamecontrolbis[gc_camtoggle][0]
|| ev->data1 == gamecontrolbis[gc_camtoggle][1])
{
if (!camtoggledelay[1])
if (!camtoggledelay2)
{
camtoggledelay[1] = NEWTICRATE / 7;
camtoggledelay2 = NEWTICRATE / 7;
CV_SetValue(&cv_chasecam[1], cv_chasecam[1].value ? 0 : 1);
}
}
if (ev->data1 == gamecontrol3[gc_camtoggle][0]
|| ev->data1 == gamecontrol3[gc_camtoggle][1])
{
if (!camtoggledelay[2])
if (!camtoggledelay3)
{
camtoggledelay[2] = NEWTICRATE / 7;
camtoggledelay3 = NEWTICRATE / 7;
CV_SetValue(&cv_chasecam[2], cv_chasecam[2].value ? 0 : 1);
}
}
if (ev->data1 == gamecontrol4[gc_camtoggle][0]
|| ev->data1 == gamecontrol4[gc_camtoggle][1])
{
if (!camtoggledelay[3])
if (!camtoggledelay4)
{
camtoggledelay[3] = NEWTICRATE / 7;
camtoggledelay4 = NEWTICRATE / 7;
CV_SetValue(&cv_chasecam[3], cv_chasecam[3].value ? 0 : 1);
}
}
if (ev->data1 == gamecontrol[gc_spectate][0]
|| ev->data1 == gamecontrol[gc_spectate][1])
{
if (!spectatedelay[0])
if (!spectatedelay)
{
spectatedelay[0] = NEWTICRATE / 7;
spectatedelay = NEWTICRATE / 7;
COM_ImmedExecute("changeteam spectator");
}
}
if (ev->data1 == gamecontrolbis[gc_spectate][0]
|| ev->data1 == gamecontrolbis[gc_spectate][1])
{
if (!spectatedelay[1])
if (!spectatedelay2)
{
spectatedelay[1] = NEWTICRATE / 7;
spectatedelay2 = NEWTICRATE / 7;
COM_ImmedExecute("changeteam2 spectator");
}
}
if (ev->data1 == gamecontrol3[gc_spectate][0]
|| ev->data1 == gamecontrol3[gc_spectate][1])
{
if (!spectatedelay[2])
if (!spectatedelay3)
{
spectatedelay[2] = NEWTICRATE / 7;
spectatedelay3 = NEWTICRATE / 7;
COM_ImmedExecute("changeteam3 spectator");
}
}
if (ev->data1 == gamecontrol4[gc_spectate][0]
|| ev->data1 == gamecontrol4[gc_spectate][1])
{
if (!spectatedelay[3])
if (!spectatedelay4)
{
spectatedelay[3] = NEWTICRATE / 7;
spectatedelay4 = NEWTICRATE / 7;
COM_ImmedExecute("changeteam4 spectator");
}
}
if (ev->data1 == gamecontrol[gc_director][0] || ev->data1 == gamecontrol[gc_director][1])
{
K_ToggleDirector();
K_ToggleDirector(0);
}
else if (ev->data1 == gamecontrolbis[gc_director][0] || ev->data1 == gamecontrolbis[gc_director][1])
{
K_ToggleDirector(1);
}
else if (ev->data1 == gamecontrol3[gc_director][0] || ev->data1 == gamecontrol3[gc_director][1])
{
K_ToggleDirector(2);
}
else if (ev->data1 == gamecontrol4[gc_director][0] || ev->data1 == gamecontrol4[gc_director][1])
{
K_ToggleDirector(3);
}
if (ev->data1 == gamecontrol[gc_freecam][0] || ev->data1 == gamecontrol[gc_freecam][1])
@@ -1665,14 +1714,13 @@ INT32 G_CountPlayersPotentiallyViewable(boolean active)
// Reset camera position, angle and interpolation on a view
// after changing state.
//
void G_FixCamera(UINT8 view)
static void G_FixCamera(UINT8 view)
{
player_t *player = &players[displayplayers[view - 1]];
// The order of displayplayers can change, which would
// invalidate localangle.
if (!P_MobjWasRemoved(player->mo))
localangle[view - 1] = player->mo->angle;
localangle[view - 1] = (angle_t)(player->cmd.angleturn << 16);
P_ResetCamera(player, &camera[view - 1]);
@@ -1729,14 +1777,7 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
(*displayplayerp) = playernumd;
/* If a viewpoint changes, reset the camera to clear uninitialized memory. */
if (viewnum > splits)
{
G_FixCamera(viewd);
}
else if ((*displayplayerp) != olddisplayplayer)
{
G_FixCamera(viewnum);
}
G_FixCamera(viewd);
}
if (demo.playback && viewnum == 1)
@@ -1963,14 +2004,23 @@ void G_Ticker(boolean run)
if (pausedelay)
pausedelay--;
for (UINT8 j = 0; j < MAXSPLITSCREENPLAYERS;j++)
{
if (camtoggledelay[j])
camtoggledelay[j]--;
if (camtoggledelay)
camtoggledelay--;
if (camtoggledelay2)
camtoggledelay2--;
if (camtoggledelay3)
camtoggledelay3--;
if (camtoggledelay4)
camtoggledelay4--;
if (spectatedelay[j])
spectatedelay[j]--;
}
if (spectatedelay)
spectatedelay--;
if (spectatedelay2)
spectatedelay2--;
if (spectatedelay3)
spectatedelay3--;
if (spectatedelay4)
spectatedelay4--;
if (gametic % NAMECHANGERATE == 0)
{
@@ -2267,9 +2317,13 @@ void G_PlayerReborn(INT32 player)
if (p-players == consoleplayer)
{
if (mapmusic.flags & MUSIC_RELOADRESET)
if (mapmusflags & MUSIC_RELOADRESET)
{
S_HandleReloadResetMusic();
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
mapmusname[6] = 0;
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
mapmusresume = 0;
songcredit = true;
}
}
@@ -4027,7 +4081,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
globalweather = mapheaderinfo[gamemap-1]->weather;
// Don't carry over custom music change to another map.
mapmusic.flags |= MUSIC_RELOADRESET;
mapmusflags |= MUSIC_RELOADRESET;
automapactive = false;
imcontinuing = false;
@@ -4507,7 +4561,7 @@ void G_ReadDemoExtraData(void)
if (extradata & DXD_RESPAWN)
{
if (players[p].mo)
P_DamageMobj(players[p].mo, NULL, NULL, DMG_INSTAKILL); // Is this how this should work..?
P_DamageMobj(players[p].mo, NULL, NULL, 10000); // Is this how this should work..?
}
if (extradata & DXD_SKIN)
{
@@ -4573,7 +4627,7 @@ void G_ReadDemoExtraData(void)
{
players[p].spectator = true;
if (players[p].mo)
P_DamageMobj(players[p].mo, NULL, NULL, DMG_INSTAKILL);
P_DamageMobj(players[p].mo, NULL, NULL, 10000);
else
players[p].playerstate = PST_REBORN;
}
@@ -4600,23 +4654,18 @@ void G_ReadDemoExtraData(void)
while (p != DW_END)
{
UINT32 rng;
UINT32 checkrng;
switch (p)
{
case DW_RNG:
rng = READUINT32(demobuf.p);
checkrng = P_GetRandSeed();
if (checkrng != rng)
if (P_GetRandSeed() != rng)
{
if (demosynced)
{
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced (RNG)!\n"));
CONS_Printf("expected rng %d got %d\n", rng, checkrng);
}
demosynced = false;
P_SetRandSeed(rng);
if (demosynced)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
demosynced = false;
}
}
@@ -4882,7 +4931,7 @@ void G_GhostAddHit(INT32 playernum, mobj_t *victim)
ghostext[playernum].flags |= EZT_HIT;
ghostext[playernum].hits++;
ghostext[playernum].hitlist = Z_Realloc(ghostext[playernum].hitlist, ghostext[playernum].hits * sizeof(mobj_t *), PU_LEVEL, NULL);
P_SetTarget(ghostext[playernum].hitlist + (ghostext[playernum].hits-1), victim);
ghostext[playernum].hitlist[ghostext[playernum].hits-1] = victim;
}
void G_WriteAllGhostTics(void)
@@ -4893,7 +4942,6 @@ void G_WriteAllGhostTics(void)
UINT8 *save_demo_p = demobuf.p;
#define CHECKSPACE(num) if (demobuf.p+(num) > demoend) { demobuf.p = save_demo_p; G_CheckDemoStatus(); return; }
boolean toobig = false;
INT32 i, counter = leveltime;
for (i = 0; i < MAXPLAYERS; i++)
@@ -4906,32 +4954,18 @@ void G_WriteAllGhostTics(void)
counter++;
if (multiplayer && ((counter % cv_netdemosyncquality.value) != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size.
if (counter % cv_netdemosyncquality.value != 0) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size.
continue;
CHECKSPACE(1);
WRITEUINT8(demobuf.p, i);
G_WriteGhostTic(players[i].mo, i);
// attention here for the ticcmd size!
// latest demos with mouse aiming byte in ticcmd
if (demobuf.p >= demoend - (13 + 9 + 9))
{
toobig = true;
break;
}
}
CHECKSPACE(1);
WRITEUINT8(demobuf.p, 0xFF);
if (toobig)
{
G_CheckDemoStatus(); // no more space
return;
}
#undef CHECKSPACE
}
@@ -5106,7 +5140,6 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
WRITEFIXED(demobuf.p,mo->y);
WRITEFIXED(demobuf.p,mo->z);
WRITEANGLE(demobuf.p,mo->angle);
P_SetTarget(ghostext[playernum].hitlist+i, NULL);
}
Z_Free(ghostext[playernum].hitlist);
ghostext[playernum].hits = 0;
@@ -5129,17 +5162,23 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
}
*ziptic_p = ziptic;
// attention here for the ticcmd size!
// latest demos with mouse aiming byte in ticcmd
if (demobuf.p >= demoend - (13 + 9))
{
G_CheckDemoStatus(); // no more space
return;
}
#undef CHECKSPACE
}
void G_ConsAllGhostTics(void)
{
UINT8 p;
if (!demobuf.p || !demo.deferstart)
if (!demobuf.p)
return;
p = READUINT8(demobuf.p);
UINT8 p = READUINT8(demobuf.p);
while (p != 0xFF)
{
@@ -5165,6 +5204,8 @@ void G_ConsGhostTic(INT32 playernum)
fixed_t syncleeway;
boolean nightsfail = false;
if (!demobuf.p || !demo.deferstart)
return;
if (!(demoflags & DF_GHOST))
return; // No ghost data to use.
@@ -5247,10 +5288,7 @@ void G_ConsGhostTic(INT32 playernum)
if (mobj && mobj->health != health) // Wasn't damaged?! This is desync! Fix it!
{
if (demosynced)
{
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced (health)!\n"));
CONS_Printf("expected health %d got %d\n", health, mobj->health);
}
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
demosynced = false;
P_DamageMobj(mobj, players[0].mo, players[0].mo, 1);
}
@@ -5283,7 +5321,7 @@ void G_ConsGhostTic(INT32 playernum)
if (ghostext[playernum].desyncframes >= 2)
{
if (demosynced)
CONS_Alert(CONS_WARNING, "Demo playback has desynced (player %s)!\n", player_names[playernum]);
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
demosynced = false;
P_UnsetThingPosition(testmo);
@@ -5313,11 +5351,7 @@ void G_ConsGhostTic(INT32 playernum)
)
{
if (demosynced)
{
CONS_Alert(CONS_WARNING, "Demo playback has desynced (item/bumpers)!(player %s)!\n", player_names[playernum]);
CONS_Printf("expected item type %d got %d\n", ghostext[playernum].kartitem, players[playernum].kartstuff[k_itemtype]);
CONS_Printf("expected item amount %d got %d\n", ghostext[playernum].kartamount, players[playernum].kartstuff[k_itemamount]);
}
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
demosynced = false;
players[playernum].kartstuff[k_itemtype] = ghostext[playernum].kartitem;
@@ -6006,7 +6040,7 @@ void G_RecordDemo(const char *name)
maxsize = cv_maxdemosize.value*1024*1024;
demobuf.buffer = Z_Malloc(maxsize + 100*1024, PU_STATIC, NULL);
demobuf.buffer = Z_Malloc(maxsize, PU_STATIC, NULL);
demoend = demobuf.buffer + maxsize;
if (demobuf.buffer)
@@ -6024,7 +6058,7 @@ void G_RecordMetal(void)
Z_Free(demobuf.buffer);
demobuf.p = NULL;
metalrecording = false;
demobuf.buffer = Z_Malloc(maxsize + 100*1024, PU_STATIC, NULL);
demobuf.buffer = Z_Malloc(maxsize, PU_STATIC, NULL);
demoend = demobuf.buffer + maxsize;
if (demobuf.buffer)
@@ -6044,23 +6078,10 @@ void G_BeginRecording(void)
UINT8 *m;
if (!cv_recordmultiplayerdemos.value)
{
G_ResetDemoRecording();
return;
}
if (demobuf.buffer == NULL)
{
CONS_Alert(CONS_ERROR, "No demo buffer allocated\n");
G_ResetDemoRecording();
if (demobuf.p || demobuf.buffer == NULL)
return;
}
if (demobuf.p)
{
G_ResetDemoRecording();
return;
}
memset(name,0,sizeof(name));
@@ -6216,20 +6237,8 @@ void G_BeginMetal(void)
{
mobj_t *mo = players[consoleplayer].mo;
if (demobuf.buffer == NULL)
{
CONS_Alert(CONS_ERROR, "No metal demo buffer allocated\n");
metalrecording = false;
if (demobuf.p || demobuf.buffer == NULL)
return;
}
if (demobuf.p)
{
Z_Free(demobuf.buffer);
demobuf.buffer = NULL;
metalrecording = false;
return;
}
demobuf.p = demobuf.buffer;
@@ -6845,6 +6854,9 @@ void G_DoPlayDemo(char *defdemoname)
boolean spectator;
UINT8 slots[MAXPLAYERS], kartspeed[MAXPLAYERS], kartweight[MAXPLAYERS], numslots = 0;
if (demobuf.buffer == NULL)
return;
G_InitDemoRewind();
skin[16] = '\0';
@@ -7301,8 +7313,11 @@ post_compat:
players[i].kartweight = kartweight[i];
}
if (cv_director.value)
CV_SetValue(&cv_director, 0);
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
directorstate[i] = cv_director[i].value;
CV_SetValue(&cv_director[i], 0);
}
demo.deferstart = true;
}
@@ -7827,6 +7842,7 @@ void G_DoneLevelLoad(void)
// Stops metal sonic's demo. Separate from other functions because metal + replays can coexist
void G_StopMetalDemo(void)
{
// Metal Sonic finishing doesn't end the game, dammit.
Z_Free(metalbuffer);
metalbuffer = NULL;
@@ -7866,6 +7882,14 @@ void G_StopDemo(void)
{
Z_Free(demobuf.buffer);
demobuf.buffer = NULL;
if (demo.playback)
{
for (UINT8 i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
CV_SetValue(&cv_director[i], directorstate[i]);
directorstate[i] = 0;
}
}
demo.playback = false;
if (demo.title)
modeattacking = false;
@@ -8161,3 +8185,32 @@ boolean G_GetRetryFlag(void)
{
return retrying;
}
// Time utility functions
INT32 G_TicsToHours(tic_t tics)
{
return tics/(3600*TICRATE);
}
INT32 G_TicsToMinutes(tic_t tics, boolean full)
{
if (full)
return tics/(60*TICRATE);
else
return tics/(60*TICRATE)%60;
}
INT32 G_TicsToSeconds(tic_t tics)
{
return (tics/TICRATE)%60;
}
INT32 G_TicsToCentiseconds(tic_t tics)
{
return (INT32)((tics%TICRATE) * (100.00f/TICRATE));
}
INT32 G_TicsToMilliseconds(tic_t tics)
{
return (INT32)((tics%TICRATE) * (1000.00f/TICRATE));
}
+25 -47
View File
@@ -66,6 +66,9 @@ struct demovars_s {
DSM_WILLSAVE,
DSM_SAVED
} savemode;
boolean freecam;
};
extern struct demovars_s demo;
@@ -115,12 +118,12 @@ extern consvar_t cv_songcredits;
extern consvar_t cv_showfreeplay;
extern consvar_t cv_growmusic, cv_supermusic;
extern consvar_t cv_pauseifunfocused;
extern consvar_t cv_invertmouse;
//extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4;
extern consvar_t cv_invertmouse/*, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove*/;
extern consvar_t cv_invertmouse2/*, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2*/;
extern consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_moveaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_camturnaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_camstrafeaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_brakeaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_aimaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_lookaxis[MAXSPLITSCREENPLAYERS];
@@ -146,27 +149,24 @@ extern consvar_t cv_##name##_yoffset;
DECL_HUD_OFFSET_X(name)\
DECL_HUD_OFFSET_Y(name)
DECL_HUD_OFFSET(item); // Item box
DECL_HUD_OFFSET(time); // Time
DECL_HUD_OFFSET(laps); // Number of laps
DECL_HUD_OFFSET(dnft); // Countdown (did not finish timer)
DECL_HUD_OFFSET(speed); // Speedometer
DECL_HUD_OFFSET(posi); // Position in race
DECL_HUD_OFFSET(wheel); // RA Wheel
DECL_HUD_OFFSET(face); // Mini rankings
DECL_HUD_OFFSET(stcd); // Starting countdown
DECL_HUD_OFFSET(item); // Item box
DECL_HUD_OFFSET(time); // Time
DECL_HUD_OFFSET(laps); // Number of laps
DECL_HUD_OFFSET(dnft); // Countdown (did not finish timer)
DECL_HUD_OFFSET(speed); // Speedometer
DECL_HUD_OFFSET(posi); // Position in race
DECL_HUD_OFFSET(face); // Mini rankings
DECL_HUD_OFFSET(stcd); // Starting countdown
DECL_HUD_OFFSET_Y(chek); // Check gfx
DECL_HUD_OFFSET(mini); // Minimap
DECL_HUD_OFFSET(want); // Wanted
DECL_HUD_OFFSET(stat); // Stats
DECL_HUD_OFFSET(mini); // Minimap
DECL_HUD_OFFSET(want); // Wanted
DECL_HUD_OFFSET(stat); // Stats
#undef DECL_HUD_OFFSET
#undef DECL_HUD_OFFSET_X
#undef DECL_HUD_OFFSET_Y
extern consvar_t cv_showinput;
extern consvar_t cv_posanim;
extern consvar_t cv_smallposnum;
extern consvar_t cv_newspeedometer;
extern consvar_t cv_saltyhop;
@@ -180,7 +180,6 @@ extern consvar_t cv_sliptideroll;
extern consvar_t cv_slamsound;
extern consvar_t cv_sloperolldist;
extern consvar_t cv_sparkroll;
extern consvar_t cv_spinoutroll;
extern consvar_t cv_cechotoggle;
@@ -193,8 +192,6 @@ typedef enum
AXISNONE = 0,
AXISTURN,
AXISMOVE,
AXISCAMTURN,
AXISCAMSTRAFE,
AXISBRAKE,
AXISAIM,
AXISLOOK,
@@ -232,6 +229,8 @@ extern angle_t localangle[MAXSPLITSCREENPLAYERS];
extern INT32 localaiming[MAXSPLITSCREENPLAYERS]; // should be an angle_t but signed
extern boolean camspin[MAXSPLITSCREENPLAYERS]; // SRB2Kart
extern tic_t directortoggletimer;
//
// GAME
//
@@ -433,32 +432,13 @@ void G_ClearRecords(void);
tic_t G_GetBestTime(INT16 map);
// Time utility functions
FUNCMATH INT32 G_TicsToHours(tic_t tics);
FUNCMATH INT32 G_TicsToMinutes(tic_t tics, boolean full);
FUNCMATH INT32 G_TicsToSeconds(tic_t tics);
FUNCMATH INT32 G_TicsToCentiseconds(tic_t tics);
FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics);
FUNCINLINE static ATTRINLINE FUNCMATH INT32 G_TicsToHours(tic_t tics)
{
return tics/(3600*TICRATE);
}
FUNCINLINE static ATTRINLINE FUNCMATH INT32 G_TicsToMinutes(tic_t tics, boolean full)
{
return full ? (tics/(60*TICRATE)) : (tics/(60*TICRATE)%60);
}
FUNCINLINE static ATTRINLINE FUNCMATH INT32 G_TicsToSeconds(tic_t tics)
{
return (tics/TICRATE)%60;
}
FUNCINLINE static ATTRINLINE FUNCMATH INT32 G_TicsToCentiseconds(tic_t tics)
{
return (INT32)((tics%TICRATE) * (100.00f/TICRATE));
}
FUNCINLINE static ATTRINLINE FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics)
{
return (INT32)((tics%TICRATE) * (1000.00f/TICRATE));
}
boolean K_DirectorIsPlayerAlone(void); // idk where else to put this lol
// Don't split up TOL handling
INT16 G_TOLFlag(INT32 pgametype);
@@ -466,6 +446,4 @@ INT16 G_TOLFlag(INT32 pgametype);
INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon, INT16 *extbuffer);
void G_AddMapToBuffer(INT16 map);
void G_FixCamera(UINT8 view);
#endif
+102 -34
View File
@@ -33,7 +33,9 @@ static CV_PossibleValue_t turnsmooth_cons_t[] = {{2, "Slow"}, {1, "Fast"}, {0, "
// mouse values are used once
consvar_t cv_mousesens = {"mousesens", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mousesens2 = {"mousesens2", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mouseysens = {"mouseysens", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mouseysens2 = {"mouseysens2", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_turnsmooth = {"turnsmoothing", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -123,6 +125,8 @@ static void led_off_handle4(void)
INT32 mousex, mousey;
INT32 mlooky; // like mousey but with a custom sensitivity for mlook
INT32 mouse2x, mouse2y, mlook2y;
// joystick values are repeated
INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET],
joy3xmove[JOYAXISSET], joy3ymove[JOYAXISSET], joy4xmove[JOYAXISSET], joy4ymove[JOYAXISSET];
@@ -144,6 +148,7 @@ typedef struct
} dclick_t;
static dclick_t mousedclicks[MOUSEBUTTONS];
static dclick_t joydclicks[JOYBUTTONS + JOYHATS*4];
static dclick_t mouse2dclicks[MOUSEBUTTONS];
static dclick_t joy2dclicks[JOYBUTTONS + JOYHATS*4];
static dclick_t joy3dclicks[JOYBUTTONS + JOYHATS*4];
static dclick_t joy4dclicks[JOYBUTTONS + JOYHATS*4];
@@ -228,6 +233,14 @@ void G_MapEventsToControls(event_t *ev)
if (ev->data3 != INT32_MAX) joy4ymove[i] = ev->data3;
break;
case ev_mouse2: // buttons are virtual keys
if (menuactive || CON_Ready() || chat_on)
break;
mouse2x = (INT32)(ev->data2*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
mouse2y = (INT32)(ev->data3*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
mlook2y = (INT32)(ev->data3*((cv_mouseysens2.value*cv_mousesens2.value)/110.0f + 0.1f));
break;
default:
break;
}
@@ -245,6 +258,12 @@ void G_MapEventsToControls(event_t *ev)
gamekeydown[KEY_DBLJOY1+i] = flag;
}
for (i = 0; i < MOUSEBUTTONS; i++)
{
flag = G_CheckDoubleClick(gamekeydown[KEY_2MOUSE1+i], &mouse2dclicks[i]);
gamekeydown[KEY_DBL2MOUSE1+i] = flag;
}
for (i = 0; i < JOYBUTTONS + JOYHATS*4; i++)
{
flag = G_CheckDoubleClick(gamekeydown[KEY_2JOY1+i], &joy2dclicks[i]);
@@ -382,8 +401,18 @@ static keyname_t keynames[] =
{KEY_MOUSE1+5,"MOUSE6"},
{KEY_MOUSE1+6,"MOUSE7"},
{KEY_MOUSE1+7,"MOUSE8"},
{KEY_2MOUSE1+0,"SEC_MOUSE2"}, // BP: sorry my mouse handler swap button 1 and 2
{KEY_2MOUSE1+1,"SEC_MOUSE1"},
{KEY_2MOUSE1+2,"SEC_MOUSE3"},
{KEY_2MOUSE1+3,"SEC_MOUSE4"},
{KEY_2MOUSE1+4,"SEC_MOUSE5"},
{KEY_2MOUSE1+5,"SEC_MOUSE6"},
{KEY_2MOUSE1+6,"SEC_MOUSE7"},
{KEY_2MOUSE1+7,"SEC_MOUSE8"},
{KEY_MOUSEWHEELUP, "Wheel 1 UP"},
{KEY_MOUSEWHEELDOWN, "Wheel 1 Down"},
{KEY_2MOUSEWHEELUP, "Wheel 2 UP"},
{KEY_2MOUSEWHEELDOWN, "Wheel 2 Down"},
{KEY_JOY1+0, "JOY1"},
{KEY_JOY1+1, "JOY2"},
@@ -394,7 +423,7 @@ static keyname_t keynames[] =
{KEY_JOY1+6, "JOY7"},
{KEY_JOY1+7, "JOY8"},
{KEY_JOY1+8, "JOY9"},
#if !defined (NOMOREJOYBTN_1S)
// we use up to 32 buttons in DirectInput
{KEY_JOY1+9, "JOY10"},
@@ -447,6 +476,14 @@ static keyname_t keynames[] =
{KEY_DBLMOUSE1+5, "DBLMOUSE6"},
{KEY_DBLMOUSE1+6, "DBLMOUSE7"},
{KEY_DBLMOUSE1+7, "DBLMOUSE8"},
{KEY_DBL2MOUSE1+0, "DBLSEC_MOUSE2"}, // BP: sorry my mouse handler swap button 1 and 2
{KEY_DBL2MOUSE1+1, "DBLSEC_MOUSE1"},
{KEY_DBL2MOUSE1+2, "DBLSEC_MOUSE3"},
{KEY_DBL2MOUSE1+3, "DBLSEC_MOUSE4"},
{KEY_DBL2MOUSE1+4, "DBLSEC_MOUSE5"},
{KEY_DBL2MOUSE1+5, "DBLSEC_MOUSE6"},
{KEY_DBL2MOUSE1+6, "DBLSEC_MOUSE7"},
{KEY_DBL2MOUSE1+7, "DBLSEC_MOUSE8"},
{KEY_DBLJOY1+0, "DBLJOY1"},
{KEY_DBLJOY1+1, "DBLJOY2"},
@@ -831,6 +868,7 @@ static keyname_t keynames[] =
{KEY_DBL4HAT1+13, "DBLFOR_HATDOWN4"},
{KEY_DBL4HAT1+14, "DBLFOR_HATLEFT4"},
{KEY_DBL4HAT1+15, "DBLFOR_HATRIGHT4"},
};
static const char *gamecontrolname[num_gamecontrols] =
@@ -867,78 +905,93 @@ static const char *gamecontrolname[num_gamecontrols] =
"freecam",
"camfloat",
"camsink",
"strafeleft",
"straferight",
};
#define NUMKEYNAMES (sizeof (keynames)/sizeof (keyname_t))
#include "k_kart.h"
UINT16 G_GetSkinColor(INT32 playernum)
inline UINT16 G_GetSkinColor(INT32 player)
{
if (gamestate == GS_LEVEL)
{
player_t *player = &players[displayplayers[playernum]];
// make rgb rainbow vomit when invul or flash blue when grow
if (cv_ledpowerup[player].value && gamestate == GS_LEVEL && players[displayplayers[player]].mo && (players[displayplayers[player]].kartstuff[k_invincibilitytimer] || players[displayplayers[player]].powers[pw_invulnerability] || players[displayplayers[player]].kartstuff[k_growshrinktimer]))
return players[displayplayers[player]].mo->color;
// make rgb rainbow vomit when invul or flash blue when grow
if (cv_ledpowerup[playernum].value && player->mo && (player->kartstuff[k_invincibilitytimer] || player->kartstuff[k_growshrinktimer] || player->powers[pw_invulnerability]))
return player->mo->color;
// take actual player skincolour when ingame
if (player->skincolor)
return player->skincolor;
}
// take actual player skincolour when ingame
if (gamestate == GS_LEVEL && players[displayplayers[player]].skincolor)
return players[displayplayers[player]].skincolor;
// otherwise just fallback to whatever the cvar is
switch (playernum)
switch (player)
{
case 0:
return cv_playercolor.value;
break;
case 1:
return cv_playercolor2.value;
break;
case 2:
return cv_playercolor3.value;
break;
case 3:
return cv_playercolor4.value;
break;
default:
return 0;
break;
}
return 0;
}
void G_SetPlayerGamepadIndicatorColor(INT32 playernum, UINT16 color)
void G_SetPlayerGamepadIndicatorColor(INT32 player, UINT16 color)
{
INT32 device;
UINT16 skincolor;
byteColor_t byte_color;
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
I_Assert(player >= 0 && player < MAXSPLITSCREENPLAYERS);
if (cv_gamepadled[playernum].value == 0)
if (cv_gamepadled[player].value == 0)
return;
device = cv_usejoystick[player].value;
if (device <= 0)
{
return;
}
skincolor = color ? color : G_GetSkinColor(playernum);
skincolor = color ? color : G_GetSkinColor(player);
byte_color = V_GetColor(colortranslations[skincolor][8]).s;
I_SetGamepadIndicatorColor(playernum, byte_color.red, byte_color.green, byte_color.blue);
I_SetGamepadIndicatorColor(device, byte_color.red, byte_color.green, byte_color.blue);
}
static void G_ResetPlayerGamepadIndicatorColor(INT32 playernum)
static void G_ResetPlayerGamepadIndicatorColor(INT32 player)
{
if (cv_gamepadled[playernum].value == 0)
if (cv_gamepadled[player].value == 0)
{
I_SetGamepadIndicatorColor(playernum, 0, 0, 255);
INT32 device = cv_usejoystick[player].value;
if (device <= 0)
return;
I_SetGamepadIndicatorColor(device, 0, 0, 255);
}
else
G_SetPlayerGamepadIndicatorColor(playernum, 0);
G_SetPlayerGamepadIndicatorColor(player, 0);
}
static void G_ResetPlayerDeviceRumble(INT32 playernum)
static void G_ResetPlayerDeviceRumble(INT32 player)
{
I_GamepadRumble(playernum, 0, 0, 0);
INT32 device_id;
device_id = cv_usejoystick[player].value;
if (device_id < 1)
{
return;
}
I_GamepadRumble(device_id, 0, 0, 0);
}
void G_ResetAllDeviceRumbles(void)
@@ -950,20 +1003,29 @@ void G_ResetAllDeviceRumbles(void)
for (i = 0; i < devices; i++)
{
I_GamepadRumble(devices, 0, 0, 0);
INT32 device_id = cv_usejoystick[i].value;
I_GamepadRumble(device_id, 0, 0, 0);
}
}
void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration)
void G_PlayerDeviceRumble(INT32 player, UINT16 low_strength, UINT16 high_strength, UINT32 duration)
{
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
INT32 device_id;
if (cv_rumble[playernum].value == 0)
if (cv_rumble[player].value == 0)
{
return;
}
I_GamepadRumble(playernum, low_strength, high_strength, duration);
device_id = cv_usejoystick[player].value;
if (device_id < 1)
{
return;
}
I_GamepadRumble(device_id, low_strength, high_strength, duration);
}
//
@@ -1080,6 +1142,12 @@ void G_Controldefault(UINT8 player)
//gamecontrol[gc_screenshot ][1] = KEY_HAT1+1; // D-Pad Down // absolutely fucking NOT
gamecontrol[gc_talkkey ][1] = KEY_HAT1+1; // D-Pad Down
gamecontrol[gc_scores ][1] = KEY_HAT1+0; // D-Pad Up
gamecontrol[gc_camfloat ][0] = 'a';
gamecontrol[gc_camsink ][0] = 'd';
gamecontrol[gc_camfloat ][1] = KEY_JOY1+0; // A
gamecontrol[gc_camsink ][1] = KEY_JOY1+1; // B
}
if (player == 0 || player == 2)
+13 -8
View File
@@ -41,10 +41,12 @@ typedef enum
KEY_DBLJOY1 = KEY_DBLMOUSE1 + MOUSEBUTTONS,
KEY_DBLHAT1 = KEY_DBLJOY1 + JOYBUTTONS,
KEY_2JOY1 = KEY_DBLHAT1 + MOUSEBUTTONS,
KEY_2MOUSE1 = KEY_DBLHAT1 + JOYHATS*4,
KEY_2JOY1 = KEY_2MOUSE1 + MOUSEBUTTONS,
KEY_2HAT1 = KEY_2JOY1 + JOYBUTTONS,
KEY_DBL2JOY1 = KEY_2HAT1 + MOUSEBUTTONS,
KEY_DBL2MOUSE1 = KEY_2HAT1 + JOYHATS*4,
KEY_DBL2JOY1 = KEY_DBL2MOUSE1 + MOUSEBUTTONS,
KEY_DBL2HAT1 = KEY_DBL2JOY1 + JOYBUTTONS,
KEY_3JOY1 = KEY_DBL2HAT1 + JOYHATS*4,
@@ -61,8 +63,10 @@ typedef enum
KEY_MOUSEWHEELUP = KEY_DBL4HAT1 + JOYHATS*4,
KEY_MOUSEWHEELDOWN = KEY_MOUSEWHEELUP + 1,
KEY_2MOUSEWHEELUP = KEY_MOUSEWHEELDOWN + 1,
KEY_2MOUSEWHEELDOWN = KEY_2MOUSEWHEELUP + 1,
NUMINPUTS = KEY_MOUSEWHEELDOWN + 1,
NUMINPUTS = KEY_2MOUSEWHEELDOWN + 1,
} key_input_e;
typedef enum
@@ -99,13 +103,12 @@ typedef enum
gc_freecam, // Toggle for freecam while ingame
gc_camfloat, // alternative button for raising cam
gc_camsink, // alternative button for sinking
gc_strafeleft,
gc_straferight,
num_gamecontrols
} gamecontrols_e;
// mouse values are used once
extern consvar_t cv_mousesens, cv_mouseysens;
extern consvar_t cv_mousesens2, cv_mouseysens2;
extern consvar_t cv_controlperkey, cv_turnsmooth;
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS];
@@ -113,6 +116,7 @@ extern consvar_t cv_ledpowerup[MAXSPLITSCREENPLAYERS];
extern INT32 mousex, mousey;
extern INT32 mlooky; //mousey with mlookSensitivity
extern INT32 mouse2x, mouse2y, mlook2y;
extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET],
joy3xmove[JOYAXISSET], joy3ymove[JOYAXISSET], joy4xmove[JOYAXISSET], joy4ymove[JOYAXISSET];
@@ -133,10 +137,11 @@ extern INT32 gamecontrol4[num_gamecontrols][2];
// peace to my little coder fingers!
// check a gamecontrol being active or not
UINT16 G_GetSkinColor(INT32 playernum);
void G_SetPlayerGamepadIndicatorColor(INT32 playernum, UINT16 color);
UINT16 G_GetSkinColor(INT32 player);
INT32 G_GetDeviceForPlayer(INT32 player);
void G_SetPlayerGamepadIndicatorColor(INT32 player, UINT16 color);
void G_PlayerDeviceRumble(INT32 player, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void G_ResetAllDeviceRumbles(void);
void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
// remaps the input event to a game control.
void G_MapEventsToControls(event_t *ev);
+85
View File
@@ -0,0 +1,85 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//-----------------------------------------------------------------------------
/// \file
/// \brief 3D sound import/export prototypes for low-level hardware interface
#ifndef __HW_3DS_DRV_H__
#define __HW_3DS_DRV_H__
// Use standart hardware API
#include "hw_dll.h"
#include "hws_data.h"
#if defined (HAVE_SDL) || !defined (HWD)
EXPORT void HWRAPI(Shutdown) (void);
#endif
// Use standart Init and Shutdown functions
EXPORT INT32 HWRAPI (Startup) (I_Error_t FatalErrorFunction, snddev_t *snd_dev);
EXPORT u_int HWRAPI (AddSfx) (sfx_data_t *sfx);
EXPORT INT32 HWRAPI (AddSource) (source3D_data_t *src, u_int sfxhandle);
EXPORT INT32 HWRAPI (StartSource) (INT32 handle);
EXPORT void HWRAPI (StopSource) (INT32 handle);
EXPORT INT32 HWRAPI (GetHW3DSVersion) (void);
EXPORT void HWRAPI (BeginFrameUpdate) (void);
EXPORT void HWRAPI (EndFrameUpdate) (void);
EXPORT INT32 HWRAPI (IsPlaying) (INT32 handle);
EXPORT void HWRAPI (UpdateListener) (listener_data_t *data, INT32 num);
EXPORT void HWRAPI (UpdateSourceParms) (INT32 handle, INT32 vol, INT32 sep);
EXPORT void HWRAPI (SetGlobalSfxVolume) (INT32 volume);
EXPORT INT32 HWRAPI (SetCone) (INT32 handle, cone_def_t *cone_def);
EXPORT void HWRAPI (Update3DSource) (INT32 handle, source3D_pos_t *data);
EXPORT INT32 HWRAPI (ReloadSource) (INT32 handle, u_int sfxhandle);
EXPORT void HWRAPI (KillSource) (INT32 handle);
EXPORT void HWRAPI (KillSfx) (u_int sfxhandle);
EXPORT void HWRAPI (GetHW3DSTitle) (char *buf, size_t size);
#if !defined (_CREATE_DLL_)
struct hardware3ds_s
{
Startup pfnStartup;
AddSfx pfnAddSfx;
AddSource pfnAddSource;
StartSource pfnStartSource;
StopSource pfnStopSource;
GetHW3DSVersion pfnGetHW3DSVersion;
BeginFrameUpdate pfnBeginFrameUpdate;
EndFrameUpdate pfnEndFrameUpdate;
IsPlaying pfnIsPlaying;
UpdateListener pfnUpdateListener;
UpdateSourceParms pfnUpdateSourceParms;
SetGlobalSfxVolume pfnSetGlobalSfxVolume;
SetCone pfnSetCone;
Update3DSource pfnUpdate3DSource;
ReloadSource pfnReloadSource;
KillSource pfnKillSource;
KillSfx pfnKillSfx;
Shutdown pfnShutdown;
GetHW3DSTitle pfnGetHW3DSTitle;
};
extern struct hardware3ds_s hw3ds_driver;
#define HW3DS hw3ds_driver
#endif // _CREATE_DLL_
#endif // __HW_3DS_DRV_H__
+996
View File
@@ -0,0 +1,996 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief Hardware 3D sound general code
#include "../doomdef.h"
#ifdef HW3SOUND
#include "../i_sound.h"
#include "../s_sound.h"
#include "../w_wad.h"
#include "../z_zone.h"
#include "../g_game.h"
#include "../tables.h"
#include "../sounds.h"
#include "../r_main.h"
#include "../r_things.h"
#include "../m_random.h"
#include "../p_local.h"
#include "hw3dsdrv.h"
#include "hw3sound.h"
#define ANGLE2DEG(x) (((double)(x)) / ((double)ANGLE_45/45))
#define NORM_PITCH 128
#define NORM_PRIORITY 64
#define NORM_SEP 128
#if 1
#define TPS(x) (x)
#else //Alam_GBC: MPS, not MPF!
#define TPS(x) ((float)(x)/(float)TICRATE)
#endif
struct hardware3ds_s hw3ds_driver;
typedef struct source_s
{
sfxinfo_t *sfxinfo;
const void *origin;
INT32 handle; // Internal source handle
channel_type_t type; // Sound type (attack, scream, etc)
} source_t;
typedef struct ambient_sdata_s
{
source3D_data_t left;
source3D_data_t right;
} ambient_sdata_t;
typedef struct ambient_source_s
{
source_t left;
source_t right;
} ambient_source_t;
// Static sources
// This sources always creates
static source_t p_attack_source; // Player attack source
static source_t p_attack_source2; // Player2 attack source
static source_t p_scream_source; // Player scream source
static source_t p_scream_source2; // Player2 scream source
static ambient_source_t ambient_source; // Ambinet sound sources
// abuse???
//static source3D_data_t p_attack_sdata; // ?? Now just holds precalculated player attack source data
//static source3D_data_t p_default_sdata;// ?? ---- // ---- // ---- // ---- player scream source data
static ambient_sdata_t ambient_sdata; // Precalculated datas of an ambient sound sources
// Stack of dynamic sources
static source_t *sources = NULL; // Much like original channels
static INT32 num_sources = 0;
// Current mode of 3D sound system
// Default is original (stereo) mode
INT32 hws_mode = HWS_DEFAULT_MODE;
//=============================================================================
void HW3S_SetSourcesNum(void)
{
INT32 i;
// Allocating the internal channels for mixing
// (the maximum number of sounds rendered
// simultaneously) within zone memory.
if (sources)
HW3S_StopSounds();
Z_Free(sources);
if (cv_numChannels.value <= STATIC_SOURCES_NUM)
I_Error("HW3S_SetSourcesNum: Number of sound sources cannot be less than %d\n", STATIC_SOURCES_NUM + 1);
num_sources = cv_numChannels.value - STATIC_SOURCES_NUM;
sources = (source_t *) Z_Malloc(num_sources * sizeof (*sources), PU_STATIC, 0);
// Free all channels for use
for (i = 0; i < num_sources; i++)
{
sources[i].sfxinfo = NULL;
sources[i].type = CT_NORMAL;
sources[i].handle = -1;
}
}
//=============================================================================
static void HW3S_KillSource(INT32 snum)
{
source_t * s = &sources[snum];
if (s->sfxinfo)
{
HW3DS.pfnStopSource(s->handle);
HW3DS.pfnKillSource(s->handle);
s->handle = -1;
s->sfxinfo->usefulness--;
s->origin = NULL;
s->sfxinfo = NULL;
}
}
//=============================================================================
/*
static void HW3S_StopSource(INT32 snum)
{
source_t * s = &sources[snum];
if (s->sfxinfo)
{
// stop the sound playing
HW3DS.pfnStopSource(s->handle);
}
}
*/
//=============================================================================
void HW3S_StopSound(void *origin)
{
INT32 snum;
for (snum = 0; snum < num_sources; snum++)
{
if (sources[snum].sfxinfo && sources[snum].origin == origin)
{
HW3S_KillSource(snum);
break;
}
}
}
void HW3S_StopSoundByID(void *origin, sfxenum_t sfx_id)
{
INT32 snum;
for (snum = 0; snum < num_sources; snum++)
{
if (sources[snum].sfxinfo == &S_sfx[sfx_id] && sources[snum].origin == origin)
{
HW3S_KillSource(snum);
break;
}
}
}
void HW3S_StopSoundByNum(sfxenum_t sfxnum)
{
INT32 snum;
for (snum = 0; snum < num_sources; snum++)
{
if (sources[snum].sfxinfo == &S_sfx[sfxnum])
{
HW3S_KillSource(snum);
break;
}
}
}
//=============================================================================
void HW3S_StopSounds(void)
{
INT32 snum;
// kill all playing sounds at start of level
// (trust me - a good idea)
for (snum = 0; snum < num_sources; snum++)
if (sources[snum].sfxinfo)
HW3S_KillSource(snum);
// Also stop all static sources
HW3DS.pfnStopSource(p_attack_source.handle);
HW3DS.pfnStopSource(p_attack_source2.handle);
HW3DS.pfnStopSource(p_scream_source.handle);
HW3DS.pfnStopSource(p_scream_source2.handle);
HW3DS.pfnStopSource(ambient_source.left.handle);
HW3DS.pfnStopSource(ambient_source.right.handle);
}
//=============================================================================
static INT32 HW3S_GetSource(const void *origin, sfxinfo_t *sfxinfo, boolean splitsound)
{
//
// If none available, return -1. Otherwise source #.
// source number to use
INT32 snum;
source_t * src;
INT32 sep = NORM_SEP, pitch = NORM_PITCH, volume = 255;
(void)splitsound;
// Find an open source
for (snum = 0, src = sources; snum < num_sources; src++, snum++)
{
if (!src->sfxinfo)
break;
#if 0
if (origin && src->origin == origin)
{
HW3S_KillSource(snum);
break;
}
#endif
}
#if 0
// Check to see if it is audible
if (origin && origin != listenmobj)
{
INT32 rc;
rc = S_AdjustSoundParams(listenmobj, origin, &volume, &sep, &pitch, sfxinfo);
if (!rc)
return -1;
}
#else
(void)origin;
(void)pitch;
(void)volume;
(void)sep;
#endif
// None available
if (snum == num_sources)
{
// Look for lower priority
for (snum = 0, src = sources; snum < num_sources; src++, snum++)
if (src->sfxinfo->priority <= sfxinfo->priority)
break;
if (snum == num_sources)
{
// No lower priority. Sorry, Charlie.
return -1;
}
else
{
// Otherwise, kick out lower priority
HW3S_KillSource(snum);
}
}
return snum;
}
//=============================================================================
static void HW3S_FillSourceParameters
(const mobj_t *origin,
source3D_data_t *data,
channel_type_t c_type)
{
fixed_t x = 0, y = 0, z = 0;
data->max_distance = MAX_DISTANCE;
data->min_distance = MIN_DISTANCE;
if (origin && origin != players[displayplayers[0]].mo)
{
data->head_relative = false;
data->pos.momx = TPS(FIXED_TO_FLOAT(origin->momx));
data->pos.momy = TPS(FIXED_TO_FLOAT(origin->momy));
data->pos.momz = TPS(FIXED_TO_FLOAT(origin->momz));
x = origin->x;
y = origin->y;
z = origin->z;
if (c_type == CT_ATTACK)
{
const angle_t an = origin->angle >> ANGLETOFINESHIFT;
x += FixedMul(16*FRACUNIT, FINECOSINE(an));
y += FixedMul(16*FRACUNIT, FINESINE(an));
z += origin->height >> 1;
}
else if (c_type == CT_SCREAM)
z += origin->height - (5 * FRACUNIT);
}
else
{
data->head_relative = true;
data->pos.momx = 0.0f;
data->pos.momy = 0.0f;
data->pos.momz = 0.0f;
}
data->pos.x = FIXED_TO_FLOAT(x);
data->pos.y = FIXED_TO_FLOAT(y);
data->pos.z = FIXED_TO_FLOAT(z);
}
#define HEADER_SIZE 8
//==============================================================
/*
static void make_outphase_sfx(void *dest, void *src, INT32 size)
{
SINT8 *s = (SINT8 *)src + HEADER_SIZE, *d = (SINT8 *)dest + HEADER_SIZE;
M_Memcpy(dest, src, HEADER_SIZE);
size -= HEADER_SIZE;
while (size--)
*d++ = -(*s++);
}
*/
//INT32 HW3S_Start3DSound(const void *origin, source3D_data_t *source_parm, cone_def_t *cone_parm, channel_type_t channel, INT32 sfx_id, INT32 vol, INT32 pitch);
//=============================================================================
INT32 HW3S_I_StartSound(const void *origin_p, source3D_data_t *source_parm, channel_type_t c_type, sfxenum_t sfx_id, INT32 volume, INT32 pitch, INT32 sep)
{
sfxinfo_t *sfx;
const mobj_t *origin = (const mobj_t *)origin_p;
source3D_data_t source3d_data;
INT32 s_num = 0;
source_t *source = NULL;
mobj_t *listenmobj = players[displayplayers[0]].mo; // TODO: Kart 4P does not support sounds properly here
mobj_t *listenmobj2 = NULL;
if (splitscreen) listenmobj2 = players[displayplayers[1]].mo;
if (sound_disabled)
return -1;
sfx = &S_sfx[sfx_id];
if (sfx->skinsound!=-1 && origin && origin->skin)
{
// it redirect player sound to the sound in the skin table
sfx_id = ((skin_t *)origin->skin)->soundsid[sfx->skinsound];
sfx = &S_sfx[sfx_id];
}
if (!sfx->data)
sfx->data = HW3S_GetSfx(sfx);
// judgecutor 08-16-2002
// Sound pitching for both Doom and Heretic
#if 0
if (cv_rndsoundpitch.value)
{
/*if (gamemode != heretic)
{
if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit)
pitch += 8 - (M_RandomByte()&15);
else if (sfx_id != sfx_itemup && sfx_id != sfx_tink)
pitch += 16 - (M_RandomByte()&31);
}
else*/
pitch = 128 + (M_RandomByte() & 7) - (M_RandomByte() & 7);
}
#endif
if (pitch < 0)
pitch = NORMAL_PITCH;
if (pitch > 255)
pitch = 255;
if (sep < 0)
sep = 128;
if (splitscreen && listenmobj2) // Copy the sound for the split player
{
if (c_type != CT_NORMAL && origin && (origin == listenmobj2))
{
if (c_type == CT_ATTACK)
{
if (origin == listenmobj2)
source = &p_attack_source;
else
source = &p_attack_source2;
}
else
{
if (origin == listenmobj2)
source = &p_scream_source;
else
source = &p_scream_source2;
}
if (source->sfxinfo != sfx)
{
HW3DS.pfnStopSource(source->handle);
source->handle = HW3DS.pfnReloadSource(source->handle, sfx->volume);
//I_OutputMsg("PlayerSound data reloaded\n");
}
}
else if (c_type == CT_AMBIENT)
{
// sfx_data_t outphased_sfx;
if (ambient_source.left.sfxinfo != sfx)
{
HW3DS.pfnStopSource(ambient_source.left.handle);
HW3DS.pfnStopSource(ambient_source.right.handle);
// judgecutor:
// Outphased sfx's temporarily not used!!!
/*
outphased_sfx.data = Z_Malloc(sfx_data.length, PU_STATIC, 0);
make_outphase_sfx(outphased_sfx.data, sfx_data.data, sfx_data.length);
outphased_sfx.length = sfx_data.length;
outphased_sfx.id = sfx_data.id;
*/
ambient_source.left.handle = HW3DS.pfnReloadSource(ambient_source.left.handle, (u_int)sfx->length);
//ambient_source.right.handle = HW3DS.pfnReloadSource(ambient_source.right.handle, &outphased_sfx);
ambient_source.right.handle = HW3DS.pfnReloadSource(ambient_source.right.handle, (u_int)sfx->length);
ambient_source.left.sfxinfo = ambient_source.right.sfxinfo = sfx;
//Z_Free(outphased_sfx.data);
}
HW3DS.pfnUpdateSourceParms(ambient_source.left.handle, volume, -1);
HW3DS.pfnUpdateSourceParms(ambient_source.right.handle, volume, -1);
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
// Ambient sound is special case
HW3DS.pfnStartSource(ambient_source.left.handle);
HW3DS.pfnStartSource(ambient_source.right.handle);
}
else
{
s_num = HW3S_GetSource(origin, sfx, true);
if (s_num < 0)
{
//I_OutputMsg("No free source, aborting\n");
return -1;
}
source = &sources[s_num];
if (origin && c_type == CT_NORMAL)
{
if (!source_parm)
{
source_parm = &source3d_data;
source3d_data.permanent = 0;
HW3S_FillSourceParameters(origin, source_parm, c_type);
}
source->handle = HW3DS.pfnAddSource(source_parm, (u_int)sfx->length);
}
else
source->handle = HW3DS.pfnAddSource(NULL, (u_int)sfx->length);
}
// increase the usefulness
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
source->sfxinfo = sfx;
source->origin = origin;
HW3DS.pfnStartSource(source->handle);
}
if (c_type != CT_NORMAL && origin && (origin == listenmobj))
{
if (c_type == CT_ATTACK)
{
if (origin == listenmobj)
source = &p_attack_source;
else
source = &p_attack_source2;
}
else
{
if (origin == listenmobj)
source = &p_scream_source;
else
source = &p_scream_source2;
}
if (source->sfxinfo != sfx)
{
HW3DS.pfnStopSource(source->handle);
source->handle = HW3DS.pfnReloadSource(source->handle, sfx->volume);
//I_OutputMsg("PlayerSound data reloaded\n");
}
}
else if (c_type == CT_AMBIENT)
{
// sfx_data_t outphased_sfx;
if (ambient_source.left.sfxinfo != sfx)
{
HW3DS.pfnStopSource(ambient_source.left.handle);
HW3DS.pfnStopSource(ambient_source.right.handle);
// judgecutor:
// Outphased sfx's temporarily not used!!!
/*
outphased_sfx.data = Z_Malloc(sfx_data.length, PU_STATIC, 0);
make_outphase_sfx(outphased_sfx.data, sfx_data.data, sfx_data.length);
outphased_sfx.length = sfx_data.length;
outphased_sfx.id = sfx_data.id;
*/
ambient_source.left.handle = HW3DS.pfnReloadSource(ambient_source.left.handle, (u_int)sfx->length);
//ambient_source.right.handle = HW3DS.pfnReloadSource(ambient_source.right.handle, &outphased_sfx);
ambient_source.right.handle = HW3DS.pfnReloadSource(ambient_source.right.handle, (u_int)sfx->length);
ambient_source.left.sfxinfo = ambient_source.right.sfxinfo = sfx;
//Z_Free(outphased_sfx.data);
}
HW3DS.pfnUpdateSourceParms(ambient_source.left.handle, volume, -1);
HW3DS.pfnUpdateSourceParms(ambient_source.right.handle, volume, -1);
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
// Ambient sound is special case
HW3DS.pfnStartSource(ambient_source.left.handle);
HW3DS.pfnStartSource(ambient_source.right.handle);
return -1;
}
else
{
s_num = HW3S_GetSource(origin, sfx, false);
if (s_num < 0)
{
//I_OutputMsg("No free source, aborting\n");
return -1;
}
source = &sources[s_num];
if (origin && c_type == CT_NORMAL)
{
if (!source_parm)
{
source_parm = &source3d_data;
source3d_data.permanent = 0;
HW3S_FillSourceParameters(origin, source_parm, c_type);
}
source->handle = HW3DS.pfnAddSource(source_parm, (u_int)sfx->length);
}
else
source->handle = HW3DS.pfnAddSource(NULL, (u_int)sfx->length);
}
// increase the usefulness
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
source->sfxinfo = sfx;
source->origin = origin;
HW3DS.pfnStartSource(source->handle);
return s_num;
}
// Start normal sound
//=============================================================================
void HW3S_StartSound(const void *origin, sfxenum_t sfx_id)
{
HW3S_I_StartSound(origin, NULL, CT_NORMAL, sfx_id, 255, NORMAL_PITCH, NORMAL_SEP);
}
//=============================================================================
void S_StartAttackSound(const void *origin, sfxenum_t sfx_id)
{
if (hws_mode != HWS_DEFAULT_MODE)
HW3S_I_StartSound(origin, NULL, CT_ATTACK, sfx_id, 255, NORMAL_PITCH, NORMAL_SEP);
else
S_StartSound(origin, sfx_id);
}
void S_StartScreamSound(const void *origin, sfxenum_t sfx_id)
{
if (hws_mode != HWS_DEFAULT_MODE)
HW3S_I_StartSound(origin, NULL, CT_SCREAM, sfx_id, 255, NORMAL_PITCH, NORMAL_SEP);
else
S_StartSound(origin, sfx_id);
}
#if 0 /// NOTE: not used
void S_StartAmbientSound(sfxenum_t sfx_id, INT32 volume)
{
if (hws_mode != HWS_DEFAULT_MODE)
{
volume += 30;
if (volume > 255)
volume = 255;
HW3S_I_StartSound(NULL, NULL, CT_AMBIENT, sfx_id, volume, NORMAL_PITCH, NORMAL_SEP);
}
else
S_StartSoundAtVolume(NULL, sfx_id, volume);
}
#endif
FUNCMATH static inline float AmbientPos(angle_t an)
{
const fixed_t fm = FixedMul(FLOAT_TO_FIXED(MIN_DISTANCE), FINESINE(an>>ANGLETOFINESHIFT));
return FIXED_TO_FLOAT(fm);
}
//=============================================================================
INT32 HW3S_Init(I_Error_t FatalErrorFunction, snddev_t *snd_dev)
{
INT32 succ;
source3D_data_t source_data;
if (HW3DS.pfnStartup(FatalErrorFunction, snd_dev))
{
// Attack source
source_data.head_relative = 1;
source_data.pos.x = 0.0f;
source_data.pos.y = 16.0f;
source_data.pos.z = -FIXED_TO_FLOAT(mobjinfo[MT_PLAYER].height >> 1);
source_data.pos.momx = 0.0f;
source_data.pos.momy = 0.0f;
source_data.pos.momz = 0.0f;
source_data.min_distance = MIN_DISTANCE;
source_data.max_distance = MAX_DISTANCE;
source_data.permanent = 1;
p_attack_source.sfxinfo = NULL;
M_Memcpy(&p_attack_source2, &p_attack_source, sizeof (source_t));
p_attack_source.handle = HW3DS.pfnAddSource(&source_data, sfx_None);
p_attack_source2.handle = HW3DS.pfnAddSource(&source_data, sfx_None);
// Scream source
source_data.pos.y = 0;
source_data.pos.z = 0;
p_scream_source.sfxinfo = NULL;
M_Memcpy(&p_scream_source2, &p_scream_source, sizeof (source_t));
p_scream_source.handle = HW3DS.pfnAddSource(&source_data, sfx_None);
p_scream_source2.handle = HW3DS.pfnAddSource(&source_data, sfx_None);
//FIXED_TO_FLOAT(mobjinfo[MT_PLAYER].height - (5 * FRACUNIT));
// Ambient sources (left and right) at 210 and 330 degree
// relative to listener
memset(&ambient_sdata, 0, sizeof (ambient_sdata));
ambient_sdata.left.head_relative = 1;
ambient_sdata.left.pos.x = ambient_sdata.left.pos.y = AmbientPos(ANG210);
ambient_sdata.left.max_distance = MAX_DISTANCE;
ambient_sdata.left.min_distance = MIN_DISTANCE;
ambient_sdata.left.permanent = 1;
M_Memcpy(&ambient_sdata.right, &ambient_sdata.left, sizeof (source3D_data_t));
ambient_sdata.right.pos.x = -ambient_sdata.left.pos.x;
ambient_source.left.handle = HW3DS.pfnAddSource(&ambient_sdata.left, sfx_None);
ambient_source.right.handle = HW3DS.pfnAddSource(&ambient_sdata.right, sfx_None);
succ = p_attack_source.handle > -1 && p_scream_source.handle > -1 &&
p_attack_source2.handle > -1 && p_scream_source2.handle > -1 &&
ambient_source.left.handle > -1 && ambient_source.right.handle > -1;
//I_OutputMsg("Player handles: attack %d, default %d\n", p_attack_source.handle, p_scream_source.handle);
return succ;
}
return 0;
}
//=============================================================================
INT32 HW3S_GetVersion(void)
{
return HW3DS.pfnGetHW3DSVersion();
}
//=============================================================================
void HW3S_BeginFrameUpdate(void)
{
if (hws_mode != HWS_DEFAULT_MODE)
HW3DS.pfnBeginFrameUpdate();
}
//=============================================================================
void HW3S_EndFrameUpdate(void)
{
if (hws_mode != HWS_DEFAULT_MODE)
HW3DS.pfnEndFrameUpdate();
}
//=============================================================================
INT32 HW3S_SoundIsPlaying(INT32 handle)
{
return HW3DS.pfnIsPlaying(handle);
}
INT32 HW3S_OriginPlaying(void *origin)
{
INT32 snum;
if (!origin)
return 0;
for (snum = 0; snum < num_sources; snum++)
if (sources[snum].origin == origin)
return 1;
return 0;
}
INT32 HW3S_IdPlaying(sfxenum_t id)
{
INT32 snum;
for (snum = 0; snum < num_sources; snum++)
if ((size_t)(sources[snum].sfxinfo - S_sfx) == (size_t)id)
return 1;
return 0;
}
INT32 HW3S_SoundPlaying(void *origin, sfxenum_t id)
{
INT32 snum;
if (!origin)
return 0;
for (snum = 0; snum < num_sources; snum++)
{
if (sources[snum].origin == origin
&& (size_t)(sources[snum].sfxinfo - S_sfx) == (size_t)id)
return 1;
}
return 0;
}
//=============================================================================
static void HW3S_UpdateListener(mobj_t *listener)
{
listener_data_t data;
if (!listener || !listener->player)
return;
if (camera.chase)
{
data.x = FIXED_TO_FLOAT(camera.x);
data.y = FIXED_TO_FLOAT(camera.y);
data.z = FIXED_TO_FLOAT(camera.z + camera.height - (5 * FRACUNIT));
data.f_angle = ANGLE2DEG(camera.angle);
data.h_angle = ANGLE2DEG(camera.aiming);
data.momx = TPS(FIXED_TO_FLOAT(camera.momx));
data.momy = TPS(FIXED_TO_FLOAT(camera.momy));
data.momz = TPS(FIXED_TO_FLOAT(camera.momz));
}
else
{
data.x = FIXED_TO_FLOAT(listener->x);
data.y = FIXED_TO_FLOAT(listener->y);
data.z = FIXED_TO_FLOAT(listener->z + listener->height - (5 * FRACUNIT));
data.f_angle = ANGLE2DEG(listener->angle);
data.h_angle = ANGLE2DEG(listener->player->aiming);
data.momx = TPS(FIXED_TO_FLOAT(listener->momx));
data.momy = TPS(FIXED_TO_FLOAT(listener->momy));
data.momz = TPS(FIXED_TO_FLOAT(listener->momz));
}
HW3DS.pfnUpdateListener(&data, 1);
}
static void HW3S_UpdateListener2(mobj_t *listener)
{
listener_data_t data;
if (!listener || !listener->player)
{
HW3DS.pfnUpdateListener(NULL, 2);
return;
}
if (camera2.chase)
{
data.x = FIXED_TO_FLOAT(camera2.x);
data.y = FIXED_TO_FLOAT(camera2.y);
data.z = FIXED_TO_FLOAT(camera2.z + camera2.height - (5 * FRACUNIT));
data.f_angle = ANGLE2DEG(camera2.angle);
data.h_angle = ANGLE2DEG(camera2.aiming);
data.momx = TPS(FIXED_TO_FLOAT(camera2.momx));
data.momy = TPS(FIXED_TO_FLOAT(camera2.momy));
data.momz = TPS(FIXED_TO_FLOAT(camera2.momz));
}
else
{
data.x = FIXED_TO_FLOAT(listener->x);
data.y = FIXED_TO_FLOAT(listener->y);
data.z = FIXED_TO_FLOAT(listener->z + listener->height - (5 * FRACUNIT));
data.f_angle = ANGLE2DEG(listener->angle);
data.h_angle = ANGLE2DEG(listener->player->aiming);
data.momx = TPS(FIXED_TO_FLOAT(listener->momx));
data.momy = TPS(FIXED_TO_FLOAT(listener->momy));
data.momz = TPS(FIXED_TO_FLOAT(listener->momz));
}
HW3DS.pfnUpdateListener(&data, 2);
}
void HW3S_SetSfxVolume(INT32 volume)
{
HW3DS.pfnSetGlobalSfxVolume(volume);
}
static void HW3S_Update3DSource(source_t *src)
{
source3D_data_t data;
data.permanent = 0;
HW3S_FillSourceParameters(src->origin, &data, src->type);
HW3DS.pfnUpdate3DSource(src->handle, &data.pos);
}
void HW3S_UpdateSources(void)
{
mobj_t *listener = players[displayplayers[0]].mo;
mobj_t *listener2 = NULL;
source_t *src;
INT32 audible, snum, volume, sep, pitch;
if (splitscreen) listener2 = players[displayplayers[1]].mo;
HW3S_UpdateListener2(listener2);
HW3S_UpdateListener(listener);
for (snum = 0, src = sources; snum < num_sources; src++, snum++)
{
if (src->sfxinfo)
{
#if 0
if (HW3DS.pfnIsPlaying(src->handle))
{
if (src->origin)
{
// initialize parameters
volume = 255; // 8 bits internal volume precision
pitch = NORM_PITCH;
sep = NORM_SEP;
// check non-local sounds for distance clipping
// or modify their params
if (src->origin && listener != src->origin && !(listener2 && src->origin == listener2))
{
INT32 audible2;
INT32 volume2 = volume, sep2 = sep, pitch2 = pitch;
audible = S_AdjustSoundParams(listener, src->origin, &volume, &sep, &pitch,
src->sfxinfo);
if (listener2)
{
audible2 = S_AdjustSoundParams(listener2,
src->origin, &volume2, &sep2, &pitch2, src->sfxinfo);
if (audible2 && (!audible || (audible && volume2 > volume)))
{
audible = true;
volume = volume2;
sep = sep2;
pitch = pitch2;
}
}
if (audible)
HW3S_Update3DSource(src); // Update positional sources
else
HW3S_KillSource(snum); //Kill it!
}
}
}
else
{
// Source allocated but stopped. Kill.
HW3S_KillSource(snum);
}
#else
if (src->origin && listener != src->origin && !(listener2 && src->origin == listener2))
HW3S_Update3DSource(src); // Update positional sources
(void)pitch;
(void)sep;
(void)volume;
(void)audible;
#endif
}
}
}
void HW3S_Shutdown(void)
{
HW3DS.pfnShutdown();
}
void *HW3S_GetSfx(sfxinfo_t *sfx)
{
sfx_data_t sfx_data;
if (sfx->lumpnum == LUMPERROR)
sfx->lumpnum = S_GetSfxLumpNum (sfx);
sfx_data.length = W_LumpLength(sfx->lumpnum);
sfx_data.data = Z_Malloc(sfx_data.length, PU_SOUND, &sfx->data);
W_ReadLump(sfx->lumpnum, sfx_data.data);
sfx_data.priority = sfx->priority;
sfx->length = HW3DS.pfnAddSfx(&sfx_data);
Z_ChangeTag(sfx->data, PU_CACHE);
return sfx_data.data;
}
void HW3S_FreeSfx(sfxinfo_t *sfx)
{
INT32 snum;
for (snum = 0; snum < num_sources; snum++)
{
if (sources[snum].sfxinfo == sfx)
{
HW3S_KillSource(snum);
break;
}
}
if (sfx->length > 0)
HW3DS.pfnKillSfx((u_int)sfx->length);
sfx->length = 0;
sfx->lumpnum = LUMPERROR;
Z_Free(sfx->data);
sfx->data = NULL;
}
#endif
+106
View File
@@ -0,0 +1,106 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//-----------------------------------------------------------------------------
/// \file
/// \brief High-level functions of hardware 3D sound
#ifndef __HW3_SOUND_H__
#define __HW3_SOUND_H__
#ifdef HW3SOUND
#include "hws_data.h"
//#include "../s_sound.h"
//#include "../p_mobj.h"
// Default sound mode (original stereo mode)
enum
{
HWS_DEFAULT_MODE = 0,
HWS_DS3D,
HWS_OTHER,
HWS_FMOD3D,
HWS_OPENAL,
};
typedef enum
{
CT_NORMAL = 0,
CT_ATTACK,
CT_SCREAM,
CT_AMBIENT,
} channel_type_t;
extern INT32 hws_mode; // Current sound mode
#if defined (HW3DS) || defined (DOXYGEN)
INT32 HW3S_Init(I_Error_t FatalErrorFunction, snddev_t *snd_dev);
#endif
void HW3S_Shutdown(void);
INT32 HW3S_GetVersion(void);
// Common case - start 3D or 2D source
void HW3S_StartSound(const void *origin, sfxenum_t sfx_id);
// Special cases of 3D sources
void S_StartAmbientSound(sfxenum_t sfx_id, INT32 volume);
void S_StartAttackSound(const void *origin, sfxenum_t sfx_id);
void S_StartScreamSound(const void *origin, sfxenum_t sfx_id);
// Starts 3D sound with specified parameters
// origin - for object movement tracking. NULL are possible value (no movement tracking)
// source_parm - 3D source parameters (position etc.)
// cone_parm - 3D source cone parameters. NULL are possible value (default cone will be used)
// channel -
// sfx_id - sfx id
// vol - sound volume
// pitch - sound pitching value
// Returns: - sound id
INT32 HW3S_I_StartSound(const void *origin, source3D_data_t *source_parm, channel_type_t channel, sfxenum_t sfx_id, INT32 vol, INT32 pitch, INT32 sep);
void HW3S_StopSoundByID(void *origin, sfxenum_t sfx_id);
void HW3S_StopSoundByNum(sfxenum_t sfxnum);
void HW3S_StopSound(void *origin);
void HW3S_StopSounds(void);
void HW3S_BeginFrameUpdate(void);
void HW3S_EndFrameUpdate(void);
void HW3S_UpdateSources(void);
void HW3S_SetSfxVolume(INT32 volume);
// Utility functions
INT32 HW3S_SoundIsPlaying(INT32 handle);
void HW3S_SetSourcesNum(void);
INT32 HW3S_OriginPlaying(void *origin);
INT32 HW3S_IdPlaying(sfxenum_t id);
INT32 HW3S_SoundPlaying(void *origin, sfxenum_t id);
void *HW3S_GetSfx(sfxinfo_t *sfx);
void HW3S_FreeSfx(sfxinfo_t *sfx);
#else // HW3SOUND
//#define S_StartAmbientSound(i,v) S_StartSoundAtVolume(NULL, i, v)
#define S_StartAttackSound S_StartSound
#define S_StartScreamSound S_StartSound
#endif // HW3SOUND
INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source,
INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
#endif // __HW3_SOUND_H__
+28 -20
View File
@@ -141,19 +141,27 @@ static int comparePolygons(const void *p1, const void *p2)
PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
int diff;
INT64 diff64;
UINT32 downloaded1 = 0;
UINT32 downloaded2 = 0;
int shader1 = (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) ? -1 : poly1->shader;
int shader2 = (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) ? -1 : poly2->shader;
int shader1 = poly1->shader;
int shader2 = poly2->shader;
// make skywalls and horizon lines first in order
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
shader1 = -1;
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
shader2 = -1;
diff = shader1 - shader2;
if (diff != 0) return diff;
// skywalls and horizon lines must retain their order for horizon lines to work
if (shader1 == -1 && shader2 == -1)
return poly1 - poly2;
diff = shader1 - shader2;
if (diff != 0) return diff;
UINT32 downloaded1 = poly1->texture ? poly1->texture->downloaded : 0; // there should be a opengl texture name here, usable for comparisons
UINT32 downloaded2 = poly2->texture ? poly2->texture->downloaded : 0;
if (poly1->texture)
downloaded1 = poly1->texture->downloaded; // there should be a opengl texture name here, usable for comparisons
if (poly2->texture)
downloaded2 = poly2->texture->downloaded;
diff64 = downloaded1 - downloaded2;
if (diff64 != 0) return diff64;
@@ -172,10 +180,6 @@ static int comparePolygons(const void *p1, const void *p2)
diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start;
if (diff != 0) return diff;
diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end;
if (diff != 0) return diff;
diff = poly1->surf.LightInfo.directional - poly2->surf.LightInfo.directional;
return diff;
}
@@ -186,15 +190,21 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
int diff;
INT64 diff64;
GLMipmap_t *texture1 = (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) ? NULL : poly1->texture;
GLMipmap_t *texture2 = (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) ? NULL : poly2->texture;
GLMipmap_t *texture1 = poly1->texture;
GLMipmap_t *texture2 = poly2->texture;
UINT32 downloaded1 = 0;
UINT32 downloaded2 = 0;
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
texture1 = NULL;
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
texture2 = NULL;
if (texture1)
downloaded1 = texture1->downloaded; // there should be a opengl texture name here, usable for comparisons
if (texture2)
downloaded2 = texture2->downloaded;
// skywalls and horizon lines must retain their order for horizon lines to work
if (!texture1 && !texture2)
return poly1 - poly2;
UINT32 downloaded1 = texture1 ? texture1->downloaded : 0; // there should be a opengl texture name here, usable for comparisons
UINT32 downloaded2 = texture2 ? texture2->downloaded : 0;
diff64 = downloaded1 - downloaded2;
if (diff64 != 0) return diff64;
@@ -233,7 +243,6 @@ void HWR_RenderBatches(void)
nextSurfaceInfo.LightInfo.fade_end = 0;
nextSurfaceInfo.LightInfo.fade_start = 0;
nextSurfaceInfo.LightInfo.light_level = 0;
nextSurfaceInfo.LightInfo.directional = false;
currently_batching = false;// no longer collecting batches
if (!polygonArraySize)
@@ -385,8 +394,7 @@ void HWR_RenderBatches(void)
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level ||
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end ||
currentSurfaceInfo.LightInfo.directional != nextSurfaceInfo.LightInfo.directional)
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end)
{
changeState = true;
changeSurfaceInfo = true;
+9 -20
View File
@@ -319,7 +319,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe
patch_t *realpatch;
INT32 blockwidth, blockheight, blocksize;
INT32 i, idx;
INT32 i;
boolean skyspecial = false; //poor hack for Legacy large skies..
RGBA_t *palette;
@@ -368,10 +368,12 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe
col = palette[HWR_CHROMAKEY_EQUIVALENTCOLORINDEX];
for (idx = 0, j = 0; j < blockheight; j++)
for (j = 0; j < blockheight; j++)
{
for (i = 0; i < blockwidth; i++, idx++)
for (i = 0; i < blockwidth; i++)
{
int idx = (j*blockwidth+i);
block[4*idx+0] = col.s.red;
block[4*idx+1] = col.s.green;
block[4*idx+2] = col.s.blue;
@@ -384,11 +386,8 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{
realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
if (realpatch != NULL)
{
HWR_DrawTexturePatchInCache(&gltex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
Z_ChangeTag(realpatch, PU_HWRCACHE_UNLOCKED);
}
HWR_DrawTexturePatchInCache(&gltex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
Z_ChangeTag(realpatch, PU_HWRCACHE_UNLOCKED);
}
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
@@ -411,16 +410,6 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe
// patch may be NULL if glMipmap has been initialised already and makebitmap is false
void HWR_MakePatch (patch_t *patch, GLPatch_t *glPatch, GLMipmap_t *glMipmap, boolean makebitmap)
{
if (glMipmap == NULL)
return;
if (patch == NULL || glPatch == NULL)
{
Z_Free(glMipmap->data);
glMipmap->data = NULL;
return;
}
// don't do it twice (like a cache)
if (glMipmap->width == 0)
{
@@ -640,7 +629,8 @@ static void HWR_CacheFlat(GLMipmap_t *glMipmap, lumpnum_t flatlumpnum)
glMipmap->height = (UINT16)pflatsize;
// the flat raw data needn't be converted with palettized textures
W_ReadLump(flatlumpnum, Z_Malloc(size, PU_HWRCACHE, &glMipmap->data));
W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum),
PU_HWRCACHE, &glMipmap->data));
#ifdef GLENCORE
flat = glMipmap->data;
@@ -835,7 +825,6 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
stepy = ((INT32)SHORT(fmheight)<<FRACBITS)/pblockheight;
stepx = ((INT32)SHORT(fmwidth)<<FRACBITS)/pblockwidth;
posy = 0;
for (j = 0; j < pblockheight; j++)
{
posx = 0;
+1 -1
View File
@@ -333,7 +333,7 @@ angle_t gld_FrustumAngle(angle_t tiltangle)
// ok, this is a gross hack that barely works...
// but at least it doesn't overestimate too much...
clipfov = atan(1 / projMatrix[0]) * 360.0f / M_PIl;
clipfov = atan(1 / projMatrix[0]) * 360 / M_PIl;
floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * clipfov / 90.0f;
if (floatangle >= 180.0)
return 0xffffffff;
+29 -21
View File
@@ -121,24 +121,38 @@ typedef struct
poly_t *planepoly; // the generated convex polygon
} extrasubsector_t;
// Kart features
#define USE_FTRANSFORM_ANGLEZ
#define USE_FTRANSFORM_MIRROR
// Vanilla features
//#define USE_MODEL_NEXTFRAME
typedef struct
{
FLOAT x,y,z; // position
#ifdef USE_FTRANSFORM_ANGLEZ
FLOAT anglex, angley, anglez; // aimingangle / viewangle
FLOAT anglex2, anglez2; // secondaries
#else
FLOAT anglex, angley; // aimingangle / viewangle
FLOAT anglex2; // secondaries
#endif
FLOAT scalex, scaley, scalez;
FLOAT fovangle;
FLOAT spritexscale, spriteyscale;
FLOAT fovxangle, fovyangle;
UINT8 splitscreen;
boolean flip; // screenflip
boolean roll;
boolean rollmodel;
SINT8 rollflip;
FLOAT rollangle;
UINT8 rotaxis;
FLOAT centerx, centery;
FLOAT rollx, rollz;
#ifdef USE_FTRANSFORM_MIRROR
boolean mirror; // SRB2Kart: Encore Mode
boolean mirrorflip; // Encore Mode with Flipcam
#endif
boolean shearing; // 14042019
float viewaiming; // 17052019
} FTransform;
@@ -232,22 +246,22 @@ enum EPolyFlags
{
// the first 5 are mutually exclusive
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pixels are discarded (holes in texture)
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture)
PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency
PF_Environment = 0x00000004, // Poly should be drawn environment mapped. (Hurdler: used for text drawing)
PF_Additive = 0x00000008, // Source blending factor is additive.
PF_Subtractive = 0x00000010, // Subtractive color blending
PF_ReverseSubtract = 0x00000020, // Reverse subtract, used in wall splats (decals)
PF_Multiplicative = 0x00000040, // Multiplicative color blending
PF_Fog = 0x20000000, // Fog blocks
PF_NoAlphaTest = 0x40000000, // Disables alpha testing
PF_Blending = (PF_Masked|PF_Translucent|PF_Environment|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Fog) & ~PF_NoAlphaTest,
PF_Additive = 0x00000004, // Poly is added to the frame buffer
PF_Environment = 0x00000008, // Poly should be drawn environment mapped.
// Hurdler: used for text drawing
PF_Substractive = 0x00000010, // for splat
PF_NoAlphaTest = 0x00000020, // hiden param
PF_Fog = 0x00000040, // Fog blocks
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest,
// other flag bits
PF_Occlude = 0x00000100, // Updates the depth buffer
PF_NoDepthTest = 0x00000200, // Disables the depth test mode
PF_Invisible = 0x00000400, // Disables write to color buffer
PF_Decal = 0x00000800, // Enables polygon offset
PF_Occlude = 0x00000100, // Update the depth buffer
PF_NoDepthTest = 0x00000200, // Disable the depth test mode
PF_Invisible = 0x00000400, // Disable write to color buffer
PF_Decal = 0x00000800, // Enable polygon offset
PF_Modulated = 0x00001000, // Modulation (multiply output with constant RGBA)
// When set, pass the color constant into the FSurfaceInfo -> FlatColor
PF_NoTexture = 0x00002000, // Disable texture
@@ -289,7 +303,6 @@ struct FLightInfo
FUINT light_level;
FUINT fade_start;
FUINT fade_end;
boolean directional;
};
typedef struct FLightInfo FLightInfo;
@@ -328,11 +341,6 @@ typedef enum hwdsetspecialstate hwdspecialstate_t;
enum hwdshaderinfo
{
HWD_SHADERINFO_LEVELTIME = 1,
HWD_SHADERINFO_LIGHT_X,
HWD_SHADERINFO_LIGHT_Y,
HWD_SHADERINFO_LIGHT_Z,
HWD_SHADERINFO_LIGHT_CONTRAST,
HWD_SHADERINFO_LIGHT_BACKLIGHT,
};
typedef enum hwdshaderinfo hwdshaderinfo_t;
+67 -94
View File
@@ -62,9 +62,6 @@ static UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229
static UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255};
static UINT8 softwaretranstogl_lo[11] = { 0, 12, 24, 36, 48, 60, 71, 83, 95,111,127};
static const float FLOATBASEVIDWIDTH = (float)BASEVIDWIDTH;
static const float FLOATBASEVIDHEIGHT = (float)BASEVIDHEIGHT;
//
// -----------------+
// HWR_DrawPatch : Draw a 'tile' graphic
@@ -129,14 +126,13 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option)
GL_DrawPolygon(NULL, v, 4, flags);
}
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, INT32 bflags)
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap)
{
FOutVector v[4];
FBITFIELD flags;
float cx = FIXED_TO_FLOAT(x);
float cy = FIXED_TO_FLOAT(y);
UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT);
UINT8 blendmode = ((bflags & V_BLENDMASK) >> V_BLENDSHIFT);
// 3--2
// | /|
@@ -147,9 +143,6 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
if (alphalevel >= 10 && alphalevel < 13)
return;
const float fvw = (float)vid.width;
const float fvh = (float)vid.height;
// make patch ready in hardware cache
if (!colormap)
HWR_GetPatch(gpatch);
@@ -233,21 +226,21 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
Z_Free(realpatch);
}
// centre screen
if (fabsf(fvw - FLOATBASEVIDWIDTH * dupx) > 1.0E-36f)
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (option & V_SNAPTORIGHT)
cx += (fvw - (FLOATBASEVIDWIDTH * dupx));
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += (fvw - (FLOATBASEVIDWIDTH * dupx))/2;
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
if (fabsf(fvh - FLOATBASEVIDHEIGHT * dupy) > 1.0E-36f)
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOTOP)) == (V_SPLITSCREEN|V_SNAPTOTOP))
cy += (fvh/2 - (FLOATBASEVIDHEIGHT/2 * dupy));
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
else if (option & V_SNAPTOBOTTOM)
cy += (fvh - (FLOATBASEVIDHEIGHT * dupy));
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += (fvh - (FLOATBASEVIDHEIGHT * dupy))/2;
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
}
}
}
@@ -264,12 +257,12 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
}
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
cx = -1.0f + (cx / (vid.width / 2.0f));
cy = 1.0f - (cy / (vid.height / 2.0f));
cx = -1 + (cx / (vid.width/2));
cy = 1 - (cy / (vid.height/2));
// fwidth and fheight are similar
fwidth /= fvw / 2.0f;
fheight /= fvh / 2.0f;
fwidth /= vid.width / 2;
fheight /= vid.height / 2;
// set the polygon vertices to the right positions
v[0].x = v[3].x = cx;
@@ -294,11 +287,7 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = gpatch->max_t;
// whoops
if (blendmode)
flags = HWR_GetBlendModeFlag(blendmode+1)|PF_NoDepthTest;
else
flags = PF_Translucent|PF_NoDepthTest;
flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
@@ -306,17 +295,14 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
flags |= PF_ForceWrapY;
// clip it since it is used for bunny scroll in doom I
if (alphalevel)
{
FSurfaceInfo Surf;
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[hudtrans];
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[hudtrans];
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[hudtrans];
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
GL_DrawPolygon(&Surf, v, 4, flags);
}
@@ -341,9 +327,6 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
if (alphalevel >= 10 && alphalevel < 13)
return;
const float fvw = (float)vid.width;
const float fvh = (float)vid.height;
// make patch ready in hardware cache
HWR_GetPatch(gpatch);
@@ -394,21 +377,21 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
Z_Free(realpatch);
}
// centre screen
if (fabsf(fvw - FLOATBASEVIDWIDTH * dupx) > 1.0E-36f)
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (option & V_SNAPTORIGHT)
cx += (fvw - (FLOATBASEVIDWIDTH * dupx));
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += (fvw - (FLOATBASEVIDWIDTH * dupx))/2;
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
if (fabsf(fvh - FLOATBASEVIDHEIGHT * dupy) > 1.0E-36f)
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOTOP)) == (V_SPLITSCREEN|V_SNAPTOTOP))
cy += (fvh/2 - (FLOATBASEVIDHEIGHT/2 * dupy));
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
else if (option & V_SNAPTOBOTTOM)
cy += (fvh - (FLOATBASEVIDHEIGHT * dupy));
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += (fvh - (FLOATBASEVIDHEIGHT * dupy))/2;
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
}
}
}
@@ -440,12 +423,12 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
}
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
cx = -1.0f + (cx / (vid.width / 2.0f));
cy = 1.0f - (cy / (vid.height / 2.0f));
cx = -1 + (cx / (vid.width/2));
cy = 1 - (cy / (vid.height/2));
// fwidth and fheight are similar
fwidth /= fvw / 2.0f;
fheight /= fvh / 2.0f;
fwidth /= vid.width / 2;
fheight /= vid.height / 2;
// set the polygon vertices to the right positions
v[0].x = v[3].x = cx;
@@ -473,12 +456,10 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
{
FSurfaceInfo Surf;
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value];
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[cv_translucenthud.value];
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value];
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
GL_DrawPolygon(&Surf, v, 4, flags);
}
@@ -830,9 +811,6 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
fy = (float)y;
fw = fh = (float)wh;
const float fvw = (float)vid.width;
const float fvh = (float)vid.height;
if (!(color & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
@@ -842,20 +820,20 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
fw *= dupx;
fh *= dupy;
if (fabsf(fvw - (FLOATBASEVIDWIDTH * dupx)) > 1.0E-36f)
if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
{
if (color & V_SNAPTORIGHT)
fx += (fvw - (FLOATBASEVIDWIDTH * dupx));
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += (fvw - (FLOATBASEVIDWIDTH * dupx)) / 2;
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (fabsf(fvh - (FLOATBASEVIDHEIGHT * dupy)) > 1.0E-36f)
if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy));
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(color & V_SNAPTOTOP))
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy)) / 2;
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
}
@@ -876,16 +854,16 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
return;
if (fx + fw > vid.width)
{
fwait = fw - (fvw- fx);
fw = fvw - fx;
fwait = fw - ((float)vid.width - fx);
fw = (float)vid.width - fx;
}
if (fy + fh > vid.height)
fh = fvh - fy;
fh = (float)vid.height - fy;
fx = -1.0f + fx / (vid.width / 2.0f);
fy = 1.0f - fy / (vid.height / 2.0f);
fw = fw / (fvw / 2.0f);
fh = fh / (fvh / 2.0f);
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
@@ -929,9 +907,6 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
fw = (float)w;
fh = (float)h;
const float fvw = (float)vid.width;
const float fvh = (float)vid.height;
if (!(options & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
@@ -953,25 +928,25 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
fw *= dupx;
fh *= dupy;
if (fabsf(fvw - (FLOATBASEVIDWIDTH * dupx)) > 1.0E-36f)
if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
{
if (options & V_SNAPTORIGHT)
fx += (fvw - (FLOATBASEVIDWIDTH * dupx));
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(options & V_SNAPTOLEFT))
fx += (fvw - (FLOATBASEVIDWIDTH * dupx)) / 2;
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (fabsf(fvh - (FLOATBASEVIDHEIGHT * dupy)) > 1.0E-36f)
if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
{
// same thing here
if (options & V_SNAPTOBOTTOM)
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy));
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(options & V_SNAPTOTOP))
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy)) / 2;
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
if (options & V_SPLITSCREEN)
fy += (FLOATBASEVIDHEIGHT * dupy)/2;
fy += ((float)BASEVIDHEIGHT * dupy)/2;
if (options & V_HORZSCREEN)
fx += (FLOATBASEVIDWIDTH * dupx)/2;
fx += ((float)BASEVIDWIDTH * dupx)/2;
}
@@ -991,14 +966,14 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = fvw - fx;
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = fvh - fy;
fh = (float)vid.height - fy;
fx = -1.0f + fx / (vid.width / 2.0f);
fy = 1.0f - fy / (vid.height / 2.0f);
fw = fw / (fvw / 2.0f);
fh = fh / (fvh / 2.0f);
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
@@ -1043,9 +1018,6 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
fw = (float)w;
fh = (float)h;
const float fvw = (float)vid.width;
const float fvh = (float)vid.height;
if (!(color & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
@@ -1067,25 +1039,26 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
fw *= dupx;
fh *= dupy;
if (fabsf(fvw - FLOATBASEVIDWIDTH * dupx) > 1.0E-36f)
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (color & V_SNAPTORIGHT)
fx += (fvw - (FLOATBASEVIDWIDTH * dupx));
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += (fvw - (FLOATBASEVIDWIDTH * dupx)) / 2;
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (fabsf(fvh - FLOATBASEVIDHEIGHT * dupy) > 1.0E-36f)
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy));
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(color & V_SNAPTOTOP))
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy)) / 2;
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
if (color & V_SPLITSCREEN)
fy += (FLOATBASEVIDHEIGHT * dupy)/2;
fy += ((float)BASEVIDHEIGHT * dupy)/2;
if (color & V_HORZSCREEN)
fx += (FLOATBASEVIDWIDTH * dupx)/2;
fx += ((float)BASEVIDWIDTH * dupx)/2;
}
if (fx >= vid.width || fy >= vid.height)
@@ -1104,14 +1077,14 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = fvw - fx;
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = fvh - fy;
fh = (float)vid.height - fy;
fx = -1.0f + fx / (vid.width / 2.0f);
fy = 1.0f - fy / (vid.height / 2.0f);
fw = fw / (fvw / 2.0f);
fh = fh / (fvh / 2.0f);
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
@@ -1154,7 +1127,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
#define _FILE_OFFSET_BITS 0
#endif
#include "png.h"
#include "png.h"
#ifdef PNG_WRITE_SUPPORTED
#define USE_PNG // PNG is only used if write is supported (see ../m_misc.c)
#endif
-2
View File
@@ -43,8 +43,6 @@ typedef struct gl_vissprite_s
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
} gl_vissprite_t;
void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32 *lightlevel, boolean model);
// --------
// hw_bsp.c
// --------
+281 -410
View File
File diff suppressed because it is too large. Load diff
+23 -64
View File
@@ -20,7 +20,6 @@
#ifndef __HWR_MAIN_H__
#define __HWR_MAIN_H__
#include "hw_gl.h"
#include "hw_glob.h"
#include "hw_data.h"
#include "hw_defs.h"
@@ -30,7 +29,6 @@
#include "../d_player.h"
#include "../r_defs.h"
#include "../m_perfstats.h"
#include "../v_video.h"
#define GLENCORE
@@ -58,11 +56,11 @@ extern sector_t *gl_backsector;
enum
{
HWR_STENCIL_NORMAL,
HWR_STENCIL_BEGIN,
HWR_STENCIL_REVERSE,
HWR_STENCIL_DEPTH,
HWR_STENCIL_SKY
HWR_STENCIL_NORMAL,
HWR_STENCIL_BEGIN,
HWR_STENCIL_REVERSE,
HWR_STENCIL_DEPTH,
HWR_STENCIL_SKY
};
// Performance stats
@@ -86,7 +84,7 @@ extern boolean gl_shadersavailable;
// hw_draw.c
void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, INT32 bflags);
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap);
void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right.
@@ -104,65 +102,39 @@ boolean HWR_Screenshot(const char *lbmname);
void HWR_SetViewSize(void);
void HWR_AddCommands(void);
void HWR_RenderPlayerView(void);
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player);
void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, player_t *player, int stencil_level, boolean allow_portals);
void HWR_ClearSkyDome(void);
void HWR_BuildSkyDome(void);
void HWR_SetTransform(float fpov);
void HWR_SetTransform(float fpov, player_t *player);
void HWR_ClearClipper(void);
void HWR_SetStencilState(int state, int level);
boolean HWR_UseShader(void);
boolean HWR_ShouldUsePaletteRendering(void);
boolean HWR_PalRenderFlashpal(void);
// My original intention was to split hw_main.c
// into files like hw_bsp.c, hw_sprites.c...
// hw_main.c: Lighting and fog
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap, const boolean directional);
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum);
FBITFIELD HWR_GetBlendModeFlag(INT32 ast);
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf);
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
// Get amount of memory used by gpu textures in bytes;
FUNCINLINE static ATTRINLINE INT32 HWR_GetTextureUsed(void)
{
return GL_GetTextureUsed();
}
// Get amount of memory used by gpu textures in bytes
INT32 HWR_GetTextureUsed(void);
// hw_main.c: Post-rendering
void HWR_StartScreenWipe(void);
void HWR_EndScreenWipe(void);
void HWR_DrawIntermissionBG(void);
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
FUNCINLINE static ATTRINLINE void HWR_StartScreenWipe(void)
{
GL_MakeScreenTexture(HWD_SCREENTEXTURE_WIPE_START);
}
FUNCINLINE static ATTRINLINE void HWR_EndScreenWipe(void)
{
GL_MakeScreenTexture(HWD_SCREENTEXTURE_WIPE_END);
}
FUNCINLINE static ATTRINLINE void HWR_DrawIntermissionBG(void)
{
GL_DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0);
}
FUNCINLINE static ATTRINLINE void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
{
GL_RenderVhsEffect(upbary, downbary, updistort, downdistort, barsize);
}
FUNCINLINE static ATTRINLINE void HWR_MakeScreenFinalTexture(void)
{
GL_MakeScreenTexture(HWD_SCREENTEXTURE_GENERIC2);
}
FUNCINLINE static ATTRINLINE void HWR_DrawScreenFinalTexture(INT32 width, INT32 height, boolean useshader)
{
GL_DrawScreenFinalTexture(HWD_SCREENTEXTURE_GENERIC2, width, height, useshader);
}
void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
void HWR_MakeScreenFinalTexture(void);
void HWR_DrawScreenFinalTexture(INT32 width, INT32 height, boolean useshader);
// hw_main.c: Segs
void HWR_ProcessSeg(void); // Sort of like GLWall::Process in GZDoom
@@ -209,23 +181,10 @@ extern consvar_t cv_glrenderdistance;
extern consvar_t cv_glhorizonlines;
extern consvar_t cv_glportals;
extern consvar_t cv_glfovchange;
extern consvar_t cv_glpaletterendering;
extern consvar_t cv_glpalettedepth;
extern consvar_t cv_glflashpal;
FUNCINLINE static ATTRINLINE boolean HWR_UseShader(void)
{
return (cv_glshaders.value && gl_shadersavailable);
}
FUNCINLINE static ATTRINLINE boolean HWR_ShouldUsePaletteRendering(void)
{
return (cv_glpaletterendering.value && (pLocalPalette != NULL) && HWR_UseShader());
}
FUNCINLINE static ATTRINLINE boolean HWR_PalRenderFlashpal(void)
{
return (HWR_ShouldUsePaletteRendering() && cv_glflashpal.value);
}
#endif
+90 -57
View File
@@ -1120,7 +1120,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
{
sector_t *sector = spr->mobj->subsector->sector;
extracolormap_t *colormap = sector->extra_colormap;
INT32 lightlevel = 255;
UINT8 lightlevel = 255;
if (sector->numlights)
{
@@ -1143,9 +1143,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
colormap = sector->extra_colormap;
}
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, true);
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !(spr->mobj->frame & FF_FULLBRIGHT));
HWR_Lighting(&Surf, lightlevel, colormap);
}
else
{
@@ -1163,6 +1161,8 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
spritedef_t *sprdef;
spriteframe_t *sprframe;
spriteinfo_t *sprinfo;
INT32 rollfactor = 0;
angle_t ang;
interpmobjstate_t interp;
if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || R_QuickCamDist(spr->mobj->x, spr->mobj->y) < cv_maxinterpdist.value))
@@ -1179,31 +1179,13 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
// Apparently people don't like jump frames like that, so back it goes
//if (tics > durs)
//durs = tics;
INT32 blendmode;
if (spr->mobj->frame & FF_BLENDMASK)
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = spr->mobj->blendmode;
blendmode = min(AST_MODULATE, blendmode);
if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
}
else if (spr->mobj->frame & FF_TRANSMASK)
{
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
Surf.PolyFlags = HWR_SurfaceBlend(blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
}
else
{
// this hack is dumb, but the blendmodes refuse to work otherwise
Surf.PolyColor.s.alpha = (blendmode == AST_TRANSLUCENT) ? 0xFF : 0xFE;
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
}
Surf.PolyColor.s.alpha = 0xFF;
// dont forget to enabled the depth test because we can't do this like
// before: polygons models are not sorted
@@ -1359,7 +1341,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
p.x = FIXED_TO_FLOAT(interp.x);
p.y = FIXED_TO_FLOAT(interp.y)+md2->offset;
if (flip)
if (spr->mobj->eflags & MFE_VERTICALFLIP)
p.z = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
else
p.z = FIXED_TO_FLOAT(interp.z);
@@ -1382,58 +1364,109 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
const fixed_t anglef = AngleFixed((R_PointToAngle(interp.x, interp.y))-ANGLE_180);
p.angley = FIXED_TO_FLOAT(anglef);
}
p.rollangle = 0.0f;
p.rollflip = 1;
p.rotaxis = 0;
p.spritexscale = FIXED_TO_FLOAT(spr->mobj->spritexscale);
p.spriteyscale = FIXED_TO_FLOAT(spr->mobj->spriteyscale);
const angle_t sliptideroll = ((cv_sliptideroll.value && spr->mobj->player) ? spr->mobj->player->sliproll : 0);
const SINT8 flipfactor = flip ? -1 : 1;
angle_t sliptideroll = ((cv_sloperoll.value && cv_sliptideroll.value && spr->mobj->player) ? spr->mobj->player->sliproll : 0);
if (spr->mobj->rollangle || sliptideroll)
{
angle_t rollang = sliptideroll
? (spr->mobj->rollangle) + (sliptideroll * spr->mobj->player->kartstuff[k_aizdriftstrat])
: (spr->mobj->rollangle);
angle_t rollang = 0;
rollfactor = ((spr->mobj->rollmodel == true) ? 1 : 0);
rollang = sliptideroll
? (spr->mobj->rollangle * rollfactor) + (sliptideroll * spr->mobj->player->kartstuff[k_aizdriftstrat])
: (spr->mobj->rollangle * rollfactor);
fixed_t anglef = AngleFixed(rollang);
p.rollangle = FIXED_TO_FLOAT(anglef);
p.rollmodel = (spr->mobj->rollmodel);
p.roll = true;
p.rollangle = 0.0f;
// rotation pivot
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2)*(p.spritexscale);
p.centery = FIXED_TO_FLOAT(spr->mobj->height/2)*(p.spriteyscale);
if (anglef)
{
fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know
// rotation axis
if (sprinfo->available)
p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis);
p.rollangle = FIXED_TO_FLOAT(anglef);
p.roll = true;
// rotation pivot
if (sprinfo->available)
{
p.centerx = FIXED_TO_FLOAT(sprinfo->pivot[frame].x);
p.centery = FIXED_TO_FLOAT(sprinfo->pivot[frame].y);
}
else
{
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height/2);
}
// rotation axes relative to camera
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
}
// for NiGHTS specifically but should work everywhere else
ang = R_PointToAngle (spr->mobj->x, spr->mobj->y) - (spr->mobj->player ? spr->mobj->player->frameangle : spr->mobj->angle);
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
p.rollflip = 1;
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
p.rollflip = -1;
}
// slope pitch and roll
p.anglex += flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.sloperoll));
p.anglez -= flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.slopepitch));
p.anglex = 0.0f;
p.anglex2 = 0.0f;
#ifdef USE_FTRANSFORM_ANGLEZ
// Slope rotation from Kart
p.anglez = 0.0f;
p.anglez2 = 0.0f;
// use secondary angles for the slope rotation
if (spr->mobj->standingslope)
{
fixed_t tempz = spr->mobj->standingslope->normal.z;
fixed_t tempy = spr->mobj->standingslope->normal.y;
fixed_t tempx = spr->mobj->standingslope->normal.x;
fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
p.anglez2 = FIXED_TO_FLOAT(tempangle);
tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy));
p.anglex2 = FIXED_TO_FLOAT(tempangle);
}
else if ((spr->mobj->sloperoll || spr->mobj->slopepitch) && (!P_IsObjectOnGround(spr->mobj)) && (!paused))
{
SINT8 flipfactor = flip ? -1 : 1;
angle_t camang = R_PointToAngle(interp.x, interp.y);
angle_t mobjang;
if (spr->mobj->flags & (MF_NOTHINK|MF_SCENERY))
mobjang = spr->mobj->angle;
else
mobjang = interp.angle;
angle_t fmoang;
fmoang = camang - mobjang;
// slopepitch
p.anglex += flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINESINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.slopepitch)) );
p.anglez -= flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINECOSINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.slopepitch)) );
// sloperoll
p.anglex += flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINECOSINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.sloperoll)) );
p.anglez += flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINESINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.sloperoll)) );
p.roll = true;
}
// pitch and roll
p.anglex += flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.roll));
p.anglez -= flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.pitch));
if (interp.roll || interp.pitch)
{
SINT8 flipfactor = flip ? -1 : 1;
p.anglex += flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.roll));
p.anglez -= flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.pitch));
p.roll = true;
}
#endif
p.flip = atransform.flip;
#ifdef USE_FTRANSFORM_MIRROR
p.mirror = atransform.mirror; // from Kart
#endif
GL_SetShader(SHADER_MODEL); // model shader
{
SINT8 flipfactor = flip ? -1 : 1;
float this_scale = FIXED_TO_FLOAT(interp.scale);
float xs = this_scale * FIXED_TO_FLOAT(interp.spritexscale);
+3 -3
View File
@@ -132,7 +132,7 @@ void HWR_PortalFrame(gl_portal_t* portal)
{
portalclipline = NULL;
portalcullsector = NULL;
viewsector = R_PointInSubsector(viewx, viewy)->sector;
viewsector = R_PointInSubsectorFast(viewx, viewy)->sector;
}
}
@@ -160,7 +160,7 @@ static void HWR_RenderPortalSeg(gl_portal_t* portal, SINT8 state)
void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float fpov, player_t *player, int stencil_level)
{
// draw portal seg to stencil buffer with increment
HWR_SetTransform(fpov);
HWR_SetTransform(fpov, player);
HWR_ClearClipper();
HWR_SetStencilState(HWR_STENCIL_BEGIN, stencil_level);
@@ -180,7 +180,7 @@ void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float
}
// remove portal seg from stencil buffer
HWR_SetTransform(fpov);
HWR_SetTransform(fpov, player);
HWR_ClearClipper();
HWR_SetStencilState(HWR_STENCIL_REVERSE, stencil_level);
+12 -13
View File
@@ -36,7 +36,7 @@ static struct {
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
// Model shader
{GLSL_MODEL_LIGHTING_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
// Water shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WATER_FRAGMENT_SHADER},
@@ -400,18 +400,17 @@ void HWR_CompileShaders(void)
int HWR_GetShaderFromTarget(int shader_target)
{
if (cv_glshaders.value == 1)
{
int custom_shader = gl_shadertargets[shader_target].custom_shader;
// use custom shader if following are true
// - custom shader exists
// - custom shader has been compiled successfully
// - custom shaders are enabled
if (custom_shader != -1 && gl_shaders[custom_shader].compiled)
return custom_shader;
}
return gl_shadertargets[shader_target].base_shader;
int custom_shader = gl_shadertargets[shader_target].custom_shader;
// use custom shader if following are true
// - custom shader exists
// - custom shader has been compiled successfully
// - custom shaders are enabled
// - custom shaders are allowed by the server
if (custom_shader != -1 && gl_shaders[custom_shader].compiled &&
cv_glshaders.value == 1)
return custom_shader;
else
return gl_shadertargets[shader_target].base_shader;
}
static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum)
+2 -36
View File
@@ -31,31 +31,6 @@
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
"}\0"
// reinterpretation of sprite lighting for models
// it's a combination of how it works for normal sprites & papersprites
#define GLSL_MODEL_LIGHTING_VERTEX_SHADER \
"uniform float lighting;\n" \
"uniform vec3 light_dir;\n" \
"uniform float light_contrast;\n" \
"uniform float light_backlight;\n" \
"void main()\n" \
"{\n" \
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
"float light = lighting;\n" \
"if (length(light_dir) > 0.000001) {\n" \
"mat4 m4 = gl_ProjectionMatrix * gl_ModelViewMatrix;\n" \
"mat3 m3 = mat3( m4[0].xyz, m4[1].xyz, m4[2].xyz );\n" \
"float extralight = -dot(normalize(gl_Normal * m3), normalize(light_dir));\n" \
"extralight *= light_contrast - light_backlight;\n" \
"extralight *= lighting / 255.0;\n" \
"light += extralight * 2.5;\n" \
"}\n" \
"light = clamp(light / 255.0, 0.0, 1.0);\n" \
"gl_FrontColor = vec4(light, light, light, 1.0);\n" \
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
"}\0"
// ==================
// Fragment shaders
// ==================
@@ -220,28 +195,21 @@
// hand tuned adjustments for light level calculation
#define GLSL_FLOOR_FUDGES \
"#version 120\n" \
"#define STARTMAP_FUDGE 1.06\n" \
"#define SCALE_FUDGE 1.15\n"
#define GLSL_WALL_FUDGES \
"#version 120\n" \
"#define STARTMAP_FUDGE 1.05\n" \
"#define SCALE_FUDGE 2.2\n"
#define GLSL_FLOOR_FRAGMENT_SHADER \
"#version 120\n" \
GLSL_FLOOR_FUDGES \
GLSL_SOFTWARE_FRAGMENT_SHADER
// this is very backwards
// but we wanna have the game look like vanilla does
// oh well
#define GLSL_WALL_FRAGMENT_SHADER \
"#version 120\n" \
"#ifdef SRB2_PALETTE_RENDERING\n" \
GLSL_WALL_FUDGES \
"#else\n" \
GLSL_FLOOR_FUDGES \
"#endif\n" \
GLSL_SOFTWARE_FRAGMENT_SHADER
//
@@ -259,7 +227,6 @@
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n"
#define GLSL_WATER_FRAGMENT_SHADER \
"#version 120\n" \
GLSL_FLOOR_FUDGES \
"const float freq = 0.025;\n" \
"const float amp = 0.025;\n" \
@@ -308,7 +275,6 @@
// The floor fudges are used, but should the wall fudges be used instead? or something inbetween?
// or separate values for floors and walls? (need to change more than this shader for that)
#define GLSL_FOG_FRAGMENT_SHADER \
"#version 120\n" \
GLSL_FLOOR_FUDGES \
"uniform vec4 tint_color;\n" \
"uniform vec4 fade_color;\n" \
+123
View File
@@ -0,0 +1,123 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2005 by SRB2 Jr. Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief 3D sound definitions
#ifndef __HWS_DATA_H__
#define __HWS_DATA_H__
#define NORMAL_SEP 128
// abuse?
#define STATIC_SOURCES_NUM 6 // Total number of static sources
#define MIN_DISTANCE 160.0f
#define MAX_DISTANCE 1200.0f
typedef struct source_pos_s
{
double x;
double y;
double z;
} source_pos_t;
typedef struct source3D_pos_s
{
float x;
float y;
float z;
//float angle;
float momx;
float momy;
float momz;
} source3D_pos_t;
enum {NORMAL_PITCH = 128};
/*typedef struct source2D_data_s
{
INT32 volume;
INT32 sep;
} source2D_data_t;*/
// General 3D sound source description
typedef struct source3D_data_s
{
float min_distance; //
float max_distance; //
INT32 head_relative; //
INT32 permanent; //
source3D_pos_t pos; // source position in 3D
} source3D_data_t;
// Sound data
typedef struct sfx_data_s
{
size_t length;
void *data;
INT32 priority;
INT32 sep; // Only when source is 2D sound
} sfx_data_t;
// Sound cone (for 3D sources)
typedef struct cone_def_s
{
float inner;
float outer;
INT32 outer_gain;
/*float f_angle;
float h_angle;*/
} cone_def_t;
typedef struct listener_data_s
{
// Listener position
double x;
double y;
double z;
// Listener front and head orientation (degrees)
double f_angle;
double h_angle;
// Listener momentums
double momx;
double momy;
double momz;
} listener_data_t;
typedef struct snddev_s
{
INT32 sample_rate;
INT32 bps;
size_t numsfxs;
// Windows specific data
#ifdef _WIN32
UINT32 cooplevel;
HWND hWnd;
#endif
} snddev_t;
#endif //__HWS_DATA_H__
+231 -301
View File
@@ -109,6 +109,7 @@ static GLint min_filter = GL_LINEAR;
static GLint mag_filter = GL_LINEAR;
static GLint anisotropic_filter = 0;
boolean supportMipMap = false;
static FTransform md2_transform;
const GLubyte *gl_version = NULL;
const GLubyte *gl_renderer = NULL;
@@ -494,10 +495,6 @@ static PFNglDeleteBuffers pglDeleteBuffers;
typedef void (APIENTRY *PFNglColorPointer) (GLint, GLenum, GLsizei, const GLvoid*);
static PFNglColorPointer pglColorPointer;
/* 2.0 functions */
typedef void (APIENTRY * PFNglBlendEquation) (GLenum mode);
static PFNglBlendEquation pglBlendEquation;
/* 1.2 Parms */
/* GL_CLAMP_TO_EDGE_EXT */
#ifndef GL_CLAMP_TO_EDGE
@@ -670,9 +667,6 @@ typedef enum
gluniform_lighting,
gluniform_fade_start,
gluniform_fade_end,
gluniform_light_dir,
gluniform_light_contrast,
gluniform_light_backlight,
// palette rendering
gluniform_palette_tex, // 1d texture containing a palette
@@ -710,11 +704,6 @@ static gl_shaderstate_t gl_shaderstate;
// Shader info
static float shader_leveltime = 0;
static float shader_light_x = 0.0f;
static float shader_light_y = 0.0f;
static float shader_light_z = 0.0f;
static INT32 shader_light_contrast = 0;
static INT32 shader_light_backlight = 0;
// Lactozilla: Shader functions
static boolean GL_Shader_CompileProgram(gl_shader_t *shader, GLint i);
@@ -750,9 +739,6 @@ void SetupGLFunc4(void)
pglBufferData = GetGLFunc("glBufferData");
pglDeleteBuffers = GetGLFunc("glDeleteBuffers");
pglColorPointer = GetGLFunc("glColorPointer");
/* 2.0 funcs */
pglBlendEquation = GetGLFunc("glBlendEquation");
pglStencilFuncSeparate = GetGLFunc("glStencilFuncSeparate");
pglStencilOpSeparate = GetGLFunc("glStencilOpSeparate");
@@ -875,21 +861,6 @@ void GL_SetShaderInfo(hwdshaderinfo_t info, INT32 value)
case HWD_SHADERINFO_LEVELTIME:
shader_leveltime = (((float)(value-1)) + FIXED_TO_FLOAT(rendertimefrac)) / TICRATE;
break;
case HWD_SHADERINFO_LIGHT_X:
shader_light_x = FixedToFloat(value);
break;
case HWD_SHADERINFO_LIGHT_Y:
shader_light_y = FixedToFloat(value);
break;
case HWD_SHADERINFO_LIGHT_Z:
shader_light_z = FixedToFloat(value);
break;
case HWD_SHADERINFO_LIGHT_CONTRAST:
shader_light_contrast = value;
break;
case HWD_SHADERINFO_LIGHT_BACKLIGHT:
shader_light_backlight = value;
break;
default:
break;
}
@@ -1170,7 +1141,7 @@ static void GL_Framebuffer_Delete(void)
FramebufferObject = 0;
}
void GL_Framebuffer_Unbind(void)
inline void GL_Framebuffer_Unbind(void)
{
if (!supportFBO || fboinit == false)
return;
@@ -1182,7 +1153,7 @@ void GL_Framebuffer_Unbind(void)
pglBindRenderbuffer(GL_RENDERBUFFER, 0);
}
void GL_Framebuffer_Enable(void)
inline void GL_Framebuffer_Enable(void)
{
if (!supportFBO || !UseScreenFBO())
return;
@@ -1432,11 +1403,7 @@ void GL_Draw2DLine(F2DCoord * v1, F2DCoord * v2, RGBA_t Color)
pglEnableClientState(GL_TEXTURE_COORD_ARRAY);
pglEnable(GL_TEXTURE_2D);
}
// -----------------+
// SetBlend : Set render mode
// -----------------+
// PF_Masked - we could use an ALPHA_TEST of GL_EQUAL, and alpha ref of 0,
// is it faster when pixels are discarded ?
static void Clamp2D(GLenum pname)
{
pglTexParameteri(GL_TEXTURE_2D, pname, GL_CLAMP); // fallback clamp
@@ -1445,186 +1412,149 @@ static void Clamp2D(GLenum pname)
#endif
}
static void GL_SetBlendEquation(GLenum mode)
{
if (pglBlendEquation)
pglBlendEquation(mode);
}
static void GL_SetBlendMode(FBITFIELD flags)
{
// Set blending function
switch (flags)
{
case PF_Translucent & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
break;
case PF_Masked & PF_Blending:
// Hurdler: does that mean lighting is only made by alpha src?
// it sounds ok, but not for polygonsmooth
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture
break;
case PF_Additive & PF_Blending:
case PF_Subtractive & PF_Blending:
case PF_ReverseSubtract & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
break;
case PF_Environment & PF_Blending:
pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
break;
case PF_Multiplicative & PF_Blending:
pglBlendFunc(GL_DST_COLOR, GL_ZERO);
break;
case PF_Fog & PF_Fog:
// Sryder: Fog
// multiplies input colour by input alpha, and destination colour by input colour, then adds them
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
break;
default: // must be 0, otherwise it's an error
// No blending
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
break;
}
// Set blending equation
switch (flags)
{
case PF_Subtractive & PF_Blending:
GL_SetBlendEquation(GL_FUNC_SUBTRACT);
break;
case PF_ReverseSubtract & PF_Blending:
// good for shadow
// not really but what else ?
GL_SetBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
break;
default:
GL_SetBlendEquation(GL_FUNC_ADD);
break;
}
// Alpha test
switch (flags)
{
case PF_Masked & PF_Blending:
pglAlphaFunc(GL_GREATER, 0.5f);
break;
case PF_Translucent & PF_Blending:
case PF_Additive & PF_Blending:
case PF_Subtractive & PF_Blending:
case PF_ReverseSubtract & PF_Blending:
case PF_Environment & PF_Blending:
case PF_Multiplicative & PF_Blending:
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case PF_Fog & PF_Fog:
pglAlphaFunc(GL_ALWAYS, 0.0f); // Don't discard zero alpha fragments
break;
default:
pglAlphaFunc(GL_GREATER, 0.5f);
break;
}
}
// -----------------+
// SetBlend : Set render mode
// -----------------+
// PF_Masked - we could use an ALPHA_TEST of GL_EQUAL, and alpha ref of 0,
// is it faster when pixels are discarded ?
void GL_SetBlend(FBITFIELD PolyFlags)
{
const FBITFIELD Xor = CurrentPolyFlags^PolyFlags;;
const FBITFIELD Xor = (CurrentPolyFlags ^ PolyFlags);
if (Xor & (PF_Blending|PF_RemoveYWrap|PF_ForceWrapX|PF_ForceWrapY|PF_Occlude|PF_NoTexture|PF_Modulated|PF_NoDepthTest|PF_Decal|PF_Invisible))
if (!(Xor & (PF_Blending|PF_RemoveYWrap|PF_ForceWrapX|PF_ForceWrapY|PF_Occlude|PF_NoTexture|PF_Modulated|PF_NoDepthTest|PF_Decal|PF_Invisible|PF_NoAlphaTest)))
{
if (Xor & PF_Blending) // if blending mode must be changed
GL_SetBlendMode(PolyFlags & PF_Blending);
CurrentPolyFlags = PolyFlags;
return;
}
if (Xor & PF_NoAlphaTest)
if (Xor & PF_Blending) // if blending mode must be changed
{
switch (PolyFlags & PF_Blending)
{
if (PolyFlags & PF_NoAlphaTest)
pglDisable(GL_ALPHA_TEST);
else
pglEnable(GL_ALPHA_TEST); // discard 0 alpha pixels (holes in texture)
}
if (Xor & PF_Decal)
{
if (PolyFlags & PF_Decal)
pglEnable(GL_POLYGON_OFFSET_FILL);
else
pglDisable(GL_POLYGON_OFFSET_FILL);
}
if (Xor & PF_NoDepthTest)
{
if (PolyFlags & PF_NoDepthTest)
pglDepthFunc(GL_ALWAYS); //pglDisable(GL_DEPTH_TEST);
else
pglDepthFunc(GL_LEQUAL); //pglEnable(GL_DEPTH_TEST);
}
if (Xor & PF_RemoveYWrap)
{
if (PolyFlags & PF_RemoveYWrap)
Clamp2D(GL_TEXTURE_WRAP_T);
}
if (Xor & PF_ForceWrapX)
{
if (PolyFlags & PF_ForceWrapX)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
}
if (Xor & PF_ForceWrapY)
{
if (PolyFlags & PF_ForceWrapY)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
if (Xor & PF_Modulated)
{
#if defined (__unix__) || defined (UNIXCOMMON)
if (oglflags & GLF_NOTEXENV)
{
if (!(PolyFlags & PF_Modulated))
pglColor4ubv(white);
}
else
#endif
if (PolyFlags & PF_Modulated)
{ // mix texture colour with Surface->PolyColor
pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
else
{ // colour from texture is unchanged before blending
pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
}
if (Xor & PF_Occlude) // depth test but (no) depth write
{
if (PolyFlags&PF_Occlude)
{
pglDepthMask(1);
}
else
pglDepthMask(0);
}
////Hurdler: not used if we don't define POLYSKY
if (Xor & PF_Invisible)
{
if (PolyFlags&PF_Invisible)
pglBlendFunc(GL_ZERO, GL_ONE); // transparent blending
else
{ // big hack: (TODO: manage that better)
// we test only for PF_Masked because PF_Invisible is only used
// (for now) with it (yeah, that's crappy, sorry)
if ((PolyFlags&PF_Blending)==PF_Masked)
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO);
}
}
if (PolyFlags & PF_NoTexture)
{
GL_SetNoTexture();
case (PF_Translucent & PF_Blending):
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case (PF_Masked & PF_Blending):
// Hurdler: does that mean lighting is only made by alpha src?
// it sounds ok, but not for polygonsmooth
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture
pglAlphaFunc(GL_GREATER, 0.5f);
break;
case (PF_Additive & PF_Blending):
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case (PF_Environment & PF_Blending):
pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case (PF_Substractive & PF_Blending):
// good for shadow
// not really but what else ?
pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case (PF_Fog & PF_Fog):
// Sryder: Fog
// multiplies input colour by input alpha, and destination colour by input colour, then adds them
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
pglAlphaFunc(GL_ALWAYS, 0.0f); // Don't discard zero alpha fragments
break;
default : // must be 0, otherwise it's an error
// No blending
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
pglAlphaFunc(GL_GREATER, 0.5f);
break;
}
}
CurrentPolyFlags = PolyFlags;
if (Xor & PF_NoAlphaTest)
{
if (PolyFlags & PF_NoAlphaTest)
pglDisable(GL_ALPHA_TEST);
else
pglEnable(GL_ALPHA_TEST); // discard 0 alpha pixels (holes in texture)
}
if (Xor & PF_Decal)
{
if (PolyFlags & PF_Decal)
pglEnable(GL_POLYGON_OFFSET_FILL);
else
pglDisable(GL_POLYGON_OFFSET_FILL);
}
if (Xor & PF_NoDepthTest)
{
if (PolyFlags & PF_NoDepthTest)
pglDepthFunc(GL_ALWAYS); //pglDisable(GL_DEPTH_TEST);
else
pglDepthFunc(GL_LEQUAL); //pglEnable(GL_DEPTH_TEST);
}
if (Xor & PF_RemoveYWrap)
{
if (PolyFlags & PF_RemoveYWrap)
Clamp2D(GL_TEXTURE_WRAP_T);
}
if (Xor & PF_ForceWrapX)
{
if (PolyFlags & PF_ForceWrapX)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
}
if (Xor & PF_ForceWrapY)
{
if (PolyFlags & PF_ForceWrapY)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
if (Xor & PF_Modulated)
{
#if defined (__unix__) || defined (UNIXCOMMON)
if (oglflags & GLF_NOTEXENV)
{
if (!(PolyFlags & PF_Modulated))
pglColor4ubv(white);
}
else
#endif
// mix texture colour with Surface->PolyColor
if (PolyFlags & PF_Modulated)
pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// colour from texture is unchanged before blending
else
pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
if (Xor & PF_Occlude) // depth test but (no) depth write
{
if (PolyFlags & PF_Occlude)
pglDepthMask(1);
else
pglDepthMask(0);
}
////Hurdler: not used if we don't define POLYSKY
if (Xor & PF_Invisible)
{
if (PolyFlags&PF_Invisible)
pglBlendFunc(GL_ZERO, GL_ONE); // transparent blending
else
{ // big hack: (TODO: manage that better)
// we test only for PF_Masked because PF_Invisible is only used
// (for now) with it (yeah, that's crappy, sorry)
if ((PolyFlags & PF_Blending) == PF_Masked)
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO);
}
}
if (PolyFlags & PF_NoTexture)
GL_SetNoTexture();
CurrentPolyFlags = PolyFlags;
}
static void GL_AllocTextureBuffer(GLMipmap_t *pTexInfo)
@@ -1651,7 +1581,6 @@ static void GL_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;
@@ -1680,13 +1609,18 @@ static void GL_UpdateTexture(GLMipmap_t *pTexInfo)
const int chromakeyed = (pTexInfo->flags & TF_CHROMAKEYED);
for (idx = 0, j = 0; j < h; j++)
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++, idx++)
for (i = 0; i < w; i++)
{
int idx = (w*j+i);
if (chromakeyed && (*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX))
{
tex[idx].s = (byteColor_t){0, 0, 0, 0};
tex[idx].s.red = 0;
tex[idx].s.green = 0;
tex[idx].s.blue = 0;
tex[idx].s.alpha = 0;
pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it
}
else
@@ -1715,10 +1649,12 @@ static void GL_UpdateTexture(GLMipmap_t *pTexInfo)
ptex = tex = textureBuffer;
texformat = GL_LUMINANCE_ALPHA;
for (idx = 0, j = 0; j < h; j++)
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++, idx++)
for (i = 0; i < w; i++)
{
int idx = (w*j+i);
tex[idx].s.red = *pImgData;
tex[idx].s.green = *pImgData;
tex[idx].s.blue = *pImgData;
@@ -1733,13 +1669,17 @@ static void GL_UpdateTexture(GLMipmap_t *pTexInfo)
ptex = tex = textureBuffer;
texformat = GL_ALPHA;
memset(&tex->s, 255, sizeof(byteColor_t)*w*h); // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't
for (idx = 0, j = 0; j < h; j++)
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++, idx++)
for (i = 0; i < w; i++)
{
tex[idx].s.alpha = *pImgData++;
int idx = (w*j+i);
tex[idx].s.red = 255; // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't
tex[idx].s.green = 255;
tex[idx].s.blue = 255;
tex[idx].s.alpha = *pImgData;
pImgData++;
}
}
break;
@@ -1891,32 +1831,11 @@ static void GL_Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRG
UNIFORM_4(shader->uniforms[gluniform_tint_color], tint->red, tint->green, tint->blue, tint->alpha, pglUniform4f);
UNIFORM_4(shader->uniforms[gluniform_fade_color], fade->red, fade->green, fade->blue, fade->alpha, pglUniform4f);
boolean directional = false;
if (Surface != NULL)
{
UNIFORM_1(shader->uniforms[gluniform_lighting], (GLfloat)Surface->LightInfo.light_level, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_fade_start], (GLfloat)Surface->LightInfo.fade_start, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_fade_end], (GLfloat)Surface->LightInfo.fade_end, pglUniform1f);
directional = Surface->LightInfo.directional;
}
else
{
UNIFORM_1(shader->uniforms[gluniform_lighting], 255, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_fade_start], 0, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_fade_end], 31, pglUniform1f);
}
if (directional)
{
UNIFORM_3(shader->uniforms[gluniform_light_dir], shader_light_x, shader_light_y, shader_light_z, pglUniform3f);
UNIFORM_1(shader->uniforms[gluniform_light_contrast], shader_light_contrast, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_light_backlight], shader_light_backlight, pglUniform1f);
}
else
{
UNIFORM_3(shader->uniforms[gluniform_light_dir], 0, 0, 0, pglUniform3f);
UNIFORM_1(shader->uniforms[gluniform_light_contrast], 0, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_light_backlight], 0, pglUniform1f);
}
UNIFORM_1(shader->uniforms[gluniform_leveltime], shader_leveltime, pglUniform1f);
@@ -2041,9 +1960,6 @@ static boolean GL_Shader_CompileProgram(gl_shader_t *shader, GLint i)
shader->uniforms[gluniform_lighting] = GETUNI("lighting");
shader->uniforms[gluniform_fade_start] = GETUNI("fade_start");
shader->uniforms[gluniform_fade_end] = GETUNI("fade_end");
shader->uniforms[gluniform_light_dir] = GETUNI("light_dir");
shader->uniforms[gluniform_light_contrast] = GETUNI("light_contrast");
shader->uniforms[gluniform_light_backlight] = GETUNI("light_backlight");
// palette rendering
shader->uniforms[gluniform_palette_tex] = GETUNI("palette_tex");
@@ -2633,10 +2549,13 @@ void GL_DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics
poly.green = byte2float[Surface->PolyColor.s.green];
poly.blue = byte2float[Surface->PolyColor.s.blue];
poly.alpha = byte2float[Surface->PolyColor.s.alpha];
pglColor4ubv((GLubyte*)&Surface->PolyColor.s);
GL_SetBlend((poly.alpha < 1 ? Surface->PolyFlags : (PF_Masked|PF_Occlude))|PF_Modulated);
if (poly.alpha < 1)
GL_SetBlend(PF_Translucent|PF_Modulated);
else
GL_SetBlend(PF_Masked|PF_Modulated|PF_Occlude);
pglColor4ubv((GLubyte*)&Surface->PolyColor.s);
tint.red = byte2float[Surface->TintColor.s.red];
tint.green = byte2float[Surface->TintColor.s.green];
@@ -2661,6 +2580,7 @@ void GL_DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics
pglEnable(GL_CULL_FACE);
pglEnable(GL_NORMALIZE);
#ifdef USE_FTRANSFORM_MIRROR
// flipped is if the object is vertically flipped
// hflipped is if the object is horizontally flipped
// pos->flip is if the screen is flipped vertically
@@ -2673,6 +2593,13 @@ void GL_DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics
else
pglCullFace(GL_BACK);
}
#else
// pos->flip is if the screen is flipped too
if (flipped ^ hflipped ^ pos->flip) // If one or three of these are active, but not two, invert the model's culling
pglCullFace(GL_FRONT);
else
pglCullFace(GL_BACK);
#endif
pglPushMatrix(); // should be the same as glLoadIdentity
pglTranslatef(pos->x, pos->z, pos->y);
@@ -2680,15 +2607,30 @@ void GL_DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics
scaley = -scaley;
if (hflipped)
scalez = -scalez;
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f);
pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f);
#ifdef USE_FTRANSFORM_ANGLEZ
pglRotatef(pos->anglez2, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart
#endif
pglRotatef(pos->anglex2, -1.0f, 0.0f, 0.0f);
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
if (pos->roll)
{
float roll = (1.0f * pos->rollflip);
pglTranslatef(pos->centerx, pos->centery, 0);
pglRotatef(pos->rollangle, pos->rollx, 0.0f, pos->rollz);
// rotate model for pitch and roll
pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f);
#ifdef USE_FTRANSFORM_ANGLEZ
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f);
#endif
if (pos->rotaxis == 2) // Z
pglRotatef(pos->rollangle, 0.0f, 0.0f, roll);
else if (pos->rotaxis == 1) // Y
pglRotatef(pos->rollangle, 0.0f, roll, 0.0f);
else // X
pglRotatef(pos->rollangle, roll, 0.0f, 0.0f);
pglTranslatef(-pos->centerx, -pos->centery, 0);
}
@@ -2811,14 +2753,20 @@ void GL_SetTransform(FTransform *stransform)
if (stransform)
{
used_fov = stransform->fovangle;
used_fov = stransform->fovxangle;
shearing = stransform->shearing;
// keep a trace of the transformation for md2
memcpy(&md2_transform, stransform, sizeof (md2_transform));
#ifdef USE_FTRANSFORM_MIRROR
// mirroring from Kart
if (stransform->mirror)
pglScalef(-stransform->scalex, stransform->scaley, -stransform->scalez);
else if (stransform->mirrorflip)
pglScalef(-stransform->scalex, -stransform->scaley, -stransform->scalez);
else if (stransform->flip)
else
#endif
if (stransform->flip)
pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez);
else
pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez);
@@ -2896,7 +2844,7 @@ void GL_PostImgRedraw(float points[SCREENVERTS][SCREENVERTS][2])
INT32 x, y;
float float_x, float_y, float_nextx, float_nexty;
float xfix, yfix;
INT32 texsizew = 512, texsizey = 512;
INT32 texsize = 512;
const float blackBack[16] =
{
@@ -2910,15 +2858,12 @@ void GL_PostImgRedraw(float points[SCREENVERTS][SCREENVERTS][2])
return;
// look for power of two that is large enough for the screen
while (texsizew < screen_width)
texsizew <<= 1;
while (texsizey < screen_height)
texsizey <<= 1;
while (texsize < screen_width || texsize < screen_height)
texsize <<= 1;
// X/Y stretch fix for all resolutions(!)
xfix = (float)(texsizew)/((float)((screen_width)/(float)(SCREENVERTS-1)));
yfix = (float)(texsizey)/((float)((screen_height)/(float)(SCREENVERTS-1)));
xfix = (float)(texsize)/((float)((screen_width)/(float)(SCREENVERTS-1)));
yfix = (float)(texsize)/((float)((screen_height)/(float)(SCREENVERTS-1)));
pglDisable(GL_DEPTH_TEST);
pglDisable(GL_BLEND);
@@ -2991,7 +2936,7 @@ void GL_FlushScreenTextures(void)
void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags)
{
float xfix, yfix;
INT32 texsizew = 512, texsizey = 512;
INT32 texsize = 512;
const float screenVerts[12] =
{
@@ -3007,14 +2952,11 @@ void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags)
return;
// look for power of two that is large enough for the screen
while (texsizew < screen_width)
texsizew <<= 1;
while (texsize < screen_width || texsize < screen_height)
texsize <<= 1;
while (texsizey < screen_height)
texsizey <<= 1;
xfix = 1/((float)(texsizew)/((float)((screen_width))));
yfix = 1/((float)(texsizey)/((float)((screen_height))));
xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height))));
// const float screenVerts[12]
@@ -3047,7 +2989,7 @@ void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags)
// Do screen fades!
void GL_DoScreenWipe(int wipeStart, int wipeEnd)
{
INT32 texsizew = 512, texsizey = 512;
INT32 texsize = 512;
float xfix, yfix;
INT32 fademaskdownloaded = tex_downloaded; // the fade mask that has been set
@@ -3074,14 +3016,11 @@ void GL_DoScreenWipe(int wipeStart, int wipeEnd)
return;
// look for power of two that is large enough for the screen
while (texsizew < screen_width)
texsizew <<= 1;
while (texsize < screen_width || texsize < screen_height)
texsize <<= 1;
while (texsizey < screen_height)
texsizey <<= 1;
xfix = 1/((float)(texsizew)/((float)((screen_width))));
yfix = 1/((float)(texsizey)/((float)((screen_height))));
xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height))));
// const float screenVerts[12]
@@ -3141,7 +3080,7 @@ void GL_DoScreenWipe(int wipeStart, int wipeEnd)
void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
{
INT32 texsizew = 512, texsizey = 512;
INT32 texsize = 512;
int tex = HWD_SCREENTEXTURE_VHS;
float xfix, yfix;
float fix[8];
@@ -3160,14 +3099,11 @@ void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8
return;
// look for power of two that is large enough for the screen
while (texsizew < screen_width)
texsizew <<= 1;
while (texsize < screen_width || texsize < screen_height)
texsize <<= 1;
while (texsizey < screen_height)
texsizey <<= 1;
xfix = 1/((float)(texsizew)/((float)((screen_width))));
yfix = 1/((float)(texsizey)/((float)((screen_height))));
xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height))));
// Slight fuzziness
GL_MakeScreenTexture(tex);
@@ -3251,18 +3187,15 @@ void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8
// Create a texture from the screen.
void GL_MakeScreenTexture(int tex)
{
INT32 texsizew = 512, texsizey = 512;
INT32 texsize = 512;
boolean firstTime = (screenTextures[tex] == 0);
if (!gl_enable_screen_textures)
return;
// look for power of two that is large enough for the screen
while (texsizew < screen_width)
texsizew <<= 1;
while (texsizey < screen_height)
texsizey <<= 1;
while (texsize < screen_width || texsize < screen_height)
texsize <<= 1;
// Create screen texture
if (firstTime)
@@ -3275,10 +3208,10 @@ void GL_MakeScreenTexture(int tex)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsizew, texsizey, 0);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
}
else
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsizew, texsizey);
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
tex_downloaded = screenTextures[tex];
}
@@ -3289,7 +3222,7 @@ void GL_DrawScreenFinalTexture(int tex, INT32 width, INT32 height, boolean usesh
float origaspect, newaspect;
float xoff = 1, yoff = 1; // xoffset and yoffset for the polygon to have black bars around the screen
FRGBAFloat clearColour;
INT32 texsizew = 512, texsizey = 512;
INT32 texsize = 512;
float off[12];
float fix[8];
@@ -3298,14 +3231,11 @@ void GL_DrawScreenFinalTexture(int tex, INT32 width, INT32 height, boolean usesh
return;
// look for power of two that is large enough for the screen
while (texsizew < screen_width)
texsizew <<= 1;
while (texsize < screen_width || texsize < screen_height)
texsize <<= 1;
while (texsizey < screen_height)
texsizey <<= 1;
xfix = 1/((float)(texsizew)/((float)((screen_width))));
yfix = 1/((float)(texsizey)/((float)((screen_height))));
xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height))));
origaspect = (float)screen_width / screen_height;
newaspect = (float)width / height;
@@ -3362,7 +3292,7 @@ void GL_DrawScreenFinalTexture(int tex, INT32 width, INT32 height, boolean usesh
pglVertexPointer(3, GL_FLOAT, 0, off);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (useshader)
pglUseProgram(0);
File diff suppressed because it is too large. Load diff
+59
View File
@@ -0,0 +1,59 @@
[Project]
FileName=s_ds3d.dev
Name=s_ds3d
Ver=1
IsCpp=1
Type=3
Compiler=-D_M_IX86=500_@@_-Wall_@@_-D_WINDOWS_@@_-Os_@@_-fno-strict-aliasing_@@_-fomit-frame-pointer_@@_
CppCompiler=
Includes=
Linker=--def ../s_mingw.def_@@_-luuid_@@_-ldsound_@@_
Libs=
UnitCount=1
Folders=
ObjFiles=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Icon=
ExeOutput=C:\srb2demo2
ObjectOutput=..\..\..\objs\Mingw\s_ds3d
OverrideOutput=1
OverrideOutputName=s_ds3d.dll
HostApplication=
CommandLine=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=00000000000000000111d0
UseCustomMakefile=0
CustomMakefile=
[Unit1]
FileName=s_ds3d.c
Folder=
Compile=1
CompileCpp=0
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=0.1
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=s_ds3d.exe
ProductName=s_ds3d
ProductVersion=0.1
AutoIncBuildNr=0
+99
View File
@@ -0,0 +1,99 @@
# Microsoft Developer Studio Project File - Name="s_ds3d" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=s_ds3d - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "s_ds3d.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "s_ds3d.mak" CFG="s_ds3d - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "s_ds3d - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "s_ds3d - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "s_ds3d - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\..\bin\VC\Release\s_ds3d"
# PROP Intermediate_Dir "..\..\..\objs\VC\Release\s_ds3d"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_DS3D_EXPORTS" /YX /FD /c
# ADD CPP /nologo /G5 /MT /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x40c /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 dsound.lib /nologo /dll /pdb:"..\..\..\bin\VC\Release\s_ds3d.pdb" /machine:I386 /out:"..\..\..\bin\VC\Release\s_ds3d.dll"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "s_ds3d - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\..\bin\VC\Debug\s_ds3d"
# PROP Intermediate_Dir "..\..\..\objs\VC\Debug\s_ds3d"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_DS3D_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x40c /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 dsound.lib /nologo /dll /pdb:"..\..\..\bin\VC\Debug\s_ds3d.pdb" /debug /machine:I386 /out:"..\..\..\bin\VC\Debug\s_ds3d.dll" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none /incremental:no /nodefaultlib
!ENDIF
# Begin Target
# Name "s_ds3d - Win32 Release"
# Name "s_ds3d - Win32 Debug"
# Begin Source File
SOURCE=.\s_ds3d.c
# End Source File
# End Target
# End Project
File diff suppressed because it is too large. Load diff
+59
View File
@@ -0,0 +1,59 @@
[Project]
FileName=s_fmod.dev
Name=s_fmod
Ver=1
IsCpp=1
Type=3
Compiler=-D_M_IX86=500_@@_-Wall_@@_-D_WINDOWS_@@_-Os_@@_-fomit-frame-pointer_@@_
CppCompiler=
Includes=..\..\win32\FMOD
Linker=--def ../s_mingw.def_@@_-lfmod_@@_
Libs=..\..\win32\FMOD
UnitCount=1
Folders=
ObjFiles=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Icon=
ExeOutput=C:\srb2demo2
ObjectOutput=..\..\..\objs\Mingw\s_fmod
OverrideOutput=1
OverrideOutputName=s_fmod.dll
HostApplication=
CommandLine=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=00000000000000000111d0
UseCustomMakefile=0
CustomMakefile=
[Unit1]
FileName=s_fmod.c
Folder=
Compile=1
CompileCpp=0
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=1
Minor=0
Release=8
Build=42
LanguageID=1033
CharsetID=1252
CompanyName=Alam Arias
FileVersion=1.42
FileDescription=SRB2 Sound API DLL for FMOD
InternalName=Super FMOD!
LegalCopyright=
LegalTrademarks=
OriginalFilename=s_fmod.dll
ProductName=s_fmod
ProductVersion=0.1
AutoIncBuildNr=0
+97
View File
@@ -0,0 +1,97 @@
# Microsoft Developer Studio Project File - Name="s_fmod" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=s_fmod - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "s_fmod.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "s_fmod.mak" CFG="s_fmod - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "s_fmod - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "s_fmod - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "s_fmod - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\..\bin\VC\Release\s_fmod"
# PROP Intermediate_Dir "..\..\..\objs\VC\Release\s_fmod"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_FMOD_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 fmodvc.lib /nologo /dll /pdb:"..\..\..\bin\VC\Release\s_fmod.pdb" /machine:I386 /out:"..\..\..\bin\VC\Release\s_fmod.dll"
!ELSEIF "$(CFG)" == "s_fmod - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\..\bin\VC\Debug\s_fmod"
# PROP Intermediate_Dir "..\..\..\objs\VC\Debug\s_fmod"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_FMOD_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /FR /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 fmodvc.lib /nologo /dll /pdb:"..\..\..\bin\VC\Debug\s_fmod.pdb" /debug /machine:I386 /out:"..\..\..\bin\VC\Debug\s_fmod.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "s_fmod - Win32 Release"
# Name "s_fmod - Win32 Debug"
# Begin Source File
SOURCE=.\s_fmod.c
# End Source File
# End Target
# End Project
+998
View File
@@ -0,0 +1,998 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief General driver for 3D sound system
///
/// Implementend via OpenAL API
#ifdef _WINDOWS
//#define WIN32_LEAN_AND_MEAN
#define RPC_NO_WINDOWS_H
#include <windows.h>
#include <stdio.h>
FILE* logstream = NULL;
#else
#include <stdarg.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#ifndef HAVE_SDL // let not make a logstream here is we are inline the HW3D in the SDL binary
FILE* logstream = NULL;
#endif
#endif
#ifdef __APPLE__
#include <al.h> //Main AL
#include <alc.h> //Helpers
#else
#include <AL/al.h> //Main AL
#include <AL/alc.h> //Helpers
#endif
#define _CREATE_DLL_
#include "../../doomdef.h"
#include "../hw3dsdrv.h"
//#undef DEBUG_TO_FILE
//#if defined ( HAVE_SDL ) && !defined ( LOGMESSAGES )
#define DEBUG_TO_FILE
//#endif
// Internal sound stack
typedef struct stack_snd_s
{
ALuint ALsource;// 3D data of 3D source
ALint sfx_id;// Currently unused
ALint LRU;// Currently unused
ALboolean permanent;// Flag of static source
} stack_snd_t;
#ifndef AL_INVALID
#define AL_INVALID (-1)
#endif
static I_Error_t I_ErrorOpenAl = NULL;
static stack_snd_t *ALstack = NULL; // Sound stack
static ALsizei allocated_sounds = 0; // Size of stack
static ALsizei allocate_delta = 16;
static ALCdevice *ALCDevice = NULL;
static ALCcontext *ALContext = NULL;
static ALenum ALo_Lasterror = AL_NO_ERROR;
static ALenum ALCo_Lasterror = ALC_NO_ERROR;
static ALenum ALo_GetError(ALvoid)
{
ALo_Lasterror = alGetError();
return ALo_Lasterror;
}
static ALenum ALCo_GetError(ALvoid)
{
ALCo_Lasterror = alcGetError(ALCDevice);
return ALCo_Lasterror;
}
static ALfloat ALvol(ALint vol, ALsizei step)
{
return ((ALfloat)vol)/(ALfloat)step;
}
/*
static ALfloat Alpitch(ALint pitch)
{
#if 1
pitch = NORMAL_PITCH;
#endif
return pitch < NORMAL_PITCH ?
(float)(pitch + NORMAL_PITCH) / (NORMAL_PITCH * 2)
:(float)pitch / (float)NORMAL_PITCH;
}
*/
static const ALchar *GetALErrorString(ALenum err)
{
switch (err)
{
case AL_NO_ERROR:
return "There no error";
break;
case AL_INVALID_NAME:
return "Invalid name";
break;
case AL_INVALID_ENUM:
return "Invalid enum";
break;
case AL_INVALID_VALUE:
return "Invalid value";
break;
case AL_INVALID_OPERATION:
return "Invalid operation";
break;
case AL_OUT_OF_MEMORY:
return "Out Of Memory";
break;
default:
return alGetString(err);
break;
}
}
static const ALchar *GetALCErrorString(ALenum err)
{
switch (err)
{
case ALC_NO_ERROR:
return "There no error";
break;
case ALC_INVALID_DEVICE:
return "Invalid Device";
break;
case ALC_INVALID_CONTEXT:
return "Invalid Context";
break;
case ALC_INVALID_ENUM:
return "Invalid enum";
break;
case ALC_INVALID_VALUE:
return "Invalid value";
break;
case ALC_OUT_OF_MEMORY:
return "Out Of Memory";
break;
default:
return alcGetString(ALCDevice, err);
break;
}
}
/***************************************************************
*
* DBG_Printf
* Output error messages to debug log if DEBUG_TO_FILE is defined,
* else do nothing
*
**************************************************************
*/
// -----------------+
// DBG_Printf : Output error messages to debug log if DEBUG_TO_FILE is defined,
// : else do nothing
// Returns :
// -----------------+
FUNCPRINTF void DBG_Printf(const char *lpFmt, ... )
{
#ifdef DEBUG_TO_FILE
char str[4096] = "";
va_list arglist;
va_start(arglist, lpFmt);
vsnprintf(str, 4096, lpFmt, arglist);
va_end(arglist);
if (logstream)
fwrite(str, strlen(str), 1 , logstream);
#else
lpFmt = NULL;
#endif
}
/***************************************************************
*
* Grow internal sound stack by allocate_delta amount
*
***************************************************************
*/
static ALboolean reallocate_stack(void)
{
stack_snd_t *new_stack;
if (ALstack)
new_stack = realloc(ALstack, sizeof (stack_snd_t) * (allocated_sounds + allocate_delta));
else
new_stack = malloc(sizeof (stack_snd_t) * (allocate_delta));
if (new_stack)
{
ALsizei clean_stack;
ALstack = new_stack;
memset(&ALstack[allocated_sounds], 0, allocate_delta * sizeof (stack_snd_t));
for (clean_stack = allocated_sounds; clean_stack < allocated_sounds; clean_stack++)
ALstack[clean_stack].ALsource = (ALuint)AL_INVALID;
allocated_sounds += allocate_delta;
return AL_TRUE;
}
return AL_FALSE;
}
/***************************************************************
*
* Destroys source in stack
*
***************************************************************
*/
static ALvoid kill_sound(stack_snd_t *snd)
{
if (alIsSource(snd->ALsource))
alDeleteSources(1,&snd->ALsource);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alDeleteSources, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
memset(snd,0, sizeof (stack_snd_t));
snd->ALsource = (ALuint)AL_INVALID;
}
/***************************************************************
*
* Returns free (unused) source stack slot
* If none available sound stack will be increased
*
***************************************************************
*/
static ALsizei find_handle(void)
{
ALsizei free_sfx = 0;
stack_snd_t *snd;
for (snd = ALstack; free_sfx < allocated_sounds; snd++, free_sfx++)
{
if (snd->permanent)
continue;
if (snd->ALsource==(ALuint)AL_INVALID)
break;
if (!alIsSource(snd->ALsource))
break;
ALo_GetError();
if (snd->sfx_id == 0)
break;
}
// No suitable resource found so increase sound stack
//DBG_Printf("sfx chan %d\n", free_sfx);
if (free_sfx == allocated_sounds)
{
DBG_Printf("No free or same sfx found so increase stack (currently %d srcs)\n", allocated_sounds);
free_sfx = reallocate_stack() ? free_sfx : (ALsizei)AL_INVALID;
}
return free_sfx;
}
static ALvoid ALSetPan(ALuint sid, INT32 sep)
{
ALfloat facing[3] ={0.0f, 0.0f, 0.0f}; //Alam: bad?
const ALfloat fsep = (ALfloat)sep;
const ALfloat nsep = (ALfloat)NORMAL_SEP;
if (sep)
{
facing[0] = (ALfloat)(fsep/nsep);
facing[2] = 1.0f;
}
alSourcefv(sid, AL_POSITION, facing);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alSourcefv, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
/******************************************************************************
*
* Initialise driver and listener
*
*****************************************************************************/
EXPORT INT32 HWRAPI( Startup ) (I_Error_t FatalErrorFunction, snddev_t *snd_dev)
{
ALenum model = AL_INVERSE_DISTANCE_CLAMPED;
ALCboolean inited = ALC_FALSE;
ALCint AlSetup[8] = {ALC_FREQUENCY,22050,ALC_REFRESH,35,ALC_SYNC,AL_FALSE,ALC_INVALID,ALC_INVALID};
#if (defined (_WIN32) || defined (_WIN64)) && 0
const ALCubyte *ALCdriver = alcGetString(NULL,ALC_DEFAULT_DEVICE_SPECIFIER);
const ALCubyte *DSdriver = "DirectSound";
if (!strcmp((const ALCbyte *)ALCdriver,"DirectSound3D")) //Alam: OpenAL's DS3D is buggy
ALCDevice = alcOpenDevice(DSdriver); //Open DirectSound
else //Alam: The OpenAl device
ALCDevice = alcOpenDevice(ALCdriver); //Open Default
#else
ALCDevice = alcOpenDevice(alcGetString(NULL,ALC_DEFAULT_DEVICE_SPECIFIER));
#endif
if (ALCo_GetError() != ALC_NO_ERROR || !ALCDevice)
{
DBG_Printf("S_OpenAl: Error %s when opening device!\n", GetALCErrorString(ALCo_Lasterror));
return inited;
}
else
{
DBG_Printf("Driver Name : %s\n", alcGetString(ALCDevice,ALC_DEVICE_SPECIFIER));
DBG_Printf("Extensions : %s\n", alcGetString(ALCDevice,ALC_EXTENSIONS));
DBG_Printf("S_OpenAl: OpenAl Device %s opened\n",alcGetString(ALCDevice, ALC_DEVICE_SPECIFIER));
}
I_ErrorOpenAl = FatalErrorFunction;
AlSetup[1] = snd_dev->sample_rate; //ALC_FREQUENCY
AlSetup[1] = 44100;
AlSetup[3] = 35; //ALC_REFRESH
//Alam: The Environment?
ALContext = alcCreateContext(ALCDevice,AlSetup);
if (ALCo_GetError() != ALC_NO_ERROR || !ALContext)
{
DBG_Printf("S_OpenAl: Error %s when making the environment!\n",GetALCErrorString(ALCo_Lasterror));
return inited;
}
else
{
DBG_Printf("S_OpenAl: OpenAl environment made\n");
}
alcMakeContextCurrent(ALContext);
if (ALCo_GetError() != ALC_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when setting the environment!\n",GetALCErrorString(ALCo_Lasterror));
return inited;
}
else
{
DBG_Printf("S_OpenAl: OpenAl environment setted up\n");
}
DBG_Printf("Vendor : %s\n", alGetString(AL_VENDOR));
DBG_Printf("Renderer : %s\n", alGetString(AL_RENDERER));
DBG_Printf("Version : %s\n", alGetString(AL_VERSION));
DBG_Printf("Extensions : %s\n", alGetString(AL_EXTENSIONS));
alDopplerFactor(0.0f);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when setting Doppler Factor!\n",GetALErrorString(ALo_Lasterror));
return inited;
}
else
{
DBG_Printf("S_OpenAl: Doppler Factor of %f setted\n", alGetDouble(AL_DOPPLER_FACTOR));
}
alSpeedOfSound(600.0f);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when setting Speed of Sound!\n",GetALErrorString(ALo_Lasterror));
return inited;
}
else
{
DBG_Printf("S_OpenAl: Speed of Sound set to %f\n", alGetDouble(AL_SPEED_OF_SOUND));
}
alDistanceModel(model);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when setting Distance Model!\n",GetALErrorString(ALo_Lasterror));
return inited;
}
else
{
//DBG_Printf("S_OpenAl: %s mode setted\n",alGetString(model));
}
inited = reallocate_stack();
return inited;
}
/******************************************************************************
*
* Shutdown 3D Sound
*
******************************************************************************/
EXPORT void HWRAPI( Shutdown ) ( void )
{
ALsizei i;
DBG_Printf ("S_OpenAL Shutdown()\n");
for (i = 0; i < allocated_sounds; i++)
{
StopSource(i);
kill_sound(ALstack + i);
}
#if defined(linux) || defined(__linux) || defined(__linux__)
alcMakeContextCurrent(NULL);
//TODO:check?
#endif
if (ALContext)
{
alcDestroyContext(ALContext);
ALContext = NULL;
}
if (ALstack)
{
free(ALstack);
ALstack = NULL;
}
//TODO:check?
if (ALCDevice)
{
alcCloseDevice(ALCDevice);
ALCDevice = NULL;
}
//TODO:check?
}
#ifdef _MSC_VER
#pragma warning(disable : 4200)
#pragma pack(1)
#endif
typedef struct
{
ALushort header; // 3?
ALushort samplerate; // 11025+
ALushort samples; // number of samples
ALushort dummy; // 0
ALubyte data[0]; // data;
} ATTRPACK dssfx_t;
#ifdef _MSC_VER
#pragma pack()
#pragma warning(default : 4200)
#endif
static ALsizei getfreq(ALvoid *sfxdata, size_t len)
{
dssfx_t *dsfx = sfxdata;
const ALsizei freq = SHORT(dsfx->samplerate);
if (len <= 8)
return 0;
else
return freq;
}
static ALsizei makechan(ALuint sfxhandle, ALboolean perm)
{
ALsizei chan = find_handle();
if (chan == (ALsizei)AL_INVALID) return chan;
alGenSources(1, &ALstack[chan].ALsource);
if (ALo_GetError() != AL_NO_ERROR || !alIsSource(ALstack[chan].ALsource))
{
DBG_Printf("S_OpenAl: Error %s when make an ALSource!\n",GetALErrorString(ALo_Lasterror));
ALstack[chan].ALsource = (ALuint)AL_INVALID;
return (ALsizei)AL_INVALID;
}
ALstack[chan].permanent = perm;
alSourceQueueBuffers(ALstack[chan].ALsource, 1, &sfxhandle);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when queue up an alSource!\n",GetALErrorString(ALo_Lasterror));
}
return chan;
}
/******************************************************************************
*
* Creates ?D source
*
******************************************************************************/
EXPORT INT32 HWRAPI ( AddSource ) (source3D_data_t *src, u_int sfxhandle)
{
ALsizei chan = makechan(sfxhandle, (ALboolean)(src?src->permanent:AL_FALSE));
ALuint sid = (ALuint)AL_INVALID;
if (chan == (ALsizei)AL_INVALID)
return AL_INVALID;
else
sid = ALstack[chan].ALsource;
if (src) //3D
{
#if 0
alSourcef(sid, AL_REFERENCE_DISTANCE, src->min_distance);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_REFERENCE_DISTANCE, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSourcef(sid, AL_MAX_DISTANCE, src->max_distance);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_MAX_DISTANCE, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
#endif
if (src->head_relative)
alSourcei(sid, AL_SOURCE_RELATIVE, AL_TRUE);
else
alSourcei(sid, AL_SOURCE_RELATIVE, AL_FALSE);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_SOURCE_RELATIVE, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSource3f(sid, AL_POSITION, src->pos.x, src->pos.z, src->pos.y);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_POSITION, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSource3f(sid, AL_VELOCITY, src->pos.momx, src->pos.momz, src->pos.momy);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_VELOCITY, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
else //2D
{
alSourcei(sid, AL_SOURCE_RELATIVE, AL_TRUE);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_SOURCE_RELATIVE, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
alSourcef(sid, AL_ROLLOFF_FACTOR, 0.0f);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_ROLLOFF_FACTOR, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSourcef(sid, AL_REFERENCE_DISTANCE, 0.0f);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_REFERENCE_DISTANC, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
return chan;
}
EXPORT INT32 HWRAPI ( StartSource ) (INT32 chan)
{
ALint state = AL_NONE;
ALuint sid = (ALuint)AL_INVALID;
if (chan <= AL_INVALID || !alIsSource(ALstack[chan].ALsource))
return AL_FALSE;
else
sid = ALstack[chan].ALsource;
ALo_GetError();
alSourcePlay(sid);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alSourcePlay, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alGetSourcei(sid, AL_SOURCE_STATE, &state);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alGetSourcei, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
return (state == AL_PLAYING);
}
EXPORT void HWRAPI ( StopSource) (INT32 chan)
{
ALuint sfxhandle = AL_NONE;
ALuint sid = (ALuint)AL_INVALID;
if (chan <= AL_INVALID || !alIsSource(ALstack[chan].ALsource))
return;
else
sid = ALstack[chan].ALsource;
ALo_GetError();
#if 1
alSourceQueueBuffers(sid, 1, &sfxhandle);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alSourceQueueBuffers, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
#else
alSourceStop(sid);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alSourceStop, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
#endif
}
EXPORT INT32 HWRAPI ( GetHW3DSVersion) (void)
{
return VERSION;
}
EXPORT void HWRAPI (BeginFrameUpdate) (void)
{
alcSuspendContext(ALContext);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alcSuspendContext, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
EXPORT void HWRAPI (EndFrameUpdate) (void)
{
alcProcessContext(ALContext);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alcProcessContext, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
EXPORT INT32 HWRAPI (IsPlaying) (INT32 chan)
{
ALint state = AL_NONE;
ALuint sid = (ALuint)AL_INVALID;
if (chan <= AL_INVALID || !alIsSource(ALstack[chan].ALsource))
return AL_FALSE;
else
sid = ALstack[chan].ALsource;
ALo_GetError();
alGetSourcei(sid, AL_SOURCE_STATE, &state);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alGetSourcei, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
return (state == AL_PLAYING);
}
/******************************************************************************
* UpdateListener
*
* Set up main listener properties:
* - position
* - orientation
* - velocity
*****************************************************************************/
EXPORT void HWRAPI (UpdateListener) (listener_data_t *data, INT32 num)
{
if (num != 1) return;
if (data)
{
ALfloat facing[6];
ALdouble f_angle = 0.0;
if (data->f_angle) f_angle = (ALdouble)((data->f_angle) / 180.0l * M_PIl);
facing[0] = (ALfloat)cos(f_angle);
facing[1] = 0.0f;
facing[2] = (ALfloat)sin(f_angle);
facing[3] = 0.0f;
facing[4] = 1.0f;
facing[5] = 0.0f;
alListener3f(AL_POSITION,(ALfloat)-data->x,(ALfloat)data->z,(ALfloat)data->y);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_POSITIO, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alListener3f(AL_VELOCITY,(ALfloat)data->momx,(ALfloat)data->momz,(ALfloat)data->momy);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_VELOCITY, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alListenerfv(AL_ORIENTATION, facing);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_ORIENTATION, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
else
{
DBG_Printf("Error: 1st listener data is missing\n");
}
}
/******************************************************************************
*
* Update volume for 2D source and separation (panning) of 2D source
*
*****************************************************************************/
EXPORT void HWRAPI (UpdateSourceParms) (INT32 chan, INT32 vol, INT32 sep)
{
ALuint sid = AL_NONE;
ALint is2d = AL_FALSE;
if (chan > AL_INVALID && !alIsSource(ALstack[chan].ALsource))
return;
else
sid = ALstack[chan].ALsource;
alGetSourcei(sid, AL_SOURCE_RELATIVE, &is2d);
if (!is2d)
return;
if (vol != -1)
{
alSourcef(sid,AL_GAIN,ALvol(vol,256));
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alSourcef, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
if (sep != -1)
{
ALSetPan(sid,sep-NORMAL_SEP);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: ALSetPan, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
}
// --------------------------------------------------------------------------
// Set the global volume for sound effects
// --------------------------------------------------------------------------
EXPORT void HWRAPI (SetGlobalSfxVolume) (INT32 vol)
{
alListenerf(AL_GAIN, ALvol(vol,32));
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_GAIN, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
//Alam: Not Used?
EXPORT INT32 HWRAPI (SetCone) (INT32 chan, cone_def_t *cone_def)
{
ALuint sid = AL_NONE;
ALint is2d = AL_FALSE;
if (chan > AL_INVALID && !alIsSource(ALstack[chan].ALsource))
return AL_FALSE;
else
sid = ALstack[chan].ALsource;
alGetSourcei(sid, AL_SOURCE_RELATIVE, &is2d);
if(is2d || !cone_def)
return AL_FALSE;
alSourcef(sid,AL_CONE_INNER_ANGLE,cone_def->inner);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_CONE_INNER_ANGLE, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSourcef(sid,AL_CONE_OUTER_ANGLE,cone_def->outer);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_CONE_OUTER_ANGL, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSourcei(sid,AL_CONE_OUTER_GAIN, cone_def->outer_gain);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_CONE_OUTER_GAIN, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
return AL_TRUE;
}
EXPORT void HWRAPI (Update3DSource) (INT32 chan, source3D_pos_t *sfx)
{
ALuint sid = AL_NONE;
ALint is2d = AL_FALSE;
if (chan > AL_INVALID && !alIsSource(ALstack[chan].ALsource))
return;
else
sid = ALstack[chan].ALsource;
alGetSourcei(sid, AL_SOURCE_RELATIVE, &is2d);
if (is2d)
return;
alSource3f(sid, AL_POSITION, sfx->x, sfx->z, sfx->y);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_POSITION, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSource3f(sid, AL_VELOCITY, sfx->momx, sfx->momz, sfx->momy);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_VELOCITY, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
//-------------------------------------------------------------
// Load new sound data into source
//-------------------------------------------------------------
EXPORT INT32 HWRAPI (ReloadSource) (INT32 chan, u_int sfxhandle)
{
ALuint sid;
if (chan <= AL_INVALID || !alIsSource(ALstack[chan].ALsource) || !alIsBuffer(sfxhandle))
return AL_INVALID;
else
sid = ALstack[chan].ALsource;
ALo_GetError();
alSourceQueueBuffers(sid, 1, &sfxhandle);
if (ALo_GetError() == AL_INVALID_OPERATION) //Alam: not needed?
{
alSourceStop(sid);
alSourcei(sid, AL_BUFFER, sfxhandle);
ALo_GetError();
}
if (ALo_Lasterror != AL_NO_ERROR)
{
DBG_Printf("%s: alSourcei, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
return chan;
}
/******************************************************************************
*
* Destroy source and remove it from stack if it is a 2D source.
* Otherwise put source into cache
*
*****************************************************************************/
EXPORT void HWRAPI (KillSource) (INT32 chan)
{
if (chan > AL_INVALID && (ALsizei)chan <= allocated_sounds)
kill_sound(ALstack + chan);
}
EXPORT u_int HWRAPI (AddSfx) (sfx_data_t *sfx)
{
ALuint chan = (ALuint)AL_INVALID;
ALsizei freq = 11025;
ALubyte *data = NULL;
ALsizei size = 0;
if (!sfx)
return 0;
else
{
data = ((ALubyte *)sfx->data)+8;
size = (ALsizei)(sfx->length-8);
}
alGenBuffers(1, &chan);
if (ALo_GetError() != AL_NO_ERROR || !alIsBuffer(chan))
{
DBG_Printf("S_OpenAl: Error %s when make an ALBuffer!\n",GetALErrorString(ALo_Lasterror));
return (u_int)AL_INVALID;
}
freq = getfreq(sfx->data, sfx->length);
alBufferData(chan, AL_FORMAT_MONO8, data, size, freq);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when setting up a alBuffer!\n",GetALErrorString(ALo_Lasterror));
}
return chan;
}
EXPORT void HWRAPI (KillSfx) (u_int sfxhandle)
{
ALuint ALsfx = sfxhandle;
if (!alIsBuffer(ALsfx))
return;
alDeleteBuffers(1, &ALsfx);
if (ALo_GetError() == AL_INVALID_OPERATION)
{
// Buffer leak
}
else if (ALo_Lasterror != AL_NO_ERROR)
{
DBG_Printf("%s: alDeleteBuffers, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
EXPORT void HWRAPI (GetHW3DSTitle) (char *buf, size_t size)
{
strncpy(buf, "OpenAL", size);
}
#ifdef _WINDOWS
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved) // reserved
{
// Perform actions based on the reason for calling.
UNREFERENCED_PARAMETER(lpvReserved);
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
#ifdef DEBUG_TO_FILE
logstream = fopen("s_openal.log", "wt");
if (logstream == NULL)
return FALSE;
#endif
DisableThreadLibraryCalls(hinstDLL);
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
#ifdef DEBUG_TO_FILE
if ( logstream)
{
fclose(logstream);
logstream = NULL;
}
#endif
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
#elif !defined (_WINDOWS)
// **************************************************************************
// FUNCTIONS
// **************************************************************************
EXPORT void _init()
{
#ifdef DEBUG_TO_FILE
logstream = fopen("s_openal.log", "w+");
#endif
}
EXPORT void _fini()
{
#ifdef DEBUG_TO_FILE
if (logstream)
fclose(logstream);
logstream = NULL;
#endif
}
#endif
+59
View File
@@ -0,0 +1,59 @@
[Project]
FileName=s_openal.dev
Name=s_openal
Ver=1
IsCpp=1
Type=3
Compiler=-D_M_IX86=500_@@_-Wall_@@_-fexceptions_@@_-D_WINDOWS_@@_
CppCompiler=
Includes=
Linker=--def ../s_mingw.def_@@_-lopenal32_@@_
Libs=
UnitCount=1
Folders=
ObjFiles=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Icon=
ExeOutput=..\..\..\bin
ObjectOutput=..\..\..\objs\Mingw\s_opengl
OverrideOutput=0
OverrideOutputName=s_openal.dll
HostApplication=
CommandLine=
UseCustomMakefile=0
CustomMakefile=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000010001001001001
[Unit1]
FileName=s_openal.c
Folder=
Compile=1
CompileCpp=0
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=0.1
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=s_openal.dll
ProductName=s_openal
ProductVersion=0.1
AutoIncBuildNr=0
+98
View File
@@ -0,0 +1,98 @@
# Microsoft Developer Studio Project File - Name="s_openal" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=s_openal - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "s_openal.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "s_openal.mak" CFG="s_openal - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "s_openal - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "s_openal - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "s_openal - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\..\bin\VC\Release\s_openal"
# PROP Intermediate_Dir "..\..\..\objs\VC\Release\s_openal"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_OPENAL_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /win32
# SUBTRACT MTL /mktyplib203
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 OpenAL32.lib /nologo /dll /pdb:"..\..\..\bin\VC\Release\s_openal.pdb" /machine:I386 /out:"C:\srb2demo2\s_openal.dll"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "s_openal - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\..\bin\VC\Debug\s_openal"
# PROP Intermediate_Dir "..\..\..\objs\VC\Debug\s_openal"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_OPENAL_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /D "_MBCS" /D "_USRDLL" /D "S_OPENAL_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 OpenAL32.lib /nologo /dll /pdb:"..\..\..\bin\VC\Debug\s_openal.pdb" /debug /machine:I386 /out:"C:\srb2demo2\s_openaldebug.dll" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "s_openal - Win32 Release"
# Name "s_openal - Win32 Debug"
# Begin Source File
SOURCE=.\s_openal.c
# End Source File
# End Target
# End Project
+116 -104
View File
@@ -26,7 +26,6 @@
#include "i_video.h"
#include "i_system.h"
#include "r_fps.h"
#include "st_stuff.h" // ST_HEIGHT
#include "r_local.h"
@@ -70,6 +69,7 @@ patch_t *hu_font[HU_FONTSIZE];
patch_t *kart_font[KART_FONTSIZE]; // SRB2kart
patch_t *tny_font[HU_FONTSIZE];
patch_t *tallnum[10]; // 0-9
patch_t *nightsnum[10]; // 0-9
// Level title and credits fonts
patch_t *lt_font[LT_FONTSIZE];
@@ -100,8 +100,24 @@ patch_t *rflagico;
patch_t *bflagico;
patch_t *rmatcico;
patch_t *bmatcico;
patch_t *tagico;
patch_t *tallminus;
//-------------------------------------------
// coop hud
//-------------------------------------------
patch_t *emeraldpics[7];
patch_t *tinyemeraldpics[7];
static patch_t *emblemicon;
static patch_t *tokenicon;
//-------------------------------------------
// misc vars
//-------------------------------------------
// crosshair 0 = off, 1 = cross, 2 = angle, 3 = point, see m_menu.c
static patch_t *crosshair[HU_CROSSHAIRS]; // 3 precached crosshair graphics
// song credits
static patch_t *songcreditbg;
@@ -365,6 +381,8 @@ void HU_LoadGraphics(void)
{
sprintf(buffer, "STTNUM%d", i);
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "NGTNUM%d", i);
nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "PINGN%d", i);
pingnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "OPPRNK0%d", i);
@@ -374,6 +392,32 @@ void HU_LoadGraphics(void)
// minus for negative tallnums
tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX);
// cache the crosshairs, don't bother to know which one is being used,
// just cache all 3, they're so small anyway.
for (i = 0; i < HU_CROSSHAIRS; i++)
{
sprintf(buffer, "CROSHAI%c", '1'+i);
crosshair[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
emblemicon = W_CachePatchName("EMBLICON", PU_HUDGFX);
tokenicon = W_CachePatchName("TOKNICON", PU_HUDGFX);
emeraldpics[0] = W_CachePatchName("CHAOS1", PU_HUDGFX);
emeraldpics[1] = W_CachePatchName("CHAOS2", PU_HUDGFX);
emeraldpics[2] = W_CachePatchName("CHAOS3", PU_HUDGFX);
emeraldpics[3] = W_CachePatchName("CHAOS4", PU_HUDGFX);
emeraldpics[4] = W_CachePatchName("CHAOS5", PU_HUDGFX);
emeraldpics[5] = W_CachePatchName("CHAOS6", PU_HUDGFX);
emeraldpics[6] = W_CachePatchName("CHAOS7", PU_HUDGFX);
tinyemeraldpics[0] = W_CachePatchName("TEMER1", PU_HUDGFX);
tinyemeraldpics[1] = W_CachePatchName("TEMER2", PU_HUDGFX);
tinyemeraldpics[2] = W_CachePatchName("TEMER3", PU_HUDGFX);
tinyemeraldpics[3] = W_CachePatchName("TEMER4", PU_HUDGFX);
tinyemeraldpics[4] = W_CachePatchName("TEMER5", PU_HUDGFX);
tinyemeraldpics[5] = W_CachePatchName("TEMER6", PU_HUDGFX);
tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX);
songcreditbg = W_CachePatchName("K_SONGCR", PU_HUDGFX);
// cache ping gfx:
@@ -1154,7 +1198,7 @@ void HU_Ticker(void)
|| hu_redownloadinggamestate
#endif
)
resynch_ticker++; //tic tic tic tic tic
resynch_ticker++; //tic tic tic tic tic
HU_TickSongCredits();
}
@@ -2187,7 +2231,7 @@ void HU_DrawSongCredits(void)
//
void HU_Drawer(void)
{
if (cv_vhseffect.value && ((paused && !camera[R_GetViewNumber()].freecam) || (demo.playback && cv_playbackspeed.value > 1)))
if (cv_vhseffect.value && (paused || (demo.playback && cv_playbackspeed.value > 1)))
V_DrawVhsEffect(demo.rewinding);
#ifndef NONET
@@ -2245,6 +2289,22 @@ void HU_Drawer(void)
if (gamestate != GS_LEVEL)
return;
// draw the crosshair, not when viewing demos nor with chasecam
/*if (!automapactive && !demo.playback)
{
if (cv_crosshair.value && !camera[0].chase && !players[displayplayers[0]].spectator)
HU_DrawCrosshair();
if (cv_crosshair2.value && !camera[1].chase && !players[displayplayers[1]].spectator)
HU_DrawCrosshair2();
if (cv_crosshair3.value && !camera[2].chase && !players[displayplayers[2]].spectator)
HU_DrawCrosshair3();
if (cv_crosshair4.value && !camera[3].chase && !players[displayplayers[3]].spectator)
HU_DrawCrosshair4();
}*/
// draw song credits
if (cv_songcredits.value)
HU_DrawSongCredits();
@@ -2356,138 +2416,92 @@ Ping_gfx_num (int lag)
return 4;
}
static int
Ping_gfx_color (int lag)
{
if (lag < 2)
return SKINCOLOR_JAWZ;
else if (lag < 4)
return SKINCOLOR_MINT;
else if (lag < 7)
return SKINCOLOR_GOLD;
else if (lag < 10)
return SKINCOLOR_RED;
else
return SKINCOLOR_WHITE; // SKINCOLOR_MAGENTA
}
static const UINT8 *
Ping_gfx_colormap (UINT32 lag, boolean gentleman)
{
const UINT8 *colormap = NULL;
if (K_UseColorHud())
colormap = R_GetTranslationColormap(TC_RAINBOW, Ping_gfx_color(lag), GTC_CACHE);
if (servermaxping && lag > servermaxping && hu_tick < 4)
{
// flash ping red if too high
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE);
}
else if (gentleman)
{
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PASTEL, GTC_CACHE);
}
return colormap;
}
static UINT32
Ping_conversion (UINT32 lag)
{
if (cv_pingmeasurement.value)
{
lag = (INT32)(lag * (1000.00f / TICRATE));
}
return lag;
}
//
// HU_drawPing
//
void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags)
void HU_drawPing(INT32 x, INT32 y, UINT32 lag, INT32 flags)
{
UINT8 *colormap = NULL;
INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
INT32 gfxnum; // gfx to draw
//SRB2/Kart v1.0 style
UINT8 numbars = 0; // how many ping bars do we draw?
UINT8 barcolor = 31; // color we use for the bars (green, yellow, red or black)
SINT8 i = 0;
SINT8 yoffset = 6;
//INT32 dx;
UINT32 lag = playerpingtable[pnum];
const boolean gentleman = (cv_mindelay.value && (lag < (tic_t)simulated_lag));
if (gentleman)
gfxnum = Ping_gfx_num(lag);
if (!cv_pingstyle.value)
{
lag = simulated_lag;
}
if (cv_pingstyle.value == 0) // kart
{
gfxnum = Ping_gfx_num(lag);
if (measureid == 1)
V_DrawScaledPatch(x+11 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
if (cv_pingicon.value)
V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]);
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+9, flags, Ping_conversion(lag), Ping_gfx_colormap(lag, gentleman));
if (servermaxping && lag > servermaxping && hu_tick < 4)
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE); // flash ping red if too high
if (cv_pingmeasurement.value)
lag = (INT32)(lag * (1000.00f / TICRATE));
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+9, flags, lag, colormap);
if (measureid == 0)
V_DrawScaledPatch(x+1 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
V_DrawScaledPatch(x+1 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
}
else if (cv_pingstyle.value == 1) // old style ping
else if (cv_pingstyle.value) // old style ping
{
if (cv_pingicon.value)
{
if (lag < 4)
{
numbars = 3;
barcolor = 184;
}
else if (lag < 7)
{
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103;
}
else if (lag < 10)
{
numbars = 1;
barcolor = 155; // need a better red
}
else // brazil
{
numbars = 0;
barcolor = 31;
}
}
if (cv_pingmeasurement.value)
lag = (INT32)(lag * (1000.00f / TICRATE));
if (vid.width >= 640) // how sad, we're using a shit resolution.
{
if (measureid == 1)
{
V_DrawRightAlignedSmallString(x+12, y+13, V_ALLOWLOWERCASE|flags, va("%dms", Ping_conversion(lag)));
//dx = x+1 - (V_SmallStringWidth(va("%dms", lag), V_ALLOWLOWERCASE|flags)/2);
//V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE|flags, va("%dms", lag));
V_DrawRightAlignedSmallString(x+12, y+13, V_ALLOWLOWERCASE|flags, va("%dms", lag));
}
else if (measureid == 0)
{
V_DrawRightAlignedSmallString(x+12, y+13, flags, va("d%d", Ping_conversion(lag)));
//dx = x+1 - (V_SmallStringWidth(va("d%d", lag), flags)/2);
//V_DrawSmallString(dx, y+4, flags, va("d%d", lag));
V_DrawRightAlignedSmallString(x+12, y+13, flags, va("d%d", lag));
}
}
if (cv_pingicon.value)
{
switch (lag)
{
case 0 ... 1:
numbars = 3;
barcolor = 215; // Blue
break;
case 2 ... 3:
numbars = 3;
barcolor = 184; // Green
break;
case 4 ... 6:
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103; // Yellow
break;
case 7 ... 9:
numbars = 1;
barcolor = 155; // Red
break;
default: // Brazil
numbars = 0;
barcolor = 31; // black
break;
}
if (gentleman)
{
barcolor = 194; // make it purplish
// bars get indirectly set earlier
}
for (i = 0; (i < 3); i++) // Draw the ping bar
{
for (i=0; (i<3); i++) // Draw the ping bar
{
V_DrawFill(x+2 *(i-1)+7, y+8+yoffset-4, 2, 8-yoffset, 31|flags);
if (i < numbars)
@@ -2581,10 +2595,8 @@ static inline void HU_DrawSpectatorTicker(void)
}
}
if ((netgame && i != serverplayer) || (cv_mindelay.value && P_IsLocalPlayer(&players[i])))
{
HU_drawPlayerPing((templength - duptweak)+8, height-20, i, V_TRANSLUCENT);
}
if (netgame && i != serverplayer)
HU_drawPing((templength - duptweak)+8, height-20, playerpingtable[i], V_TRANSLUCENT);
}
if ((length += len) >= dupadjust+8)
+7 -1
View File
@@ -42,6 +42,8 @@
#define CRED_FONTEND 'Z' // the last font character
#define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1)
#define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init();
extern char *shiftxform; // english translation shift table
extern char english_shiftxform[];
@@ -88,14 +90,18 @@ extern patch_t *tallnum[10];
extern patch_t *pingnum[10];
extern patch_t *pinggfx[5];
extern patch_t *ranknum[10];
extern patch_t *nightsnum[10];
extern patch_t *framecounter;
extern patch_t *frameslash;
extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *emeraldpics[7];
extern patch_t *tinyemeraldpics[7];
extern patch_t *rflagico;
extern patch_t *bflagico;
extern patch_t *rmatcico;
extern patch_t *bmatcico;
extern patch_t *tagico;
extern patch_t *tallminus;
// set true whenever the tab rankings are being shown for any reason
@@ -119,7 +125,7 @@ void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);
void HU_clearChatChars(void);
void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags); // Lat': Ping drawer for scoreboard.
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags); // Lat': Ping drawer for scoreboard.
//void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
//void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);
+10 -4
View File
@@ -226,8 +226,6 @@ void I_InitJoystick4(void);
*/
INT32 I_NumJoys(void);
extern INT32 numcontrollers;
/** \brief The *I_GetJoyName function
\param joyindex which joystick
@@ -236,8 +234,8 @@ extern INT32 numcontrollers;
*/
const char *I_GetJoyName(INT32 joyindex);
void I_GamepadRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void I_SetGamepadIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 blue);
void I_GamepadRumble(INT32 device_id, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void I_SetGamepadIndicatorColor(INT32 device_id, UINT8 red, UINT8 green, UINT8 blue);
#ifndef NOMUMBLE
#include "p_mobj.h" // mobj_t
@@ -251,6 +249,10 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener);
*/
void I_StartupMouse(void);
/** \brief Startup the second mouse
*/
void I_StartupMouse2(void);
/** \brief setup timer irq and user timer routine.
*/
void I_StartupTimer(void);
@@ -313,6 +315,10 @@ const char *I_LocateWad(void);
*/
void I_GetJoystickEvents(UINT8 index);
/** \brief Mouses events
*/
void I_GetMouseEvents(void);
char *I_GetEnv(const char *name);
INT32 I_PutEnv(char *variable);
+4
View File
@@ -1669,6 +1669,7 @@ boolean I_InitTcpNetwork(void)
// server address only in ip
if (serverhostname[0])
{
CV_Set(&cv_lastserver, serverhostname);
COM_BufAddText("connect \"");
COM_BufAddText(serverhostname);
COM_BufAddText("\"\n");
@@ -1678,6 +1679,9 @@ boolean I_InitTcpNetwork(void)
}
else
{
// Not quite sure if we want to save that but i'll do that for now
CV_Set(&cv_lastserver, "any");
// so we're on a LAN
COM_BufAddText("connect any\n");
+1 -1
View File
@@ -61,7 +61,7 @@ void I_UpdateTime(fixed_t timescale)
ticratescaled = (double)TICRATE * FIXED_TO_FLOAT(timescale);
enterprecise = I_GetPreciseTime();
elapsedseconds = (double)((INT64)enterprecise - oldenterprecise) / I_GetPrecisePrecision();
elapsedseconds = (double)(enterprecise - oldenterprecise) / I_GetPrecisePrecision();
tictimer += elapsedseconds;
while (tictimer > 1.0/ticratescaled)
{
+106 -75
View File
@@ -20,6 +20,8 @@
#include "p_local.h"
#include "st_stuff.h"
#include "r_fps.h"
#define SWITCHTIME TICRATE * 5 // cooldown between unforced switches
#define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart?
#define TRANSFERTIME TICRATE // how long to delay reaction shots?
@@ -29,6 +31,7 @@
struct directorinfo
{
UINT8 viewnum;
player_t* viewplayer;
tic_t cooldown; // how long has it been since we last switched?
tic_t freeze; // when nonzero, fixed switch pending, freeze logic!
@@ -40,6 +43,27 @@ struct directorinfo
INT32 boredom[MAXPLAYERS]; // how long has a given position had no credible attackers?
} directorinfo;
struct directorinfo directorinfosplit[MAXSPLITSCREENPLAYERS];
boolean K_DirectorIsPlayerAlone(void)
{
UINT8 pingame = 0;
// Gotta check how many players are active at this moment.
for (UINT8 i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
pingame++;
if (pingame >= 2) // we dont need to check further
break;
}
return (pingame <= 1);
}
static inline boolean race_rules(void)
{
return gametype == GT_RACE;
@@ -50,33 +74,38 @@ static fixed_t ScaleFromMap(fixed_t n, fixed_t scale)
return FixedMul(n, FixedDiv(scale, mapobjectscale));
}
boolean K_DirectorIsAvailable(void)
boolean K_DirectorIsAvailable(UINT8 viewnum)
{
if (splitscreen || (demo.playback && demo.title) || modeattacking)
if ((demo.playback && demo.title) || modeattacking)
return false;
return ((gamestate == GS_LEVEL) && ((demo.playback && !camera[0].freecam) || (players[consoleplayer].spectator && (D_NumPlayers() > 1))));
return ((gamestate == GS_LEVEL) && (viewnum <= splitscreen) && (demo.playback || (players[g_localplayers[viewnum]].spectator && !K_DirectorIsPlayerAlone())));
}
static boolean K_DirectorIsEnabled(void)
static boolean K_DirectorIsEnabled(const UINT8 viewnum)
{
return (cv_director.value && K_DirectorIsAvailable());
return (cv_director[viewnum].value && K_DirectorIsAvailable(viewnum));
}
void K_InitDirector(void)
{
INT32 playernum;
directorinfo.cooldown = SWITCHTIME;
directorinfo.freeze = 0;
directorinfo.attacker = 0;
directorinfo.maxdist = 0;
directorinfo.viewplayer = NULL;
directorinfo.viewnum = 0;
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
for (UINT8 i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
directorinfo.sortedplayers[playernum] = -1;
directorinfo.gap[playernum] = INT32_MAX;
directorinfo.boredom[playernum] = 0;
directorinfosplit[i].cooldown = SWITCHTIME;
directorinfosplit[i].freeze = 0;
directorinfosplit[i].attacker = 0;
directorinfosplit[i].maxdist = 0;
directorinfosplit[i].viewplayer = NULL;
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
{
directorinfosplit[i].sortedplayers[playernum] = -1;
directorinfosplit[i].gap[playernum] = INT32_MAX;
directorinfosplit[i].boredom[playernum] = 0;
}
}
}
@@ -139,13 +168,13 @@ static fixed_t K_GetFinishGap(INT32 leader, INT32 follower)
}
}
static void K_UpdateDirectorPositions(void)
static void K_UpdateDirectorPositions(const UINT8 viewnum)
{
INT32 playernum;
INT32 position;
player_t* target;
memset(directorinfo.sortedplayers, -1, sizeof(directorinfo.sortedplayers));
memset(directorinfosplit[viewnum].sortedplayers, -1, sizeof(directorinfo.sortedplayers));
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
{
@@ -153,43 +182,43 @@ static void K_UpdateDirectorPositions(void)
if (playeringame[playernum] && !target->spectator && target->kartstuff[k_position] > 0)
{
directorinfo.sortedplayers[target->kartstuff[k_position] - 1] = playernum;
directorinfosplit[viewnum].sortedplayers[target->kartstuff[k_position] - 1] = playernum;
}
}
for (position = 0; position < MAXPLAYERS - 1; position++)
{
directorinfo.gap[position] = INT32_MAX;
directorinfosplit[viewnum].gap[position] = INT32_MAX;
if (directorinfo.sortedplayers[position] == -1 || directorinfo.sortedplayers[position + 1] == -1)
if (directorinfosplit[viewnum].sortedplayers[position] == -1 || directorinfosplit[viewnum].sortedplayers[position + 1] == -1)
{
continue;
}
directorinfo.gap[position] = ScaleFromMap(K_GetFinishGap(directorinfo.sortedplayers[position], directorinfo.sortedplayers[position + 1]), FRACUNIT);
directorinfosplit[viewnum].gap[position] = ScaleFromMap(K_GetFinishGap(directorinfosplit[viewnum].sortedplayers[position], directorinfosplit[viewnum].sortedplayers[position + 1]), FRACUNIT);
if (directorinfo.gap[position] >= BREAKAWAYDIST)
if (directorinfosplit[viewnum].gap[position] >= BREAKAWAYDIST)
{
directorinfo.boredom[position] = (INT32)(min(BOREDOMTIME * 2, directorinfo.boredom[position] + 1));
directorinfosplit[viewnum].boredom[position] = (INT32)(min(BOREDOMTIME * 2, directorinfosplit[viewnum].boredom[position] + 1));
}
else if (directorinfo.boredom[position] > 0)
else if (directorinfosplit[viewnum].boredom[position] > 0)
{
directorinfo.boredom[position]--;
directorinfosplit[viewnum].boredom[position]--;
}
}
if (directorinfo.sortedplayers[0] == -1)
if (directorinfosplit[viewnum].sortedplayers[0] == -1)
{
directorinfo.maxdist = -1;
directorinfosplit[viewnum].maxdist = -1;
return;
}
directorinfo.maxdist = ScaleFromMap(K_GetDistanceToFinish(players[directorinfo.sortedplayers[0]]), FRACUNIT);
directorinfosplit[viewnum].maxdist = ScaleFromMap(K_GetDistanceToFinish(players[directorinfosplit[viewnum].sortedplayers[0]]), FRACUNIT);
}
static boolean K_CanSwitchDirector(void)
static boolean K_CanSwitchDirector(const UINT8 viewnum)
{
if (directorinfo.cooldown > 0)
if (directorinfosplit[viewnum].cooldown > 0)
{
return false;
}
@@ -197,9 +226,9 @@ static boolean K_CanSwitchDirector(void)
return true;
}
static void K_DirectorSwitch(INT32 player, boolean force)
static void K_DirectorSwitch(INT32 player, boolean force, const UINT8 viewnum)
{
if (!K_DirectorIsEnabled())
if (!K_DirectorIsEnabled(viewnum))
{
return;
}
@@ -209,45 +238,45 @@ static void K_DirectorSwitch(INT32 player, boolean force)
return;
}
if (!force && !K_CanSwitchDirector())
if (!force && !K_CanSwitchDirector(viewnum))
{
return;
}
G_ResetView(1, player, true);
directorinfo.cooldown = SWITCHTIME;
G_ResetView(viewnum+1, player, true);
directorinfosplit[viewnum].cooldown = SWITCHTIME;
}
static void K_DirectorForceSwitch(INT32 player, INT32 time)
static void K_DirectorForceSwitch(INT32 player, INT32 time, const UINT8 viewnum)
{
if (players[player].exiting)
{
return;
}
directorinfo.attacker = player;
directorinfo.freeze = time;
directorinfosplit[viewnum].attacker = player;
directorinfosplit[viewnum].freeze = time;
}
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source)
{
if (!K_DirectorIsEnabled())
if (!K_DirectorIsEnabled(directorinfo.viewnum))
{
return;
}
if (directorinfo.viewplayer != player)
if (directorinfosplit[directorinfo.viewnum].viewplayer != player)
{
return;
}
if (inflictor && inflictor->player)
{
K_DirectorForceSwitch(inflictor->player - players, TRANSFERTIME);
K_DirectorForceSwitch(inflictor->player - players, TRANSFERTIME, directorinfo.viewnum);
}
else if (source && source->player)
{
K_DirectorForceSwitch(source->player - players, TRANSFERTIME);
K_DirectorForceSwitch(source->player - players, TRANSFERTIME, directorinfo.viewnum);
}
}
@@ -267,14 +296,14 @@ void K_DrawDirectorDebugger(void)
V_DrawThinString(40, 0, V_70TRANS, va("CONF?"));
V_DrawThinString(80, 0, V_70TRANS, va("GAP"));
V_DrawThinString(120, 0, V_70TRANS, va("BORED"));
V_DrawThinString(150, 0, V_70TRANS, va("COOLDOWN: %d", directorinfo.cooldown));
V_DrawThinString(230, 0, V_70TRANS, va("MAXDIST: %d", directorinfo.maxdist));
V_DrawThinString(150, 0, V_70TRANS, va("COOLDOWN: %d", directorinfosplit[0].cooldown));
V_DrawThinString(230, 0, V_70TRANS, va("MAXDIST: %d", directorinfosplit[0].maxdist));
for (position = 0; position < MAXPLAYERS - 1; position++)
{
ytxt = 10 * (position + 1);
leader = directorinfo.sortedplayers[position];
follower = directorinfo.sortedplayers[position + 1];
leader = directorinfosplit[0].sortedplayers[position];
follower = directorinfosplit[0].sortedplayers[position + 1];
if (leader == -1 || follower == -1)
break;
@@ -287,15 +316,15 @@ void K_DrawDirectorDebugger(void)
V_DrawThinString(40, ytxt, V_70TRANS, va("NG"));
}
V_DrawThinString(80, ytxt, V_70TRANS, va("%d", directorinfo.gap[position]));
V_DrawThinString(80, ytxt, V_70TRANS, va("%d", directorinfosplit[0].gap[position]));
if (directorinfo.boredom[position] >= BOREDOMTIME)
if (directorinfosplit[0].boredom[position] >= BOREDOMTIME)
{
V_DrawThinString(120, ytxt, V_70TRANS, va("BORED"));
}
else
{
V_DrawThinString(120, ytxt, V_70TRANS, va("%d", directorinfo.boredom[position]));
V_DrawThinString(120, ytxt, V_70TRANS, va("%d", directorinfosplit[0].boredom[position]));
}
V_DrawThinString(150, ytxt, V_70TRANS, va("%s", player_names[leader]));
@@ -303,37 +332,38 @@ void K_DrawDirectorDebugger(void)
}
}
void K_UpdateDirector(void)
void K_UpdateDirector(const UINT8 viewnum)
{
INT32 targetposition;
directorinfo.viewplayer = &players[displayplayers[0]];
directorinfo.viewnum = viewnum;
directorinfosplit[directorinfo.viewnum].viewplayer = &players[displayplayers[directorinfo.viewnum]];
if (!K_DirectorIsEnabled())
if (!K_DirectorIsEnabled(directorinfo.viewnum))
{
return;
}
K_UpdateDirectorPositions();
K_UpdateDirectorPositions(directorinfo.viewnum);
if (directorinfo.cooldown > 0) {
directorinfo.cooldown--;
if (directorinfosplit[directorinfo.viewnum].cooldown > 0) {
directorinfosplit[directorinfo.viewnum].cooldown--;
}
// handle pending forced switches
if (directorinfo.freeze > 0)
if (directorinfosplit[directorinfo.viewnum].freeze > 0)
{
if (!(--directorinfo.freeze))
K_DirectorSwitch(directorinfo.attacker, true);
if (!(--directorinfosplit[directorinfo.viewnum].freeze))
K_DirectorSwitch(directorinfosplit[directorinfo.viewnum].attacker, true, directorinfo.viewnum);
return;
}
// if there's only one player left in the list, just switch to that player
if (directorinfo.sortedplayers[0] != -1 && (directorinfo.sortedplayers[1] == -1 ||
if (directorinfosplit[directorinfo.viewnum].sortedplayers[0] != -1 && (directorinfosplit[directorinfo.viewnum].sortedplayers[1] == -1 ||
// TODO: Battle; I just threw this together quick. Focus on leader.
!race_rules()))
{
K_DirectorSwitch(directorinfo.sortedplayers[0], false);
K_DirectorSwitch(directorinfosplit[directorinfo.viewnum].sortedplayers[0], false, directorinfo.viewnum);
return;
}
@@ -345,39 +375,39 @@ void K_UpdateDirector(void)
INT32 target;
// you are out of players, try again
if (directorinfo.sortedplayers[targetposition] == -1)
if (directorinfosplit[directorinfo.viewnum].sortedplayers[targetposition] == -1)
{
break;
}
// pair too far apart? try the next one
if (directorinfo.boredom[targetposition - 1] >= BOREDOMTIME)
if (directorinfosplit[directorinfo.viewnum].boredom[targetposition - 1] >= BOREDOMTIME)
{
continue;
}
// pair finished? try the next one
if (players[directorinfo.sortedplayers[targetposition]].exiting)
if (players[directorinfosplit[directorinfo.viewnum].sortedplayers[targetposition]].exiting)
{
continue;
}
// don't risk switching away from forward pairs at race end, might miss something!
if (directorinfo.maxdist > PINCHDIST)
if (directorinfosplit[directorinfo.viewnum].maxdist > PINCHDIST)
{
// if the "next" player is close enough, they should be able to see everyone fine!
// walk back through the standings to find a vantage that gets everyone in frame.
// (also creates a pretty cool effect w/ overtakes at speed)
while (targetposition < MAXPLAYERS && directorinfo.gap[targetposition] < WALKBACKDIST)
while (targetposition < MAXPLAYERS && directorinfosplit[directorinfo.viewnum].gap[targetposition] < WALKBACKDIST)
{
targetposition++;
}
}
target = directorinfo.sortedplayers[targetposition];
target = directorinfosplit[directorinfo.viewnum].sortedplayers[targetposition];
// stop here since we're already viewing this player
if (displayplayers[0] == target)
if (displayplayers[directorinfo.viewnum] == target)
{
break;
}
@@ -385,31 +415,32 @@ void K_UpdateDirector(void)
// if we're certain the back half of the pair is actually in this position, try to switch
if (!players[target].kartstuff[k_positiondelay])
{
K_DirectorSwitch(target, false);
K_DirectorSwitch(target, false, directorinfo.viewnum);
}
// even if we're not certain, if we're cetain we're watching the WRONG player, try to switch
if (directorinfo.viewplayer->kartstuff[k_position] != targetposition+1 && !directorinfo.viewplayer->kartstuff[k_positiondelay])
if (directorinfosplit[directorinfo.viewnum].viewplayer->kartstuff[k_position] != targetposition+1 && !directorinfosplit[directorinfo.viewnum].viewplayer->kartstuff[k_positiondelay])
{
K_DirectorSwitch(target, false);
K_DirectorSwitch(target, false, directorinfo.viewnum);
}
break;
}
}
void K_ToggleDirector(void)
void K_ToggleDirector(const UINT8 viewnum)
{
if (!K_DirectorIsAvailable())
if (!K_DirectorIsAvailable(viewnum))
return;
if (!K_DirectorIsEnabled())
G_AdjustView(viewnum+1, 1, true);
if (!K_DirectorIsEnabled(viewnum))
{
G_AdjustView(1, 1, true);
directorinfo.cooldown = 0; // switch immediately
directorinfosplit[viewnum].cooldown = 0; // switch immediately
}
directortoggletimer = 0;
CV_SetValue(&cv_director, (cv_director.value ^ 1));
CV_SetValue(&cv_director[viewnum], (cv_director[viewnum].value ^ 1));
}
+3 -3
View File
@@ -10,9 +10,9 @@
/// \file k_director.h
/// \brief SRB2kart automatic spectator camera.
boolean K_DirectorIsAvailable(void);
boolean K_DirectorIsAvailable(UINT8 viewnum);
void K_InitDirector(void);
void K_UpdateDirector(void);
void K_UpdateDirector(UINT8 viewnum);
void K_DrawDirectorDebugger(void);
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source);
void K_ToggleDirector(void);
void K_ToggleDirector(UINT8 viewnum);
+421 -1004
View File
File diff suppressed because it is too large. Load diff
+6 -12
View File
@@ -11,7 +11,6 @@
#define KART_FULLTURN 800
extern UINT8 colortranslations[MAXTRANSLATIONS][16];
extern const char *KartColor_Names[MAXSKINCOLORS];
extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2];
@@ -23,25 +22,20 @@ boolean K_UseColorHud(void);
void K_RegisterKartStuff(void);
extern consvar_t cv_coloredspeedlines, cv_coloredsneakertrail;
extern consvar_t cv_bananajitter;
extern consvar_t cv_bananthrowroll;
extern consvar_t cv_airsparks;
extern consvar_t cv_colorizedhud, cv_colorizeditembox, cv_colorizedhudcolor;
extern consvar_t cv_colorizedhud;
extern consvar_t cv_colorizeditembox;
extern consvar_t cv_colorizedhudcolor;
extern consvar_t cv_darkitembox;
extern consvar_t cv_biglaps;
extern consvar_t cv_highresportrait;
extern consvar_t cv_stat_xoffset, cv_stat_yoffset;
extern consvar_t cv_stat_xoffset;
extern consvar_t cv_stat_yoffset;
extern consvar_t cv_showstats;
extern consvar_t cv_fancyroulette;
extern consvar_t cv_showlaptimes;
extern consvar_t cv_battlespeedo;
extern consvar_t cv_multiitemicon;
extern consvar_t cv_huditemamount;
#define NUMSPEEDOSTUFF 6
extern CV_PossibleValue_t speedo_cons_t[NUMSPEEDOSTUFF];
extern CV_PossibleValue_t driftgaugestyle_cons_t[NUMSPEEDOSTUFF];
boolean K_IsPlayerLosing(player_t *player);
boolean K_IsPlayerWanted(player_t *player);
@@ -61,7 +55,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor);
void K_StealBumper(player_t *player, player_t *victim, boolean force);
void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source);
void K_SpawnMineExplosion(mobj_t *source, UINT8 color);
void K_RollMobjBySlopes(mobj_t *mo, pslope_t *slope);
void K_RollMobjBySlopes(mobj_t *mo, boolean usedistance);
void K_SpawnBoostTrail(player_t *player);
void K_SpawnSparkleTrail(mobj_t *mo);
void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent);
+30
View File
@@ -1910,6 +1910,15 @@ msgstr ""
msgid " Not found: %s\n"
msgstr ""
#: hardware/s_ds3d/s_ds3d.c:617 p_tick.c:168 sdl/i_sound.c:1347
#: win32/win_snd.c:1073 win32/win_snd.c:1431
msgid "Done\n"
msgstr ""
#: hardware/s_ds3d/s_ds3d.c:617 win32/win_snd.c:1073
msgid "Failed\n"
msgstr ""
#: hu_stuff.c:375
msgid "The chat is muted. You can't say anything at the moment.\n"
msgstr ""
@@ -3165,6 +3174,21 @@ msgstr ""
msgid "I_ShutdownMusic: "
msgstr ""
#: sdl/i_sound.c:1494
msgid " disabled loading FMOD\n"
msgstr ""
#: sdl/i_sound.c:1513
msgid " failed to load FMOD\n"
msgstr ""
#: sdl/i_sound.c:1522 win32/win_snd.c:1237
#, c-format
msgid ""
"Wrong FMOD DLL version.\n"
"You should be using FMOD %s\n"
msgstr ""
#: sdl/i_sound.c:1611
msgid "I_InitMusic:"
msgstr ""
@@ -3779,6 +3803,12 @@ msgstr ""
msgid "%d mixer devices available\n"
msgstr ""
#: win32/win_snd.c:1227
msgid ""
" failed to load FMOD\n"
" no DigiMusic support\n"
msgstr ""
#: win32/win_snd.c:1289
msgid "No MIDI devices available, music is disabled\n"
msgstr ""
+30
View File
@@ -1994,6 +1994,15 @@ msgstr ""
msgid " Not found: %s\n"
msgstr ""
#: hardware/s_ds3d/s_ds3d.c:617 p_tick.c:168 sdl/i_sound.c:1347
#: win32/win_snd.c:1071 win32/win_snd.c:1429
msgid "Done\n"
msgstr ""
#: hardware/s_ds3d/s_ds3d.c:617 win32/win_snd.c:1071
msgid "Failed\n"
msgstr ""
#: hu_stuff.c:405
msgid "The chat is muted. You can't say anything at the moment.\n"
msgstr ""
@@ -3368,6 +3377,21 @@ msgstr ""
msgid "I_ShutdownMusic: "
msgstr ""
#: sdl/i_sound.c:1494
msgid " disabled loading FMOD\n"
msgstr ""
#: sdl/i_sound.c:1513
msgid " failed to load FMOD\n"
msgstr ""
#: sdl/i_sound.c:1522 win32/win_snd.c:1235
#, c-format
msgid ""
"Wrong FMOD DLL version.\n"
"You should be using FMOD %s\n"
msgstr ""
#: sdl/i_sound.c:1611
msgid "I_InitMusic:"
msgstr ""
@@ -3975,6 +3999,12 @@ msgstr ""
msgid "%d mixer devices available\n"
msgstr ""
#: win32/win_snd.c:1225
msgid ""
" failed to load FMOD\n"
" no DigiMusic support\n"
msgstr ""
#: win32/win_snd.c:1287
msgid "No MIDI devices available, music is disabled\n"
msgstr ""
+28 -29
View File
@@ -64,7 +64,7 @@ static UINT8 * hooksErrored;
static int errorRef;
FUNCINLINE static ATTRINLINE boolean mobj_hook_available(int hook_type, mobjtype_t mobj_type)
static boolean mobj_hook_available(int hook_type, mobjtype_t mobj_type)
{
return
(
@@ -73,7 +73,7 @@ FUNCINLINE static ATTRINLINE boolean mobj_hook_available(int hook_type, mobjtype
);
}
FUNCINLINE static ATTRINLINE unsigned hook_in_list
static unsigned hook_in_list
(
const char * const name,
const char * const * const list
@@ -106,7 +106,7 @@ static void get_table(lua_State *L)
lua_remove(L, -2);
}
FUNCINLINE static ATTRINLINE void add_hook_to_table(lua_State *L, int n)
static void add_hook_to_table(lua_State *L, int n)
{
lua_pushnumber(L, nextid);
lua_rawseti(L, -2, n);
@@ -175,14 +175,14 @@ static void add_string_hook(lua_State *L, int type)
add_hook_to_table(L, ++hook->numGeneric);
}
FUNCINLINE static ATTRINLINE void add_hook(hook_t *map)
static void add_hook(hook_t *map)
{
Z_Realloc(map->ids, (map->numHooks + 1) * sizeof *map->ids,
PU_STATIC, &map->ids);
map->ids[map->numHooks++] = nextid;
}
FUNCINLINE static ATTRINLINE void add_mobj_hook(lua_State *L, int hook_type)
static void add_mobj_hook(lua_State *L, int hook_type)
{
mobjtype_t mobj_type = luaL_optnumber(L, 3, MT_NULL);
@@ -191,7 +191,7 @@ FUNCINLINE static ATTRINLINE void add_mobj_hook(lua_State *L, int hook_type)
add_hook(&mobjHookIds[mobj_type][hook_type]);
}
FUNCINLINE static ATTRINLINE void add_hud_hook(lua_State *L, int idx)
static void add_hud_hook(lua_State *L, int idx)
{
add_hook(&hudHookIds[luaL_checkoption(L,
idx, "game", hudHookNames)]);
@@ -263,6 +263,7 @@ int LUA_HookLib(lua_State *L)
return 0;
}
int lib_hudadd(lua_State *L);/* yeah compiler */
int lib_hudadd(lua_State *L)
{
@@ -296,24 +297,24 @@ enum {
SINDEX = 2,/* string itself is pushed in case of string hook */
};
FUNCINLINE static ATTRINLINE void push_error_handler(void)
static void push_error_handler(void)
{
lua_getref(gL, errorRef);
}
/* repush hook string */
FUNCINLINE static ATTRINLINE void push_string(void)
static void push_string(void)
{
lua_pushvalue(gL, SINDEX);
}
FUNCINLINE static ATTRINLINE boolean begin_hook_values(Hook_State *hook)
static boolean begin_hook_values(Hook_State *hook)
{
hook->top = lua_gettop(gL);
return true;
}
FUNCINLINE static ATTRINLINE void start_hook_stack(void)
static void start_hook_stack(void)
{
lua_settop(gL, 0);
push_error_handler();
@@ -342,7 +343,7 @@ static boolean init_hook_type
return false;
}
FUNCINLINE static ATTRINLINE boolean prepare_hook
static boolean prepare_hook
(
Hook_State * hook,
int default_status,
@@ -355,7 +356,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_hook
hookIds[hook_type].numHooks);
}
FUNCINLINE static ATTRINLINE boolean prepare_mobj_hook
static boolean prepare_mobj_hook
(
Hook_State * hook,
int default_status,
@@ -372,7 +373,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_mobj_hook
mobj_hook_available(hook_type, mobj_type));
}
FUNCINLINE static ATTRINLINE boolean prepare_string_hook
static boolean prepare_string_hook
(
Hook_State * hook,
int default_status,
@@ -392,7 +393,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_string_hook
return false;
}
FUNCINLINE static ATTRINLINE void init_hook_call
static void init_hook_call
(
Hook_State * hook,
int results,
@@ -405,13 +406,13 @@ FUNCINLINE static ATTRINLINE void init_hook_call
hook->results_handler = results_handler;
}
FUNCINLINE static ATTRINLINE void get_hook(Hook_State *hook, const int *ids, int n)
static void get_hook(Hook_State *hook, const int *ids, int n)
{
hook->id = ids[n];
lua_getref(gL, hookRefs[hook->id]);
}
FUNCINLINE static ATTRINLINE void get_hook_from_table(Hook_State *hook, int n)
static void get_hook_from_table(Hook_State *hook, int n)
{
lua_rawgeti(gL, -1, n);
hook->id = lua_tonumber(gL, -1);
@@ -443,7 +444,7 @@ static int call_single_hook_no_copy(Hook_State *hook)
return 1;
}
FUNCINLINE static ATTRINLINE int call_single_hook(Hook_State *hook)
static int call_single_hook(Hook_State *hook)
{
int i;
@@ -453,7 +454,7 @@ FUNCINLINE static ATTRINLINE int call_single_hook(Hook_State *hook)
return call_single_hook_no_copy(hook);
}
FUNCINLINE static ATTRINLINE int call_hook_table_for(Hook_State *hook, int n)
static int call_hook_table_for(Hook_State *hook, int n)
{
int k;
@@ -466,12 +467,12 @@ FUNCINLINE static ATTRINLINE int call_hook_table_for(Hook_State *hook, int n)
return n;
}
FUNCINLINE static ATTRINLINE int call_hook_table(Hook_State *hook)
static int call_hook_table(Hook_State *hook)
{
return call_hook_table_for(hook, lua_objlen(gL, -1));
}
FUNCINLINE static ATTRINLINE int call_mapped(Hook_State *hook, const hook_t *map)
static int call_mapped(Hook_State *hook, const hook_t *map)
{
int k;
@@ -502,7 +503,7 @@ static int call_string_hooks(Hook_State *hook)
return calls;
}
FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
static int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
{
return call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
}
@@ -545,7 +546,7 @@ static int call_hooks
#define res_none NULL
FUNCINLINE static ATTRINLINE void res_true(Hook_State *hook)
static void res_true(Hook_State *hook)
{
if (lua_toboolean(gL, -1))
hook->status = true;
@@ -557,7 +558,7 @@ FUNCINLINE static ATTRINLINE void res_true(Hook_State *hook)
hook->status = false;
}*/
FUNCINLINE static ATTRINLINE void res_force(Hook_State *hook)
static void res_force(Hook_State *hook)
{
if (!lua_isnil(gL, -1))
{
@@ -568,7 +569,7 @@ FUNCINLINE static ATTRINLINE void res_force(Hook_State *hook)
}
}
FUNCINLINE static ATTRINLINE void res_hud(Hook_State *hook)
static void res_hud(Hook_State *hook)
{
(void)hook;
@@ -699,8 +700,6 @@ static void hook_think_frame(int type)
const hook_t * map = &hookIds[type];
int k;
const boolean perfstats = (cv_perfstats.value >= 3);
if (prepare_hook(&hook, 0, type))
{
init_hook_call(&hook, 0, res_none);
@@ -709,7 +708,7 @@ static void hook_think_frame(int type)
{
get_hook(&hook, map->ids, k);
if (perfstats)
if (cv_perfstats.value >= 3)
{
lua_pushvalue(gL, -1);/* need the function again */
time_taken = I_GetPreciseTime();
@@ -717,7 +716,7 @@ static void hook_think_frame(int type)
call_single_hook(&hook);
if (perfstats)
if (cv_perfstats.value >= 3)
{
lua_Debug ar;
time_taken = I_GetPreciseTime() - time_taken;
@@ -809,7 +808,7 @@ typedef struct {
ticcmd_t * cmd;
} BotAI_State;
FUNCINLINE static ATTRINLINE boolean checkbotkey(const char *field)
static boolean checkbotkey(const char *field)
{
return lua_toboolean(gL, -1) && strcmp(lua_tostring(gL, -2), field) == 0;
}
+12 -38
View File
@@ -397,18 +397,6 @@ static int libd_cachePatch(lua_State *L)
return 1;
}
#ifdef ROTSPRITE
static int libd_cachePatchRotated(lua_State *L)
{
HUDONLY
angle_t rollangle = luaL_checkangle(L, 2);
INT32 rot = R_GetRollAngle(rollangle);
LUA_PushUserdata(L, W_CachePatchNameRotated(luaL_checkstring(L, 1), rot, PU_STATIC), META_PATCH);
return 1;
}
#endif
// this is structured like getSprite2Patch in vanilla 2.2
// v.getSpritePatch(skin, sprite, [frame, [angle, [rollangle]]])
static int libd_getSpritePatch(lua_State *L)
@@ -474,16 +462,12 @@ static int libd_getSpritePatch(lua_State *L)
if (skn < 0) // standard sprite
{
sprdef = &sprites[i];
#ifdef ROTSPRITE
sprinfo = &spriteinfo[i];
#endif
}
else // player skin
{
sprdef = &skins[skn].spritedef;
#ifdef ROTSPRITE
sprinfo = &skins[skn].sprinfo;
#endif
}
// set frame number
@@ -504,15 +488,13 @@ static int libd_getSpritePatch(lua_State *L)
if (angle >= 8) // out of range?
angle = (angle & 7); // modulus angle by 8
#ifdef ROTSPRITE
// rotsprite?????
if (lua_isnumber(L, 4))
if (lua_isnumber(L, 4) && cv_sloperoll.value)
{
angle_t rollangle = luaL_checkangle(L, 4);
INT32 rot = R_GetRollAngle(rollangle);
if (rot)
{
if (rot) {
patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), false, sprinfo, rot);
LUA_PushUserdata(L, rotsprite, META_PATCH);
lua_pushboolean(L, false);
@@ -520,7 +502,6 @@ static int libd_getSpritePatch(lua_State *L)
return 3;
}
}
#endif
// push both the patch and its "flip" value
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_STATIC), META_PATCH);
@@ -530,7 +511,7 @@ static int libd_getSpritePatch(lua_State *L)
static int libd_draw(lua_State *L)
{
INT32 x, y, flags, blend;
INT32 x, y, flags;
patch_t *patch;
UINT8 *colormap = NULL;
huddrawlist_h list;
@@ -542,7 +523,6 @@ static int libd_draw(lua_State *L)
flags = luaL_optinteger(L, 4, 0);
if (!lua_isnoneornil(L, 5))
colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP));
blend = luaL_optinteger(L, 6, 0);
flags &= ~V_PARAMMASK; // Don't let crashes happen.
@@ -551,16 +531,16 @@ static int libd_draw(lua_State *L)
lua_pop(L, 1);
if (LUA_HUD_IsDrawListValid(list))
LUA_HUD_AddDraw(list, x, y, patch, flags, colormap, blend);
LUA_HUD_AddDraw(list, x, y, patch, flags, colormap);
else
V_DrawBlendingFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, flags, patch, colormap, blend);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, flags, patch, colormap);
return 0;
}
static int libd_drawScaled(lua_State *L)
{
fixed_t x, y, scale;
INT32 flags, blend;
INT32 flags;
patch_t *patch;
UINT8 *colormap = NULL;
huddrawlist_h list;
@@ -575,7 +555,6 @@ static int libd_drawScaled(lua_State *L)
flags = luaL_optinteger(L, 5, 0);
if (!lua_isnoneornil(L, 6))
colormap = *((UINT8 **)luaL_checkudata(L, 6, META_COLORMAP));
blend = luaL_optinteger(L, 7, 0);
flags &= ~V_PARAMMASK; // Don't let crashes happen.
@@ -584,9 +563,9 @@ static int libd_drawScaled(lua_State *L)
lua_pop(L, 1);
if (LUA_HUD_IsDrawListValid(list))
LUA_HUD_AddDrawScaled(list, x, y, scale, patch, flags, colormap, blend);
LUA_HUD_AddDrawScaled(list, x, y, scale, patch, flags, colormap);
else
V_DrawBlendingFixedPatch(x, y, scale, flags, patch, colormap, blend);
V_DrawFixedPatch(x, y, scale, flags, patch, colormap);
return 0;
}
@@ -730,7 +709,7 @@ static int libd_drawOnMinimap(lua_State *L)
if (LUA_HUD_IsDrawListValid(list))
{
LUA_HUD_AddDrawScaled(list, amxpos, amypos, scale, patch, splitflags, colormap, 0);
LUA_HUD_AddDrawScaled(list, amxpos, amypos, scale, patch, splitflags, colormap);
}
else
{
@@ -743,7 +722,7 @@ static int libd_drawOnMinimap(lua_State *L)
static int libd_drawStretched(lua_State *L)
{
fixed_t x, y, hscale, vscale;
INT32 flags, blend;
INT32 flags;
patch_t *patch;
UINT8 *colormap = NULL;
huddrawlist_h list;
@@ -761,7 +740,6 @@ static int libd_drawStretched(lua_State *L)
flags = luaL_optinteger(L, 6, 0);
if (!lua_isnoneornil(L, 7))
colormap = *((UINT8 **)luaL_checkudata(L, 7, META_COLORMAP));
blend = luaL_optinteger(L, 8, 0);
flags &= ~V_PARAMMASK; // Don't let crashes happen.
@@ -770,9 +748,9 @@ static int libd_drawStretched(lua_State *L)
lua_pop(L, 1);
if (LUA_HUD_IsDrawListValid(list))
LUA_HUD_AddDrawStretched(list, x, y, hscale, vscale, patch, flags, colormap, blend);
LUA_HUD_AddDrawStretched(list, x, y, hscale, vscale, patch, flags, colormap);
else
V_DrawStretchyFixedPatch(x, y, hscale, vscale, flags, patch, colormap, blend);
V_DrawStretchyFixedPatch(x, y, hscale, vscale, flags, patch, colormap);
return 0;
}
@@ -1194,10 +1172,6 @@ static int libd_interpLatch(lua_State *L)
static luaL_Reg lib_draw[] = {
{"patchExists", libd_patchExists},
{"cachePatch", libd_cachePatch},
#ifdef ROTSPRITE
// Is this ifdef nonsense? Yes.
{"cachePatchRotated", libd_cachePatchRotated},
#endif
{"draw", libd_draw},
{"drawScaled", libd_drawScaled},
{"drawStretched", libd_drawStretched},
+6 -13
View File
@@ -69,7 +69,6 @@ typedef struct drawitem_s {
size_t stroffset; // offset into strbuf to get str
};
const UINT8 *colormap;
INT32 blend;
} drawitem_t;
// The internal structure of a drawlist.
@@ -346,8 +345,7 @@ void LUA_HUD_AddDraw(
INT32 y,
patch_t *patch,
INT32 flags,
UINT8 *colormap,
INT32 blend
UINT8 *colormap
)
{
size_t i = AllocateDrawItem(list);
@@ -359,7 +357,6 @@ void LUA_HUD_AddDraw(
item->patch = patch;
item->flags = flags;
item->colormap = colormap;
item->blend = blend;
}
void LUA_HUD_AddDrawScaled(
@@ -369,8 +366,7 @@ void LUA_HUD_AddDrawScaled(
fixed_t scale,
patch_t *patch,
INT32 flags,
UINT8 *colormap,
INT32 blend
UINT8 *colormap
)
{
size_t i = AllocateDrawItem(list);
@@ -383,7 +379,6 @@ void LUA_HUD_AddDrawScaled(
item->patch = patch;
item->flags = flags;
item->colormap = colormap;
item->blend = blend;
}
void LUA_HUD_AddDrawStretched(
@@ -394,8 +389,7 @@ void LUA_HUD_AddDrawStretched(
fixed_t vscale,
patch_t *patch,
INT32 flags,
UINT8 *colormap,
INT32 blend
UINT8 *colormap
)
{
size_t i = AllocateDrawItem(list);
@@ -409,7 +403,6 @@ void LUA_HUD_AddDrawStretched(
item->patch = patch;
item->flags = flags;
item->colormap = colormap;
item->blend = blend;
}
void LUA_HUD_AddDrawNum(
@@ -641,17 +634,17 @@ void LUA_HUD_DrawList(huddrawlist_h list)
case DI_Draw:
if (!item->patch || item->patch == NULL)
return;
V_DrawBlendingFixedPatch(LERPS(x), LERPS(y), FRACUNIT, item->flags, item->patch, item->colormap, item->blend);
V_DrawFixedPatch(LERPS(x), LERPS(y), FRACUNIT, item->flags, item->patch, item->colormap);
break;
case DI_DrawScaled:
if (!item->patch || item->patch == NULL)
return;
V_DrawBlendingFixedPatch(LERPS(x), LERPS(y), LERP(scale), item->flags, item->patch, item->colormap, item->blend);
V_DrawFixedPatch(LERPS(x), LERPS(y), LERP(scale), item->flags, item->patch, item->colormap);
break;
case DI_DrawStretched:
if (!item->patch || item->patch == NULL)
return;
V_DrawStretchyFixedPatch(LERPS(x), LERPS(y), LERP(hscale), LERP(vscale), item->flags, item->patch, item->colormap, item->blend);
V_DrawStretchyFixedPatch(LERPS(x), LERPS(y), LERP(hscale), LERP(vscale), item->flags, item->patch, item->colormap);
break;
case DI_DrawNum:
V_DrawTallNum(LERPS(x), LERPS(y), item->flags, item->num);
+3 -6
View File
@@ -40,8 +40,7 @@ void LUA_HUD_AddDraw(
INT32 y,
patch_t *patch,
INT32 flags,
UINT8 *colormap,
INT32 blend
UINT8 *colormap
);
void LUA_HUD_AddDrawStretched(
huddrawlist_h list,
@@ -51,8 +50,7 @@ void LUA_HUD_AddDrawStretched(
fixed_t vscale,
patch_t *patch,
INT32 flags,
UINT8 *colormap,
INT32 blend
UINT8 *colormap
);
void LUA_HUD_AddDrawScaled(
huddrawlist_h list,
@@ -61,8 +59,7 @@ void LUA_HUD_AddDrawScaled(
fixed_t scale,
patch_t *patch,
INT32 flags,
UINT8 *colormap,
INT32 blend
UINT8 *colormap
);
void LUA_HUD_AddDrawNum(
huddrawlist_h list,
-13
View File
@@ -94,7 +94,6 @@ enum line_e {
line_sidenum,
line_frontside,
line_backside,
line_alpha,
line_slopetype,
line_frontsector,
line_backsector,
@@ -116,7 +115,6 @@ static const char *const line_opt[] = {
"sidenum",
"frontside",
"backside",
"alpha",
"slopetype",
"frontsector",
"backsector",
@@ -188,7 +186,6 @@ enum ffloor_e {
ffloor_next,
ffloor_prev,
ffloor_alpha,
ffloor_blend,
};
static const char *const ffloor_opt[] = {
@@ -207,7 +204,6 @@ static const char *const ffloor_opt[] = {
"next",
"prev",
"alpha",
"blend",
NULL};
static int ffloor_fields_ref = LUA_NOREF;
@@ -656,9 +652,6 @@ static int line_get(lua_State *L)
return 0;
LUA_PushUserdata(L, &sides[line->sidenum[1]], META_SIDE);
return 1;
case line_alpha:
lua_pushfixed(L, line->alpha);
return 1;
case line_slopetype:
switch(line->slopetype)
{
@@ -1175,9 +1168,6 @@ static int ffloor_get(lua_State *L)
case ffloor_alpha:
lua_pushinteger(L, ffloor->alpha);
return 1;
case ffloor_blend:
lua_pushinteger(L, ffloor->blend);
return 1;
}
return 0;
}
@@ -1256,9 +1246,6 @@ static int ffloor_set(lua_State *L)
case ffloor_alpha:
ffloor->alpha = (INT32)luaL_checkinteger(L, 3);
break;
case ffloor_blend:
ffloor->blend = (INT32)luaL_checkinteger(L, 3);
break;
}
return 0;
}
+3 -38
View File
@@ -40,7 +40,6 @@ int mobj_sprev_unimplemented(lua_State *L);
int mobj_angle_setter(lua_State *L);
int mobj_sloperoll_noop(lua_State *L);
int mobj_spritescale_setter(lua_State *L);
int mobj_spriteoffset_setter(lua_State *L);
int mobj_touching_sectorlist_unimplemented(lua_State *L);
int mobj_radius_setter(lua_State *L);
int mobj_height_setter(lua_State *L);
@@ -53,7 +52,6 @@ int mobj_skin_setter(lua_State *L);
int mobj_localskin_getter(lua_State *L);
int mobj_localskin_setter(lua_State *L);
int mobj_color_setter(lua_State *L);
int mobj_blendmode_setter(lua_State *L);
int mobj_bnext_noset(lua_State *L);
int mobj_bprev_unimplemented(lua_State *L);
int mobj_hnext_setter(lua_State *L);
@@ -96,10 +94,9 @@ static const udata_field_t mobj_fields[] = {
FIELD(mobj_t, anim_duration, udatalib_getter_uint16, udatalib_setter_uint16),
FIELD(mobj_t, spritexscale, udatalib_getter_fixed, mobj_spritescale_setter),
FIELD(mobj_t, spriteyscale, udatalib_getter_fixed, mobj_spritescale_setter),
FIELD(mobj_t, spritexoffset, udatalib_getter_fixed, mobj_spriteoffset_setter),
FIELD(mobj_t, spriteyoffset, udatalib_getter_fixed, mobj_spriteoffset_setter),
FIELD(mobj_t, spritexoffset, udatalib_getter_fixed, udatalib_setter_fixed),
FIELD(mobj_t, spriteyoffset, udatalib_getter_fixed, udatalib_setter_fixed),
FIELD(mobj_t, touching_sectorlist, mobj_touching_sectorlist_unimplemented, mobj_touching_sectorlist_unimplemented),
FIELD(mobj_t, lightlevel, udatalib_getter_int16, udatalib_setter_int16),
FIELD(mobj_t, subsector, udatalib_getter_subsector, mobj_nosetpos_subsector),
FIELD(mobj_t, floorz, udatalib_getter_fixed, mobj_nosetpos_floorz),
FIELD(mobj_t, ceilingz, udatalib_getter_fixed, mobj_nosetpos_ceilingz),
@@ -117,7 +114,6 @@ static const udata_field_t mobj_fields[] = {
FIELD(mobj_t, skin, mobj_skin_getter, mobj_skin_setter),
FIELD(mobj_t, localskin, mobj_localskin_getter, mobj_localskin_setter),
FIELD(mobj_t, color, udatalib_getter_uint8, mobj_color_setter),
FIELD(mobj_t, blendmode, udatalib_getter_int32, mobj_blendmode_setter),
FIELD(mobj_t, bnext, udatalib_getter_mobj, mobj_bnext_noset),
FIELD(mobj_t, bprev, mobj_bprev_unimplemented, mobj_bprev_unimplemented),
FIELD(mobj_t, hnext, udatalib_getter_mobj, mobj_hnext_setter),
@@ -150,6 +146,7 @@ static const udata_field_t mobj_fields[] = {
FIELD(mobj_t, standingslope, udatalib_getter_slope, mobj_standingslope_noset),
FIELD(mobj_t, colorized, udatalib_getter_boolean, udatalib_setter_boolean),
FIELD(mobj_t, mirrored, udatalib_getter_boolean, udatalib_setter_boolean),
FIELD(mobj_t, rollmodel, udatalib_getter_boolean, udatalib_setter_boolean),
{ NULL, 0, NULL, NULL },
};
#undef FIELD
@@ -280,26 +277,6 @@ int mobj_spritescale_setter(lua_State *L)
return 0;
}
int mobj_spriteoffset_setter(lua_State *L)
{
mobj_t *mo = GETMO();
fixed_t *spriteoffset;
UDATALIB_GETFIELD(fixed_t, spriteoffset);
if (!mo->player)
*spriteoffset = luaL_checkfixed(L, 2);
else
{
// Mmm yea
if (spriteoffset == &mo->spritexoffset)
mo->realxoffset = luaL_checkfixed(L, 2);
else
mo->realyoffset = luaL_checkfixed(L, 2);
}
return 0;
}
int mobj_radius_setter(lua_State *L)
{
mobj_t *mo = GETMO();
@@ -499,18 +476,6 @@ int mobj_color_setter(lua_State *L)
return 0;
}
int mobj_blendmode_setter(lua_State *L)
{
mobj_t *mo = GETMO();
INT32 blendmode = (INT32)luaL_checkinteger(L, 2);
if (blendmode < 0 || blendmode > AST_OVERLAY)
return luaL_error(L, "mobj.blendmode %d out of range (0 - %d).", blendmode, AST_OVERLAY);
mo->blendmode = blendmode;
return 0;
}
int mobj_hnext_setter(lua_State *L)
{
mobj_t *mo = GETMO();
+3 -2
View File
@@ -157,8 +157,9 @@ static const udata_field_t player_fields[] = {
FIELD(player_t, grieftime, udatalib_getter_tic, udatalib_setter_tic),
FIELD(player_t, griefstrikes, udatalib_getter_uint8, udatalib_setter_uint8),
FIELD(player_t, splitscreenindex, udatalib_getter_uint8, player_splitscreenindex_noset),
#ifdef HWRENDER
FIELD(player_t, fovadd, udatalib_getter_fixed, udatalib_setter_fixed), // Mmm yeah thats definitely synch safe
#endif
// Same as player.name
{ "sliproll", 0, player_sliproll_getter, player_sliproll_noset },
{ "viewrollangle", 0, player_viewrollangle_getter, player_viewrollangle_noset },
@@ -881,4 +882,4 @@ int LUA_PlayerLib(lua_State *L)
lua_setglobal(L, "displayplayers");
return 0;
}
}
+147 -68
View File
@@ -504,8 +504,6 @@ void LUA_InvalidateLevel(void)
{
thinker_t *th;
size_t i;
ffloor_t *rover = NULL;
if (!gL)
return;
@@ -517,55 +515,32 @@ void LUA_InvalidateLevel(void)
for (i = 0; i < numsubsectors; i++)
LUA_InvalidateUserdata(&subsectors[i]);
for (i = 0; i < numsectors; i++)
{
LUA_InvalidateUserdata(&sectors[i]);
LUA_InvalidateUserdata(&sectors[i].lines);
if (sectors[i].ffloors)
{
for (rover = sectors[i].ffloors; rover; rover = rover->next)
LUA_InvalidateUserdata(rover);
}
}
for (i = 0; i < numlines; i++)
{
LUA_InvalidateUserdata(&lines[i]);
LUA_InvalidateUserdata(lines[i].sidenum);
}
for (i = 0; i < numsides; i++)
LUA_InvalidateUserdata(&sides[i]);
for (i = 0; i < numvertexes; i++)
LUA_InvalidateUserdata(&vertexes[i]);
for (pslope_t *slope = slopelist; slope; slope = slope->next)
{
LUA_InvalidateUserdata(slope);
LUA_InvalidateUserdata(&slope->normal);
LUA_InvalidateUserdata(&slope->o);
LUA_InvalidateUserdata(&slope->d);
}
}
void LUA_InvalidateMapthings(void)
{
size_t i;
if (!gL)
return;
for (i = 0; i < nummapthings; i++)
{
LUA_InvalidateUserdata(&mapthings[i]);
}
}
void LUA_InvalidatePlayer(player_t *player)
{
if (!gL)
return;
LUA_InvalidateUserdata(player);
LUA_InvalidateUserdata(player->powers);
LUA_InvalidateUserdata(player->kartstuff);
@@ -611,7 +586,7 @@ static const struct {
{META_SUBSECTOR,ARCH_SUBSECTOR},
{META_SECTOR, ARCH_SECTOR},
{META_SLOPE, ARCH_SLOPE},
{META_MAPHEADER,ARCH_MAPHEADER},
{META_MAPHEADER, ARCH_MAPHEADER},
{NULL, ARCH_NULL}
};
@@ -965,7 +940,7 @@ static void ArchiveTables(UINT8 **p)
}
}
static UINT8 UnArchiveValue(UINT8 **p, int TABLESINDEX, boolean network)
static UINT8 UnArchiveValue(UINT8 **p, int TABLESINDEX)
{
UINT8 type = READUINT8(*p);
switch (type)
@@ -1017,12 +992,6 @@ static UINT8 UnArchiveValue(UINT8 **p, int TABLESINDEX, boolean network)
LUA_PushUserdata(gL, &states[READUINT16(*p)], META_STATE);
break;
case ARCH_MOBJ:
if (network == false) // for replays :chaosleep:
{
*p += sizeof(UINT32); // Skip this data, we can't read a mobj here, it'd point to garbage and crash the game.
return 3; // Don't set the field
}
LUA_PushUserdata(gL, P_FindNewPosition(READUINT32(*p)), META_MOBJ);
break;
case ARCH_PLAYER:
@@ -1064,6 +1033,106 @@ static UINT8 UnArchiveValue(UINT8 **p, int TABLESINDEX, boolean network)
return 0;
}
// Unarchives from demo_p:
// Return values:
// 0: Normal
// 1: Read table key
// 2: Read table value
// 3: Don't use setfield
static UINT8 UnArchiveValueDemo(UINT8 **p, int TABLESINDEX, char field[1024])
{
UINT8 type = READUINT8(*p);
switch (type)
{
case ARCH_NULL:
lua_pushnil(gL);
break;
case ARCH_BOOLEAN:
lua_pushboolean(gL, READUINT8(*p));
break;
case ARCH_SIGNED:
lua_pushinteger(gL, READFIXED(*p));
break;
case ARCH_STRING:
{
UINT16 len = READUINT16(*p); // length of string, including embedded zeros
char *value;
UINT16 i = 0;
// See my comments in the ArchiveValue function;
// it's much the same for reading strings as writing them!
// (i.e. we can't use READSTRING either)
// -- Monster Iestyn 05/08/18
value = malloc(len); // make temp buffer of size len
// now read the actual string
while (i < len)
value[i++] = READCHAR(*p); // read chars individually, including the embedded zeros
lua_pushlstring(gL, value, len); // push the string (note: this function supports embedded zeros)
free(value); // free the buffer
break;
}
case ARCH_TABLE:
{
UINT16 tid = READUINT16(*p);
lua_rawgeti(gL, TABLESINDEX, tid);
if (lua_isnil(gL, -1))
{
lua_pop(gL, 1);
lua_newtable(gL);
lua_pushvalue(gL, -1);
lua_rawseti(gL, TABLESINDEX, tid);
return 2;
}
break;
}
case ARCH_MOBJINFO:
LUA_PushUserdata(gL, &mobjinfo[READUINT16(*p)], META_MOBJINFO);
break;
case ARCH_STATE:
LUA_PushUserdata(gL, &states[READUINT16(*p)], META_STATE);
break;
case ARCH_MOBJ:
*p += sizeof(UINT32); // Skip this data, we can't read a mobj here, it'd point to garbage and crash the game.
if (field)
CONS_Alert(CONS_WARNING,"Cannot read mobj_t stored in player variable \'%s\'. Desyncs may occur.\n", field);
else
CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n");
return 3; // Don't set the field
case ARCH_PLAYER:
LUA_PushUserdata(gL, &players[READUINT8(*p)], META_PLAYER);
break;
case ARCH_MAPTHING:
LUA_PushUserdata(gL, &mapthings[READUINT16(*p)], META_MAPTHING);
break;
case ARCH_VERTEX:
LUA_PushUserdata(gL, &vertexes[READUINT16(*p)], META_VERTEX);
break;
case ARCH_LINE:
LUA_PushUserdata(gL, &lines[READUINT16(*p)], META_LINE);
break;
case ARCH_SIDE:
LUA_PushUserdata(gL, &sides[READUINT16(*p)], META_SIDE);
break;
case ARCH_SUBSECTOR:
LUA_PushUserdata(gL, &subsectors[READUINT16(*p)], META_SUBSECTOR);
break;
case ARCH_SECTOR:
LUA_PushUserdata(gL, &sectors[READUINT16(*p)], META_SECTOR);
break;
case ARCH_SLOPE:
LUA_PushUserdata(gL, P_SlopeById(READUINT16(*p)), META_SLOPE);
break;
case ARCH_MAPHEADER:
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(*p)], META_MAPHEADER);
break;
case ARCH_TEND:
return 1;
}
return 0;
}
static void UnArchiveExtVars(UINT8 **p, void *pointer, boolean network)
{
int TABLESINDEX;
@@ -1083,25 +1152,29 @@ static void UnArchiveExtVars(UINT8 **p, void *pointer, boolean network)
TABLESINDEX = lua_gettop(gL);
lua_createtable(gL, 0, field_count); // pointer's ext vars subtable
for (i = 0; i < field_count; i++)
if (network)
{
UINT8 ret;
READSTRING(*p, field);
ret = UnArchiveValue(p, TABLESINDEX, network);
if (ret == 1)
for (i = 0; i < field_count; i++)
{
CONS_Alert(CONS_ERROR, "Unexpected end marker when reading ExtVars (field '%s')\n", field);
break;
}
else if (ret == 3) // This will return 3 if we shouldn't set this field.
{
CONS_Alert(CONS_WARNING,"Cannot read mobj_t stored in player variable \'%s\'. Desyncs may occur.\n", field);
continue;
}
READSTRING(*p, field);
lua_setfield(gL, -2, field);
if (UnArchiveValue(p, TABLESINDEX) == 1)
{
CONS_Alert(CONS_ERROR, "Unexpected end marker when reading ExtVars (field '%s')\n", field);
break;
}
lua_setfield(gL, -2, field);
}
}
else
{
for (i = 0; i < field_count; i++)
{
READSTRING(*p, field);
if (UnArchiveValueDemo(p, TABLESINDEX, field) != 3) // This will return 3 if we shouldn't set this field.
lua_setfield(gL, -2, field);
}
}
lua_getfield(gL, LUA_REGISTRYINDEX, LREG_EXTVARS);
@@ -1118,7 +1191,7 @@ static int NetUnArchive(lua_State *L)
savebuffer_t *save = lua_touserdata(L, lua_upvalueindex(2));
int i, n = lua_gettop(L);
for (i = 1; i <= n; i++)
UnArchiveValue(&save->p, TABLESINDEX, true);
UnArchiveValue(&save->p, TABLESINDEX);
return n;
}
@@ -1148,29 +1221,35 @@ static void UnArchiveTables(UINT8 **p, boolean network)
{
UINT8 ret;
ret = UnArchiveValue(p, TABLESINDEX, network);
if (ret == 3)
if (network)
{
CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n");
lua_pushnil(gL);
}
else if (ret == 1) // read key
break;
if (UnArchiveValue(p, TABLESINDEX) == 1) // read key
break;
ret = UnArchiveValue(p, TABLESINDEX, network);
if (ret == 1)
{
CONS_Alert(CONS_ERROR, "Unexpected end of save reached (Corrupted save?)\n");
lua_pop(gL, 1); // Pop key
break;
ret = UnArchiveValue(p, TABLESINDEX);
if (ret == 1)
{
CONS_Alert(CONS_ERROR, "Unexpected end of save reached (Corrupted save?)\n");
lua_pop(gL, 1); // Pop key
break;
}
else if (ret == 2) // read value
n++;
}
else if (ret == 3)
else
{
CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n");
lua_pushnil(gL);
ret = UnArchiveValueDemo(p, TABLESINDEX, NULL);
if (ret == 3)
lua_pushnil(gL);
else if (ret == 1) // read key
break;
ret = UnArchiveValueDemo(p, TABLESINDEX, NULL);
if (ret == 3)
lua_pushnil(gL);
else if (ret == 2) // read value
n++;
}
else if (ret == 2) // read value
n++;
if (lua_isnil(gL, -2)) // if key is nil (if a function etc was accidentally saved)
{
+2 -9
View File
@@ -32,7 +32,6 @@ consvar_t cv_gif_downscale = {"gif_downscale", "On", CV_SAVE, CV_OnOff, NULL, 0
#ifdef HAVE_ANIGIF
static boolean gif_optimize = false; // So nobody can do something dumb
static boolean gif_downscale = false; // like changing cvars mid output
static RGBA_t *gif_palette = NULL;
static FILE *gif_out = NULL;
static INT32 gif_frames = 0;
@@ -462,15 +461,13 @@ static size_t gifframe_size = 8192;
// converts an RGB frame to a frame with a palette.
//
#ifdef HWRENDER
static colorlookup_t gif_colorlookup;
static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
{
UINT8 r, g, b;
size_t src, dest;
int x, y;
InitColorLUT(&gif_colorlookup, gif_palette, true);
InitColorLUT();
for (x = 0; x < vid.width; x += scrbuf_downscaleamt)
{
@@ -482,7 +479,7 @@ static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
r = (UINT8)linear[src];
g = (UINT8)linear[src + 1];
b = (UINT8)linear[src + 2];
scr[dest] = GetColorLUTDirect(&gif_colorlookup, r, g, b);
scr[dest] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS];
}
}
}
@@ -639,10 +636,6 @@ INT32 GIF_open(const char *filename)
gif_optimize = (!!cv_gif_optimize.value);
gif_downscale = (!!cv_gif_downscale.value);
// no master palettes in SRB2Kart land
gif_palette = pLocalPalette;
GIF_headwrite();
gif_frames = 0;
return 1;
+418 -409
View File
File diff suppressed because it is too large. Load diff
+4 -3
View File
@@ -64,6 +64,10 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines);
// Same but with extra flags applied
void M_DrawTextBoxFlags(INT32 x, INT32 y, INT32 width, INT32 boxlines, INT32 flags);
// Draw text input
typedef struct textinput_s textinput_t;
void M_DrawTextInput(INT32 x, INT32 y, textinput_t *input, INT32 flags);
// Used in d_netcmd to restart time attack
void M_ModeAttackRetry(INT32 choice);
@@ -286,9 +290,6 @@ void Screenshot_option_Onchange(void);
// Addons menu updating
void Addons_option_Onchange(void);
// Moviemode menu updating
void Moviemode_option_Onchange(void);
// Player distortion menu updating
void PDistort_menu_Onchange(void);
+14 -121
View File
@@ -110,9 +110,6 @@ consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL,
static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}};
consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_movie_option = {"movie_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Moviemode_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_movie_folder = {"movie_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t zlib_mem_level_t[] = {
{1, "(Min Memory) 1"},
{2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"},
@@ -1147,25 +1144,19 @@ static inline moviemode_t M_StartMovieGIF(const char *pathname)
void M_StartMovie(void)
{
#if NUMSCREENS > 2
char pathname[MAX_WADPATH];
const char *pathname = ".";
if (moviemode)
return;
if (cv_movie_option.value == 0)
strcpy(pathname, usehome ? srb2home : srb2path);
else if (cv_movie_option.value == 1)
strcpy(pathname, srb2home);
else if (cv_movie_option.value == 2)
strcpy(pathname, srb2path);
else if (cv_movie_option.value == 3 && *cv_movie_folder.string != '\0')
strcpy(pathname, cv_movie_folder.string);
if (cv_movie_option.value != 3)
{
strcat(pathname, PATHSEP"gifs"PATHSEP);
I_mkdir(pathname, 0755);
}
if (cv_screenshot_option.value == 0)
pathname = usehome ? srb2home : srb2path;
else if (cv_screenshot_option.value == 1)
pathname = srb2home;
else if (cv_screenshot_option.value == 2)
pathname = srb2path;
else if (cv_screenshot_option.value == 3 && *cv_screenshot_folder.string != '\0')
pathname = cv_screenshot_folder.string;
if (rendermode == render_none)
I_Error("Can't make a movie without a render system\n");
@@ -1491,8 +1482,7 @@ void M_ScreenShot(void)
void M_DoScreenShot(void)
{
#if NUMSCREENS > 2
const char *freename = NULL;
char pathname[MAX_WADPATH];
const char *freename = NULL, *pathname = ".";
boolean ret = false;
UINT8 *linear = NULL;
@@ -1504,19 +1494,13 @@ void M_DoScreenShot(void)
return;
if (cv_screenshot_option.value == 0)
strcpy(pathname, usehome ? srb2home : srb2path);
pathname = usehome ? srb2home : srb2path;
else if (cv_screenshot_option.value == 1)
strcpy(pathname, srb2home);
pathname = srb2home;
else if (cv_screenshot_option.value == 2)
strcpy(pathname, srb2path);
pathname = srb2path;
else if (cv_screenshot_option.value == 3 && *cv_screenshot_folder.string != '\0')
strcpy(pathname, cv_screenshot_folder.string);
if (cv_screenshot_option.value != 3)
{
strcat(pathname, PATHSEP"screenshots"PATHSEP);
I_mkdir(pathname, 0755);
}
pathname = cv_screenshot_folder.string;
#ifdef USE_PNG
freename = Newsnapshotfile(pathname,"png");
@@ -2092,94 +2076,3 @@ const char *M_FileError(FILE *fp)
else
return "end-of-file";
}
/** Return the number of parts of this path.
*/
int M_PathParts(const char *path)
{
int n;
const char *p;
const char *t;
if (path == NULL)
return 0;
for (n = 0, p = path ;; ++n)
{
t = p;
if (( p = strchr(p, PATHSEP[0]) ))
p += strspn(p, PATHSEP);
else
{
if (*t)/* there is something after the final delimiter */
n++;
break;
}
}
return n;
}
/** Check whether a path is an absolute path.
*/
boolean M_IsPathAbsolute(const char *path)
{
#ifdef _WIN32
return ( strncmp(&path[1], ":\\", 2) == 0 );
#else
return ( path[0] == '/' );
#endif
}
/** I_mkdir for each part of the path.
*/
void M_MkdirEachUntil(const char *cpath, int start, int end, int mode)
{
char path[MAX_WADPATH];
char *p;
char *t;
if (end > 0 && end <= start)
return;
strlcpy(path, cpath, sizeof path);
#ifdef _WIN32
if (strncmp(&path[1], ":\\", 2) == 0)
p = &path[3];
else
#endif
p = path;
if (end > 0)
end -= start;
for (; start > 0; --start)
{
p += strspn(p, PATHSEP);
if (!( p = strchr(p, PATHSEP[0]) ))
return;
}
p += strspn(p, PATHSEP);
for (;;)
{
if (end > 0 && !--end)
break;
t = p;
if (( p = strchr(p, PATHSEP[0]) ))
{
*p = '\0';
I_mkdir(path, mode);
*p = PATHSEP[0];
p += strspn(p, PATHSEP);
}
else
{
if (*t)
I_mkdir(path, mode);
break;
}
}
}
void M_MkdirEach(const char *path, int start, int mode)
{
M_MkdirEachUntil(path, start, -1, mode);
}
+1 -6
View File
@@ -30,7 +30,7 @@ typedef enum {
extern moviemode_t moviemode;
extern consvar_t cv_screenshot_option, cv_screenshot_folder;
extern consvar_t cv_moviemode, cv_movie_folder, cv_movie_option;
extern consvar_t cv_moviemode;
extern consvar_t cv_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits;
extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa;
extern consvar_t cv_apng_delay;
@@ -99,11 +99,6 @@ void strcatbf(char *s1, const char *s2, const char *s3);
const char *M_FileError(FILE *handle);
int M_PathParts (const char *path);
boolean M_IsPathAbsolute (const char *path);
void M_MkdirEach (const char *path, int start, int mode);
void M_MkdirEachUntil (const char *path, int start, int end, int mode);
// counting bits, for weapon ammo code, usually
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
+10 -16
View File
@@ -452,7 +452,7 @@ static int PS_DrawPerfRows(int x, int y, int color, perfstatrow_t *rows)
return draw_y;
}
static void PS_UpdateMetricHistory(ps_metric_t *metric, boolean time_metric, boolean frame_metric)
static void PS_UpdateMetricHistory(ps_metric_t *metric, boolean time_metric, boolean frame_metric, boolean set_user)
{
int index = frame_metric ? ps_frame_index : ps_tick_index;
@@ -460,7 +460,7 @@ static void PS_UpdateMetricHistory(ps_metric_t *metric, boolean time_metric, boo
{
// allocate history table
int value_size = time_metric ? sizeof(precise_t) : sizeof(INT32);
void** memory_user = &metric->history;
void** memory_user = set_user ? &metric->history : NULL;
metric->history = Z_Calloc(value_size * cv_ps_samplesize.value, PU_PERFSTATS,
memory_user);
@@ -490,7 +490,7 @@ static void PS_UpdateRowHistories(perfstatrow_t *rows, boolean frame_metric)
for (row = rows; row->lores_label; row++)
{
if (PS_IsRowValid(row))
PS_UpdateMetricHistory(row->metric, !!(row->flags & PS_TIME), frame_metric);
PS_UpdateMetricHistory(row->metric, !!(row->flags & PS_TIME), frame_metric, true);
}
}
@@ -577,7 +577,8 @@ static void PS_CountThinkers(void)
ps_removecount.value.i = 0;
for (thinker = thinkercap.next; thinker != &thinkercap; thinker = thinker->next)
{
ps_thinkercount.value.i++;
if (thinker->function.acp1 != (actionf_p1)P_NullPrecipThinker)
ps_thinkercount.value.i++;
if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
ps_removecount.value.i++;
@@ -592,18 +593,11 @@ static void PS_CountThinkers(void)
else
ps_regularcount.value.i++;
}
else if (thinker->function.acp1 == (actionf_p1)P_NullPrecipThinker)
ps_precipcount.value.i++;
else
ps_otherthcount.value.i++;
}
for (thinker = precipcap.next; thinker != &precipcap; thinker = thinker->next)
{
if (thinker->function.acp1 != (actionf_p1)P_NullPrecipThinker)
continue; // not a precipmobj thinker
ps_precipcount.value.i++;
}
/*for (i = 0; i < NUM_THINKERLISTS; i++)
{
for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next)
@@ -676,17 +670,17 @@ void PS_UpdateTickStats(void)
if (cv_perfstats.value == 3)
{
for (i = 0; i < thinkframe_hooks_length; i++)
PS_UpdateMetricHistory(&thinkframe_hooks[i].time_taken, true, false);
PS_UpdateMetricHistory(&thinkframe_hooks[i].time_taken, true, false, false);
}
else if (cv_perfstats.value == 4)
{
for (i = 0; i < prethinkframe_hooks_length; i++)
PS_UpdateMetricHistory(&prethinkframe_hooks[i].time_taken, true, false);
PS_UpdateMetricHistory(&prethinkframe_hooks[i].time_taken, true, false, false);
}
else if (cv_perfstats.value == 5)
{
for (i = 0; i < postthinkframe_hooks_length; i++)
PS_UpdateMetricHistory(&postthinkframe_hooks[i].time_taken, true, false);
PS_UpdateMetricHistory(&postthinkframe_hooks[i].time_taken, true, false, false);
}
}
if (cv_perfstats.value)
-71
View File
@@ -1,7 +1,4 @@
#include "m_textinput.h"
#include "m_menu.h" // MAXSTRINGLENGTH
#include "v_video.h"
#include "r_main.h" // renderisnewtic
#include "i_system.h"
#include "keys.h"
#include "console.h"
@@ -135,8 +132,6 @@ void M_TextInputInit(textinput_t *input, char *buffer, size_t buffer_size)
input->buffer = buffer;
input->buffer_size = buffer_size;
input->skull = 0;
M_TextInputClear(input);
}
@@ -319,69 +314,3 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key)
return true;
}
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH)
{
if (renderisnewtic)
input->skull++;
input->skull %= 8;
char nametodraw[MAXSTRINGLENGTH*2+1] = {0};
size_t drawstart = 0;
size_t drawend = 0; // Only used for selection
INT32 skullx = x;
while (V_SubStringWidth(input->buffer+drawstart, input->cursor-drawstart, V_ALLOWLOWERCASE) > MAXINPUTWIDTH)
++drawstart;
size_t drawlength = V_SubStringLengthToFit(input->buffer+drawstart, MAXINPUTWIDTH+8, V_ALLOWLOWERCASE)+1;
drawend = drawstart + drawlength;
memcpy(nametodraw, input->buffer+drawstart, drawlength);
if (input->length)
skullx += V_SubStringWidth(nametodraw, input->cursor-drawstart, V_ALLOWLOWERCASE);
V_DrawString(x, y, V_ALLOWLOWERCASE|flags, nametodraw);
// draw text cursor for name
if (input->skull < 4) // blink cursor
V_DrawCharacter(skullx, y+3, '_'|flags, false);
// draw selection
if (input->select != input->cursor)
{
size_t start = min(input->select, input->cursor);
size_t end = max(input->select, input->cursor);
INT32 startx = 0;
INT32 width = 0;
// I couldn't figure out one formula so here's bunch of separate cases
if (start < drawstart && end > drawend) // Selection covers whole visible portion of demo name
{
startx = -2;
width = V_StringWidth(nametodraw, V_ALLOWLOWERCASE)+4;
}
else if (start < drawstart) // Only left side of selection is off visible part
{
startx = -2;
size_t len = (end - start) - (drawstart - start);
width = V_SubStringWidth(nametodraw, len, V_ALLOWLOWERCASE)+2;
}
else if (end > drawend) // Only right side of selection is off visible part
{
startx = V_SubStringWidth(nametodraw, start-drawstart, V_ALLOWLOWERCASE);
width = V_StringWidth(nametodraw+(start-drawstart), V_ALLOWLOWERCASE)+2;
}
else // All selection is on visible part
{
startx = V_SubStringWidth(nametodraw, start-drawstart, V_ALLOWLOWERCASE);
width = V_SubStringWidth(nametodraw+(start-drawstart), end-start, V_ALLOWLOWERCASE);
}
V_DrawFill(x+startx, y, width, 8, 103|V_TRANSLUCENT|flags);
}
}
-5
View File
@@ -10,8 +10,6 @@ typedef struct textinput_s {
char *buffer;
size_t buffer_size;
unsigned skull;
} textinput_t;
void M_TextInputInit(textinput_t *input, char *buffer, size_t buffer_size);
@@ -22,7 +20,4 @@ void M_TextInputSetString(textinput_t *input, const char *c);
boolean M_TextInputHandle(textinput_t *input, INT32 key);
#define M_DrawTextInput(x, y, input, flags) M_DrawTextInputScroll((x), (y), (input), (flags), ((input)->buffer_size-1)*8)
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH);
#endif
+8 -6
View File
@@ -25,6 +25,10 @@
#include "lua_hook.h"
#include "k_kart.h" // SRB2kart
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
#endif
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
INT32 var1;
@@ -3920,12 +3924,10 @@ void A_MineExplode(mobj_t *actor)
for (d = 0; d < 16; d++)
K_SpawnKartExplosion(actor->x, actor->y, actor->z, explodedist + 32*mapobjectscale, 32, type, d*(ANGLE_45/4), true, false, actor->target); // 32 <-> 64
skincolors_t color = SKINCOLOR_KETCHUP;
if (actor->target && actor->target->player)
color = actor->target->player->skincolor;
K_SpawnMineExplosion(actor, color);
K_SpawnMineExplosion(actor, actor->target->player->skincolor);
else
K_SpawnMineExplosion(actor, SKINCOLOR_KETCHUP);
P_SpawnMobj(actor->x, actor->y, actor->z, MT_MINEEXPLOSIONSOUND);
@@ -10139,7 +10141,7 @@ void A_RemoteDamage(mobj_t *actor)
if (locvar2 == 1) // Kill mobj!
{
if (target->player) // players die using P_DamageMobj instead for some reason
P_DamageMobj(target, source, source, DMG_INSTAKILL);
P_DamageMobj(target, source, source, 10000);
else
P_KillMobj(target, source, source);
}
+26 -20
View File
@@ -327,7 +327,7 @@ void T_MoveFloor(floormove_t *movefloor)
movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1;
movefloor->sector->floorspeed = movefloor->speed * movefloor->direction;
movefloor->delaytimer = movefloor->delay;
movefloor->sector->moved = true;
P_RecalcPrecipInSector(movefloor->sector);
return; // not break, why did this work? Graue 04-03-2004
case bounceFloorCrush: // Graue 03-27-2004
if (movefloor->floordestheight == lines[movefloor->texture].frontsector->floorheight)
@@ -343,14 +343,14 @@ void T_MoveFloor(floormove_t *movefloor)
movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1;
movefloor->sector->floorspeed = movefloor->speed * movefloor->direction;
movefloor->delaytimer = movefloor->delay;
movefloor->sector->moved = true;
P_RecalcPrecipInSector(movefloor->sector);
return; // not break, why did this work? Graue 04-03-2004
case crushFloorOnce:
movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight;
movefloor->direction = -1;
movefloor->sector->soundorg.z = movefloor->sector->floorheight;
S_StartSound(&movefloor->sector->soundorg,sfx_pstop);
movefloor->sector->moved = true;
P_RecalcPrecipInSector(movefloor->sector);
return;
default:
break;
@@ -376,7 +376,7 @@ void T_MoveFloor(floormove_t *movefloor)
movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1;
movefloor->sector->floorspeed = movefloor->speed * movefloor->direction;
movefloor->delaytimer = movefloor->delay;
movefloor->sector->moved = true;
P_RecalcPrecipInSector(movefloor->sector);
return; // not break, why did this work? Graue 04-03-2004
case bounceFloorCrush: // Graue 03-27-2004
if (movefloor->floordestheight == lines[movefloor->texture].frontsector->floorheight)
@@ -392,13 +392,13 @@ void T_MoveFloor(floormove_t *movefloor)
movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1;
movefloor->sector->floorspeed = movefloor->speed * movefloor->direction;
movefloor->delaytimer = movefloor->delay;
movefloor->sector->moved = true;
P_RecalcPrecipInSector(movefloor->sector);
return; // not break, why did this work? Graue 04-03-2004
case crushFloorOnce:
movefloor->sector->floordata = NULL; // Clear up the thinker so others can use it
P_RemoveThinker(&movefloor->thinker);
movefloor->sector->floorspeed = 0;
movefloor->sector->moved = true;
P_RecalcPrecipInSector(movefloor->sector);
return;
default:
break;
@@ -415,7 +415,7 @@ void T_MoveFloor(floormove_t *movefloor)
else
movefloor->sector->floorspeed = 0;
movefloor->sector->moved = true;
P_RecalcPrecipInSector(movefloor->sector);
}
//
@@ -817,6 +817,7 @@ void T_BounceCheese(levelspecthink_t *bouncer)
bouncer->sector->floorheight = bouncer->sector->ceilingheight - (halfheight*2);
T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling
T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor
P_RecalcPrecipInSector(actionsector);
bouncer->sector->ceilingdata = NULL;
bouncer->sector->floordata = NULL;
bouncer->sector->floorspeed = 0;
@@ -832,6 +833,7 @@ void T_BounceCheese(levelspecthink_t *bouncer)
bouncer->sector->floorheight = floorheight;
T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling
T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor
P_RecalcPrecipInSector(actionsector);
bouncer->sector->ceilingdata = NULL;
bouncer->sector->floordata = NULL;
bouncer->sector->floorspeed = 0;
@@ -911,6 +913,9 @@ void T_BounceCheese(levelspecthink_t *bouncer)
if (bouncer->distance > 0)
bouncer->distance--;
if (actionsector)
P_RecalcPrecipInSector(actionsector);
}
#undef speed
#undef distance
@@ -1097,6 +1102,7 @@ void T_StartCrumble(elevator_t *elevator)
{
sector = &sectors[i];
sector->moved = true;
P_RecalcPrecipInSector(sector);
}
}
@@ -1150,7 +1156,7 @@ void T_MarioBlock(levelspecthink_t *block)
}
for (i = -1; (i = P_FindSectorFromTag((INT16)block->vars[0], i)) >= 0 ;)
sectors[i].moved = true;
P_RecalcPrecipInSector(&sectors[i]);
#undef speed
#undef direction
@@ -1266,7 +1272,7 @@ void T_FloatSector(levelspecthink_t *floater)
else if (floater->sector->crumblestate == 0 || floater->sector->crumblestate >= 3/* || floatanyway*/)
EV_BounceSector(floater->sector, FRACUNIT, floater->sourceline);
actionsector->moved = true;
P_RecalcPrecipInSector(actionsector);
}
}
@@ -1968,7 +1974,7 @@ void T_ThwompSector(levelspecthink_t *thwomp)
thwomp->sector->floorspeed = 0;
}
actionsector->moved = true;
P_RecalcPrecipInSector(actionsector);
#undef speed
#undef direction
#undef distance
@@ -2113,11 +2119,11 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
sec = &sectors[secnum];
FOFsector = false;
const INT32 secspecial = GETSECSPECIAL(sec->special, 2);
INT32 special = GETSECSPECIAL(sec->special, 2);
if (secspecial == 3 || secspecial == 5)
if (special == 3 || special == 5)
floortouch = true;
else if (secspecial >= 1 && secspecial <= 8)
else if (special >= 1 && special <= 8)
floortouch = false;
else
continue;
@@ -2249,7 +2255,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
continue;
if (!(players[i].mo->subsector->sector == sec
|| P_PlayerTouchingSectorSpecial(&players[i], 2, GETSECSPECIAL(sec->special, 2)) == sec))
|| P_PlayerTouchingSectorSpecial(&players[i], 2, special) == sec))
continue;
if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec))
@@ -2293,9 +2299,9 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
while ((affectPlayer = P_HavePlayersEnteredArea(playersArea, oldPlayersArea, inAndOut)) != -1)
{
const INT32 secspecial = GETSECSPECIAL(sec->special, 2);
INT32 special = GETSECSPECIAL(sec->special, 2);
if (secspecial == 2 || secspecial == 3)
if (special == 2 || special == 3)
{
for (i = 0; i < MAXPLAYERS; i++)
{
@@ -2497,7 +2503,7 @@ void T_RaiseSector(levelspecthink_t *raise)
raise->sector->floorspeed = raise->vars[3]*raise->vars[8];
for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;)
sectors[i].moved = true;
P_RecalcPrecipInSector(&sectors[i]);
}
void T_CameraScanner(elevator_t *elevator)
@@ -2914,12 +2920,12 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
fixed_t a, b, c;
mobjtype_t type = MT_ROCKCRUMBLE1;
const fixed_t spacing = 48*mapobjectscale;
const INT32 secspecial = GETSECSPECIAL(rover->master->frontsector->special, 3);
INT32 special = GETSECSPECIAL(rover->master->frontsector->special, 3);
// If the control sector has a special
// of Section3:7-15, use the custom debris.
if (secspecial >= 8)
type = MT_ROCKCRUMBLE1+(secspecial-7);
if (special >= 8)
type = MT_ROCKCRUMBLE1+(special-7);
// soundorg z height never gets set normally, so MEH.
sec->soundorg.z = sec->floorheight;
+7 -11
View File
@@ -2364,9 +2364,10 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
* player is hit by a ring, the player who shot it. In some
* cases, the target will go after this object after
* receiving damage. This can be NULL.
* \param damage Amount of damage to be dealt. DMG_INSTAKILL is instant death.
* \param damage Amount of damage to be dealt. 10000 is instant death.
* \return True if the target sustained damage, otherwise false.
* \todo Clean up this mess, split into multiple functions.
* \todo Get rid of the magic number 10000.
* \sa P_KillMobj
*/
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
@@ -2377,18 +2378,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (objectplacing)
return false;
// well no clue but this may happen ig
if (!target)
return false;
if (target->health <= 0)
return false;
// Spectator handling
if (netgame)
{
if (damage == DMG_SPECTATOR && target->player && target->player->spectator)
damage = DMG_INSTAKILL;
if (damage == 42000 && target->player && target->player->spectator)
damage = 10000;
else if (target->player && target->player->spectator)
return false;
@@ -2400,7 +2397,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!metalrecording)
{
UINT8 shouldForce = LUA_HookShouldDamage(target, inflictor, source, damage);
if (P_MobjWasRemoved(target))
return (shouldForce == 1); // mobj was removed
if (shouldForce == 1)
@@ -2528,7 +2524,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
{
if ((G_BattleGametype()) && cv_suddendeath.value
&& !player->powers[pw_flashing] && !player->powers[pw_invulnerability])
damage = DMG_INSTAKILL;
damage = 10000;
}
// Player hits another player
@@ -2542,7 +2538,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false;
// Instant-Death
if (damage == DMG_INSTAKILL)
if (damage == 10000)
P_KillPlayer(player, source, damage);
else if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->powers[pw_flashing])
{
@@ -2595,7 +2591,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
else
{
player->health -= damage; // mirror mobj health here
if (damage < DMG_INSTAKILL)
if (damage < 10000)
{
target->player->powers[pw_flashing] = K_GetKartFlashing(target->player);
if (damage > 0) // don't spill emeralds/ammo/panels for shield damage
+8 -27
View File
@@ -66,19 +66,16 @@
// both the head and tail of the thinker list
extern thinker_t thinkercap;
extern thinker_t precipcap;
extern mobj_t *mobjcache;
void P_InitThinkers(void);
void P_AddThinker(thinker_t *thinker);
void P_AddPrecipThinker(thinker_t *thinker);
void P_RemoveThinker(thinker_t *thinker);
void P_UnlinkThinker(thinker_t *thinker);
//
// P_USER
//
typedef struct camera_s
{
boolean chase;
@@ -95,9 +92,6 @@ typedef struct camera_s
// Freecam: aiming needs to be reset after switching from chasecam
boolean reset_aiming;
// Hold up/down to pan the camera vertically
SINT8 dpad_y_held;
// Things used by FS cameras.
fixed_t viewheight;
angle_t startangle;
@@ -127,30 +121,17 @@ typedef struct camera_s
// SRB2Kart: camera pans while drifting
fixed_t pan;
// postproccess effects
UINT8 postimg;
} camera_t;
// post process types
enum
{
POSTIMG_WATER = 1, // Underwater screen effect.
POSTIMG_MOTION = 1<<1, // Unused motion blur effect.
POSTIMG_FLIP = 1<<2, // Flipcam screen effect.
POSTIMG_HEAT = 1<<3, // Heatwave screen effect.
POSTIMG_MIRROR = 1<<4, // encore screen effect.
};
extern camera_t camera[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_height[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_rotate[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_timeover[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_rotspeed[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_freecam_speed[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_freecam_speed;
extern consvar_t cv_tilting;
extern consvar_t cv_quaketilt;
@@ -172,7 +153,6 @@ void P_SlideCameraMove(camera_t *thiscam);
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled);
void P_ResetLocalCamAiming(player_t *player);
void P_ToggleDemoCamera(UINT8 viewnum);
void P_CalcChasePostImg(player_t *player, camera_t *thiscam);
boolean P_PlayerInPain(player_t *player);
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
void P_ResetPlayer(player_t *player);
@@ -257,6 +237,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
mobj_t *P_SpawnShadowMobj(mobj_t * caster);
void P_RecalcPrecipInSector(sector_t *sector);
void P_PrecipitationEffects(void);
void P_RemoveMobj(mobj_t *th);
@@ -314,7 +295,7 @@ void P_ColorTeamMissile(mobj_t *missile, player_t *source);
// Special utility to return +1 or -1 depending on mobj's gravity
FUNCINLINE static ATTRINLINE SINT8 P_MobjFlip(const mobj_t *mobj)
{
return (mobj && (mobj->eflags & MFE_VERTICALFLIP)) ? -1 : 1;
return (mobj && mobj->eflags & MFE_VERTICALFLIP) ? -1 : 1;
}
fixed_t P_GetMobjGravity(mobj_t *mo);
@@ -371,6 +352,8 @@ extern line_t *ceilingline;
extern line_t *blockingline;
extern msecnode_t *sector_list;
extern mprecipsecnode_t *precipsector_list;
void P_UnsetThingPosition(mobj_t *thing);
void P_SetThingPosition(mobj_t *thing);
void P_SetUnderlayPosition(mobj_t *thing);
@@ -394,6 +377,7 @@ void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fix
boolean P_CheckSector(sector_t *sector, boolean crunch);
void P_DelSeclist(msecnode_t *node);
void P_DelPrecipSeclist(mprecipsecnode_t *node);
void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y);
void P_Initsecnode(void);
@@ -421,6 +405,7 @@ extern precipmobj_t **precipblocklinks; // special blockmap for precip rendering
extern struct minimapinfo
{
patch_t *minimap_pic;
UINT8 mapthingcount;
INT32 min_x, min_y;
INT32 max_x, max_y;
INT32 map_w, map_h;
@@ -444,10 +429,6 @@ typedef struct BasicFF_s
INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000.
} BasicFF_t;
// replace damage magic numbers with smth readable
#define DMG_INSTAKILL 10000
#define DMG_SPECTATOR 42000
void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period);
void P_ForceConstant(const BasicFF_t *FFInfo);
void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End);
+266 -61
View File
@@ -46,6 +46,9 @@ static INT32 tmflags;
fixed_t tmx;
fixed_t tmy;
static precipmobj_t *tmprecipthing;
static fixed_t preciptmbbox[4];
// If "floatok" true, move would be ok
// if within "tmfloorz - tmceilingz".
boolean floatok;
@@ -65,6 +68,7 @@ line_t *ceilingline;
line_t *blockingline;
msecnode_t *sector_list = NULL;
mprecipsecnode_t *precipsector_list = NULL;
camera_t *mapcampointer;
//
@@ -72,9 +76,9 @@ camera_t *mapcampointer;
//
//
// P_MoveOrigin - P_TeleportMove which KEEPS interpolation values.
// P_TeleportMove
//
boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
static boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
{
// the move is ok,
// so link the thing into its new position
@@ -104,19 +108,28 @@ boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
return true;
}
//
// P_SetOrigin - P_TeleportMove which RESETS interpolation values.
//
boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
{
if (P_MoveOrigin(thing, x, y, z))
boolean result = P_TeleportMove(thing, x, y, z);
if (result == true)
{
thing->old_x = thing->x;
thing->old_y = thing->y;
thing->old_z = thing->z;
}
return true;
return result;
}
//
// P_MoveOrigin - P_TeleportMove which KEEPS interpolation values.
//
boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
{
return P_TeleportMove(thing, x, y, z);
}
// =========================================================================
@@ -222,15 +235,14 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (!demo.playback || P_AnalogMove(object->player))
{
for (UINT8 j = 0; j <= splitscreen; ++j)
{
INT32 id = (j == 0 ? consoleplayer : displayplayers[j]);
if (object->player == &players[id])
{
localangle[j] = spring->angle;
break;
}
}
if (object->player == &players[consoleplayer])
localangle[0] = spring->angle;
else if (object->player == &players[displayplayers[1]])
localangle[1] = spring->angle;
else if (object->player == &players[displayplayers[2]])
localangle[2] = spring->angle;
else if (object->player == &players[displayplayers[3]])
localangle[3] = spring->angle;
}
}
@@ -712,7 +724,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[thing->player-players]));
I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[thing->player-players]);
P_DamageMobj(thing, tmthing, tmthing->target, DMG_INSTAKILL);
P_DamageMobj(thing, tmthing, tmthing->target, 10000);
P_KillMobj(tmthing, thing, thing);
}
@@ -979,7 +991,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[tmthing->player-players]));
I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[tmthing->player-players]);
P_DamageMobj(tmthing, thing, thing->target, DMG_INSTAKILL);
P_DamageMobj(tmthing, thing, thing->target, 10000);
P_KillMobj(thing, tmthing, tmthing);
}
@@ -1714,10 +1726,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmbbox[BOXRIGHT] = x + tmthing->radius;
tmbbox[BOXLEFT] = x - tmthing->radius;
if (thing->x != x || thing->y != y || thing->subsector == NULL)
newsubsec = R_PointInSubsector(x, y);
else
newsubsec = thing->subsector;
newsubsec = R_PointInSubsector(x, y);
ceilingline = blockingline = NULL;
@@ -1739,7 +1748,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight, midheight;
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
@@ -1804,10 +1813,10 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
continue;
}
midheight = (bottomheight + ((topheight - bottomheight)/2));
delta1 = thing->z - midheight;
delta2 = thingtop - midheight;
delta1 = thing->z - (bottomheight
+ ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight
+ ((topheight - bottomheight)/2));
if (topheight > tmfloorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM))
@@ -1838,13 +1847,10 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
BMBOUNDFIX(xl, xh, yl, yh);
// Check polyobjects and see if tmfloorz/tmceilingz need to be altered
// do we really have to iterate through the complete blockmap for polyobjects if there are no polyobjects on the map?
if (numPolyObjects)
{
validcount++;
for (by = yl; by <= yh; by++)
{
for (bx = xl; bx <= xh; bx++)
{
INT32 offset;
@@ -1895,14 +1901,12 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
delta1 = thing->z - (polybottom + ((polytop - polybottom)/2));
delta2 = thingtop - (polybottom + ((polytop - polybottom)/2));
if (polytop > tmfloorz && abs(delta1) < abs(delta2))
{
if (polytop > tmfloorz && abs(delta1) < abs(delta2)) {
tmfloorz = tmdropoffz = polytop;
tmfloorslope = NULL;
}
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2))
{
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) {
tmceilingz = tmdrpoffceilz = polybottom;
tmceilingslope = NULL;
}
@@ -1910,7 +1914,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
plink = (polymaplink_t *)(plink->link.next);
}
}
}
}
// tmfloorthing is set when tmfloorz comes from a thing's top
@@ -1991,11 +1994,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
tmbbox[BOXRIGHT] = x + thiscam->radius;
tmbbox[BOXLEFT] = x - thiscam->radius;
if (thiscam->x != x || thiscam->y != y || thiscam->subsector == NULL)
newsubsec = R_PointInSubsector(x, y);
else
newsubsec = thiscam->subsector;
newsubsec = R_PointInSubsector(x, y);
ceilingline = blockingline = NULL;
mapcampointer = thiscam;
@@ -2074,8 +2073,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
BMBOUNDFIX(xl, xh, yl, yh);
// Check polyobjects and see if tmfloorz/tmceilingz need to be altered
// do we really have to iterate through the complete blockmap for polyobjects if there are no polyobjects on the map?
if (numPolyObjects)
{
validcount++;
@@ -2167,8 +2164,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
//
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
{
subsector_t *s;
subsector_t *s = R_PointInSubsector(x, y);
boolean retval = true;
boolean itsatwodlevel = false;
UINT8 i;
@@ -2178,11 +2174,6 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
if (dedicated) // this crashes so don't even try it
return false;
if (thiscam->x != x || thiscam->y != y || thiscam->subsector == NULL)
s = R_PointInSubsector(x, y);
else
s = thiscam->subsector;
if (twodlevel)
itsatwodlevel = true;
else
@@ -2376,13 +2367,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
radius = MAXRADIUS/2;
do {
if (thing->flags & MF_NOCLIP)
{
if (thing->flags & MF_NOCLIP) {
tryx = x;
tryy = y;
}
else
{
} else {
if (x-tryx > radius)
tryx += radius;
else if (x-tryx < -radius)
@@ -2404,16 +2392,19 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
//All things are affected by their scale.
fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale);
INT32 special = 0;
if (thing->player)
{
special = GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1);
// If using type Section1:13, double the maxstep.
if (P_PlayerTouchingSectorSpecial(thing->player, 1, 13)
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 13)
|| special == 13)
maxstep <<= 1;
// If using type Section1:12, no maxstep. For ledges you don't want the player to climb! (see: Egg Zeppelin & SMK port walls)
else if (P_PlayerTouchingSectorSpecial(thing->player, 1, 12)
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 12)
|| special == 12)
maxstep = 0;
}
@@ -2459,7 +2450,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
else if (maxstep > 0 && !(
thing->player && (
P_PlayerTouchingSectorSpecial(thing->player, 1, 14)
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)
|| special == 14)
)) // Step down
{
// If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS
@@ -2523,16 +2514,14 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (!(thing->flags & MF_NOCLIPHEIGHT))
{
// Assign thing's standingslope if needed
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP))
{
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) {
if (!startingonground && tmfloorslope)
P_HandleSlopeLanding(thing, tmfloorslope);
if (thing->momz <= 0)
thing->standingslope = tmfloorslope;
}
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP))
{
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
if (!startingonground && tmceilingslope)
P_HandleSlopeLanding(thing, tmceilingslope);
@@ -3661,7 +3650,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
{
// Crush the object
if (netgame && thing->player && thing->player->spectator)
P_DamageMobj(thing, NULL, NULL, DMG_SPECTATOR); // Respawn crushed spectators
P_DamageMobj(thing, NULL, NULL, 42000); // Respawn crushed spectators
else
{
if (!killer)
@@ -3671,7 +3660,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
killer->threshold = 44; // Special flag for crushing
}
if (!thing->player)
P_DamageMobj(thing, killer, killer, DMG_INSTAKILL);
P_DamageMobj(thing, killer, killer, 10000);
else
K_SquishPlayer(thing->player, killer, killer); // SRB2kart - Squish instead of kill
}
@@ -3717,6 +3706,8 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
sec->moved = true;
P_RecalcPrecipInSector(sec);
if (!sector->attachedsolid[i])
continue;
@@ -3777,6 +3768,8 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
sec->moved = true;
P_RecalcPrecipInSector(sec);
if (!sector->attachedsolid[i])
continue;
@@ -3827,10 +3820,12 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
*/
static msecnode_t *headsecnode = NULL;
static mprecipsecnode_t *headprecipsecnode = NULL;
void P_Initsecnode(void)
{
headsecnode = NULL;
headprecipsecnode = NULL;
}
// P_GetSecnode() retrieves a node from the freelist. The calling routine
@@ -3850,6 +3845,20 @@ static msecnode_t *P_GetSecnode(void)
return node;
}
static mprecipsecnode_t *P_GetPrecipSecnode(void)
{
mprecipsecnode_t *node;
if (headprecipsecnode)
{
node = headprecipsecnode;
headprecipsecnode = headprecipsecnode->m_thinglist_next;
}
else
node = Z_Calloc(sizeof (*node), PU_LEVEL, NULL);
return node;
}
// P_PutSecnode() returns a node to the freelist.
static inline void P_PutSecnode(msecnode_t *node)
@@ -3858,6 +3867,13 @@ static inline void P_PutSecnode(msecnode_t *node)
headsecnode = node;
}
// Tails 08-25-2002
static inline void P_PutPrecipSecnode(mprecipsecnode_t *node)
{
node->m_thinglist_next = headprecipsecnode;
headprecipsecnode = node;
}
// P_AddSecnode() searches the current list to see if this sector is
// already there. If not, it adds a sector node at the head of the list of
// sectors this object appears in. This is called when creating a list of
@@ -3903,6 +3919,47 @@ static msecnode_t *P_AddSecnode(sector_t *s, mobj_t *thing, msecnode_t *nextnode
return node;
}
// More crazy crap Tails 08-25-2002
static mprecipsecnode_t *P_AddPrecipSecnode(sector_t *s, precipmobj_t *thing, mprecipsecnode_t *nextnode)
{
mprecipsecnode_t *node;
node = nextnode;
while (node)
{
if (node->m_sector == s) // Already have a node for this sector?
{
node->m_thing = thing; // Yes. Setting m_thing says 'keep it'.
return nextnode;
}
node = node->m_sectorlist_next;
}
// Couldn't find an existing node for this sector. Add one at the head
// of the list.
node = P_GetPrecipSecnode();
// mark new nodes unvisited.
node->visited = 0;
node->m_sector = s; // sector
node->m_thing = thing; // mobj
node->m_sectorlist_prev = NULL; // prev node on Thing thread
node->m_sectorlist_next = nextnode; // next node on Thing thread
if (nextnode)
nextnode->m_sectorlist_prev = node; // set back link on Thing
// Add new node at head of sector thread starting at s->touching_thinglist
node->m_thinglist_prev = NULL; // prev node on sector thread
node->m_thinglist_next = s->touching_preciplist; // next node on sector thread
if (s->touching_preciplist)
node->m_thinglist_next->m_thinglist_prev = node;
s->touching_preciplist = node;
return node;
}
// P_DelSecnode() deletes a sector node from the list of
// sectors this object appears in. Returns a pointer to the next node
// on the linked list, or NULL.
@@ -3945,6 +4002,45 @@ static msecnode_t *P_DelSecnode(msecnode_t *node)
return tn;
}
// Tails 08-25-2002
static mprecipsecnode_t *P_DelPrecipSecnode(mprecipsecnode_t *node)
{
mprecipsecnode_t *tp; // prev node on thing thread
mprecipsecnode_t *tn; // next node on thing thread
mprecipsecnode_t *sp; // prev node on sector thread
mprecipsecnode_t *sn; // next node on sector thread
if (!node)
return NULL;
// Unlink from the Thing thread. The Thing thread begins at
// sector_list and not from mobj_t->touching_sectorlist.
tp = node->m_sectorlist_prev;
tn = node->m_sectorlist_next;
if (tp)
tp->m_sectorlist_next = tn;
if (tn)
tn->m_sectorlist_prev = tp;
// Unlink from the sector thread. This thread begins at
// sector_t->touching_thinglist.
sp = node->m_thinglist_prev;
sn = node->m_thinglist_next;
if (sp)
sp->m_thinglist_next = sn;
else
node->m_sector->touching_preciplist = sn;
if (sn)
sn->m_thinglist_prev = sp;
// Return this node to the freelist
P_PutPrecipSecnode(node);
return tn;
}
// Delete an entire sector list
void P_DelSeclist(msecnode_t *node)
{
@@ -3952,6 +4048,13 @@ void P_DelSeclist(msecnode_t *node)
node = P_DelSecnode(node);
}
// Tails 08-25-2002
void P_DelPrecipSeclist(mprecipsecnode_t *node)
{
while (node)
node = P_DelPrecipSecnode(node);
}
// PIT_GetSectors
// Locates all the sectors the object is in by looking at the lines that
// cross through it. You have already decided that the object is allowed
@@ -3992,6 +4095,41 @@ static inline boolean PIT_GetSectors(line_t *ld)
return true;
}
// Tails 08-25-2002
static inline boolean PIT_GetPrecipSectors(line_t *ld)
{
if (preciptmbbox[BOXRIGHT] <= ld->bbox[BOXLEFT] ||
preciptmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT] ||
preciptmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] ||
preciptmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
return true;
if (P_BoxOnLineSide(preciptmbbox, ld) != -1)
return true;
if (ld->polyobj) // line belongs to a polyobject, don't add it
return true;
// This line crosses through the object.
// Collect the sector(s) from the line and add to the
// sector_list you're examining. If the Thing ends up being
// allowed to move to this position, then the sector_list
// will be attached to the Thing's mobj_t at touching_sectorlist.
precipsector_list = P_AddPrecipSecnode(ld->frontsector, tmprecipthing, precipsector_list);
// Don't assume all lines are 2-sided, since some Things
// like MT_TFOG are allowed regardless of whether their radius takes
// them beyond an impassable linedef.
// Use sidedefs instead of 2s flag to determine two-sidedness.
if (ld->backsector)
precipsector_list = P_AddPrecipSecnode(ld->backsector, tmprecipthing, precipsector_list);
return true;
}
// P_CreateSecNodeList alters/creates the sector_list that shows what sectors
// the object resides in.
@@ -4078,6 +4216,73 @@ void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y)
}
}
// More crazy crap Tails 08-25-2002
void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y)
{
INT32 xl, xh, yl, yh, bx, by;
mprecipsecnode_t *node = precipsector_list;
precipmobj_t *saved_tmthing = tmprecipthing; /* cph - see comment at func end */
// First, clear out the existing m_thing fields. As each node is
// added or verified as needed, m_thing will be set properly. When
// finished, delete all nodes where m_thing is still NULL. These
// represent the sectors the Thing has vacated.
while (node)
{
node->m_thing = NULL;
node = node->m_sectorlist_next;
}
tmprecipthing = thing;
preciptmbbox[BOXTOP] = y + 2*FRACUNIT;
preciptmbbox[BOXBOTTOM] = y - 2*FRACUNIT;
preciptmbbox[BOXRIGHT] = x + 2*FRACUNIT;
preciptmbbox[BOXLEFT] = x - 2*FRACUNIT;
validcount++; // used to make sure we only process a line once
xl = (unsigned)(preciptmbbox[BOXLEFT] - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)(preciptmbbox[BOXRIGHT] - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)(preciptmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(preciptmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
P_BlockLinesIterator(bx, by, PIT_GetPrecipSectors);
// Add the sector of the (x, y) point to sector_list.
precipsector_list = P_AddPrecipSecnode(thing->subsector->sector, thing, precipsector_list);
// Now delete any nodes that won't be used. These are the ones where
// m_thing is still NULL.
node = precipsector_list;
while (node)
{
if (!node->m_thing)
{
if (node == precipsector_list)
precipsector_list = node->m_sectorlist_next;
node = P_DelPrecipSecnode(node);
}
else
node = node->m_sectorlist_next;
}
/* cph -
* This is the strife we get into for using global variables. tmthing
* is being used by several different functions calling
* P_BlockThingIterator, including functions that can be called *from*
* P_BlockThingIterator. Using a global tmthing is not reentrant.
* OTOH for Boom/MBF demos we have to preserve the buggy behavior.
* Fun. We restore its previous value unless we're in a Boom/MBF demo.
*/
tmprecipthing = saved_tmthing;
}
/* cphipps 2004/08/30 -
* Must clear tmthing at tic end, as it might contain a pointer to a removed thinker, or the level might have ended/been ended and we clear the objects it was pointing too. Hopefully we don't need to carry this between tics for sync. */
void P_MapStart(void)
+154 -170
View File
@@ -296,7 +296,7 @@ void P_CameraLineOpening(line_t *linedef)
{
frontfloor = sectors[front->camsec].floorheight;
frontceiling = sectors[front->camsec].ceilingheight;
if (sectors[front->camsec].f_slope)
if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera[0].x, camera[0].y);
if (sectors[front->camsec].c_slope)
frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera[0].x, camera[0].y);
@@ -306,7 +306,7 @@ void P_CameraLineOpening(line_t *linedef)
{
frontfloor = sectors[front->heightsec].floorheight;
frontceiling = sectors[front->heightsec].ceilingheight;
if (sectors[front->heightsec].f_slope)
if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera[0].x, camera[0].y);
if (sectors[front->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera[0].x, camera[0].y);
@@ -316,12 +316,11 @@ void P_CameraLineOpening(line_t *linedef)
frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef);
frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef);
}
if (back->camsec >= 0)
{
backfloor = sectors[back->camsec].floorheight;
backceiling = sectors[back->camsec].ceilingheight;
if (sectors[back->camsec].f_slope)
if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera[0].x, camera[0].y);
if (sectors[back->camsec].c_slope)
frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera[0].x, camera[0].y);
@@ -330,7 +329,7 @@ void P_CameraLineOpening(line_t *linedef)
{
backfloor = sectors[back->heightsec].floorheight;
backceiling = sectors[back->heightsec].ceilingheight;
if (sectors[back->heightsec].f_slope)
if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera[0].x, camera[0].y);
if (sectors[back->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera[0].x, camera[0].y);
@@ -341,111 +340,104 @@ void P_CameraLineOpening(line_t *linedef)
backceiling = P_CameraGetCeilingZ(mapcampointer, back, tmx, tmy, linedef);
}
fixed_t thingtop = mapcampointer->z + mapcampointer->height;
{
fixed_t thingtop = mapcampointer->z + mapcampointer->height;
if (frontceiling < backceiling)
{
opentop = frontceiling;
highceiling = backceiling;
}
else
{
opentop = backceiling;
highceiling = frontceiling;
}
if (frontfloor > backfloor)
{
openbottom = frontfloor;
lowfloor = backfloor;
}
else
{
openbottom = backfloor;
lowfloor = frontfloor;
}
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors)
{
ffloor_t *rover;
fixed_t highestceiling = highceiling;
fixed_t lowestceiling = opentop;
fixed_t highestfloor = openbottom;
fixed_t lowestfloor = lowfloor;
fixed_t delta1, delta2;
// Check for frontsector's fake floors
if (front->ffloors)
if (frontceiling < backceiling)
{
for (rover = front->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef);
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = bottomheight;
else if (bottomheight < highestceiling && delta1 >= delta2)
highestceiling = bottomheight;
if (topheight > highestfloor && delta1 < delta2)
highestfloor = topheight;
else if (topheight > lowestfloor && delta1 < delta2)
lowestfloor = topheight;
}
opentop = frontceiling;
highceiling = backceiling;
}
else
{
opentop = backceiling;
highceiling = frontceiling;
}
// Check for backsectors fake floors
if (back->ffloors)
if (frontfloor > backfloor)
{
for (rover = back->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef);
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = bottomheight;
else if (bottomheight < highestceiling && delta1 >= delta2)
highestceiling = bottomheight;
if (topheight > highestfloor && delta1 < delta2)
highestfloor = topheight;
else if (topheight > lowestfloor && delta1 < delta2)
lowestfloor = topheight;
}
openbottom = frontfloor;
lowfloor = backfloor;
}
else
{
openbottom = backfloor;
lowfloor = frontfloor;
}
if (highestceiling < highceiling)
highceiling = highestceiling;
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors)
{
ffloor_t *rover;
fixed_t highestceiling = highceiling;
fixed_t lowestceiling = opentop;
fixed_t highestfloor = openbottom;
fixed_t lowestfloor = lowfloor;
fixed_t delta1, delta2;
if (highestfloor > openbottom)
openbottom = highestfloor;
// Check for frontsector's fake floors
if (front->ffloors)
for (rover = front->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
if (lowestceiling < opentop)
opentop = lowestceiling;
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef);
if (lowestfloor > lowfloor)
lowfloor = lowestfloor;
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = bottomheight;
else if (bottomheight < highestceiling && delta1 >= delta2)
highestceiling = bottomheight;
if (topheight > highestfloor && delta1 < delta2)
highestfloor = topheight;
else if (topheight > lowestfloor && delta1 < delta2)
lowestfloor = topheight;
}
// Check for backsectors fake floors
if (back->ffloors)
for (rover = back->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef);
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = bottomheight;
else if (bottomheight < highestceiling && delta1 >= delta2)
highestceiling = bottomheight;
if (topheight > highestfloor && delta1 < delta2)
highestfloor = topheight;
else if (topheight > lowestfloor && delta1 < delta2)
lowestfloor = topheight;
}
if (highestceiling < highceiling)
highceiling = highestceiling;
if (highestfloor > openbottom)
openbottom = highestfloor;
if (lowestceiling < opentop)
opentop = lowestceiling;
if (lowestfloor > lowfloor)
lowfloor = lowestfloor;
}
openrange = opentop - openbottom;
return;
}
openrange = opentop - openbottom;
return;
}
void P_LineOpening(line_t *linedef, mobj_t *mobj)
@@ -474,39 +466,40 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
I_Assert(front != NULL);
I_Assert(back != NULL);
// Set open and high/low values here
fixed_t frontheight, backheight;
{ // Set open and high/low values here
fixed_t frontheight, backheight;
frontheight = P_GetCeilingZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetCeilingZ(mobj, back, tmx, tmy, linedef);
frontheight = P_GetCeilingZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetCeilingZ(mobj, back, tmx, tmy, linedef);
if (frontheight < backheight)
{
opentop = frontheight;
highceiling = backheight;
opentopslope = front->c_slope;
}
else
{
opentop = backheight;
highceiling = frontheight;
opentopslope = back->c_slope;
}
if (frontheight < backheight)
{
opentop = frontheight;
highceiling = backheight;
opentopslope = front->c_slope;
}
else
{
opentop = backheight;
highceiling = frontheight;
opentopslope = back->c_slope;
}
frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetFloorZ(mobj, back, tmx, tmy, linedef);
frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetFloorZ(mobj, back, tmx, tmy, linedef);
if (frontheight > backheight)
{
openbottom = frontheight;
lowfloor = backheight;
openbottomslope = front->f_slope;
}
else
{
openbottom = backheight;
lowfloor = frontheight;
openbottomslope = back->f_slope;
if (frontheight > backheight)
{
openbottom = frontheight;
lowfloor = backheight;
openbottomslope = front->f_slope;
}
else
{
openbottom = backheight;
lowfloor = frontheight;
openbottomslope = back->f_slope;
}
}
if (mobj)
@@ -515,33 +508,29 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
// Check for collision with front side's midtexture if Effect 4 is set
if (linedef->flags & ML_EFFECT4
&& !linedef->polyobj) // don't do anything for polyobjects! ...for now
{
&& !linedef->polyobj // don't do anything for polyobjects! ...for now
) {
side_t *side = &sides[linedef->sidenum[0]];
fixed_t textop, texbottom, texheight;
fixed_t texmid, delta1, delta2;
INT32 texnum = R_GetTextureNum(side->midtexture); // make sure the texture is actually valid
if (texnum)
{
if (texnum) {
// Get the midtexture's height
texheight = textures[texnum]->height << FRACBITS;
// Set texbottom and textop to the Z coordinates of the texture's boundaries
if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) // "infinite" repeat
{
texbottom = openbottom + side->rowoffset;
textop = opentop + side->rowoffset;
}
else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
{
texbottom = openbottom + side->rowoffset;
textop = texbottom + texheight*(side->repeatcnt+1);
}
else
{
textop = opentop + side->rowoffset;
texbottom = textop - texheight*(side->repeatcnt+1);
if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat
texbottom = openbottom + side->rowoffset;
textop = opentop + side->rowoffset;
} else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
texbottom = openbottom + side->rowoffset;
textop = texbottom + texheight*(side->repeatcnt+1);
} else {
textop = opentop + side->rowoffset;
texbottom = textop - texheight*(side->repeatcnt+1);
}
}
texmid = texbottom+(textop-texbottom)/2;
@@ -549,13 +538,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
delta1 = abs(mobj->z - texmid);
delta2 = abs(thingtop - texmid);
if (delta1 > delta2) // Below
{
if (delta1 > delta2) { // Below
if (opentop > texbottom)
opentop = texbottom;
}
else // Above
{
} else { // Above
if (openbottom < textop)
openbottom = textop;
}
@@ -563,7 +549,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
}
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors || linedef->polyobj)
if (front->ffloors || back->ffloors
|| linedef->polyobj
)
{
ffloor_t *rover;
@@ -579,7 +567,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
for (rover = front->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
@@ -597,8 +584,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{
if (bottomheight < lowestceiling)
{
if (bottomheight < lowestceiling) {
lowestceiling = bottomheight;
ceilingslope = *rover->b_slope;
}
@@ -608,8 +594,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
{
if (topheight > highestfloor)
{
if (topheight > highestfloor) {
highestfloor = topheight;
floorslope = *rover->t_slope;
}
@@ -639,8 +624,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{
if (bottomheight < lowestceiling)
{
if (bottomheight < lowestceiling) {
lowestceiling = bottomheight;
ceilingslope = *rover->b_slope;
}
@@ -650,8 +634,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
{
if (topheight > highestfloor)
{
if (topheight > highestfloor) {
highestfloor = topheight;
floorslope = *rover->t_slope;
}
@@ -667,35 +650,29 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
delta1 = abs(mobj->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
if (polysec->floorheight < lowestceiling && delta1 >= delta2)
{
if (polysec->floorheight < lowestceiling && delta1 >= delta2) {
lowestceiling = polysec->floorheight;
ceilingslope = NULL;
}
else if (polysec->floorheight < highestceiling && delta1 >= delta2)
highestceiling = polysec->floorheight;
if (polysec->ceilingheight > highestfloor && delta1 < delta2)
{
if (polysec->ceilingheight > highestfloor && delta1 < delta2) {
highestfloor = polysec->ceilingheight;
floorslope = NULL;
}
else if (polysec->ceilingheight > lowestfloor && delta1 < delta2)
lowestfloor = polysec->ceilingheight;
}
if (highestceiling < highceiling)
highceiling = highestceiling;
if (highestfloor > openbottom)
{
if (highestfloor > openbottom) {
openbottom = highestfloor;
openbottomslope = floorslope;
}
if (lowestceiling < opentop)
{
if (lowestceiling < opentop) {
opentop = lowestceiling;
opentopslope = ceilingslope;
}
@@ -782,6 +759,9 @@ void P_UnsetPrecipThingPosition(precipmobj_t *thing)
if (bprev && (*bprev = bnext) != NULL) // unlink from block map
bnext->bprev = bprev;
precipsector_list = thing->touching_sectorlist;
thing->touching_sectorlist = NULL; //to be restored by P_SetPrecipThingPosition
}
static void P_LinkToBlockMap(mobj_t *thing, mobj_t **bmap)
@@ -926,6 +906,10 @@ void P_SetPrecipitationThingPosition(precipmobj_t *thing)
{
thing->subsector = R_PointInSubsector(thing->x, thing->y);
P_CreatePrecipSecNodeList(thing, thing->x, thing->y);
thing->touching_sectorlist = precipsector_list; // Attach to Thing's precipmobj_t
precipsector_list = NULL; // clear for next time
// NOTE: this works because bnext/bprev are at the same
// offsets in precipmobj_t and mobj_t
P_LinkToBlockMap((mobj_t*)thing, (mobj_t**)precipblocklinks);
+136 -168
View File
@@ -435,7 +435,7 @@ void P_ExplodeMissile(mobj_t *mo)
}
// Hack: Release an animal.
P_DamageMobj(mo, NULL, NULL, DMG_INSTAKILL);
P_DamageMobj(mo, NULL, NULL, 10000);
}
mo->flags &= ~MF_MISSILE;
@@ -1357,16 +1357,12 @@ void P_XYMovement(mobj_t *mo)
oldy = mo->y;
// adjust various things based on slope
if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8)
{
if (!P_IsObjectOnGround(mo)) // We fell off at some point? Do the twisty thing!
{
if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) {
if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing!
P_SlopeLaunch(mo);
xmove = mo->momx;
ymove = mo->momy;
}
else // Still on the ground.
{
} else { // Still on the ground.
slopemom.x = xmove;
slopemom.y = ymove;
slopemom.z = 0;
@@ -1379,8 +1375,7 @@ void P_XYMovement(mobj_t *mo)
oldslope = mo->standingslope;
}
}
else if (P_IsObjectOnGround(mo) && !mo->momz)
} else if (P_IsObjectOnGround(mo) && !mo->momz)
predictedz = mo->z;
// Pushables can break some blocks
@@ -1887,13 +1882,13 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
const INT32 secspecial = GETSECSPECIAL(mo->subsector->sector->special, 1);
INT32 special = GETSECSPECIAL(mo->subsector->sector->special, 1);
if (((mo->z <= mo->subsector->sector->floorheight
&& !(mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR))
|| (mo->z + mo->height >= mo->subsector->sector->ceilingheight
&& (mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING)))
&& (secspecial == 6 || secspecial == 7))
&& (special == 6 || special == 7))
return true;
return false;
@@ -2485,58 +2480,55 @@ static void P_PlayerZMovement(mobj_t *mo)
msecnode_t *node;
boolean stopmovecut = false;
if (numPolyObjects)
for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
sector_t *sec = node->m_sector;
subsector_t *newsubsec;
size_t i;
for (i = 0; i < numsubsectors; i++)
{
sector_t *sec = node->m_sector;
subsector_t *newsubsec;
size_t i;
newsubsec = &subsectors[i];
for (i = 0; i < numsubsectors; i++)
if (newsubsec->sector != sec)
continue;
if (!newsubsec->polyList)
continue;
polyobj_t *po = newsubsec->polyList;
sector_t *polysec;
while(po)
{
newsubsec = &subsectors[i];
if (newsubsec->sector != sec)
continue;
if (!newsubsec->polyList)
continue;
polyobj_t *po = newsubsec->polyList;
sector_t *polysec;
while(po)
if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID))
{
if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID))
{
po = (polyobj_t *)(po->link.next);
continue;
}
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
// Moving polyobjects should act like conveyors if the player lands on one. (I.E. none of the momentum cut thing below) -Red
if ((mo->z == polysec->ceilingheight || mo->z+mo->height == polysec->floorheight) && po->thinker)
stopmovecut = true;
if (!(po->flags & POF_LDEXEC))
{
po = (polyobj_t *)(po->link.next);
continue;
}
if (mo->z == polysec->ceilingheight)
{
// We're landing on a PO, so check for
// a linedef executor.
// Trigger tags are 32000 + the PO's ID number.
P_LinedefExecute((INT16)(32000 + po->id), mo, NULL);
}
po = (polyobj_t *)(po->link.next);
continue;
}
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
// Moving polyobjects should act like conveyors if the player lands on one. (I.E. none of the momentum cut thing below) -Red
if ((mo->z == polysec->ceilingheight || mo->z+mo->height == polysec->floorheight) && po->thinker)
stopmovecut = true;
if (!(po->flags & POF_LDEXEC))
{
po = (polyobj_t *)(po->link.next);
continue;
}
if (mo->z == polysec->ceilingheight)
{
// We're landing on a PO, so check for
// a linedef executor.
// Trigger tags are 32000 + the PO's ID number.
P_LinedefExecute((INT16)(32000 + po->id), mo, NULL);
}
po = (polyobj_t *)(po->link.next);
}
}
}
@@ -3007,6 +2999,11 @@ void P_MobjCheckWater(mobj_t *mobj)
else if (mobj->eflags & MFE_VERTICALFLIP && mobj->momz > FixedMul(-min, mobj->scale))
mobj->momz = FixedMul(-min, mobj->scale);
/*if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->momz > FixedMul(max, mobj->scale))
mobj->momz = FixedMul(max, mobj->scale);
else if (mobj->eflags & MFE_VERTICALFLIP && mobj->momz < FixedMul(-max, mobj->scale))
mobj->momz = FixedMul(-max, mobj->scale);*/
p->kartstuff[k_waterskip]++;
}
@@ -3144,7 +3141,7 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
sector_t *sector;
fixed_t halfheight;
if (!thiscam || !thiscam->subsector)
if (!thiscam)
return false;
halfheight = thiscam->z + (thiscam->height >> 1);
@@ -3182,7 +3179,7 @@ static boolean P_CameraCheckWater(camera_t *thiscam)
sector_t *sector;
fixed_t halfheight;
if (!thiscam || !thiscam->subsector)
if (!thiscam)
return false;
halfheight = thiscam->z + (thiscam->height >> 1);
@@ -3235,23 +3232,16 @@ void P_DestroyRobots(void)
}
// the below is chasecam only, if you're curious. check out P_CalcPostImg in p_user.c for first person
void P_CalcChasePostImg(player_t *player, camera_t *thiscam)
static void P_CalcChasePostImg(player_t *player, camera_t *thiscam)
{
const boolean flipcam = (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP);
UINT8 postimgtype = 0;
UINT16 postimgflags = 0;
UINT8 i;
if (encoremode)
postimgtype |= POSTIMG_MIRROR;
postimgflags |= POSTIMG_MIRROR;
if (flipcam)
postimgtype |= POSTIMG_FLIP;
#ifdef HWRENDER
if (rendermode == render_opengl && splitscreen)
{
thiscam->postimg = postimgtype;
return;
}
#endif
postimgflags |= POSTIMG_FLIP;
if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
{
@@ -3266,20 +3256,27 @@ void P_CalcChasePostImg(player_t *player, camera_t *thiscam)
// Are we in water?
if (P_CameraCheckWater(&dummycam))
postimgtype |= POSTIMG_WATER;
else if (P_CameraCheckHeat(&dummycam))
postimgtype |= POSTIMG_HEAT;
postimgflags |= POSTIMG_WATER;
if (P_CameraCheckHeat(&dummycam))
postimgflags |= POSTIMG_HEAT;
}
else
{
// Are we in water?
if (P_CameraCheckWater(thiscam))
postimgtype |= POSTIMG_WATER;
else if (P_CameraCheckHeat(thiscam))
postimgtype |= POSTIMG_HEAT;
postimgflags |= POSTIMG_WATER;
if (P_CameraCheckHeat(thiscam))
postimgflags |= POSTIMG_HEAT;
}
thiscam->postimg = postimgtype;
for (i = 0; i <= splitscreen; i++)
{
if (player != &players[displayplayers[i]])
continue;
players[displayplayers[i]].postimgflags = postimgflags;
break;
}
}
// P_CameraThinker
@@ -3340,7 +3337,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
if (!itsatwodlevel)
P_CheckCameraPosition(thiscam->x, thiscam->y, thiscam);
thiscam->subsector = R_PointInSubsector(thiscam->x, thiscam->y);
thiscam->subsector = R_PointInSubsectorFast(thiscam->x, thiscam->y);
thiscam->floorz = tmfloorz;
thiscam->ceilingz = tmceilingz;
@@ -3567,22 +3564,15 @@ animonly:
}
}
static void P_CalculatePrecipFloor(precipmobj_t *mobj, boolean spawn)
static void CalculatePrecipFloor(precipmobj_t *mobj)
{
// recalculate floorz each time
const sector_t *mobjsecsubsec;
if (mobj && mobj->subsector && mobj->subsector->sector)
mobjsecsubsec = mobj->subsector->sector;
else
return;
// no need to recalc anything if not moved
if (!spawn && !mobjsecsubsec->moved)
return;
mobj->floorz = P_GetSectorFloorZAt(mobjsecsubsec, mobj->x, mobj->y);
if (mobjsecsubsec->ffloors)
{
ffloor_t *rover;
@@ -3605,6 +3595,19 @@ static void P_CalculatePrecipFloor(precipmobj_t *mobj, boolean spawn)
}
}
void P_RecalcPrecipInSector(sector_t *sector)
{
mprecipsecnode_t *psecnode;
if (!sector)
return;
sector->moved = true; // Recalc lighting and things too, maybe
for (psecnode = sector->touching_preciplist; psecnode; psecnode = psecnode->m_thinglist_next)
CalculatePrecipFloor(psecnode->m_thing);
}
//
// P_NullPrecipThinker
//
@@ -3671,9 +3674,6 @@ boolean P_PrecipThinker(precipmobj_t *mobj)
if (mobj->precipflags & PCF_SPLASH)
return true;
if (renderisnewtic)
P_CalculatePrecipFloor(mobj, false);
// adjust height
if ((mobj->z += mobj->momz) <= mobj->floorz)
{
@@ -4844,13 +4844,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
continue;
mo2 = (mobj_t *)th;
if (mo2->type != MT_BOSS3WAYPOINT)
continue;
if (!mo2->spawnpoint)
continue;
if ((mo2->spawnpoint->options & 7) == waypointNum)
if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint && (mo2->spawnpoint->options & 7) == waypointNum)
{
hitspot = mo2;
break;
@@ -5693,6 +5687,9 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
if (!dest || dest->health <= 0 || !dest->player || !source->tracer)
return;
// change angle
//source->angle = R_PointToAngle2(source->x, source->y, tx, ty);
// change slope
dist = P_AproxDistance(P_AproxDistance(tx - source->x, ty - source->y), tz - source->z);
@@ -6033,21 +6030,17 @@ static void P_KoopaThinker(mobj_t *koopa)
//
void P_RollPitchMobj(mobj_t* mobj)
{
// we dont need this in dedi do we?
if (rendermode == render_none)
return;
if (P_MobjWasRemoved(mobj))
return;
if (cv_sloperoll.value != 2)
{
mobj->sloperoll = 0;
mobj->slopepitch = 0;
mobj->sloperoll = FixedAngle(0);
mobj->slopepitch = FixedAngle(0);
return;
}
K_RollMobjBySlopes(mobj, mobj->standingslope);
K_RollMobjBySlopes(mobj, cv_sloperolldist.value && !splitscreen);
}
angle_t P_MobjPitchAndRoll(mobj_t *mobj)
@@ -7058,21 +7051,8 @@ void P_MobjThinker(mobj_t *mobj)
}
break;
//{ SRB2kart Items - Death States
case MT_BANANA:
if (cv_sloperoll.value == 2 && cv_bananthrowroll.value)
{
angle_t spin = FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h);
//mobj->angle -= spin;
if (cv_bananthrowroll.value == 1)
mobj->sloperoll += spin; // im lazy but this makes sure the banan goes back to upright when it lands lmao
else if (cv_bananthrowroll.value == 2)
mobj->rollangle += spin;
//if (P_IsObjectOnGround(mobj) && mobj->momz * P_MobjFlip(mobj) <= 0)
}
/* FALLTHRU */
case MT_ORBINAUT:
case MT_BANANA:
case MT_EGGMANITEM:
case MT_SPB:
if (P_IsObjectOnGround(mobj))
@@ -7814,18 +7794,6 @@ void P_MobjThinker(mobj_t *mobj)
}
case MT_BANANA:
case MT_EGGMANITEM:
if (cv_sloperoll.value == 2 && cv_bananthrowroll.value && !P_IsObjectOnGround(mobj))
{
// tilt n tumble
angle_t spin = FixedMul(FixedDiv(mobj->momz, 8 * mobj->scale), ANGLE_67h);
//mobj->angle += spin;
if (cv_bananthrowroll.value == 1)
mobj->sloperoll -= spin; // im lazy but this makes sure the banan goes back to upright when it lands lmao
else if (cv_bananthrowroll.value == 2)
mobj->rollangle -= spin;
}
mobj->friction = ORIG_FRICTION/4;
if (mobj->momx || mobj->momy)
P_SpawnGhostMobj(mobj);
@@ -9472,13 +9440,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
}
// Sprite rendering
mobj->blendmode = AST_TRANSLUCENT;
mobj->realxscale = mobj->realyscale = mobj->scale;
mobj->spritexscale = mobj->realxscale;
mobj->spriteyscale = mobj->realyscale;
mobj->realxoffset = mobj->realyoffset = 0;
mobj->spritexoffset = mobj->realxoffset;
mobj->spriteyoffset = mobj->realyoffset;
mobj->spritexoffset = mobj->spriteyoffset = 0;
// Funni slam sound when landing
mobj->slamsoundtimer = 0;
@@ -9909,7 +9874,6 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
mobj->radius = info->radius;
mobj->height = info->height;
mobj->flags = info->flags;
mobj->blendmode = AST_TRANSLUCENT;
mobj->health = info->spawnhealth;
@@ -10039,9 +10003,9 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
mobj->momz = cv_mobjscaleprecip.value ? FixedMul(info->speed, mapobjectscale) : info->speed;
mobj->thinker.function.acp1 = (actionf_p1)P_NullPrecipThinker;
P_AddPrecipThinker(&mobj->thinker);
P_AddThinker(&mobj->thinker);
P_CalculatePrecipFloor(mobj, true);
CalculatePrecipFloor(mobj);
if (mobj->floorz != starting_floorz)
mobj->precipflags |= PCF_FOF;
@@ -10201,6 +10165,12 @@ void P_FreePrecipMobj(precipmobj_t *mobj)
// unlink from sector and block lists
P_UnsetPrecipThingPosition(mobj);
if (precipsector_list)
{
P_DelPrecipSeclist(precipsector_list);
precipsector_list = NULL;
}
// free block
// Precipmobjs don't actually think using their thinker,
// so the free cannot be delayed.
@@ -10214,6 +10184,12 @@ void P_RemoveSavegameMobj(mobj_t *mobj)
if (((thinker_t *)mobj)->function.acp1 == (actionf_p1)P_NullPrecipThinker)
{
P_UnsetPrecipThingPosition((precipmobj_t *)mobj);
if (precipsector_list)
{
P_DelPrecipSeclist(precipsector_list);
precipsector_list = NULL;
}
}
else
{
@@ -10246,26 +10222,28 @@ consvar_t cv_suddendeath = {"suddendeath", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHE
void P_SpawnPrecipitation(void)
{
INT32 i, j, mrand;
fixed_t basex, basey, x, y, z;
INT32 i, mrand;
fixed_t basex, basey, j, x, y, z;
subsector_t *precipsector = NULL;
precipmobj_t *rainmo = NULL;
if (dedicated || !cv_drawdist_precip.value || curWeather == PRECIP_NONE || curWeather == PRECIP_STORM_NORAIN)
if (dedicated || !cv_drawdist_precip.value || curWeather == PRECIP_NONE) // SRB2Kart
return;
const fixed_t precipmoscale = (cv_mobjscaleprecip.value ? mapobjectscale : FRACUNIT);
const INT32 density = (cv_lessprecip.value ? 2 : 1); // only spawn half as much
fixed_t density = (cv_mobjscaleprecip.value ? mapobjectscale : FRACUNIT);
if (cv_lessprecip.value)
density *= 2; // just spawn half the precip
// Use the blockmap to narrow down our placing patterns
for (i = 0; i < bmapwidth*bmapheight; i += density)
for (i = 0; i < bmapwidth*bmapheight; ++i)
{
basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE;
basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE;
// If mobjscale < FRACUNIT, each blockmap cell covers
// more area so spawn more precipitation in that area.
for (j = 0; j < FRACUNIT; j += precipmoscale)
for (j = 0; j < FRACUNIT; j += density)
{
INT32 floorz;
INT32 ceilingz;
@@ -10303,9 +10281,6 @@ void P_SpawnPrecipitation(void)
else // everything else.
rainmo = P_SpawnPrecipMobj(x, y, z, MT_RAIN);
if (curWeather == PRECIP_BLANK)
rainmo->precipflags |= PCF_INVISIBLE;
floorz = rainmo->floorz >> FRACBITS;
ceilingz = rainmo->ceilingz >> FRACBITS;
@@ -10321,6 +10296,17 @@ void P_SpawnPrecipitation(void)
}
}
}
if (curWeather == PRECIP_BLANK)
{
curWeather = PRECIP_RAIN;
P_SwitchWeather(PRECIP_BLANK);
}
else if (curWeather == PRECIP_STORM_NORAIN)
{
curWeather = PRECIP_RAIN;
P_SwitchWeather(PRECIP_STORM_NORAIN);
}
}
//
@@ -10429,7 +10415,7 @@ void P_PrecipitationEffects(void)
for (y = yl; y <= yh; y += RADIUSSTEP)
for (x = xl; x <= xh; x += RADIUSSTEP)
{
if (R_PointInSubsector((fixed_t)x, (fixed_t)y)->sector->ceilingpic != skyflatnum) // Found the outdoors!
if (R_PointInSubsectorFast((fixed_t)x, (fixed_t)y)->sector->ceilingpic != skyflatnum) // Found the outdoors!
continue;
newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, (fixed_t)x, (fixed_t)y, 0);
@@ -10632,9 +10618,7 @@ void P_SpawnPlayer(INT32 playernum)
if (multiplayer && demo.playback)
; // Don't mess with spectator values since the demo setup handles them already.
else if (!G_GametypeHasSpectators())
{
p->spectator = false;
}
else if (netgame && p->jointime <= 1 && pcount)
{
p->spectator = true;
@@ -10666,9 +10650,7 @@ void P_SpawnPlayer(INT32 playernum)
SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue));
}
else // Otherwise, never spectator.
{
p->spectator = false;
}
}
if (G_GametypeHasTeams())
@@ -10728,8 +10710,6 @@ void P_SpawnPlayer(INT32 playernum)
p->hitemtimer = 0;
p->hitemvictim = 255;
p->spinoutrot = 0;
if (G_BattleGametype()) // SRB2kart
{
mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + P_GetPlayerHeight(p)+16*FRACUNIT, MT_PLAYERARROW);
@@ -10784,19 +10764,7 @@ void P_SpawnPlayer(INT32 playernum)
{
if (!p->spectator)
{
if (playernum == consoleplayer)
camera[0].freecam = false;
else if (splitscreen)
{
for (i = 1; i <= splitscreen; i++)
{
if (playernum == displayplayers[i])
{
camera[i].freecam = false;
break;
}
}
}
camera[playernum].freecam = false;
}
}
}
@@ -11651,7 +11619,7 @@ ML_NOCLIMB : Direction not controllable
mobj_t *elecmobj;
elecmobj = P_SpawnMobj(x, y, z, MT_CYBRAKDEMON_ELECTRIC_BARRIER);
P_SetTarget(&elecmobj->target, mobj);
elecmobj->angle = FixedAngle(mthing->angle*FRACUNIT);
elecmobj->angle = FixedAngle(mthing->angle*FRACUNIT);;
elecmobj->destscale = mobj->scale*2;
P_SetScale(elecmobj, elecmobj->destscale);
}
+1 -6
View File
@@ -289,15 +289,12 @@ typedef struct mobj_s
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT16 anim_duration; // for FF_ANIMATE states
INT32 blendmode; // blend mode
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale;
fixed_t old_spritexoffset, old_spriteyoffset;
INT16 lightlevel; // Add to sector lightlevel, -255 - 255
fixed_t realxscale, realyscale; // funn-E streeetch
fixed_t realxoffset, realyoffset;
fixed_t stretchslam; // "squish" effect when you land
@@ -396,6 +393,7 @@ typedef struct mobj_s
boolean resetinterp; // if true, some fields should not be interpolated (see R_InterpolateMobjState implementation)
boolean colorized; // Whether the mobj uses the rainbow colormap
boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left
boolean rollmodel; // OpenGL: Should this model rotate?
tic_t slamsoundtimer;
@@ -443,15 +441,12 @@ typedef struct precipmobj_s
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT16 anim_duration; // for FF_ANIMATE states
INT32 blendmode; // blend mode
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale;
fixed_t old_spritexoffset, old_spriteyoffset;
INT16 lightlevel; // Add to sector lightlevel, -255 - 255
fixed_t realxscale, realyscale; // funn-E streeetch
fixed_t realxoffset, realyoffset;
fixed_t stretchslam; // "squish" effect when you land
+4 -24
View File
@@ -41,18 +41,10 @@
#define FF_HORIZONTALFLIP 0x400
/// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION)
#define FF_PAPERSPRITE 0x800
/// \brief Frame flags: blend types
#define FF_BLENDMASK 0x7000
/// \brief shift for FF_BLENDMASK
#define FF_BLENDSHIFT 12
/// \brief preshifted blend flags minus 1 as effects don't distinguish between AST_COPY and AST_TRANSLUCENT
#define FF_ADD ((AST_ADD-1)<<FF_BLENDSHIFT)
#define FF_SUBTRACT ((AST_SUBTRACT-1)<<FF_BLENDSHIFT)
#define FF_REVERSESUBTRACT ((AST_REVERSESUBTRACT-1)<<FF_BLENDSHIFT)
#define FF_MODULATE ((AST_MODULATE-1)<<FF_BLENDSHIFT)
#define FF_OVERLAY ((AST_OVERLAY-1)<<FF_BLENDSHIFT)
/// \brief Frame flags: Simple stateless animation
#define FF_ANIMATE 0x4000
/// \brief Frame flags: frame always appears full bright
#define FF_FULLBRIGHT 0x8000
/// \brief Frame flags: 0 = no trans(opaque), 1-15 = transl. table
#define FF_TRANSMASK 0xf0000
/// \brief shift for FF_TRANSMASK
@@ -68,18 +60,6 @@
#define FF_TRANS80 (tr_trans80<<FF_TRANSSHIFT)
#define FF_TRANS90 (tr_trans90<<FF_TRANSSHIFT)
/// \brief Frame flags: brightness mask
#define FF_BRIGHTMASK 0x00300000
/// \brief Frame flags: frame always appears full bright
#define FF_FULLBRIGHT 0x00100000
/// \brief Frame flags: frame always appears full darkness
#define FF_FULLDARK 0x00200000
/// \brief Frame flags: frame appears between sector bright and full bright
#define FF_SEMIBRIGHT (FF_FULLBRIGHT|FF_FULLDARK)
/// \brief Frame flags: Simple stateless animation
#define FF_ANIMATE 0x10000000
/** \brief translucency tables
\todo add another asm routine which use the fg and bg indexes in the
+13 -31
View File
@@ -1680,7 +1680,8 @@ static void P_NetArchiveThinkers(savebuffer_t *save)
// save off the current thinkers
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_RemoveThinkerDelayed)
if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed
|| th->function.acp1 == (actionf_p1)P_NullPrecipThinker))
numsaved++;
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
@@ -1688,6 +1689,9 @@ static void P_NetArchiveThinkers(savebuffer_t *save)
SaveMobjThinker(save, th, tc_mobj);
continue;
}
#ifdef PARANOIA
else if (th->function.acp1 == (actionf_p1)P_NullPrecipThinker);
#endif
else if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
{
SaveCeilingThinker(save, th, tc_ceiling);
@@ -2147,19 +2151,17 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
mobj->mirrored = 0;
// Sprite Rendering stuff
mobj->blendmode = AST_TRANSLUCENT;
mobj->spritexoffset = mobj->realxoffset = 0;
mobj->spriteyoffset = mobj->realxoffset = 0;
mobj->spritexscale = mobj->realxscale = FRACUNIT;
mobj->spriteyscale = mobj->realyscale = FRACUNIT;
mobj->spritexoffset = 0;
mobj->spriteyoffset = 0;
mobj->spritexscale = FRACUNIT;
mobj->spriteyscale = FRACUNIT;
mobj->realxscale = FRACUNIT;
mobj->realyscale = FRACUNIT;
mobj->stretchslam = 0;
// Timer for slam sound effect
mobj->slamsoundtimer = 0;
// extra mobjlightlevel
mobj->lightlevel = 0;
//}
if (diff & MD_REDFLAG)
@@ -2669,8 +2671,6 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save)
{
thinker_t *currentthinker;
thinker_t *next;
thinker_t *currentprecipthinker;
thinker_t *nextprecip;
UINT8 tclass;
UINT8 restoreNum = false;
UINT32 i;
@@ -2685,7 +2685,7 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save)
{
next = currentthinker->next;
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker || currentthinker->function.acp1 == (actionf_p1)P_NullPrecipThinker)
P_RemoveSavegameMobj((mobj_t *)currentthinker); // item isn't saved, don't remove it
else
{
@@ -2695,24 +2695,6 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save)
}
}
// remove all the current precip thinkers
currentprecipthinker = precipcap.next;
for (currentprecipthinker = precipcap.next; currentprecipthinker != &precipcap; currentprecipthinker = nextprecip)
{
nextprecip = currentprecipthinker->next;
#ifdef PARANOIA
if (currentprecipthinker->function.acp1 != (actionf_p1)P_NullPrecipThinker)
{
(next->prev = currentprecipthinker->prev)->next = nextprecip;
R_DestroyLevelInterpolators(currentprecipthinker);
Z_Free(currentprecipthinker);
}
else
#endif
P_RemoveSavegameMobj((mobj_t *)currentprecipthinker); // item isn't saved, don't remove it
}
// we don't want the removed mobjs to come back
iquetail = iquehead = 0;
P_InitThinkers();
@@ -3351,7 +3333,7 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
// tell the sound code to reset the music since we're skipping what
// normally sets this flag
if (!reloading)
mapmusic.flags |= MUSIC_RELOADRESET;
mapmusflags |= MUSIC_RELOADRESET;
G_SetGamestate(READINT16(save->p));
+257 -454
View File
@@ -91,9 +91,6 @@
//
unsigned char mapmd5[16];
// true when level was loaded from netsave
boolean midgamejoin = false;
//
// MAP related Lookup tables.
// Store VERTEXES, LINEDEFS, SIDEDEFS, etc.
@@ -250,6 +247,8 @@ static SINT8 partadd_stage = -1;
static boolean partadd_replacescurrentmap = false;
static boolean partadd_important = false;
SINT8 midgamejoin = 0;
/** Logs an error about a map being corrupt, then terminate.
* This allows reporting highly technical errors for usefulness, without
* confusing a novice map designer who simply needs to run ZenNode.
@@ -279,15 +278,6 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
#define NUMLAPS_DEFAULT 3
static void P_ClearMapHeaderLighting(mapheader_lighting_t *lighting)
{
lighting->light_contrast = 8;
lighting->sprite_backlight = 0;
lighting->use_light_angle = false;
lighting->light_angle = 0;
lighting->use_custom_light = false;
}
/** Clears the data from a single map header.
*
* \param i Map number to clear header for.
@@ -334,13 +324,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
// SRB2Kart
//mapheaderinfo[num]->automap = false;
mapheaderinfo[num]->mobj_scale = FRACUNIT;
// an even further impossibility, delfile custom opts support
mapheaderinfo[num]->customopts = NULL;
mapheaderinfo[num]->numCustomOptions = 0;
P_ClearMapHeaderLighting(&mapheaderinfo[num]->lighting);
P_ClearMapHeaderLighting(&mapheaderinfo[num]->lighting_encore);
mapheaderinfo[num]->use_encore_lighting = false;
}
/** Allocates a new map-header structure.
@@ -510,137 +496,21 @@ static inline float P_SegLengthFloat(seg_t *seg)
*/
void P_UpdateSegLightOffset(seg_t *li)
{
const UINT8 contrast = maplighting.contrast;
const UINT8 contrast = 8;
const fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT;
fixed_t light = FRACUNIT;
fixed_t extralight = 0;
if (maplighting.directional == true)
{
angle_t liAngle = R_PointToAngle2(0, 0, (li->v1->x - li->v2->x), (li->v1->y - li->v2->y)) - ANGLE_90;
light = FixedMul(FINECOSINE(liAngle >> ANGLETOFINESHIFT), FINECOSINE(maplighting.angle >> ANGLETOFINESHIFT))
+ FixedMul(FINESINE(liAngle >> ANGLETOFINESHIFT), FINESINE(maplighting.angle >> ANGLETOFINESHIFT));
light = (light + FRACUNIT) / 2;
}
else
{
light = FixedDiv(R_PointToAngle2(0, 0, abs(li->v1->x - li->v2->x), abs(li->v1->y - li->v2->y)), ANGLE_90);
}
light = FixedDiv(R_PointToAngle2(0, 0, abs(li->v1->x - li->v2->x), abs(li->v1->y - li->v2->y)), ANGLE_90);
extralight = -contrastFixed + FixedMul(light, contrastFixed * 2);
// Between -2 and 2 for software, -8 and 8 for hardware
li->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT;
li->lightOffset = FixedFloor((extralight / contrast) + (FRACUNIT / 2)) / FRACUNIT;
#ifdef HWRENDER
li->hwLightOffset = FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT;
#endif
}
boolean P_SectorUsesDirectionalLighting(const sector_t *sector)
{
if (sector != NULL)
{
// automatically turned on
if (sector->ceilingpic == skyflatnum || sector->floorpic == skyflatnum)
{
// sky is visible
return true;
}
}
// default is off, for indoors
return false;
}
boolean P_ApplyLightOffset(UINT8 baselightnum, const sector_t *sector)
{
mapheader_lighting_t *lighting = &mapheaderinfo[gamemap-1]->lighting;
if (encoremode && mapheaderinfo[gamemap-1]->use_encore_lighting)
{
lighting = &mapheaderinfo[gamemap-1]->lighting_encore;
}
if (!cv_randomdirlight.value && lighting->use_custom_light == false)
return (baselightnum < LIGHTLEVELS-1 && baselightnum > 0);
if (!P_SectorUsesDirectionalLighting(sector))
{
return false;
}
// Don't apply light offsets at full bright or full dark.
// Is in steps of light num .
return (baselightnum < LIGHTLEVELS-1 && baselightnum > 0);
}
boolean P_ApplyLightOffsetFine(UINT8 baselightlevel, const sector_t *sector)
{
mapheader_lighting_t *lighting = &mapheaderinfo[gamemap-1]->lighting;
if (encoremode && mapheaderinfo[gamemap-1]->use_encore_lighting)
{
lighting = &mapheaderinfo[gamemap-1]->lighting_encore;
}
if (!cv_randomdirlight.value && lighting->use_custom_light == false)
return (baselightlevel < 255 && baselightlevel > 0);
if (!P_SectorUsesDirectionalLighting(sector))
{
return false;
}
// Don't apply light offsets at full bright or full dark.
// Uses exact light levels for more smoothness.
return (baselightlevel < 255 && baselightlevel > 0);
}
// dumb thing to reset maplight on next map change when its toggled
boolean reinitmaplight = false;
static void P_SetupDirectionalLight(void)
{
mapheader_lighting_t *lighting = &mapheaderinfo[gamemap-1]->lighting;
if (encoremode && mapheaderinfo[gamemap-1]->use_encore_lighting)
{
lighting = &mapheaderinfo[gamemap-1]->lighting_encore;
}
if (cv_randomdirlight.value && lighting->use_custom_light == false)
{
static INT16 oldmap = 0; // dont reset stuff when you restart a map
static boolean oldencore = false;
if (gamemap != oldmap || encoremode != oldencore || reinitmaplight)
{
maplighting.contrast = M_RandomRange(0, 58);
maplighting.backlight = 0;
maplighting.directional = M_RandomRange(0, 1); // either on or off
maplighting.angle = M_RandomRange(-382, 382);
reinitmaplight = false;
}
oldmap = gamemap;
oldencore = encoremode;
return;
}
else if (lighting->use_custom_light == false)
{
maplighting.contrast = 8;
maplighting.backlight = 0;
maplighting.directional = false;
maplighting.angle = 0;
}
maplighting.contrast = lighting->light_contrast;
maplighting.backlight = lighting->sprite_backlight;
maplighting.directional = lighting->use_light_angle;
maplighting.angle = lighting->light_angle;
}
// Loads the SEGS resource from a level.
static void P_LoadRawSegs(UINT8 *data)
{
@@ -650,9 +520,6 @@ static void P_LoadRawSegs(UINT8 *data)
line_t *ldef;
size_t i;
// Set map lighting settings.
P_SetupDirectionalLight();
for (i = 0; i < numsegs; i++, li++, ml++)
{
li->v1 = &vertexes[SHORT(ml->v1)];
@@ -873,6 +740,8 @@ static void P_LoadRawSectors(UINT8 *data)
ss->thinglist = NULL;
ss->touching_thinglist = NULL;
ss->touching_preciplist = NULL;
ss->floordata = NULL;
ss->ceilingdata = NULL;
ss->lightingdata = NULL;
@@ -1206,9 +1075,6 @@ static void P_SetupLines(void)
ld->dx = v2->x - v1->x;
ld->dy = v2->y - v1->y;
ld->alpha = FRACUNIT;
ld->blendmode = 0;
if (!ld->dx)
ld->slopetype = ST_VERTICAL;
else if (!ld->dy)
@@ -1316,26 +1182,6 @@ static void P_LoadLineDefs2(void)
}
break;
}
// Set alpha for translucent walls
if (ld->special >= 900 && ld->special < 909)
ld->alpha = ((909 - ld->special) << FRACBITS)/10;
// Set alpha for additive/subtractive/reverse subtractive walls
if (ld->special >= 910 && ld->special <= 939)
ld->alpha = ((10 - ld->special % 10) << FRACBITS)/10;
if (ld->special >= 910 && ld->special <= 919) // additive
ld->blendmode = AST_ADD;
if (ld->special >= 920 && ld->special <= 929) // subtractive
ld->blendmode = AST_SUBTRACT;
if (ld->special >= 930 && ld->special <= 939) // reverse subtractive
ld->blendmode = AST_REVERSESUBTRACT;
if (ld->special == 940) // modulate
ld->blendmode = AST_MODULATE;
}
}
@@ -1614,10 +1460,8 @@ static void P_LoadRawSideDefs2(void *data)
if (msd->toptexture[0] == '#')
{
char *col = msd->toptexture;
sd->toptexture =
((col[1]-'0')*100 + (col[2]-'0')*10 + col[3]-'0')+1;
if (col[4]) // extra num for blendmode
sd->toptexture += (col[4]-'0')*1000;
sd->toptexture = sd->bottomtexture =
((col[1]-'0')*100 + (col[2]-'0')*10 + col[3]-'0') + 1;
sd->midtexture = R_TextureNumForName(msd->midtexture);
}
else
@@ -2247,13 +2091,7 @@ static void P_LevelInitStuff(boolean reloadinggamestate)
players[i].lives = 1; // SRB2Kart
players[i].realtime = racecountdown = exitcountdown = 0;
for (INT32 j = 0; j < LAP__MAX; j++)
{
players[i].laptime[j] = 0;
}
players[i].driftsparkGrowTimer = 0;
curlap = bestlap = 0; // SRB2Kart
players[i].gotcontinue = false;
@@ -2599,7 +2437,7 @@ static void P_SetupCamera(UINT8 pnum, camera_t *cam)
cam->y = players[pnum].mo->y;
cam->z = players[pnum].mo->z;
cam->angle = players[pnum].mo->angle;
cam->subsector = R_PointInSubsector(cam->x, cam->y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18)
cam->subsector = R_PointInSubsectorFast(cam->x, cam->y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18)
}
else
{
@@ -2624,7 +2462,7 @@ static void P_SetupCamera(UINT8 pnum, camera_t *cam)
cam->y = thing->y;
cam->z = thing->z;
cam->angle = FixedAngle((fixed_t)thing->angle << FRACBITS);
cam->subsector = R_PointInSubsector(cam->x, cam->y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18)
cam->subsector = R_PointInSubsectorFast(cam->x, cam->y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18)
}
cam->chase = false; // tell camera to reset its position next tic
@@ -2634,25 +2472,25 @@ static void P_InitCamera(void)
{
INT32 i;
if (dedicated)
return;
for (i = 0; i <= splitscreen; i++)
if (!dedicated)
{
if (camera[i].freecam)
continue;
for (i = 0; i <= splitscreen; i++)
{
if (camera[i].freecam)
continue;
P_SetupCamera(displayplayers[i], &camera[i]);
P_SetupCamera(displayplayers[i], &camera[i]);
}
// Though, I don't think anyone would care about cam_rotate being reset back to the only value that makes sense :P
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
if (!cv_cam_rotate[i].changed)
CV_Set(&cv_cam_rotate[i], cv_cam_rotate[i].defaultvalue);
}
displayplayers[0] = consoleplayer; // Start with your OWN view, please!
}
// Though, I don't think anyone would care about cam_rotate being reset back to the only value that makes sense :P
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
if (!cv_cam_rotate[i].changed)
CV_Set(&cv_cam_rotate[i], cv_cam_rotate[i].defaultvalue);
}
displayplayers[0] = consoleplayer; // Start with your OWN view, please!
}
static boolean P_CanSave(void)
@@ -2663,7 +2501,7 @@ static boolean P_CanSave(void)
struct minimapinfo minimapinfo;
static void P_InitMinimapInfo(void)
{
lumpnum_t lumpnum;
INT32 lumpnum;
fixed_t a;
fixed_t b;
node_t *bsp = &nodes[numnodes-1];
@@ -2672,9 +2510,11 @@ static void P_InitMinimapInfo(void)
lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap)));
if (lumpnum != LUMPERROR)
if (lumpnum != -1)
minimapinfo.minimap_pic = W_CachePatchName(va("%sR", G_BuildMapName(gamemap)), PU_HUDGFX);
minimapinfo.mapthingcount = 0;
// TODO iterate over mapthings to look for possible user-defined bounds
minimapinfo.min_x = bsp->bbox[0][BOXLEFT];
minimapinfo.max_x = bsp->bbox[0][BOXRIGHT];
minimapinfo.min_y = bsp->bbox[0][BOXBOTTOM];
@@ -2723,8 +2563,72 @@ static void P_InitMinimapInfo(void)
minimapinfo.offs_y = FixedMul((minimapinfo.min_y + minimapinfo.map_h/2) << FRACBITS, minimapinfo.zoom);
}
static boolean P_RunSpecialWipe(boolean reloadinggamestate)
/** Loads a level from a lump or external wad.
*
* \param skipprecip If true, don't spawn precipitation.
* \todo Clean up, refactor, split up; get rid of the bloat.
*/
boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate)
{
// use gamemap to get map number.
// 99% of the things already did, so.
// Map header should always be in place at this point
INT32 i, loadprecip = 1, ranspecialwipe = 0;
INT32 loademblems = 1;
INT32 fromnetsave = 0;
midgamejoin = 0;
sector_t *ss;
boolean chase;
levelloading = true;
// This is needed. Don't touch.
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
CON_Drawer(); // let the user know what we are going to do
I_FinishUpdate(); // page flip or blit buffer
// Initialize sector node list.
P_Initsecnode();
if (netgame || multiplayer)
cv_debug = botskin = 0;
if (metalplayback)
G_StopMetalDemo();
// Clear CECHO messages
HU_ClearCEcho();
if (mapheaderinfo[gamemap-1]->runsoc[0] != '#')
P_RunSOC(mapheaderinfo[gamemap-1]->runsoc);
if (cv_runscripts.value && mapheaderinfo[gamemap-1]->scriptname[0] != '#')
P_RunLevelScript(mapheaderinfo[gamemap-1]->scriptname);
P_LevelInitStuff(reloadinggamestate);
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'
&& atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255)
P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter);
// chasecam on in chaos, race, coop
// chasecam off in match, tag, capture the flag
chase = true; // srb2kart: always on
if (!dedicated)
{
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
if (!cv_chasecam[i].changed)
CV_SetValue(&cv_chasecam[i], chase);
}
}
// Initial height of PointOfView
// will be set by player think.
players[consoleplayer].viewz = 1;
// Cancel all d_main.c fadeouts (keep fade in though).
if (reloadinggamestate)
wipegamestate = gamestate; // Don't fade if reloading the gamestate
@@ -2757,7 +2661,7 @@ static boolean P_RunSpecialWipe(boolean reloadinggamestate)
F_RunWipe(wipedefs[wipe_speclevel_towhite], false);
F_RunWipe(wipedefs[wipe_level_final], false);
}
locstarttime = nowtime = lastwipetic;
endtime = locstarttime + (3*TICRATE)/2;
@@ -2778,15 +2682,162 @@ static boolean P_RunSpecialWipe(boolean reloadinggamestate)
NetKeepAlive();
}
return true;
ranspecialwipe = 1;
}
return false;
}
// Make sure all sounds are stopped before Z_FreeTags.
S_StopSounds();
static void P_SetupPlayer(void)
{
INT32 i;
if (!S_PrecacheSound())
S_ClearSfx();
// As oddly named as this is, this handles music only.
// We should be fine starting it here.
if (!reloadinggamestate)
S_InitMapMusic();
levelfadecol = (encoremode && !ranspecialwipe ? 122 : 120);
// Let's fade to white here
// But only if we didn't do the encore startup wipe
if (!ranspecialwipe && !demo.rewinding && !reloadinggamestate)
{
if (rendermode != render_none)
{
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
F_WipeEndScreen();
F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false);
}
else //dedicated servers
{
F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false);
}
}
// Reset the palette now all fades have been done
if (rendermode != render_none)
V_SetPaletteLump(GetPalette()); // Set the level palette
// Print "SPEEDING OFF TO [ZONE] [ACT 1]..."
/*if (rendermode != render_none)
{
// Don't include these in the fade!
char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl,
(strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->zonttl) : // SRB2kart
((mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " Zone"),
(strlen(mapheaderinfo[gamemap-1]->actnum) > 0) ? va(", Act %s",mapheaderinfo[gamemap-1]->actnum) : "");
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
I_UpdateNoVsync();
}*/
LUA_InvalidateLevel();
for (ss = sectors; sectors+numsectors != ss; ss++)
{
Z_Free(ss->attached);
Z_Free(ss->attachedsolid);
}
// Clear pointers that would be left dangling by the purge
R_FlushTranslationColormapCache();
Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1);
#if defined (WALLSPLATS) || defined (FLOORSPLATS)
// clear the splats from previous level
R_ClearLevelSplats();
#endif
mobjcache = NULL;
R_InitializeLevelInterpolators();
P_InitThinkers();
R_InitMobjInterpolators();
P_InitCachedActions();
/// \note for not spawning precipitation, etc. when loading netgame snapshots
if (skipprecip)
{
fromnetsave = 1;
loadprecip = 0;
loademblems = 0;
midgamejoin = 1;
}
// internal game map
maplumpname = G_BuildMapName(gamemap);
lastloadedmaplumpnum = W_CheckNumForName(maplumpname);
if (lastloadedmaplumpnum == INT16_MAX)
I_Error("Map %s not found.\n", maplumpname);
curmapvirt = vres_GetMap(lastloadedmaplumpnum);
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette,
(encoremode ? W_CheckNumForName(va("%sE", maplumpname)) : LUMPERROR));
CON_SetupBackColormap();
// SRB2 determines the sky texture to be used depending on the map header.
P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true);
numdmstarts = numredctfstarts = numbluectfstarts = 0;
// reset the player starts
for (i = 0; i < MAXPLAYERS; i++)
playerstarts[i] = NULL;
for (i = 0; i < 2; i++)
skyboxmo[i] = NULL;
P_ResetWaypoints();
P_MapStart();
if (lastloadedmaplumpnum)
P_LoadMapFromFile();
P_ResetDynamicSlopes();
P_LoadThings();
P_SpawnSecretItems(loademblems);
P_InitMinimapInfo();
for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++)
if (!playerstarts[numcoopstarts])
break;
globalweather = mapheaderinfo[gamemap-1]->weather;
// set up world state
P_SpawnSpecials(fromnetsave, reloadinggamestate);
if (loadprecip) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame)
P_SpawnPrecipitation();
#ifdef HWRENDER // not win32 only 19990829 by Kin
if (rendermode == render_opengl)
{
HWR_FreeExtraSubsectors();
// stuff like HWR_CreatePlanePolygons is called there
HWR_LoadLevel();
}
#endif
// oh god I hope this helps
// (addendum: apparently it does!
// none of this needs to be done because it's not the beginning of the map when
// a netgame save is being loaded, and could actively be harmful by messing with
// the client's view of the data.)
if (fromnetsave)
goto netgameskip;
// ==========
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
@@ -2837,7 +2888,7 @@ static void P_SetupPlayer(void)
}
}
if (realnumplayers) // this should also fix the dedicated crash bug. You only pick a player if one exists to be picked.
if (realnumplayers) //this should also fix the dedicated crash bug. You only pick a player if one exists to be picked.
{
i = P_RandomKey(realnumplayers);
players[playersactive[i]].pflags |= PF_TAGIT; //choose our initial tagger before map starts.
@@ -2906,213 +2957,10 @@ static void P_SetupPlayer(void)
startedInFreePlay = true;
}
}
}
/** Loads a level from a lump or external wad.
*
* \param fromnetsave If true, skip some stuff because we're loading a netgame snapshot.
* \todo Clean up, refactor, split up; get rid of the bloat.
*/
boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
{
// use gamemap to get map number.
// 99% of the things already did, so.
// Map header should always be in place at this point
INT32 i;
boolean ranspecialwipe = false;
sector_t *ss;
midgamejoin = fromnetsave; // makes dynslopes run in P_Ticker/P_PreTicker to avoid synch issues and other stuff
levelloading = true;
// This is needed. Don't touch.
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
CON_Drawer(); // let the user know what we are going to do
I_FinishUpdate(); // page flip or blit buffer
// Initialize sector node list.
P_Initsecnode();
if (netgame || multiplayer)
cv_debug = botskin = 0;
if (metalplayback)
G_StopMetalDemo();
// Clear CECHO messages
HU_ClearCEcho();
if (mapheaderinfo[gamemap-1]->runsoc[0] != '#')
P_RunSOC(mapheaderinfo[gamemap-1]->runsoc);
if (cv_runscripts.value && mapheaderinfo[gamemap-1]->scriptname[0] != '#')
P_RunLevelScript(mapheaderinfo[gamemap-1]->scriptname);
P_LevelInitStuff(reloadinggamestate);
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'
&& atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255)
P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter);
if (!dedicated)
{
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
if (!cv_chasecam[i].changed)
CV_SetValue(&cv_chasecam[i], true); // srb2kart: always on
}
}
// Initial height of PointOfView
// will be set by player think.
players[consoleplayer].viewz = 1;
ranspecialwipe = P_RunSpecialWipe(reloadinggamestate);
// Make sure all sounds are stopped before Z_FreeTags.
S_StopSounds();
if (!S_PrecacheSound())
S_ClearSfx();
// As oddly named as this is, this handles music only.
// We should be fine starting it here.
if (!reloadinggamestate)
S_InitMapMusic();
levelfadecol = (encoremode && !ranspecialwipe ? 122 : 120);
// Let's fade to white here
// But only if we didn't do the encore startup wipe
if (!ranspecialwipe && !demo.rewinding && !reloadinggamestate)
{
if (rendermode != render_none)
{
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
F_WipeEndScreen();
F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false);
}
else //dedicated servers
{
F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false);
}
}
// Reset the palette now all fades have been done
if (rendermode != render_none)
V_SetPaletteLump(GetPalette()); // Set the level palette
// Print "SPEEDING OFF TO [ZONE] [ACT 1]..."
/*if (rendermode != render_none)
{
// Don't include these in the fade!
char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl,
(strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->zonttl) : // SRB2kart
((mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " Zone"),
(strlen(mapheaderinfo[gamemap-1]->actnum) > 0) ? va(", Act %s",mapheaderinfo[gamemap-1]->actnum) : "");
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
I_UpdateNoVsync();
}*/
LUA_InvalidateLevel();
for (ss = sectors; sectors+numsectors != ss; ss++)
{
Z_Free(ss->attached);
Z_Free(ss->attachedsolid);
}
// Clear pointers that would be left dangling by the purge
R_FlushTranslationColormapCache();
Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1);
#if defined (WALLSPLATS) || defined (FLOORSPLATS)
// clear the splats from previous level
R_ClearLevelSplats();
#endif
mobjcache = NULL;
R_InitializeLevelInterpolators();
P_InitThinkers();
R_InitMobjInterpolators();
P_InitCachedActions();
// internal game map
maplumpname = G_BuildMapName(gamemap);
lastloadedmaplumpnum = W_CheckNumForName(maplumpname);
if (lastloadedmaplumpnum == INT16_MAX)
I_Error("Map %s not found.\n", maplumpname);
curmapvirt = vres_GetMap(lastloadedmaplumpnum);
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette,
(encoremode ? W_CheckNumForName(va("%sE", maplumpname)) : LUMPERROR));
CON_SetupBackColormap();
// SRB2 determines the sky texture to be used depending on the map header.
P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true);
numdmstarts = numredctfstarts = numbluectfstarts = 0;
// reset the player starts
for (i = 0; i < MAXPLAYERS; i++)
playerstarts[i] = NULL;
for (i = 0; i < 2; i++)
skyboxmo[i] = NULL;
P_ResetWaypoints();
P_MapStart();
if (lastloadedmaplumpnum)
P_LoadMapFromFile();
P_ResetDynamicSlopes();
P_LoadThings();
P_SpawnSecretItems(!fromnetsave);
P_InitMinimapInfo();
for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++)
if (!playerstarts[numcoopstarts])
break;
globalweather = mapheaderinfo[gamemap-1]->weather;
// set up world state
P_SpawnSpecials(fromnetsave, reloadinggamestate);
if (!fromnetsave) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame)
P_SpawnPrecipitation();
#ifdef HWRENDER // not win32 only 19990829 by Kin
if (rendermode == render_opengl)
{
HWR_FreeExtraSubsectors();
// stuff like HWR_CreatePlanePolygons is called there
HWR_LoadLevel();
}
#endif
// oh god I hope this helps
// (addendum: apparently it does!
// none of this needs to be done because it's not the beginning of the map when
// a netgame save is being loaded, and could actively be harmful by messing with
// the client's view of the data.)
if (!fromnetsave)
P_SetupPlayer();
// ===========
// landing point for netgames.
netgameskip:
if (!reloadinggamestate)
{
@@ -3162,7 +3010,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
skyVisible = true;
memset(skyVisiblePerPlayer, true, sizeof(skyVisiblePerPlayer));
if (!fromnetsave) // uglier hack
if (loadprecip) // uglier hack
{ // to make a newly loaded level start on the second frame.
INT32 buf = gametic % TICQUEUE;
for (i = 0; i < MAXPLAYERS; i++)
@@ -3234,12 +3082,6 @@ boolean P_AddWadFileLocal(const char *wadfilename)
return true;
}
// check for replacement votescreen backgrounds
boolean wideracereplaced = false;
boolean racereplaced = false;
boolean widebattlereplaced = false;
boolean battlereplaced = false;
//
// Add a WAD file and do the per-WAD setup stages.
// Call P_MultiSetupWadFiles as soon as possible after any number of these.
@@ -3364,41 +3206,6 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
// TODO: Experimental SPRTINFO support, test first
R_LoadSpriteInfoLumps(wadnum, wadfiles[wadnum]->numlumps);
//
// check for votescreen replacements
//
lumpinfo = wadfiles[wadnum]->lumpinfo;
for (i = 0; i < numlumps; i++, lumpinfo++)
{
name = lumpinfo->name;
// widescreen patch Race
if (!wideracereplaced && !strncmp(name, "INTERSCW", 8))
{
wideracereplaced = true;
continue;
}
if (!racereplaced && !strncmp(name, "INTERSCR", 8))
{
racereplaced = true;
continue;
}
// widescreen patch Battle
if (!widebattlereplaced && !strncmp(name, "BATTLSCW", 8))
{
widebattlereplaced = true;
continue;
}
if (!battlereplaced && !strncmp(name, "BATTLSCR", 8))
{
battlereplaced = true;
continue;
}
}
refreshdirmenu &= ~REFRESHDIR_GAMEDATA; // Under usual circumstances we'd wait for REFRESHDIR_GAMEDATA to disappear the next frame, but it's a bit too dangerous for that...
partadd_stage = 0;
return wadnum;
@@ -3428,10 +3235,6 @@ boolean P_MultiSetupWadFiles(boolean fullsetup)
ST_LoadGraphics();
ST_ReloadSkinFaceGraphics();
// reload minimap stuff while were in the map since it may get replaced otherwise
if (gamestate == GS_LEVEL)
P_InitMinimapInfo();
if (!partadd_important)
partadd_stage = -1; // everything done
else if (fullsetup)
+3 -15
View File
@@ -19,12 +19,11 @@
#include "r_defs.h"
#include "w_wad.h"
extern SINT8 midgamejoin;
// map md5, sent to players via PT_SERVERINFO
extern unsigned char mapmd5[16];
// true when level was loaded from netsave
extern boolean midgamejoin;
// Player spawn spots for deathmatch.
#define MAX_DM_STARTS 64
extern mapthing_t *deathmatchstarts[MAX_DM_STARTS];
@@ -61,18 +60,13 @@ extern mapthing_t *mapthings;
void P_SetupLevelSky(INT32 skynum, boolean global);
void P_LoadThingsOnly(void);
boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate);
boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate);
#ifdef HWRENDER
void HWR_LoadLevel(void);
#endif
boolean P_AddWadFile(const char *wadfilename, boolean local);
boolean P_AddWadFileLocal(const char *wadfilename);
extern boolean wideracereplaced;
extern boolean racereplaced;
extern boolean widebattlereplaced;
extern boolean battlereplaced;
// WARNING: The following functions should be grouped as follows:
// any amount of PartialAdds followed by MultiSetups until returned true,
// as soon as possible.
@@ -99,14 +93,8 @@ void P_WriteThings(lumpnum_t lump);
fixed_t P_SegLength(seg_t *seg);
#endif
extern boolean reinitmaplight;
void P_UpdateSegLightOffset(seg_t *li);
boolean P_ApplyLightOffset(UINT8 baselightnum, const sector_t *sector);
boolean P_ApplyLightOffsetFine(UINT8 baselightlevel, const sector_t *sector);
boolean P_SectorUsesDirectionalLighting(const sector_t *sector);
size_t P_PrecacheLevelFlats(void);
void P_AllocMapHeader(INT16 i);
// Needed for NiGHTS
+22 -8
View File
@@ -42,16 +42,15 @@ static INT32 sightcounts[2];
static INT32 P_DivlineSide(fixed_t x, fixed_t y, const divline_t *node)
{
fixed_t left, right;
return(
return
!node->dx ? x == node->x ? 2 : x <= node->x ? node->dy > 0 : node->dy < 0 :
!node->dy ? y == node->y ? 2 : y <= node->y ? node->dx < 0 : node->dx > 0 :
(right = ((y - node->y) >> FRACBITS) * (node->dx >> FRACBITS)) <
(left = ((x - node->x) >> FRACBITS) * (node->dy >> FRACBITS)) ? 0 :
right == left ? 2 : 1);
right == left ? 2 : 1;
}
static inline INT32 P_DivlineCrossed(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, const divline_t *node)
static INT32 P_DivlineCrossed(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, const divline_t *node)
{
return (P_DivlineSide(x1, y1, node) == P_DivlineSide(x2, y2, node));
}
@@ -101,6 +100,10 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
if (P_DivlineCrossed(los->strace.x, los->strace.y, los->t2x, los->t2y, &divl))
continue;
// stop because it is not two sided
//if (!(po->flags & POF_TESTHEIGHT))
//return false;
frac = P_InterceptVector(&los->strace, &divl);
// get slopes of top and bottom of this polyobject line
@@ -109,11 +112,17 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
if (topslope >= los->topslope && bottomslope <= los->bottomslope)
return false; // view completely blocked
// TODO: figure out if it's worth considering partially blocked cases or not?
// maybe to adjust los's top/bottom slopes if needed
//if (los->topslope <= los->bottomslope)
//return false;
}
return true;
}
//
// P_CrossSubsector
//
@@ -296,19 +305,24 @@ static boolean P_CrossBSPNode(INT32 bspnum, register los_t *los, boolean fast)
{
register node_t *bsp = nodes + bspnum;
INT32 side = (fast ? R_PointOnSideFast(los->strace.x, los->strace.y, bsp) : (P_DivlineSide(los->strace.x, los->strace.y, (divline_t *)bsp) & 1));
INT32 side = (fast ? R_PointOnSideFast(los->strace.x, los->strace.y, bsp) : (P_DivlineSide(los->strace.x,los->strace.y, (divline_t *)bsp) & 1));
INT32 side2 = (fast ? R_PointOnSideFast(los->t2x, los->t2y, bsp) : P_DivlineSide(los->t2x, los->t2y, (divline_t *) bsp));
if (side == side2)
{
bspnum = bsp->children[side]; // doesn't touch the other side
}
else // the partition plane is crossed here
else
{
// the partition plane is crossed here
if (!P_CrossBSPNode(bsp->children[side], los, fast))
{
return false; // cross the starting side
bspnum = bsp->children[side^1]; // cross the ending side
}
else
{
bspnum = bsp->children[side^1]; // cross the ending side
}
}
}
+8 -40
View File
@@ -24,20 +24,20 @@
#include "w_wad.h"
pslope_t *slopelist = NULL;
static pslope_t *slopelist = NULL;
static UINT16 slopecount = 0;
// Calculate light
static void P_UpdateSlopeLightOffset(pslope_t *slope)
{
const UINT8 contrast = maplighting.contrast;
const boolean ceiling = (slope->normal.z < 0);
const UINT8 contrast = 8;
fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT;
fixed_t zMul = FRACUNIT;
fixed_t light = FRACUNIT;
angle_t slopeDir = ANGLE_MAX;
fixed_t extralight = 0;
if (slope->normal.z == 0)
{
slope->lightOffset = 0;
@@ -47,47 +47,15 @@ static void P_UpdateSlopeLightOffset(pslope_t *slope)
return;
}
if (maplighting.directional == true)
slopeDir = R_PointToAngle2(0, 0, abs(slope->normal.y), abs(slope->normal.x));
if (ceiling == true)
{
fixed_t nX = -slope->normal.x;
fixed_t nY = -slope->normal.y;
fixed_t nLen = FixedHypot(nX, nY);
if (nLen == 0)
{
slope->lightOffset = 0;
#ifdef HWRENDER
slope->hwLightOffset = 0;
#endif
return;
}
nX = FixedDiv(nX, nLen);
nY = FixedDiv(nY, nLen);
/*
* if (slope is ceiling)
* {
* // There is no good way to calculate this condition here.
* // We reverse it in R_FindPlane now.
* nX = -nX;
* nY = -nY;
}
*/
light = FixedMul(nX, FINECOSINE(maplighting.angle >> ANGLETOFINESHIFT))
+ FixedMul(nY, FINESINE(maplighting.angle >> ANGLETOFINESHIFT));
light = (light + FRACUNIT) / 2;
}
else
{
light = FixedDiv(R_PointToAngle2(0, 0, abs(slope->d.x), abs(slope->d.y)), ANGLE_90);
slopeDir ^= ANGLE_180;
}
zMul = min(FRACUNIT, abs(slope->zdelta)*3/2); // *3/2, to make 60 degree slopes match walls.
contrastFixed = FixedMul(contrastFixed, zMul);
extralight = -contrastFixed + FixedMul(light, contrastFixed * 2);
extralight = -contrastFixed + FixedMul(FixedDiv(AngleFixed(slopeDir), ANGLE_90), (contrastFixed * 2));
// Between -2 and 2 for software, -8 and 8 for hardware
slope->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT;
-2
View File
@@ -33,8 +33,6 @@ void P_CopySectorSlope(line_t *line);
pslope_t *P_SlopeById(UINT16 id);
extern pslope_t *slopelist;
//
// P_GetZAt
//
+145 -104
View File
@@ -40,6 +40,10 @@
#include "k_kart.h" // SRB2kart
#include "console.h" // CON_LogMessage
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
#endif
// Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog
#include <errno.h>
@@ -1427,14 +1431,14 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
}
else if (caller)
{
const INT32 secspecial = GETSECSPECIAL(caller->special, 2);
INT32 special = GETSECSPECIAL(caller->special, 2);
if (secspecial == 6)
if (special == 6)
{
if (!(ALL7EMERALDS(emeralds)))
return false;
}
else if (secspecial == 7) // SRB2Kart: reusing for Race Lap executor
else if (special == 7) // SRB2Kart: reusing for Race Lap executor
{
UINT8 lap;
@@ -1468,7 +1472,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
// If we were not triggered by a sector type especially for the purpose,
// a Linedef Executor linedef trigger is not handling sector triggers properly, return.
else if ((!secspecial || secspecial > 7) && (specialtype > 322))
else if ((!special || special > 7) && (specialtype > 322))
{
CONS_Alert(CONS_WARNING,
M_GetText("Linedef executor trigger isn't handling sector triggers properly!\nspecialtype = %d, if you are not a dev, report this warning instance\nalong with the wad that caused it!\n"),
@@ -1718,22 +1722,6 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller)
}
}
static boolean is_rain_type (INT32 weathernum)
{
switch (weathernum)
{
case PRECIP_SNOW:
case PRECIP_RAIN:
case PRECIP_STORM:
case PRECIP_STORM_NOSTRIKES:
case PRECIP_BLANK:
return true;
default:
return false;
}
}
//
// P_SwitchWeather
//
@@ -1741,14 +1729,53 @@ static boolean is_rain_type (INT32 weathernum)
//
void P_SwitchWeather(INT32 weathernum)
{
boolean purge = true;
boolean purge = false;
INT32 swap = 0;
if (weathernum == curWeather)
return;
if (is_rain_type(weathernum) &&
is_rain_type(curWeather))
purge = false;
switch (weathernum)
{
case PRECIP_NONE: // None
if (curWeather == PRECIP_NONE)
return; // Nothing to do.
purge = true;
break;
case PRECIP_STORM: // Storm
case PRECIP_STORM_NOSTRIKES: // Storm w/ no lightning
case PRECIP_RAIN: // Rain
if (curWeather == PRECIP_SNOW || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN)
swap = PRECIP_RAIN;
break;
case PRECIP_SNOW: // Snow
if (curWeather == PRECIP_SNOW)
return; // Nothing to do.
if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN)
swap = PRECIP_SNOW; // Need to delete the other precips.
break;
case PRECIP_STORM_NORAIN: // Storm w/o rain
if (curWeather == PRECIP_SNOW
|| curWeather == PRECIP_STORM
|| curWeather == PRECIP_STORM_NOSTRIKES
|| curWeather == PRECIP_RAIN
|| curWeather == PRECIP_BLANK)
swap = PRECIP_STORM_NORAIN;
else if (curWeather == PRECIP_STORM_NORAIN)
return;
break;
case PRECIP_BLANK:
if (curWeather == PRECIP_SNOW
|| curWeather == PRECIP_STORM
|| curWeather == PRECIP_STORM_NOSTRIKES
|| curWeather == PRECIP_RAIN)
swap = PRECIP_BLANK;
else if (curWeather == PRECIP_STORM_NORAIN)
swap = PRECIP_BLANK;
else if (curWeather == PRECIP_BLANK)
return;
break;
default:
CONS_Debug(DBG_GAMELOGIC, "P_SwitchWeather: Unknown weather type %d.\n", weathernum);
break;
}
if (purge)
{
@@ -1756,47 +1783,44 @@ void P_SwitchWeather(INT32 weathernum)
thinker_t *next;
precipmobj_t *precipmobj;
for (think = precipcap.next; think != &precipcap; think = next)
for (think = thinkercap.next; think != &thinkercap; think = next)
{
next = think->next;
#ifdef PARANOIA
if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
continue; // not a precipmobj thinker
#endif
precipmobj = (precipmobj_t *)think;
P_FreePrecipMobj(precipmobj);
}
}
else // Rather than respawn all that crap, reuse it!
else if (swap && !((swap == PRECIP_BLANK && curWeather == PRECIP_STORM_NORAIN) || (swap == PRECIP_STORM_NORAIN && curWeather == PRECIP_BLANK))) // Rather than respawn all that crap, reuse it!
{
thinker_t *think;
precipmobj_t *precipmobj;
state_t *st;
for (think = precipcap.next; think != &precipcap; think = think->next)
for (think = thinkercap.next; think != &thinkercap; think = think->next)
{
#ifdef PARANOIA
if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
continue; // not a precipmobj thinker
#endif
precipmobj = (precipmobj_t *)think;
mobjtype_t type = 0;
INT32 z = 0;
mobjtype_t type = MT_NULL;
if (weathernum == PRECIP_NONE || weathernum == PRECIP_BLANK || weathernum == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse.
if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse.
{
precipmobj->precipflags |= PCF_INVISIBLE;
continue;
}
else if (weathernum == PRECIP_RAIN || weathernum == PRECIP_STORM || weathernum == PRECIP_STORM_NOSTRIKES) // Snow To Rain
if (swap == PRECIP_RAIN) // Snow To Rain
{
type = MT_RAIN;
}
else if (weathernum == PRECIP_SNOW) // Rain To Snow
else if (swap == PRECIP_SNOW) // Rain To Snow
{
type = MT_SNOWFLAKE;
@@ -1826,45 +1850,50 @@ void P_SwitchWeather(INT32 weathernum)
}
}
boolean spawnprecip = false;
boolean dontspawn = false;
switch (weathernum)
{
case PRECIP_SNOW: // snow
curWeather = PRECIP_SNOW;
spawnprecip = true;
break;
break;
case PRECIP_RAIN: // rain
{
if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES)
dontspawn = true;
curWeather = PRECIP_RAIN;
spawnprecip = true;
break;
}
case PRECIP_STORM: // storm
{
if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES)
dontspawn = true;
curWeather = PRECIP_STORM;
spawnprecip = true;
break;
}
case PRECIP_STORM_NOSTRIKES: // storm w/o lightning
{
if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES)
dontspawn = true;
curWeather = PRECIP_STORM_NOSTRIKES;
spawnprecip = true;
break;
}
case PRECIP_STORM_NORAIN: // storm w/o rain
curWeather = PRECIP_STORM_NORAIN;
break;
case PRECIP_BLANK: //preloaded
case PRECIP_BLANK:
curWeather = PRECIP_BLANK;
spawnprecip = true;
break;
break;
default:
dontspawn = true;
curWeather = PRECIP_NONE;
break;
}
if (spawnprecip && purge)
if (!dontspawn && !swap)
P_SpawnPrecipitation();
}
@@ -2080,7 +2109,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
break;
case 413: // Change music
if (keepmapmusic && (leveltime <= MUSICSTARTTIME)) // why check for starttime? cause encore music Zzz...
if (keepmusic && (leveltime <= MUSICSTARTTIME)) //why check for starttime? cause encore music Zzz...
return;
//if (cv_ignoremusicchanges.value && (leveltime >= MUSICSTARTTIME) && !fromlapexec) // keep lap music intanct tho
@@ -2128,19 +2157,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
// Change the music and apply position/fade operations
else
{
strncpy(mapmusic.name, sides[line->sidenum[0]].text, 7);
mapmusic.name[6] = 0;
strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
mapmusname[6] = 0;
mapmusic.flags = tracknum & MUSIC_TRACKMASK;
mapmusflags = tracknum & MUSIC_TRACKMASK;
if (!(line->flags & ML_BLOCKMONSTERS))
mapmusic.flags |= MUSIC_RELOADRESET;
mapmusflags |= MUSIC_RELOADRESET;
if (line->flags & ML_BOUNCY)
mapmusic.flags |= MUSIC_FORCERESET;
mapmusflags |= MUSIC_FORCERESET;
mapmusic.position = position;
mapmusic.resume = 0;
mapmusposition = position;
mapmusresume = 0;
S_ChangeMusicEx(mapmusic.name, mapmusic.flags, !(line->flags & ML_EFFECT4), position,
S_ChangeMusicEx(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4), position,
!(line->flags & ML_EFFECT2) ? prefadems : 0,
!(line->flags & ML_EFFECT2) ? postfadems : 0);
@@ -2167,7 +2196,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
INT32 sfxnum;
//dont play any funky sound intros that may interfere with the music
if ((skipintromus || keepmapmusic) && (leveltime < MUSICSTARTTIME))
if (skipintromus && (leveltime < MUSICSTARTTIME))
return;
sfxnum = sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS;
@@ -3310,10 +3339,10 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
case 6: // Death Pit (Camera Tilt)
case 7: // Death Pit (No Camera Tilt)
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
P_DamageMobj(player->mo, NULL, NULL, DMG_INSTAKILL);
P_DamageMobj(player->mo, NULL, NULL, 10000);
break;
case 8: // Instant Kill
P_DamageMobj(player->mo, NULL, NULL, DMG_INSTAKILL);
P_DamageMobj(player->mo, NULL, NULL, 10000);
break;
case 9: // Ring Drainer (Floor Touch)
case 10: // Ring Drainer (No Floor Touch)
@@ -3561,15 +3590,14 @@ DoneSection2:
if (!demo.playback || P_AnalogMove(player))
{
for (UINT8 j = 0; j <= splitscreen; ++j)
{
INT32 id = (j == 0 ? consoleplayer : displayplayers[j]);
if (player == &players[id])
{
localangle[j] = player->mo->angle;
break;
}
}
if (player == &players[consoleplayer])
localangle[0] = player->mo->angle;
else if (player == &players[displayplayers[1]])
localangle[1] = player->mo->angle;
else if (player == &players[displayplayers[2]])
localangle[2] = player->mo->angle;
else if (player == &players[displayplayers[3]])
localangle[3] = player->mo->angle;
}
if (!(lines[i].flags & ML_EFFECT4))
@@ -3913,13 +3941,17 @@ DoneSection2:
CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players]));
// SRB2Kart: save best lap for record attack
if (player->laptime[LAP_CUR] < player->laptime[LAP_BEST] || player->laptime[LAP_BEST] == 0)
if (player == &players[consoleplayer])
{
player->laptime[LAP_BEST] = player->laptime[LAP_CUR];
if (curlap < bestlap || bestlap == 0)
bestlap = curlap;
curlap = 0;
}
// ONLY FOR HUD
player->laptime[LAP_LAST] = player->laptime[LAP_CUR];
player->laptime[LAP_CUR] = 0;
//
player->starposttime = player->realtime;
player->starpostnum = 0;
@@ -4751,34 +4783,16 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
else th = th->next;
}
if (flags & FF_TRANSLUCENT)
{
if (sides[master->sidenum[0]].toptexture > 0)
{
// for future reference, "#0" is 1, and "#255" is 256. Be warned
ffloor->alpha = sides[master->sidenum[0]].toptexture;
if (ffloor->alpha >= 1001) // fourth digit
{
ffloor->blend = (ffloor->alpha/1000)+1; // becomes an AST
ffloor->alpha %= 1000;
}
else
{
ffloor->blend = 0;
}
}
ffloor->alpha = sides[master->sidenum[0]].toptexture; // for future reference, "#0" is 1, and "#255" is 256. Be warned
else
{
ffloor->alpha = 0x80;
ffloor->blend = 0;
}
}
else
{
ffloor->alpha = 0xff;
ffloor->blend = 0;
}
ffloor->spawnalpha = ffloor->alpha; // save for netgames
@@ -5288,8 +5302,20 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
}
}
// set current weather
curWeather = mapheaderinfo[gamemap-1]->weather;
if (mapheaderinfo[gamemap-1]->weather == 2) // snow
curWeather = PRECIP_SNOW;
else if (mapheaderinfo[gamemap-1]->weather == 3) // rain
curWeather = PRECIP_RAIN;
else if (mapheaderinfo[gamemap-1]->weather == 1) // storm
curWeather = PRECIP_STORM;
else if (mapheaderinfo[gamemap-1]->weather == 5) // storm w/o rain
curWeather = PRECIP_STORM_NORAIN;
else if (mapheaderinfo[gamemap-1]->weather == 6) // storm w/o lightning
curWeather = PRECIP_STORM_NOSTRIKES;
else if (mapheaderinfo[gamemap-1]->weather == 4) // blank
curWeather = PRECIP_BLANK;
else
curWeather = PRECIP_NONE;
P_InitTagLists(); // Create xref tables for tags
P_SearchForDisableLinedefs(); // Disable linedefs are now allowed to disable *any* line
@@ -7407,18 +7433,33 @@ void T_Pusher(pusher_t *p)
if (!demo.playback || P_AnalogMove(thing->player))
{
for (UINT8 i = 0; i <= splitscreen; ++i)
if (thing->player == &players[consoleplayer])
{
INT32 id = (i == 0 ? consoleplayer : displayplayers[i]);
if (thing->player == &players[id])
{
if (thing->angle - localangle[i] > ANGLE_180)
localangle[i] -= (localangle[i] - thing->angle) / 8;
else
localangle[i] += (thing->angle - localangle[i]) / 8;
break;
}
if (thing->angle - localangle[0] > ANGLE_180)
localangle[0] -= (localangle[0] - thing->angle) / 8;
else
localangle[0] += (thing->angle - localangle[0]) / 8;
}
else if (thing->player == &players[displayplayers[1]])
{
if (thing->angle - localangle[1] > ANGLE_180)
localangle[1] -= (localangle[1] - thing->angle) / 8;
else
localangle[1] += (thing->angle - localangle[1]) / 8;
}
else if (thing->player == &players[displayplayers[2]])
{
if (thing->angle - localangle[2] > ANGLE_180)
localangle[2] -= (localangle[2] - thing->angle) / 8;
else
localangle[2] += (thing->angle - localangle[2]) / 8;
}
else if (thing->player == &players[displayplayers[3]])
{
if (thing->angle - localangle[3] > ANGLE_180)
localangle[3] -= (localangle[3] - thing->angle) / 8;
else
localangle[3] += (thing->angle - localangle[3]) / 8;
}
}
}
+31 -117
View File
@@ -49,7 +49,6 @@ tic_t leveltime;
// Both the head and tail of the thinker list.
thinker_t thinkercap;
thinker_t precipcap;
void Command_Numthinkers_f(void)
{
@@ -57,7 +56,6 @@ void Command_Numthinkers_f(void)
INT32 count = 0;
actionf_p1 action;
thinker_t *think;
thinker_t *listtype;
if (gamestate != GS_LEVEL)
{
@@ -106,9 +104,7 @@ void Command_Numthinkers_f(void)
return;
}
listtype = (num == 2) ? &precipcap : &thinkercap;
for (think = listtype->next; think != listtype; think = think->next)
for (think = thinkercap.next; think != &thinkercap; think = think->next)
{
if (think->function.acp1 != action)
continue;
@@ -185,7 +181,6 @@ void Command_CountMobjs_f(void)
void P_InitThinkers(void)
{
thinkercap.prev = thinkercap.next = &thinkercap;
precipcap.prev = precipcap.next = &precipcap;
waypointcap = NULL;
}
@@ -205,22 +200,6 @@ void P_AddThinker(thinker_t *thinker)
thinker->cachable = (thinker->function.acp1 == (actionf_p1)P_MobjThinker);
}
//
// P_AddPrecipThinker
// Adds a new precip thinker at the end of the list.
//
void P_AddPrecipThinker(thinker_t *thinker)
{
precipcap.prev->next = thinker;
thinker->next = &precipcap;
thinker->prev = precipcap.prev;
precipcap.prev = thinker;
thinker->references = 0; // killough 11/98: init reference counter to 0
thinker->cachable = false;
}
//
// killough 11/98:
//
@@ -362,6 +341,8 @@ static inline void P_RunThinkers(void)
{
for (currentthinker = thinkercap.next; currentthinker != &thinkercap; currentthinker = currentthinker->next)
{
if (currentthinker->function.acp1 == (actionf_p1)P_NullPrecipThinker)
continue;
#ifdef PARANOIA
I_Assert(currentthinker->function.acp1 != NULL)
#endif
@@ -373,32 +354,28 @@ static void P_DeviceRumbleTick(void)
{
UINT8 i;
if (dedicated || numcontrollers == 0 || gamestate != GS_LEVEL)
if (I_NumJoys() == 0 || (cv_rumble[0].value == 0 && cv_rumble[1].value == 0 && cv_rumble[2].value == 0 && cv_rumble[3].value == 0))
{
return;
}
for (i = 0; i <= splitscreen; i++)
{
player_t *player = &players[displayplayers[i]];
UINT16 low = 0;
UINT16 high = 0;
if (!cv_usejoystick[i].value || !cv_rumble[i].value)
{
if (!P_IsLocalPlayer(player))
continue;
}
player_t *player = ((i == 0) ? &players[consoleplayer] : &players[displayplayers[i]]);
if (player->spectator || !player->mo)
{
if (cv_usejoystick[i].value == 0)
continue;
}
if (camera[i].freecam)
{
if (!playeringame[displayplayers[i]] || player->spectator)
continue;
if (player->mo == NULL)
continue;
}
if (player->exiting)
{
@@ -408,48 +385,27 @@ static void P_DeviceRumbleTick(void)
if (player->kartstuff[k_spinouttimer])
{
//low = high = FRACUNIT / 6;
low = high = FixedMul((FRACUNIT / 4), (FixedDiv(player->kartstuff[k_spinouttimer], (3*TICRATE / 2))));
low = high = 65536 / 4;
}
else if (player->kartstuff[k_sneakertimer] > (sneakertime-(TICRATE/2)))
{
low = high = FRACUNIT / 8;
low = high = 65536 / 8;
}
else if ((player->kartstuff[k_offroad])
else if ((player->kartstuff[k_offroad] && !player->kartstuff[k_hyudorotimer])
&& P_IsObjectOnGround(player->mo) && player->speed != 0)
{
if (player->kartstuff[k_hyudorotimer])
{
high = FRACUNIT / 128;
}
else if (player->kartstuff[k_invincibilitytimer])
{
high = FRACUNIT / 64;
}
else
{
low = high = FRACUNIT / 64;
}
low = high = 65536 / 64;
}
else if ((player->kartstuff[k_bananadrag] > TICRATE)
&& P_IsObjectOnGround(player->mo) && player->speed != 0)
else if (player->kartstuff[k_brakedrift])
{
if (leveltime & 1) // this is actually funny lel
high = FRACUNIT / 64;
low = 0;
high = 65536 / 256;
}
if (player->kartstuff[k_brakedrift])
{
high = CLAMP((high + FRACUNIT / 256), 0, UINT16_MAX);
}
// hack alert! i just dont want this thing constantly resetting the rumble lol
if (low == 0 && high == 0)
{
if (low == 0 && high == 0)
continue;
}
G_PlayerDeviceRumble(i, low, high, 57);
G_PlayerDeviceRumble(i, low, high, 57); // hack alert! i just dont want this think constantly resetting the rumble lol
}
}
@@ -460,20 +416,7 @@ void P_RunChaseCameras(void)
for (i = 0; i <= splitscreen; i++)
{
if (camera[i].chase)
{
player_t *p = &players[displayplayers[i]];
camera_t *cam = &camera[i];
if (cv_verticallook.value && leveltime > starttime && p->mo && p->kartstuff[k_respawn] == 0 && p->kartstuff[k_throwdir] != 0)
{
if (p->speed < 6 * p->mo->scale && abs(cam->dpad_y_held) < 2*TICRATE)
cam->dpad_y_held += intsign(p->kartstuff[k_throwdir]);
}
else
cam->dpad_y_held = 0;
P_MoveChaseCamera(p, cam, false);
}
P_MoveChaseCamera(&players[displayplayers[i]], &camera[i], false);
}
}
@@ -507,32 +450,6 @@ static void P_RunQuakes(void)
--quake.time;
}
static inline void P_ResetSpriteStuff(void)
{
thinker_t *th;
if (rendermode == render_none)
return;
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
mobj_t *mo;
if (th->function.acp1 != (actionf_p1)P_MobjThinker) // not a mobj
continue;
mo = (mobj_t *)th;
if (mo->sprite == SPR_NULL || mo->flags2 & MF2_DONTDRAW || mo->type == MT_SHADOW)
continue;
mo->spritexscale = mo->realxscale;
mo->spriteyscale = mo->realyscale;
mo->spritexoffset = mo->realxoffset;
mo->spriteyoffset = mo->realyoffset;
}
}
//
// P_Ticker
//
@@ -633,8 +550,6 @@ void P_Ticker(boolean run)
ps_lua_mobjhooks.value.i = 0;
ps_checkposition_calls.value.i = 0;
P_ResetSpriteStuff();
PS_START_TIMING(ps_lua_prethinkframe_time);
LUA_HookPreThinkFrame();
PS_STOP_TIMING(ps_lua_prethinkframe_time);
@@ -676,7 +591,10 @@ void P_Ticker(boolean run)
PS_STOP_TIMING(ps_lua_thinkframe_time);
}
// Run shield positioning
//P_RunShields();
P_RunOverlays();
P_RunShadows();
P_UpdateSpecials();
@@ -706,7 +624,7 @@ void P_Ticker(boolean run)
if (!players[i].mo)
continue;
P_DamageMobj(players[i].mo, NULL, NULL, DMG_INSTAKILL);
P_DamageMobj(players[i].mo, NULL, NULL, 10000);
}
}
@@ -780,7 +698,10 @@ void P_Ticker(boolean run)
PS_STOP_TIMING(ps_lua_postthinkframe_time);
}
K_UpdateDirector();
for (i = 0; i <= splitscreen; i++)
{
K_UpdateDirector(i);
}
// Always move the camera.
P_RunChaseCameras();
@@ -859,15 +780,8 @@ void P_PreTicker(INT32 frames)
// Run any "after all the other thinkers" stuff
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (!players[i].mo || P_MobjWasRemoved(players[i].mo))
continue;
P_PlayerAfterThink(&players[i]);
}
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
P_PlayerAfterThink(&players[i]);
LUA_HookThinkFrame();
+548 -628
View File
File diff suppressed because it is too large. Load diff
-1
View File
@@ -16,7 +16,6 @@
#include <stddef.h>
#include <stdint.h>
#include "qs22j.h"
#define INSORTTHRESH 5 // if n < this use insertion sort
+54 -44
View File
@@ -265,7 +265,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
boolean underwater;
UINT8 i = R_GetViewNumber();
if (viewplayer == &players[displayplayers[i]] && camera[i].chase)
if (camera[i].chase)
heightsec = R_PointInSubsector(camera[i].x, camera[i].y)->sector->heightsec;
else if (i > splitscreen && viewmobj)
heightsec = R_PointInSubsector(pviewmobj->x, pviewmobj->y)->sector->heightsec;
@@ -423,7 +423,7 @@ static void R_AddLine(seg_t *line)
span = angle1 - angle2;
// Back side? i.e. backface culling?
if (span >= ANGLE_180 || !line->linedef)
if (span >= ANGLE_180)
return;
// Global angle needed by segcalc.
@@ -494,12 +494,11 @@ static void R_AddLine(seg_t *line)
doorclosed = 0;
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
// Closed door.
if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)
{
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \
end1 = P_GetZAt(slope, line->v1->x, line->v1->y); \
@@ -512,44 +511,57 @@ static void R_AddLine(seg_t *line)
SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector->floorheight)
SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight)
#undef SLOPEPARAMS
if (viewsector != backsector && viewsector != frontsector)
{
if ((backc1 <= frontf1 && backc2 <= frontf2)
|| (backf1 >= frontc1 && backf2 >= frontc2))
{
goto clipsolid;
}
// Check for automap fix. Store in doorclosed for r_segs.c
doorclosed = (backc1 <= backf1 && backc2 <= backf2
&& ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture)
&& ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture)
&& (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum));
if (doorclosed)
goto clipsolid;
}
// Window.
if (backc1 != frontc1 || backc2 != frontc2
|| backf1 != frontf1 || backf2 != frontf2)
{
goto clippass;
}
}
else
{
frontf1 = frontf2 = frontsector->floorheight;
frontc1 = frontc2 = frontsector->ceilingheight;
backf1 = backf2 = backsector->floorheight;
backc1 = backc2 = backsector->ceilingheight;
}
if (viewsector != backsector && viewsector != frontsector)
{
// here we're talking about a CEILING lower than a floor. ...yeah we don't even need to bother.
if (backc1 <= frontf1 && backc2 <= frontf2)
if (viewsector != backsector && viewsector != frontsector)
{
goto clipsolid;
if (backsector->ceilingheight <= frontsector->floorheight
|| backsector->floorheight >= frontsector->ceilingheight)
{
goto clipsolid;
}
// Check for automap fix. Store in doorclosed for r_segs.c
doorclosed = (backsector->ceilingheight <= backsector->floorheight
&& (backsector->ceilingheight >= frontsector->ceilingheight || curline->sidedef->toptexture)
&& (backsector->floorheight <= frontsector->floorheight || curline->sidedef->bottomtexture)
&& (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum));
if (doorclosed)
goto clipsolid;
}
// here we're talking about floors higher than ceilings, don't even bother either.
if (backf1 >= frontc1 && backf2 >= frontc2)
// Window.
if (backsector->ceilingheight != frontsector->ceilingheight
|| backsector->floorheight != frontsector->floorheight)
{
goto clipsolid;
goto clippass;
}
// Check for automap fix. Store in doorclosed for r_segs.c
doorclosed = (backc1 <= backf1 && backc2 <= backf2
&& ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture)
&& ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture)
&& (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum));
if (doorclosed)
goto clipsolid;
}
// Window.
if (backc1 != frontc1 || backc2 != frontc2
|| backf1 != frontf1 || backf2 != frontf2)
{
goto clippass;
}
// Reject empty lines used for triggers and special events.
@@ -885,9 +897,6 @@ static void R_Subsector(size_t num)
{
for (rover = frontsector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
continue;
sector_t *controlSec = &sectors[rover->secnum];
if (controlSec->moved != true)
@@ -928,7 +937,7 @@ static void R_Subsector(size_t num)
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL
, NULL
, frontsector->f_slope
, R_NoEncore(frontsector, false), false, frontsector);
, R_NoEncore(frontsector, false));
}
else
floorplane = NULL;
@@ -944,7 +953,7 @@ static void R_Subsector(size_t num)
ceilingcolormap, NULL
, NULL
, frontsector->c_slope
, R_NoEncore(frontsector, true), true, frontsector);
, R_NoEncore(frontsector, true));
}
else
ceilingplane = NULL;
@@ -994,7 +1003,7 @@ static void R_Subsector(size_t num)
*rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover
, NULL
, *rover->b_slope
, R_NoEncore(rover->master->frontsector, true), true, frontsector);
, R_NoEncore(rover->master->frontsector, true));
ffloor[numffloors].slope = *rover->b_slope;
@@ -1030,7 +1039,7 @@ static void R_Subsector(size_t num)
frontsector->lightlist[light].extra_colormap, rover
, NULL
, *rover->t_slope
, R_NoEncore(rover->master->frontsector, false), false, frontsector);
, R_NoEncore(rover->master->frontsector, false));
ffloor[numffloors].slope = *rover->t_slope;
@@ -1075,7 +1084,7 @@ static void R_Subsector(size_t num)
polysec->floorpic_angle-po->angle,
(light == -1 ? frontsector->extra_colormap : frontsector->lightlist[light].extra_colormap), NULL, po
,NULL // will ffloors be slopable eventually?
, R_NoEncore(polysec, false), false, frontsector);
, R_NoEncore(polysec, false));
ffloor[numffloors].height = polysec->floorheight;
ffloor[numffloors].polyobj = po;
@@ -1099,7 +1108,7 @@ static void R_Subsector(size_t num)
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle,
(light == -1 ? frontsector->extra_colormap : frontsector->lightlist[light].extra_colormap), NULL, po
,NULL // will ffloors be slopable eventually?
, R_NoEncore(polysec, true), false, frontsector);
, R_NoEncore(polysec, true));
ffloor[numffloors].polyobj = po;
ffloor[numffloors].height = polysec->ceilingheight;
@@ -1317,6 +1326,7 @@ void R_RenderBSPNode(INT32 bspnum)
// Decide which side the view point is on.
side = R_PointOnSideFast(viewx, viewy, bsp);
// Recursively divide front space.
R_RenderBSPNode(bsp->children[side]);
Loaded 100 of 144 files, more files were not shown because too many files have changed in this diff. Show more