Merge branch 'next' of https://git.do.srb2.org/STJr/SRB2 into lua-tag-iterator

# Conflicts:
#	src/doomtype.h
This commit is contained in:
Nev3r 2020-12-16 17:27:44 +01:00
commit b642682dde
74 changed files with 1447 additions and 1265 deletions

View File

@ -13,8 +13,7 @@
# -DHAVE_SDL -> use for the SDL interface # -DHAVE_SDL -> use for the SDL interface
# #
# Sets: # Sets:
# Compile the DirectX/Mingw version with 'make MINGW=1' # Compile the SDL/Mingw version with 'make MINGW=1'
# Compile the SDL/Mingw version with 'make MINGW=1 SDL=1'
# Compile the SDL/Linux version with 'make LINUX=1' # Compile the SDL/Linux version with 'make LINUX=1'
# Compile the SDL/Solaris version with 'make SOLARIS=1' # Compile the SDL/Solaris version with 'make SOLARIS=1'
# Compile the SDL/FreeBSD version with 'gmake FREEBSD=1' # Compile the SDL/FreeBSD version with 'gmake FREEBSD=1'
@ -103,7 +102,6 @@ ifeq ($(OS),Windows_NT) # all windows are Windows_NT...
# go for a 32-bit sdl mingw exe by default # go for a 32-bit sdl mingw exe by default
MINGW=1 MINGW=1
SDL=1
WINDOWSHELL=1 WINDOWSHELL=1
else # if you on the *nix else # if you on the *nix
@ -568,12 +566,6 @@ all: pre-build $(BIN)/$(PNDNAME)
endif endif
ifdef MINGW
ifndef SDL
all: pre-build $(BIN)/$(EXENAME) dll
endif
endif
ifdef SDL ifdef SDL
all: pre-build $(BIN)/$(EXENAME) all: pre-build $(BIN)/$(EXENAME)
endif endif
@ -653,57 +645,6 @@ endif
$(OBJDIR): $(OBJDIR):
-$(MKDIR) $(OBJDIR) -$(MKDIR) $(OBJDIR)
ifndef SDL
ifdef NOHW
dll :
else
dll : opengl_dll
endif
ifdef MINGW
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
-$(MKDIR) $(BIN)
@echo Linking R_OpenGL.dll...
$(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -lgdi32 -static-libgcc
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
ifdef SDL ifdef SDL
ifdef MINGW ifdef MINGW
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
@ -728,8 +669,6 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h
endif endif
endif endif
endif
#dependecy made by gcc itself ! #dependecy made by gcc itself !
$(OBJS): $(OBJS):
ifndef DUMMY ifndef DUMMY
@ -804,33 +743,6 @@ $(OBJDIR)/SRB2.res: win32/Srb2win.rc win32/afxres.h win32/resource.h
$(WINDRES) -i $< -O rc $(WINDRESFLAGS) --include-dir=win32 -o $@ -O coff $(WINDRES) -i $< -O rc $(WINDRESFLAGS) --include-dir=win32 -o $@ -O coff
ifdef MINGW
ifndef SDL
ifndef NOHW
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
$(echoName)
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
$(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
$(echoName)
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
endif
endif
endif
ifdef SDL ifdef SDL
ifdef MINGW ifdef MINGW

View File

@ -420,14 +420,14 @@ ifdef CYGWIN32
BIN:=$(BIN)/Cygwin BIN:=$(BIN)/Cygwin
else else
ifdef MINGW64 ifdef MINGW64
INTERFACE=win32
#NASMFORMAT=win64 #NASMFORMAT=win64
SDL=1
OBJDIR:=$(OBJDIR)/Mingw64 OBJDIR:=$(OBJDIR)/Mingw64
BIN:=$(BIN)/Mingw64 BIN:=$(BIN)/Mingw64
else else
ifdef MINGW ifdef MINGW
INTERFACE=win32
NASMFORMAT=win32 NASMFORMAT=win32
SDL=1
OBJDIR:=$(OBJDIR)/Mingw OBJDIR:=$(OBJDIR)/Mingw
BIN:=$(BIN)/Mingw BIN:=$(BIN)/Mingw
endif endif

View File

@ -686,6 +686,15 @@ static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
} }
static void codeunaryarith (FuncState *fs, OpCode op, expdesc *e) {
expdesc e2;
e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
if (op == OP_LEN || !isnumeral(e))
luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
codearith(fs, op, e, &e2);
}
static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
expdesc *e2) { expdesc *e2) {
int o1 = luaK_exp2RK(fs, e1); int o1 = luaK_exp2RK(fs, e1);
@ -703,27 +712,11 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
expdesc e2;
e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
switch (op) { switch (op) {
case OPR_MINUS: { case OPR_MINUS: codeunaryarith(fs, OP_UNM, e); break;
if (!isnumeral(e)) case OPR_BNOT: codeunaryarith(fs, OP_BNOT, e); break;
luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
codearith(fs, OP_UNM, e, &e2);
break;
}
case OPR_BNOT: {
if (e->k == VK)
luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
codearith(fs, OP_BNOT, e, &e2);
break;
}
case OPR_NOT: codenot(fs, e); break; case OPR_NOT: codenot(fs, e); break;
case OPR_LEN: { case OPR_LEN: codeunaryarith(fs, OP_LEN, e); break;
luaK_exp2anyreg(fs, e); /* cannot operate on constants */
codearith(fs, OP_LEN, e, &e2);
break;
}
default: lua_assert(0); default: lua_assert(0);
} }
} }

View File

@ -360,30 +360,48 @@ static void CON_SetupColormaps(void)
for (i = 0; i < (256*15); i++, ++memorysrc) for (i = 0; i < (256*15); i++, ++memorysrc)
*memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself...
#define colset(map, a, b, c) \ #define colset(map, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
map[1] = (UINT8)a;\ map[0x0] = (UINT8)a;\
map[3] = (UINT8)b;\ map[0x1] = (UINT8)b;\
map[9] = (UINT8)c map[0x2] = (UINT8)c;\
map[0x3] = (UINT8)d;\
map[0x4] = (UINT8)e;\
map[0x5] = (UINT8)f;\
map[0x6] = (UINT8)g;\
map[0x7] = (UINT8)h;\
map[0x8] = (UINT8)i;\
map[0x9] = (UINT8)j;\
map[0xA] = (UINT8)k;\
map[0xB] = (UINT8)l;\
map[0xC] = (UINT8)m;\
map[0xD] = (UINT8)n;\
map[0xE] = (UINT8)o;\
map[0xF] = (UINT8)p;
colset(magentamap, 177, 178, 184); // Tried to keep the colors vanilla while adding some shades in between them ~SonicX8000
colset(yellowmap, 82, 73, 66);
colset(lgreenmap, 97, 98, 106); // 0x1 0x3 0x9 0xF
colset(bluemap, 146, 147, 155); colset(magentamap, 177, 177, 178, 178, 178, 180, 180, 180, 182, 182, 182, 182, 184, 184, 184, 185);
colset(redmap, 210, 32, 39); colset(yellowmap, 82, 82, 73, 73, 73, 64, 64, 64, 66, 66, 66, 66, 67, 67, 67, 68);
colset(graymap, 6, 8, 14); colset(lgreenmap, 96, 96, 98, 98, 98, 101, 101, 101, 104, 104, 104, 104, 106, 106, 106, 107);
colset(orangemap, 51, 52, 57); colset(bluemap, 146, 146, 147, 147, 147, 149, 149, 149, 152, 152, 152, 152, 155, 155, 155, 157);
colset(skymap, 129, 130, 133); colset(redmap, 32, 32, 33, 33, 33, 35, 35, 35, 39, 39, 39, 39, 42, 42, 42, 44);
colset(purplemap, 160, 161, 163); colset(graymap, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23);
colset(aquamap, 120, 121, 123); colset(orangemap, 50, 50, 52, 52, 52, 54, 54, 54, 56, 56, 56, 56, 59, 59, 59, 60);
colset(peridotmap, 88, 188, 190); colset(skymap, 129, 129, 130, 130, 130, 131, 131, 131, 133, 133, 133, 133, 135, 135, 135, 136);
colset(azuremap, 144, 145, 170); colset(purplemap, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 163, 164, 164, 164, 165);
colset(brownmap, 219, 221, 224); colset(aquamap, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125);
colset(rosymap, 200, 201, 203); colset(peridotmap, 72, 72, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191, 191, 191, 94);
colset(invertmap, 27, 26, 22); colset(azuremap, 144, 144, 145, 145, 145, 146, 146, 146, 170, 170, 170, 170, 171, 171, 171, 172);
invertmap[26] = (UINT8)3; colset(brownmap, 219, 219, 221, 221, 221, 222, 222, 222, 224, 224, 224, 224, 227, 227, 227, 229);
colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 203, 204, 204, 204, 205);
#undef colset #undef colset
// Yeah just straight up invert it like a normal person
for (i = 0x00; i <= 0x1F; i++)
invertmap[0x1F - i] = i;
// Init back colormap // Init back colormap
CON_SetupBackColormap(); CON_SetupBackColormap();
} }

View File

@ -1595,9 +1595,7 @@ static void CL_ReloadReceivedSavegame(void)
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
#ifdef HAVE_BLUA
LUA_InvalidatePlayer(&players[i]); LUA_InvalidatePlayer(&players[i]);
#endif
sprintf(player_names[i], "Player %d", i + 1); sprintf(player_names[i], "Player %d", i + 1);
} }
@ -2260,11 +2258,15 @@ void D_SaveBan(void)
size_t i; size_t i;
banreason_t *reasonlist = reasonhead; banreason_t *reasonlist = reasonhead;
const char *address, *mask; const char *address, *mask;
const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt");
if (!reasonhead) if (!reasonhead)
{
remove(path);
return; return;
}
f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "w"); f = fopen(path, "w");
if (!f) if (!f)
{ {
@ -2308,16 +2310,14 @@ static void Ban_Add(const char *reason)
reasontail = reasonlist; reasontail = reasonlist;
} }
static void Command_ClearBans(void) static void Ban_Clear(void)
{ {
banreason_t *temp; banreason_t *temp;
if (!I_ClearBans)
return;
I_ClearBans(); I_ClearBans();
D_SaveBan();
reasontail = NULL; reasontail = NULL;
while (reasonhead) while (reasonhead)
{ {
temp = reasonhead->next; temp = reasonhead->next;
@ -2327,6 +2327,15 @@ static void Command_ClearBans(void)
} }
} }
static void Command_ClearBans(void)
{
if (!I_ClearBans)
return;
Ban_Clear();
D_SaveBan();
}
static void Ban_Load_File(boolean warning) static void Ban_Load_File(boolean warning)
{ {
FILE *f; FILE *f;
@ -2334,6 +2343,9 @@ static void Ban_Load_File(boolean warning)
const char *address, *mask; const char *address, *mask;
char buffer[MAX_WADPATH]; char buffer[MAX_WADPATH];
if (!I_ClearBans)
return;
f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r"); f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r");
if (!f) if (!f)
@ -2343,13 +2355,7 @@ static void Ban_Load_File(boolean warning)
return; return;
} }
if (I_ClearBans) Ban_Clear();
Command_ClearBans();
else
{
fclose(f);
return;
}
for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++) for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++)
{ {
@ -3026,8 +3032,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
if (pnum == consoleplayer) if (pnum == consoleplayer)
{ {
if (Playing()) LUAh_GameQuit(false);
LUAh_GameQuit();
#ifdef DUMPCONSISTENCY #ifdef DUMPCONSISTENCY
if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); if (msg == KICK_MSG_CON_FAIL) SV_SavedGame();
#endif #endif
@ -3727,8 +3732,7 @@ static void HandleConnect(SINT8 node)
static void HandleShutdown(SINT8 node) static void HandleShutdown(SINT8 node)
{ {
(void)node; (void)node;
if (Playing()) LUAh_GameQuit(false);
LUAh_GameQuit();
D_QuitNetGame(); D_QuitNetGame();
CL_Reset(); CL_Reset();
D_StartTitle(); D_StartTitle();
@ -3743,8 +3747,7 @@ static void HandleShutdown(SINT8 node)
static void HandleTimeout(SINT8 node) static void HandleTimeout(SINT8 node)
{ {
(void)node; (void)node;
if (Playing()) LUAh_GameQuit(false);
LUAh_GameQuit();
D_QuitNetGame(); D_QuitNetGame();
CL_Reset(); CL_Reset();
D_StartTitle(); D_StartTitle();
@ -4847,14 +4850,14 @@ void TryRunTics(tic_t realtics)
{ {
DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic));
ps_tictime = I_GetTimeMicros(); ps_tictime = I_GetPreciseTime();
G_Ticker((gametic % NEWTICRATERATIO) == 0); G_Ticker((gametic % NEWTICRATERATIO) == 0);
ExtraDataTicker(); ExtraDataTicker();
gametic++; gametic++;
consistancy[gametic%BACKUPTICS] = Consistancy(); consistancy[gametic%BACKUPTICS] = Consistancy();
ps_tictime = I_GetTimeMicros() - ps_tictime; ps_tictime = I_GetPreciseTime() - ps_tictime;
// Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame. // Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame.
if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value) if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value)

View File

@ -413,7 +413,7 @@ static void D_Display(void)
if (!automapactive && !dedicated && cv_renderview.value) if (!automapactive && !dedicated && cv_renderview.value)
{ {
ps_rendercalltime = I_GetTimeMicros(); ps_rendercalltime = I_GetPreciseTime();
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
{ {
topleft = screens[0] + viewwindowy*vid.width + viewwindowx; topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
@ -460,7 +460,7 @@ static void D_Display(void)
if (postimgtype2) if (postimgtype2)
V_DoPostProcessor(1, postimgtype2, postimgparam2); V_DoPostProcessor(1, postimgtype2, postimgparam2);
} }
ps_rendercalltime = I_GetTimeMicros() - ps_rendercalltime; ps_rendercalltime = I_GetPreciseTime() - ps_rendercalltime;
} }
if (lastdraw) if (lastdraw)
@ -474,7 +474,7 @@ static void D_Display(void)
lastdraw = false; lastdraw = false;
} }
ps_uitime = I_GetTimeMicros(); ps_uitime = I_GetPreciseTime();
if (gamestate == GS_LEVEL) if (gamestate == GS_LEVEL)
{ {
@ -487,7 +487,7 @@ static void D_Display(void)
} }
else else
{ {
ps_uitime = I_GetTimeMicros(); ps_uitime = I_GetPreciseTime();
} }
} }
@ -529,7 +529,7 @@ static void D_Display(void)
CON_Drawer(); CON_Drawer();
ps_uitime = I_GetTimeMicros() - ps_uitime; ps_uitime = I_GetPreciseTime() - ps_uitime;
// //
// wipe update // wipe update
@ -615,9 +615,9 @@ static void D_Display(void)
M_DrawPerfStats(); M_DrawPerfStats();
} }
ps_swaptime = I_GetTimeMicros(); ps_swaptime = I_GetPreciseTime();
I_FinishUpdate(); // page flip or blit buffer I_FinishUpdate(); // page flip or blit buffer
ps_swaptime = I_GetTimeMicros() - ps_swaptime; ps_swaptime = I_GetPreciseTime() - ps_swaptime;
} }
} }
@ -998,7 +998,7 @@ static void IdentifyVersion(void)
#define MUSICTEST(str) \ #define MUSICTEST(str) \
{\ {\
const char *musicpath = va(pandf,srb2waddir,str);\ const char *musicpath = va(pandf,srb2waddir,str);\
int ms = W_VerifyNMUSlumps(musicpath); \ int ms = W_VerifyNMUSlumps(musicpath, false); \
if (ms == 1) \ if (ms == 1) \
D_AddFile(startupwadfiles, musicpath); \ D_AddFile(startupwadfiles, musicpath); \
else if (ms == 0) \ else if (ms == 0) \
@ -1187,11 +1187,7 @@ void D_SRB2Main(void)
const char *s = M_GetNextParm(); const char *s = M_GetNextParm();
if (s) // Check for NULL? if (s) // Check for NULL?
{
if (!W_VerifyNMUSlumps(s))
G_SetGameModified(true);
D_AddFile(startuppwads, s); D_AddFile(startuppwads, s);
}
} }
} }
} }

View File

@ -214,11 +214,9 @@ consvar_t cv_respawntime = CVAR_INIT ("respawndelay", "3", CV_SAVE|CV_NETVAR|CV_
consvar_t cv_competitionboxes = CVAR_INIT ("competitionboxes", "Mystery", CV_SAVE|CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL); consvar_t cv_competitionboxes = CVAR_INIT ("competitionboxes", "Mystery", CV_SAVE|CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL);
#ifdef SEENAMES
static CV_PossibleValue_t seenames_cons_t[] = {{0, "Off"}, {1, "Colorless"}, {2, "Team"}, {3, "Ally/Foe"}, {0, NULL}}; static CV_PossibleValue_t seenames_cons_t[] = {{0, "Off"}, {1, "Colorless"}, {2, "Team"}, {3, "Ally/Foe"}, {0, NULL}};
consvar_t cv_seenames = CVAR_INIT ("seenames", "Ally/Foe", CV_SAVE, seenames_cons_t, 0); consvar_t cv_seenames = CVAR_INIT ("seenames", "Ally/Foe", CV_SAVE, seenames_cons_t, 0);
consvar_t cv_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR, CV_YesNo, NULL); consvar_t cv_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR, CV_YesNo, NULL);
#endif
// names // names
consvar_t cv_playername = CVAR_INIT ("name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange); consvar_t cv_playername = CVAR_INIT ("name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange);
@ -597,9 +595,7 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_pingtimeout); CV_RegisterVar(&cv_pingtimeout);
CV_RegisterVar(&cv_showping); CV_RegisterVar(&cv_showping);
#ifdef SEENAMES CV_RegisterVar(&cv_allowseenames);
CV_RegisterVar(&cv_allowseenames);
#endif
CV_RegisterVar(&cv_dummyconsvar); CV_RegisterVar(&cv_dummyconsvar);
} }
@ -670,6 +666,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_zlib_strategya); CV_RegisterVar(&cv_zlib_strategya);
CV_RegisterVar(&cv_zlib_window_bitsa); CV_RegisterVar(&cv_zlib_window_bitsa);
CV_RegisterVar(&cv_apng_delay); CV_RegisterVar(&cv_apng_delay);
CV_RegisterVar(&cv_apng_downscale);
// GIF variables // GIF variables
CV_RegisterVar(&cv_gif_optimize); CV_RegisterVar(&cv_gif_optimize);
CV_RegisterVar(&cv_gif_downscale); CV_RegisterVar(&cv_gif_downscale);
@ -690,9 +687,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_defaultplayercolor2); CV_RegisterVar(&cv_defaultplayercolor2);
CV_RegisterVar(&cv_defaultskin2); CV_RegisterVar(&cv_defaultskin2);
#ifdef SEENAMES
CV_RegisterVar(&cv_seenames); CV_RegisterVar(&cv_seenames);
#endif
CV_RegisterVar(&cv_rollingdemos); CV_RegisterVar(&cv_rollingdemos);
CV_RegisterVar(&cv_netstat); CV_RegisterVar(&cv_netstat);
CV_RegisterVar(&cv_netticbuffer); CV_RegisterVar(&cv_netticbuffer);
@ -878,7 +873,7 @@ void D_RegisterClientCommands(void)
// CV_RegisterVar(&cv_snapto); // CV_RegisterVar(&cv_snapto);
CV_RegisterVar(&cv_freedemocamera); CV_RegisterVar(&cv_freedemocamera);
// add cheat commands // add cheat commands
COM_AddCommand("noclip", Command_CheatNoClip_f); COM_AddCommand("noclip", Command_CheatNoClip_f);
COM_AddCommand("god", Command_CheatGod_f); COM_AddCommand("god", Command_CheatGod_f);
@ -3294,7 +3289,13 @@ static void Command_Addfile(void)
if (!isprint(fn[i]) || fn[i] == ';') if (!isprint(fn[i]) || fn[i] == ';')
return; return;
musiconly = W_VerifyNMUSlumps(fn); musiconly = W_VerifyNMUSlumps(fn, false);
if (musiconly == -1)
{
addedfiles[numfilesadded++] = fn;
continue;
}
if (!musiconly) if (!musiconly)
{ {
@ -3606,8 +3607,7 @@ static void Command_Playintro_f(void)
*/ */
FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void) FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void)
{ {
if (Playing()) LUAh_GameQuit(true);
LUAh_GameQuit();
I_Quit(); I_Quit();
} }
@ -4269,8 +4269,7 @@ void Command_ExitGame_f(void)
{ {
INT32 i; INT32 i;
if (Playing()) LUAh_GameQuit(false);
LUAh_GameQuit();
D_QuitNetGame(); D_QuitNetGame();
CL_Reset(); CL_Reset();

View File

@ -31,9 +31,7 @@ extern consvar_t cv_defaultskin;
extern consvar_t cv_defaultplayercolor2; extern consvar_t cv_defaultplayercolor2;
extern consvar_t cv_defaultskin2; extern consvar_t cv_defaultskin2;
#ifdef SEENAMES
extern consvar_t cv_seenames, cv_allowseenames; extern consvar_t cv_seenames, cv_allowseenames;
#endif
extern consvar_t cv_usemouse; extern consvar_t cv_usemouse;
extern consvar_t cv_usejoystick; extern consvar_t cv_usejoystick;
extern consvar_t cv_usejoystick2; extern consvar_t cv_usejoystick2;

View File

@ -51,7 +51,9 @@ typedef enum
SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER) SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER)
SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super
SF_NOSUPERJUMPBOOST = 1<<17, // Disable the jump boost given while super (i.e. Knuckles) SF_NOSUPERJUMPBOOST = 1<<17, // Disable the jump boost given while super (i.e. Knuckles)
SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles) SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles)
SF_NOSHIELDABILITY = 1<<19, // Disable shield abilities
// free up to and including 1<<31 // free up to and including 1<<31
} skinflags_t; } skinflags_t;

View File

@ -1522,6 +1522,13 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_SPINFIRE5", "S_SPINFIRE5",
"S_SPINFIRE6", "S_SPINFIRE6",
"S_TEAM_SPINFIRE1",
"S_TEAM_SPINFIRE2",
"S_TEAM_SPINFIRE3",
"S_TEAM_SPINFIRE4",
"S_TEAM_SPINFIRE5",
"S_TEAM_SPINFIRE6",
// Spikes // Spikes
"S_SPIKE1", "S_SPIKE1",
"S_SPIKE2", "S_SPIKE2",
@ -3478,9 +3485,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_BLUEBRICKDEBRIS", "S_BLUEBRICKDEBRIS",
"S_YELLOWBRICKDEBRIS", "S_YELLOWBRICKDEBRIS",
#ifdef SEENAMES
"S_NAMECHECK", "S_NAMECHECK",
#endif
}; };
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",
@ -4260,9 +4265,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_BLUEBRICKDEBRIS", "MT_BLUEBRICKDEBRIS",
"MT_YELLOWBRICKDEBRIS", "MT_YELLOWBRICKDEBRIS",
#ifdef SEENAMES
"MT_NAMECHECK", "MT_NAMECHECK",
#endif
}; };
const char *const MOBJFLAG_LIST[] = { const char *const MOBJFLAG_LIST[] = {
@ -4331,6 +4334,7 @@ const char *const MOBJFLAG2_LIST[] = {
"AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH
"LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) "LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
"SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) "SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use)
"SPLAT", // Object is a splat
NULL NULL
}; };
@ -4794,6 +4798,7 @@ struct int_const_s const INT_CONST[] = {
// fixed_t constants, from m_fixed.h // fixed_t constants, from m_fixed.h
{"FRACUNIT",FRACUNIT}, {"FRACUNIT",FRACUNIT},
{"FU" ,FRACUNIT},
{"FRACBITS",FRACBITS}, {"FRACBITS",FRACBITS},
// doomdef.h constants // doomdef.h constants
@ -4871,6 +4876,36 @@ struct int_const_s const INT_CONST[] = {
{"tr_trans90",tr_trans90}, {"tr_trans90",tr_trans90},
{"NUMTRANSMAPS",NUMTRANSMAPS}, {"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},
// Render flags
{"RF_HORIZONTALFLIP",RF_HORIZONTALFLIP},
{"RF_VERTICALFLIP",RF_VERTICALFLIP},
{"RF_ABSOLUTEOFFSETS",RF_ABSOLUTEOFFSETS},
{"RF_FLIPOFFSETS",RF_FLIPOFFSETS},
{"RF_SPLATMASK",RF_SPLATMASK},
{"RF_SLOPESPLAT",RF_SLOPESPLAT},
{"RF_OBJECTSLOPESPLAT",RF_OBJECTSLOPESPLAT},
{"RF_NOSPLATBILLBOARD",RF_NOSPLATBILLBOARD},
{"RF_NOSPLATROLLANGLE",RF_NOSPLATROLLANGLE},
{"RF_BLENDMASK",RF_BLENDMASK},
{"RF_FULLBRIGHT",RF_FULLBRIGHT},
{"RF_FULLDARK",RF_FULLDARK},
{"RF_NOCOLORMAPS",RF_NOCOLORMAPS},
{"RF_SPRITETYPEMASK",RF_SPRITETYPEMASK},
{"RF_PAPERSPRITE",RF_PAPERSPRITE},
{"RF_FLOORSPRITE",RF_FLOORSPRITE},
{"RF_SHADOWDRAW",RF_SHADOWDRAW},
{"RF_SHADOWEFFECTS",RF_SHADOWEFFECTS},
{"RF_DROPSHADOW",RF_DROPSHADOW},
// Level flags // Level flags
{"LF_SCRIPTISFILE",LF_SCRIPTISFILE}, {"LF_SCRIPTISFILE",LF_SCRIPTISFILE},
{"LF_SPEEDMUSIC",LF_SPEEDMUSIC}, {"LF_SPEEDMUSIC",LF_SPEEDMUSIC},
@ -4987,6 +5022,7 @@ struct int_const_s const INT_CONST[] = {
{"SF_NOSUPERSPRITES",SF_NOSUPERSPRITES}, {"SF_NOSUPERSPRITES",SF_NOSUPERSPRITES},
{"SF_NOSUPERJUMPBOOST",SF_NOSUPERJUMPBOOST}, {"SF_NOSUPERJUMPBOOST",SF_NOSUPERJUMPBOOST},
{"SF_CANBUSTWALLS",SF_CANBUSTWALLS}, {"SF_CANBUSTWALLS",SF_CANBUSTWALLS},
{"SF_NOSHIELDABILITY",SF_NOSHIELDABILITY},
// Dashmode constants // Dashmode constants
{"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD},

View File

@ -59,6 +59,12 @@ ATTRINLINE static FUNCINLINE char myfget_color(MYFILE *f)
if (c >= '0' && c <= '9') if (c >= '0' && c <= '9')
return 0x80+(c-'0'); return 0x80+(c-'0');
c = tolower(c);
if (c >= 'a' && c <= 'f')
return 0x80+10+(c-'a');
return 0x80; // Unhandled -- default to no color return 0x80; // Unhandled -- default to no color
} }

View File

@ -582,9 +582,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Dumps the contents of a network save game upon consistency failure for debugging. /// Dumps the contents of a network save game upon consistency failure for debugging.
//#define DUMPCONSISTENCY //#define DUMPCONSISTENCY
/// See name of player in your crosshair
#define SEENAMES
/// Who put weights on my recycler? ... Inuyasha did. /// Who put weights on my recycler? ... Inuyasha did.
/// \note XMOD port. /// \note XMOD port.
//#define WEIGHTEDRECYCLER //#define WEIGHTEDRECYCLER

View File

@ -401,4 +401,8 @@ unset_bit_array (bitarray_t * const array, const int value)
array[value >> 3] &= ~(1<<(value & 7)); array[value >> 3] &= ~(1<<(value & 7));
} }
#ifdef HAVE_SDL
typedef UINT64 precise_t;
#endif
#endif //__DOOMTYPE__ #endif //__DOOMTYPE__

View File

@ -1074,6 +1074,7 @@ static const char *credits[] = {
"\1Programming", "\1Programming",
"Alam \"GBC\" Arias", "Alam \"GBC\" Arias",
"Logan \"GBA\" Arias", "Logan \"GBA\" Arias",
"Zolton \"Zippy_Zolton\" Auburn",
"Colette \"fickleheart\" Bordelon", "Colette \"fickleheart\" Bordelon",
"Andrew \"orospakr\" Clunis", "Andrew \"orospakr\" Clunis",
"Sally \"TehRealSalt\" Cochenour", "Sally \"TehRealSalt\" Cochenour",
@ -1104,6 +1105,7 @@ static const char *credits[] = {
"Sean \"Sryder13\" Ryder", "Sean \"Sryder13\" Ryder",
"Ehab \"Wolfy\" Saeed", "Ehab \"Wolfy\" Saeed",
"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible "Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
"Riku \"Ors\" Salminen", // Demo consistency improvements
"Jonas \"MascaraSnake\" Sauer", "Jonas \"MascaraSnake\" Sauer",
"Wessel \"sphere\" Smit", "Wessel \"sphere\" Smit",
"\"SSNTails\"", "\"SSNTails\"",

View File

@ -1956,9 +1956,7 @@ void G_DoPlayDemo(char *defdemoname)
// Set skin // Set skin
SetPlayerSkin(0, skin); SetPlayerSkin(0, skin);
#ifdef HAVE_BLUA
LUAh_MapChange(gamemap); LUAh_MapChange(gamemap);
#endif
displayplayer = consoleplayer = 0; displayplayer = consoleplayer = 0;
memset(playeringame,0,sizeof(playeringame)); memset(playeringame,0,sizeof(playeringame));
playeringame[0] = true; playeringame[0] = true;

View File

@ -444,9 +444,7 @@ consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, j
consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
#ifdef SEENAMES
player_t *seenplayer; // player we're aiming at right now player_t *seenplayer; // player we're aiming at right now
#endif
// now automatically allocated in D_RegisterClientCommands // now automatically allocated in D_RegisterClientCommands
// so that it doesn't have to be updated depending on the value of MAXPLAYERS // so that it doesn't have to be updated depending on the value of MAXPLAYERS
@ -2232,8 +2230,35 @@ void G_Ticker(boolean run)
// Costs a life to retry ... unless the player in question is dead already, or you haven't even touched the first starpost in marathon run. // Costs a life to retry ... unless the player in question is dead already, or you haven't even touched the first starpost in marathon run.
if (marathonmode && gamemap == spmarathon_start && !players[consoleplayer].starposttime) if (marathonmode && gamemap == spmarathon_start && !players[consoleplayer].starposttime)
{ {
player_t *p = &players[consoleplayer];
marathonmode |= MA_INIT; marathonmode |= MA_INIT;
marathontime = 0; marathontime = 0;
numgameovers = tokenlist = token = 0;
countdown = countdown2 = exitfadestarted = 0;
p->playerstate = PST_REBORN;
p->starpostx = p->starposty = p->starpostz = 0;
p->lives = startinglivesbalance[0];
p->continues = 1;
p->score = 0;
// The latter two should clear by themselves, but just in case
p->pflags &= ~(PF_TAGIT|PF_GAMETYPEOVER|PF_FULLSTASIS);
// Clear cheatcodes too, just in case.
p->pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS);
p->xtralife = 0;
// Reset unlockable triggers
unlocktriggers = 0;
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
} }
else if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES) else if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES)
players[consoleplayer].lives -= 1; players[consoleplayer].lives -= 1;

View File

@ -25,9 +25,7 @@ extern char timeattackfolder[64];
extern char customversionstring[32]; extern char customversionstring[32];
#define GAMEDATASIZE (4*8192) #define GAMEDATASIZE (4*8192)
#ifdef SEENAMES
extern player_t *seenplayer; extern player_t *seenplayer;
#endif
extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
extern INT32 player_name_changes[MAXPLAYERS]; extern INT32 player_name_changes[MAXPLAYERS];

View File

@ -248,12 +248,12 @@ void HWR_RenderBatches(void)
} }
// sort polygons // sort polygons
ps_hw_batchsorttime = I_GetTimeMicros(); ps_hw_batchsorttime = I_GetPreciseTime();
if (cv_glshaders.value && gl_shadersavailable) if (cv_glshaders.value && gl_shadersavailable)
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons); qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
else else
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders); qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders);
ps_hw_batchsorttime = I_GetTimeMicros() - ps_hw_batchsorttime; ps_hw_batchsorttime = I_GetPreciseTime() - ps_hw_batchsorttime;
// sort order // sort order
// 1. shader // 1. shader
// 2. texture // 2. texture
@ -261,7 +261,7 @@ void HWR_RenderBatches(void)
// 4. colors + light level // 4. colors + light level
// not sure about what order of the last 2 should be, or if it even matters // not sure about what order of the last 2 should be, or if it even matters
ps_hw_batchdrawtime = I_GetTimeMicros(); ps_hw_batchdrawtime = I_GetPreciseTime();
currentShader = polygonArray[polygonIndexArray[0]].shader; currentShader = polygonArray[polygonIndexArray[0]].shader;
currentTexture = polygonArray[polygonIndexArray[0]].texture; currentTexture = polygonArray[polygonIndexArray[0]].texture;
@ -446,7 +446,7 @@ void HWR_RenderBatches(void)
polygonArraySize = 0; polygonArraySize = 0;
unsortedVertexArraySize = 0; unsortedVertexArraySize = 0;
ps_hw_batchdrawtime = I_GetTimeMicros() - ps_hw_batchdrawtime; ps_hw_batchdrawtime = I_GetPreciseTime() - ps_hw_batchdrawtime;
} }

View File

@ -16,7 +16,7 @@
#include "hw_data.h" #include "hw_data.h"
#include "hw_drv.h" #include "hw_drv.h"
typedef struct typedef struct
{ {
FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused
unsigned int vertsIndex;// location of verts in unsortedVertexArray unsigned int vertsIndex;// location of verts in unsortedVertexArray

View File

@ -108,7 +108,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
//Hurdler: 25/04/2000: now support colormap in hardware mode //Hurdler: 25/04/2000: now support colormap in hardware mode
if (mipmap->colormap) if (mipmap->colormap)
texel = mipmap->colormap[texel]; texel = mipmap->colormap->data[texel];
// hope compiler will get this switch out of the loops (dreams...) // hope compiler will get this switch out of the loops (dreams...)
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
@ -218,7 +218,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
//Hurdler: 25/04/2000: now support colormap in hardware mode //Hurdler: 25/04/2000: now support colormap in hardware mode
if (mipmap->colormap) if (mipmap->colormap)
texel = mipmap->colormap[texel]; texel = mipmap->colormap->data[texel];
// hope compiler will get this switch out of the loops (dreams...) // hope compiler will get this switch out of the loops (dreams...)
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
@ -659,7 +659,10 @@ void HWR_FreeTextureColormaps(patch_t *patch)
// Free image data from memory. // Free image data from memory.
if (next->data) if (next->data)
Z_Free(next->data); Z_Free(next->data);
if (next->colormap)
Z_Free(next->colormap);
next->data = NULL; next->data = NULL;
next->colormap = NULL;
HWD.pfnDeleteTexture(next); HWD.pfnDeleteTexture(next);
// Free the old colormap mipmap from memory. // Free the old colormap mipmap from memory.
@ -667,16 +670,29 @@ void HWR_FreeTextureColormaps(patch_t *patch)
} }
} }
static boolean FreeTextureCallback(void *mem)
{
patch_t *patch = (patch_t *)mem;
HWR_FreeTexture(patch);
return false;
}
static boolean FreeColormapsCallback(void *mem)
{
patch_t *patch = (patch_t *)mem;
HWR_FreeTextureColormaps(patch);
return false;
}
static void HWR_FreePatchCache(boolean freeall) static void HWR_FreePatchCache(boolean freeall)
{ {
INT32 i; boolean (*callback)(void *mem) = FreeTextureCallback;
for (i = 0; i < numwadfiles; i++) if (!freeall)
{ callback = FreeColormapsCallback;
INT32 j = 0;
for (; j < wadfiles[i]->numlumps; j++) Z_IterateTags(PU_PATCH, PU_PATCH_ROTATED, callback);
(freeall ? HWR_FreeTexture : HWR_FreeTextureColormaps)(wadfiles[i]->patchcache[j]); Z_IterateTags(PU_SPRITE, PU_HUDGFX, callback);
}
} }
// free all textures after each level // free all textures after each level
@ -977,8 +993,28 @@ static void HWR_LoadPatchMipmap(patch_t *patch, GLMipmap_t *grMipmap)
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
} }
// ----------------------+
// HWR_UpdatePatchMipmap : Updates a mipmap.
// ----------------------+
static void HWR_UpdatePatchMipmap(patch_t *patch, GLMipmap_t *grMipmap)
{
GLPatch_t *grPatch = patch->hardware;
HWR_MakePatch(patch, grPatch, grMipmap, true);
// If hardware does not have the texture, then call pfnSetTexture to upload it
// If it does have the texture, then call pfnUpdateTexture to update it
if (!grMipmap->downloaded)
HWD.pfnSetTexture(grMipmap);
else
HWD.pfnUpdateTexture(grMipmap);
HWR_SetCurrentTexture(grMipmap);
// The system-memory data can be purged now.
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
}
// -----------------+ // -----------------+
// HWR_GetPatch : Download a patch to the hardware cache and make it ready for use // HWR_GetPatch : Downloads a patch to the hardware cache and make it ready for use
// -----------------+ // -----------------+
void HWR_GetPatch(patch_t *patch) void HWR_GetPatch(patch_t *patch)
{ {
@ -1006,14 +1042,20 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
return; return;
} }
// search for the mimmap // search for the mipmap
// skip the first (no colormap translated) // skip the first (no colormap translated)
for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; ) for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; )
{ {
grMipmap = grMipmap->nextcolormap; grMipmap = grMipmap->nextcolormap;
if (grMipmap->colormap == colormap) if (grMipmap->colormap && grMipmap->colormap->source == colormap)
{ {
HWR_LoadPatchMipmap(patch, grMipmap); if (memcmp(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8)))
{
M_Memcpy(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_UpdatePatchMipmap(patch, grMipmap);
}
else
HWR_LoadPatchMipmap(patch, grMipmap);
return; return;
} }
} }
@ -1029,7 +1071,10 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
I_Error("%s: Out of memory", "HWR_GetMappedPatch"); I_Error("%s: Out of memory", "HWR_GetMappedPatch");
grMipmap->nextcolormap = newMipmap; grMipmap->nextcolormap = newMipmap;
newMipmap->colormap = colormap; newMipmap->colormap = Z_Calloc(sizeof(*newMipmap->colormap), PU_HWRPATCHCOLMIPMAP, NULL);
newMipmap->colormap->source = colormap;
M_Memcpy(newMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_LoadPatchMipmap(patch, newMipmap); HWR_LoadPatchMipmap(patch, newMipmap);
} }

View File

@ -39,6 +39,15 @@ typedef enum GLTextureFormat_e
GL_TEXFMT_ALPHA_INTENSITY_88 = 0x22, GL_TEXFMT_ALPHA_INTENSITY_88 = 0x22,
} GLTextureFormat_t; } GLTextureFormat_t;
// Colormap structure for mipmaps.
struct GLColormap_s
{
const UINT8 *source;
UINT8 data[256];
};
typedef struct GLColormap_s GLColormap_t;
// data holds the address of the graphics data cached in heap memory // data holds the address of the graphics data cached in heap memory
// NULL if the texture is not in Doom heap cache. // NULL if the texture is not in Doom heap cache.
struct GLMipmap_s struct GLMipmap_s
@ -53,7 +62,7 @@ struct GLMipmap_s
UINT32 downloaded; // The GPU has this texture. UINT32 downloaded; // The GPU has this texture.
struct GLMipmap_s *nextcolormap; struct GLMipmap_s *nextcolormap;
const UINT8 *colormap; struct GLColormap_s *colormap;
struct GLMipmap_s *nextmipmap; // Linked list of all textures struct GLMipmap_s *nextmipmap; // Linked list of all textures
}; };
@ -77,7 +86,7 @@ struct GLPatch_s
{ {
float max_s,max_t; float max_s,max_t;
GLMipmap_t *mipmap; GLMipmap_t *mipmap;
} ATTRPACK; };
typedef struct GLPatch_s GLPatch_t; typedef struct GLPatch_s GLPatch_t;
#endif //_HWR_DATA_ #endif //_HWR_DATA_

View File

@ -506,13 +506,13 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
v[0].s = v[3].s = ((sx)/(float)(gpatch->width))*hwrPatch->max_s; v[0].s = v[3].s = ((sx)/(float)(gpatch->width))*hwrPatch->max_s;
if (sx + w > gpatch->width) if (sx + w > gpatch->width)
v[2].s = v[1].s = hwrPatch->max_s; v[2].s = v[1].s = hwrPatch->max_s - ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s;
else else
v[2].s = v[1].s = ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s; v[2].s = v[1].s = ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s;
v[0].t = v[1].t = ((sy)/(float)(gpatch->height))*hwrPatch->max_t; v[0].t = v[1].t = ((sy)/(float)(gpatch->height))*hwrPatch->max_t;
if (sy + h > gpatch->height) if (sy + h > gpatch->height)
v[2].t = v[3].t = hwrPatch->max_t; v[2].t = v[3].t = hwrPatch->max_t - ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t;
else else
v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t; v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t;

View File

@ -253,6 +253,7 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_SIGN &lspr[NOLIGHT], // SPR_SIGN
&lspr[NOLIGHT], // SPR_SPIK &lspr[NOLIGHT], // SPR_SPIK
&lspr[NOLIGHT], // SPR_SFLM &lspr[NOLIGHT], // SPR_SFLM
&lspr[NOLIGHT], // SPR_TFLM
&lspr[NOLIGHT], // SPR_USPK &lspr[NOLIGHT], // SPR_USPK
&lspr[NOLIGHT], // SPR_WSPK &lspr[NOLIGHT], // SPR_WSPK
&lspr[NOLIGHT], // SPR_WSPB &lspr[NOLIGHT], // SPR_WSPB

View File

@ -147,11 +147,11 @@ static angle_t gl_aimingangle;
static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox);
// Render stats // Render stats
int ps_hw_skyboxtime = 0; precise_t ps_hw_skyboxtime = 0;
int ps_hw_nodesorttime = 0; precise_t ps_hw_nodesorttime = 0;
int ps_hw_nodedrawtime = 0; precise_t ps_hw_nodedrawtime = 0;
int ps_hw_spritesorttime = 0; precise_t ps_hw_spritesorttime = 0;
int ps_hw_spritedrawtime = 0; precise_t ps_hw_spritedrawtime = 0;
// Render stats for batching // Render stats for batching
int ps_hw_numpolys = 0; int ps_hw_numpolys = 0;
@ -161,8 +161,8 @@ int ps_hw_numshaders = 0;
int ps_hw_numtextures = 0; int ps_hw_numtextures = 0;
int ps_hw_numpolyflags = 0; int ps_hw_numpolyflags = 0;
int ps_hw_numcolors = 0; int ps_hw_numcolors = 0;
int ps_hw_batchsorttime = 0; precise_t ps_hw_batchsorttime = 0;
int ps_hw_batchdrawtime = 0; precise_t ps_hw_batchdrawtime = 0;
boolean gl_init = false; boolean gl_init = false;
boolean gl_maploaded = false; boolean gl_maploaded = false;
@ -4654,7 +4654,7 @@ static void HWR_CreateDrawNodes(void)
// that is already lying around. This should all be in some sort of linked list or lists. // that is already lying around. This should all be in some sort of linked list or lists.
sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL);
ps_hw_nodesorttime = I_GetTimeMicros(); ps_hw_nodesorttime = I_GetPreciseTime();
for (i = 0; i < numplanes; i++, p++) for (i = 0; i < numplanes; i++, p++)
{ {
@ -4709,9 +4709,9 @@ static void HWR_CreateDrawNodes(void)
} }
} }
ps_hw_nodesorttime = I_GetTimeMicros() - ps_hw_nodesorttime; ps_hw_nodesorttime = I_GetPreciseTime() - ps_hw_nodesorttime;
ps_hw_nodedrawtime = I_GetTimeMicros(); ps_hw_nodedrawtime = I_GetPreciseTime();
// Okay! Let's draw it all! Woo! // Okay! Let's draw it all! Woo!
HWD.pfnSetTransform(&atransform); HWD.pfnSetTransform(&atransform);
@ -4748,7 +4748,7 @@ static void HWR_CreateDrawNodes(void)
} }
} }
ps_hw_nodedrawtime = I_GetTimeMicros() - ps_hw_nodedrawtime; ps_hw_nodedrawtime = I_GetPreciseTime() - ps_hw_nodedrawtime;
numwalls = 0; numwalls = 0;
numplanes = 0; numplanes = 0;
@ -5295,7 +5295,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE); vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE);
} }
else else
vis->colormap = colormaps; vis->colormap = NULL;
// set top/bottom coords // set top/bottom coords
vis->gzt = gzt; vis->gzt = gzt;
@ -5396,7 +5396,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->flip = flip; vis->flip = flip;
vis->mobj = (mobj_t *)thing; vis->mobj = (mobj_t *)thing;
vis->colormap = colormaps; vis->colormap = NULL;
// set top/bottom coords // set top/bottom coords
vis->gzt = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset); vis->gzt = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset);
@ -6017,10 +6017,10 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
if (viewnumber == 0) // Only do it if it's the first screen being rendered if (viewnumber == 0) // Only do it if it's the first screen being rendered
HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs. HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs.
ps_hw_skyboxtime = I_GetTimeMicros(); ps_hw_skyboxtime = I_GetPreciseTime();
if (skybox && drawsky) // If there's a skybox and we should be drawing the sky, draw the skybox if (skybox && drawsky) // If there's a skybox and we should be drawing the sky, draw the skybox
HWR_RenderSkyboxView(viewnumber, player); // This is drawn before everything else so it is placed behind HWR_RenderSkyboxView(viewnumber, player); // This is drawn before everything else so it is placed behind
ps_hw_skyboxtime = I_GetTimeMicros() - ps_hw_skyboxtime; ps_hw_skyboxtime = I_GetPreciseTime() - ps_hw_skyboxtime;
{ {
// do we really need to save player (is it not the same)? // do we really need to save player (is it not the same)?
@ -6132,7 +6132,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
ps_numbspcalls = 0; ps_numbspcalls = 0;
ps_numpolyobjects = 0; ps_numpolyobjects = 0;
ps_bsptime = I_GetTimeMicros(); ps_bsptime = I_GetPreciseTime();
validcount++; validcount++;
@ -6170,7 +6170,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
} }
#endif #endif
ps_bsptime = I_GetTimeMicros() - ps_bsptime; ps_bsptime = I_GetPreciseTime() - ps_bsptime;
if (cv_glbatching.value) if (cv_glbatching.value)
HWR_RenderBatches(); HWR_RenderBatches();
@ -6186,12 +6186,12 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
// Draw MD2 and sprites // Draw MD2 and sprites
ps_numsprites = gl_visspritecount; ps_numsprites = gl_visspritecount;
ps_hw_spritesorttime = I_GetTimeMicros(); ps_hw_spritesorttime = I_GetPreciseTime();
HWR_SortVisSprites(); HWR_SortVisSprites();
ps_hw_spritesorttime = I_GetTimeMicros() - ps_hw_spritesorttime; ps_hw_spritesorttime = I_GetPreciseTime() - ps_hw_spritesorttime;
ps_hw_spritedrawtime = I_GetTimeMicros(); ps_hw_spritedrawtime = I_GetPreciseTime();
HWR_DrawSprites(); HWR_DrawSprites();
ps_hw_spritedrawtime = I_GetTimeMicros() - ps_hw_spritedrawtime; ps_hw_spritedrawtime = I_GetPreciseTime() - ps_hw_spritedrawtime;
#ifdef NEWCORONAS #ifdef NEWCORONAS
//Hurdler: they must be drawn before translucent planes, what about gl fog? //Hurdler: they must be drawn before translucent planes, what about gl fog?

View File

@ -116,11 +116,11 @@ extern FTransform atransform;
// Render stats // Render stats
extern int ps_hw_skyboxtime; extern precise_t ps_hw_skyboxtime;
extern int ps_hw_nodesorttime; extern precise_t ps_hw_nodesorttime;
extern int ps_hw_nodedrawtime; extern precise_t ps_hw_nodedrawtime;
extern int ps_hw_spritesorttime; extern precise_t ps_hw_spritesorttime;
extern int ps_hw_spritedrawtime; extern precise_t ps_hw_spritedrawtime;
// Render stats for batching // Render stats for batching
extern int ps_hw_numpolys; extern int ps_hw_numpolys;
@ -130,8 +130,8 @@ extern int ps_hw_numshaders;
extern int ps_hw_numtextures; extern int ps_hw_numtextures;
extern int ps_hw_numpolyflags; extern int ps_hw_numpolyflags;
extern int ps_hw_numcolors; extern int ps_hw_numcolors;
extern int ps_hw_batchsorttime; extern precise_t ps_hw_batchsorttime;
extern int ps_hw_batchdrawtime; extern precise_t ps_hw_batchdrawtime;
extern boolean gl_init; extern boolean gl_init;
extern boolean gl_maploaded; extern boolean gl_maploaded;

View File

@ -1106,11 +1106,19 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; ) for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; )
{ {
grMipmap = grMipmap->nextcolormap; grMipmap = grMipmap->nextcolormap;
if (grMipmap->colormap == colormap) if (grMipmap->colormap && grMipmap->colormap->source == colormap)
{ {
if (grMipmap->downloaded && grMipmap->data) if (grMipmap->downloaded && grMipmap->data)
{ {
HWD.pfnSetTexture(grMipmap); // found the colormap, set it to the correct texture if (memcmp(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8)))
{
M_Memcpy(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_CreateBlendedTexture(patch, blendpatch, grMipmap, skinnum, color);
HWD.pfnUpdateTexture(grMipmap);
}
else
HWD.pfnSetTexture(grMipmap); // found the colormap, set it to the correct texture
Z_ChangeTag(grMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED); Z_ChangeTag(grMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED);
return; return;
} }
@ -1128,7 +1136,10 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
if (newMipmap == NULL) if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetBlendedTexture"); I_Error("%s: Out of memory", "HWR_GetBlendedTexture");
grMipmap->nextcolormap = newMipmap; grMipmap->nextcolormap = newMipmap;
newMipmap->colormap = colormap;
newMipmap->colormap = Z_Calloc(sizeof(*newMipmap->colormap), PU_HWRPATCHCOLMIPMAP, NULL);
newMipmap->colormap->source = colormap;
M_Memcpy(newMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_CreateBlendedTexture(patch, blendpatch, newMipmap, skinnum, color); HWR_CreateBlendedTexture(patch, blendpatch, newMipmap, skinnum, color);

View File

@ -46,7 +46,13 @@ UINT32 I_GetFreeMem(UINT32 *total);
*/ */
tic_t I_GetTime(void); tic_t I_GetTime(void);
int I_GetTimeMicros(void);// provides microsecond counter for render stats /** \brief Returns precise time value for performance measurement.
*/
precise_t I_GetPreciseTime(void);
/** \brief Returns the difference between precise times as microseconds.
*/
int I_PreciseToMicros(precise_t);
/** \brief The I_Sleep function /** \brief The I_Sleep function

View File

@ -20,127 +20,121 @@
#endif #endif
#ifndef NO_IPV6 #ifndef NO_IPV6
#define HAVE_IPV6 #define HAVE_IPV6
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
#define USE_WINSOCK #define USE_WINSOCK
#if defined (_WIN64) || defined (HAVE_IPV6) #if defined (_WIN64) || defined (HAVE_IPV6)
#define USE_WINSOCK2 #define USE_WINSOCK2
#else //_WIN64/HAVE_IPV6 #else //_WIN64/HAVE_IPV6
#define USE_WINSOCK1 #define USE_WINSOCK1
#endif #endif
#endif //WIN32 OS #endif //WIN32 OS
#ifdef USE_WINSOCK2 #ifdef USE_WINSOCK2
#include <ws2tcpip.h> #include <ws2tcpip.h>
#endif #endif
#include "doomdef.h" #include "doomdef.h"
#if defined (NOMD5) && !defined (NONET) #if defined (NOMD5) && !defined (NONET)
//#define NONET //#define NONET
#endif #endif
#ifdef NONET #ifdef NONET
#undef HAVE_MINIUPNPC #undef HAVE_MINIUPNPC
#else #else
#ifdef USE_WINSOCK1 #ifdef USE_WINSOCK1
#include <winsock.h> #include <winsock.h>
#elif !defined (SCOUW2) && !defined (SCOUW7) #else
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
#include <arpa/inet.h> #include <arpa/inet.h>
#endif //normal BSD API #ifdef __APPLE_CC__
#ifndef _BSD_SOCKLEN_T_
#define _BSD_SOCKLEN_T_
#endif //_BSD_SOCKLEN_T_
#endif //__APPLE_CC__
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/ioctl.h>
#endif //normal BSD API
#ifndef USE_WINSOCK #include <errno.h>
#ifdef __APPLE_CC__ #include <time.h>
#ifndef _BSD_SOCKLEN_T_
#define _BSD_SOCKLEN_T_
#endif //_BSD_SOCKLEN_T_
#endif //__APPLE_CC__
#include <sys/socket.h>
#include <netinet/in.h>
#endif //normal BSD API
#ifndef USE_WINSOCK #if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)
#include <netdb.h> #include <sys/time.h>
#include <sys/ioctl.h> #endif // UNIXCOMMON
#endif //normal BSD API #endif
#include <errno.h> #ifdef USE_WINSOCK
#include <time.h> // some undefined under win32
#undef errno
//#define errno WSAGetLastError() //Alam_GBC: this is the correct way, right?
#define errno h_errno // some very strange things happen when not using h_error?!?
#ifdef EWOULDBLOCK
#undef EWOULDBLOCK
#endif
#define EWOULDBLOCK WSAEWOULDBLOCK
#ifdef EMSGSIZE
#undef EMSGSIZE
#endif
#define EMSGSIZE WSAEMSGSIZE
#ifdef ECONNREFUSED
#undef ECONNREFUSED
#endif
#define ECONNREFUSED WSAECONNREFUSED
#ifdef ETIMEDOUT
#undef ETIMEDOUT
#endif
#define ETIMEDOUT WSAETIMEDOUT
#ifndef IOC_VENDOR
#define IOC_VENDOR 0x18000000
#endif
#ifndef _WSAIOW
#define _WSAIOW(x,y) (IOC_IN|(x)|(y))
#endif
#ifndef SIO_UDP_CONNRESET
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
#endif
#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0x00000400
#endif
#ifndef STATUS_INVALID_PARAMETER
#define STATUS_INVALID_PARAMETER 0xC000000D
#endif
#endif // USE_WINSOCK
#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) #ifdef __DJGPP__
#include <sys/time.h> #ifdef WATTCP // Alam_GBC: Wattcp may need this
#endif // UNIXCOMMON #include <tcp.h>
#endif // !NONET #define strerror strerror_s
#else // wattcp
#include <lsck/lsck.h>
#endif // libsocket
#endif // djgpp
#ifdef USE_WINSOCK typedef union
// some undefined under win32 {
#undef errno struct sockaddr any;
//#define errno WSAGetLastError() //Alam_GBC: this is the correct way, right? struct sockaddr_in ip4;
#define errno h_errno // some very strange things happen when not using h_error?!? #ifdef HAVE_IPV6
#ifdef EWOULDBLOCK struct sockaddr_in6 ip6;
#undef EWOULDBLOCK
#endif #endif
#define EWOULDBLOCK WSAEWOULDBLOCK } mysockaddr_t;
#ifdef EMSGSIZE
#undef EMSGSIZE
#endif
#define EMSGSIZE WSAEMSGSIZE
#ifdef ECONNREFUSED
#undef ECONNREFUSED
#endif
#define ECONNREFUSED WSAECONNREFUSED
#ifdef ETIMEDOUT
#undef ETIMEDOUT
#endif
#define ETIMEDOUT WSAETIMEDOUT
#ifndef IOC_VENDOR
#define IOC_VENDOR 0x18000000
#endif
#ifndef _WSAIOW
#define _WSAIOW(x,y) (IOC_IN|(x)|(y))
#endif
#ifndef SIO_UDP_CONNRESET
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
#endif
#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0x00000400
#endif
#ifndef STATUS_INVALID_PARAMETER
#define STATUS_INVALID_PARAMETER 0xC000000D
#endif
#endif
#ifdef __DJGPP__ #ifdef HAVE_MINIUPNPC
#ifdef WATTCP // Alam_GBC: Wattcp may need this #ifdef STATIC_MINIUPNPC
#include <tcp.h> #define STATICLIB
#define strerror strerror_s #endif
#else // wattcp #include "miniupnpc/miniwget.h"
#include <lsck/lsck.h> #include "miniupnpc/miniupnpc.h"
#endif // libsocket #include "miniupnpc/upnpcommands.h"
#endif // djgpp #undef STATICLIB
static UINT8 UPNP_support = TRUE;
typedef union #endif // HAVE_MINIUPNC
{
struct sockaddr any;
struct sockaddr_in ip4;
#ifdef HAVE_IPV6
struct sockaddr_in6 ip6;
#endif
} mysockaddr_t;
#ifdef HAVE_MINIUPNPC
#ifdef STATIC_MINIUPNPC
#define STATICLIB
#endif
#include "miniupnpc/miniwget.h"
#include "miniupnpc/miniupnpc.h"
#include "miniupnpc/upnpcommands.h"
#undef STATICLIB
static UINT8 UPNP_support = TRUE;
#endif
#endif // !NONET #endif // !NONET
@ -177,32 +171,32 @@ static UINT8 UPNP_support = TRUE;
#define DEFAULTPORT "5029" #define DEFAULTPORT "5029"
#if defined (USE_WINSOCK) && !defined (NONET) #if defined (USE_WINSOCK) && !defined (NONET)
typedef SOCKET SOCKET_TYPE; typedef SOCKET SOCKET_TYPE;
#define ERRSOCKET (SOCKET_ERROR) #define ERRSOCKET (SOCKET_ERROR)
#else #else
#if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) #if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__)
typedef int SOCKET_TYPE; typedef int SOCKET_TYPE;
#else #else
typedef unsigned long SOCKET_TYPE; typedef unsigned long SOCKET_TYPE;
#endif #endif
#define ERRSOCKET (-1) #define ERRSOCKET (-1)
#endif
#if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1)
typedef int socklen_t;
#endif #endif
#ifndef NONET #ifndef NONET
static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET}; // define socklen_t in DOS/Windows if it is not already defined
static size_t mysocketses = 0; #if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1)
static int myfamily[MAXNETNODES+1] = {0}; typedef int socklen_t;
static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {ERRSOCKET}; #endif
static mysockaddr_t clientaddress[MAXNETNODES+1]; static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET};
static mysockaddr_t broadcastaddress[MAXNETNODES+1]; static size_t mysocketses = 0;
static size_t broadcastaddresses = 0; static int myfamily[MAXNETNODES+1] = {0};
static boolean nodeconnected[MAXNETNODES+1]; static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {ERRSOCKET};
static mysockaddr_t banned[MAXBANS]; static mysockaddr_t clientaddress[MAXNETNODES+1];
static UINT8 bannedmask[MAXBANS]; static mysockaddr_t broadcastaddress[MAXNETNODES+1];
static size_t broadcastaddresses = 0;
static boolean nodeconnected[MAXNETNODES+1];
static mysockaddr_t banned[MAXBANS];
static UINT8 bannedmask[MAXBANS];
#endif #endif
static size_t numbans = 0; static size_t numbans = 0;

View File

@ -150,6 +150,7 @@ char sprnames[NUMSPRITES + 1][5] =
"SIGN", // Level end sign "SIGN", // Level end sign
"SPIK", // Spike Ball "SPIK", // Spike Ball
"SFLM", // Spin fire "SFLM", // Spin fire
"TFLM", // Spin fire (team)
"USPK", // Floor spike "USPK", // Floor spike
"WSPK", // Wall spike "WSPK", // Wall spike
"WSPB", // Wall spike base "WSPB", // Wall spike base
@ -1894,6 +1895,13 @@ state_t states[NUMSTATES] =
{SPR_SFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_SPINFIRE6}, // S_SPINFIRE5 {SPR_SFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_SPINFIRE6}, // S_SPINFIRE5
{SPR_SFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_SPINFIRE1}, // S_SPINFIRE6 {SPR_SFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_SPINFIRE1}, // S_SPINFIRE6
{SPR_TFLM, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE2}, // S_TEAM_SPINFIRE1
{SPR_TFLM, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE3}, // S_TEAM_SPINFIRE2
{SPR_TFLM, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE4}, // S_TEAM_SPINFIRE3
{SPR_TFLM, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE5}, // S_TEAM_SPINFIRE4
{SPR_TFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE6}, // S_TEAM_SPINFIRE5
{SPR_TFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE1}, // S_TEAM_SPINFIRE6
// Floor Spike // Floor Spike
{SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended {SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended
{SPR_USPK, 1, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2 {SPR_USPK, 1, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2
@ -3291,18 +3299,18 @@ state_t states[NUMSTATES] =
{SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_RANDOMANIM, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP {SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_RANDOMANIM, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP
// Spindash dust // Spindash dust
{SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1 {SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1
{SPR_DUST, 1, 6, {NULL}, 0, 0, S_SPINDUST3}, // S_SPINDUST2 {SPR_DUST, 1, 6, {NULL}, 0, 0, S_SPINDUST3}, // S_SPINDUST2
{SPR_DUST, FF_TRANS30|2, 4, {NULL}, 0, 0, S_SPINDUST4}, // S_SPINDUST3 {SPR_DUST, FF_TRANS30|2, 4, {NULL}, 0, 0, S_SPINDUST4}, // S_SPINDUST3
{SPR_DUST, FF_TRANS60|3, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST4 {SPR_DUST, FF_TRANS60|3, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST4
{SPR_BUBL, 0, 7, {NULL}, 0, 0, S_SPINDUST_BUBBLE2}, // S_SPINDUST_BUBBLE1 {SPR_BUBL, 0, 7, {NULL}, 0, 0, S_SPINDUST_BUBBLE2}, // S_SPINDUST_BUBBLE1
{SPR_BUBL, 0, 6, {NULL}, 0, 0, S_SPINDUST_BUBBLE3}, // S_SPINDUST_BUBBLE2 {SPR_BUBL, 0, 6, {NULL}, 0, 0, S_SPINDUST_BUBBLE3}, // S_SPINDUST_BUBBLE2
{SPR_BUBL, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_BUBBLE4}, // S_SPINDUST_BUBBLE3 {SPR_BUBL, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_BUBBLE4}, // S_SPINDUST_BUBBLE3
{SPR_BUBL, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4 {SPR_BUBL, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4
{SPR_FPRT, 0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1 {SPR_FPRT, FF_FULLBRIGHT|0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1
{SPR_FPRT, 0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2 {SPR_FPRT, FF_FULLBRIGHT|0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2
{SPR_FPRT, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3 {SPR_FPRT, FF_FULLBRIGHT|FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3
{SPR_FPRT, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4 {SPR_FPRT, FF_FULLBRIGHT|FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4
{SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1 {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1
@ -3924,9 +3932,7 @@ state_t states[NUMSTATES] =
{SPR_BRIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_BLUEBRICKDEBRIS {SPR_BRIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_BLUEBRICKDEBRIS
{SPR_BRIY, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_YELLOWBRICKDEBRIS {SPR_BRIY, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_YELLOWBRICKDEBRIS
#ifdef SEENAMES
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
#endif
}; };
mobjinfo_t mobjinfo[NUMMOBJTYPES] = mobjinfo_t mobjinfo[NUMMOBJTYPES] =
@ -6458,8 +6464,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_fizzle, // deathsound sfx_fizzle, // deathsound
10*FRACUNIT, // speed 10*FRACUNIT, // speed
48*FRACUNIT, // radius 24*FRACUNIT, // radius
160*FRACUNIT, // height 80*FRACUNIT, // height
0, // display offset 0, // display offset
DMG_ELECTRIC, // mass DMG_ELECTRIC, // mass
1, // damage 1, // damage
@ -21653,7 +21659,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
#ifdef SEENAMES
{ // MT_NAMECHECK { // MT_NAMECHECK
-1, // doomednum -1, // doomednum
S_NAMECHECK, // spawnstate S_NAMECHECK, // spawnstate
@ -21680,7 +21685,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_NOSECTOR, // flags MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_NOSECTOR, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
#endif
}; };
skincolor_t skincolors[MAXSKINCOLORS] = { skincolor_t skincolors[MAXSKINCOLORS] = {

View File

@ -684,6 +684,7 @@ typedef enum sprite
SPR_SIGN, // Level end sign SPR_SIGN, // Level end sign
SPR_SPIK, // Spike Ball SPR_SPIK, // Spike Ball
SPR_SFLM, // Spin fire SPR_SFLM, // Spin fire
SPR_TFLM, // Spin fire (team)
SPR_USPK, // Floor spike SPR_USPK, // Floor spike
SPR_WSPK, // Wall spike SPR_WSPK, // Wall spike
SPR_WSPB, // Wall spike base SPR_WSPB, // Wall spike base
@ -2324,6 +2325,13 @@ typedef enum state
S_SPINFIRE5, S_SPINFIRE5,
S_SPINFIRE6, S_SPINFIRE6,
S_TEAM_SPINFIRE1,
S_TEAM_SPINFIRE2,
S_TEAM_SPINFIRE3,
S_TEAM_SPINFIRE4,
S_TEAM_SPINFIRE5,
S_TEAM_SPINFIRE6,
// Spikes // Spikes
S_SPIKE1, S_SPIKE1,
S_SPIKE2, S_SPIKE2,
@ -4280,9 +4288,7 @@ typedef enum state
S_BLUEBRICKDEBRIS, // for CEZ3 S_BLUEBRICKDEBRIS, // for CEZ3
S_YELLOWBRICKDEBRIS, // for CEZ3 S_YELLOWBRICKDEBRIS, // for CEZ3
#ifdef SEENAMES
S_NAMECHECK, S_NAMECHECK,
#endif
S_FIRSTFREESLOT, S_FIRSTFREESLOT,
S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1,
@ -5082,9 +5088,7 @@ typedef enum mobj_type
MT_BLUEBRICKDEBRIS, // for CEZ3 MT_BLUEBRICKDEBRIS, // for CEZ3
MT_YELLOWBRICKDEBRIS, // for CEZ3 MT_YELLOWBRICKDEBRIS, // for CEZ3
#ifdef SEENAMES
MT_NAMECHECK, MT_NAMECHECK,
#endif
MT_FIRSTFREESLOT, MT_FIRSTFREESLOT,
MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1,

View File

@ -165,6 +165,8 @@ static const struct {
{META_SKIN, "skin_t"}, {META_SKIN, "skin_t"},
{META_POWERS, "player_t.powers"}, {META_POWERS, "player_t.powers"},
{META_SOUNDSID, "skin_t.soundsid"}, {META_SOUNDSID, "skin_t.soundsid"},
{META_SKINSPRITES, "skin_t.sprites"},
{META_SKINSPRITESLIST, "skin_t.sprites[]"},
{META_VERTEX, "vertex_t"}, {META_VERTEX, "vertex_t"},
{META_LINE, "line_t"}, {META_LINE, "line_t"},

View File

@ -112,11 +112,9 @@ void LUAh_PlayerQuit(player_t *plr, kickreason_t reason); // Hook for player qui
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh.... boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh....
UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode
#ifdef SEENAMES
boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK
#endif
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink #define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing
void LUAh_GameQuit(void); // Hook for game quitting void LUAh_GameQuit(boolean quitting); // Hook for game quitting
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building player's ticcmd struct (Ported from SRB2Kart) boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building player's ticcmd struct (Ported from SRB2Kart)
boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes

View File

@ -25,7 +25,7 @@
#include "m_perfstats.h" #include "m_perfstats.h"
#include "d_netcmd.h" // for cv_perfstats #include "d_netcmd.h" // for cv_perfstats
#include "i_system.h" // I_GetTimeMicros #include "i_system.h" // I_GetPreciseTime
static UINT8 hooksAvailable[(hook_MAX/8)+1]; static UINT8 hooksAvailable[(hook_MAX/8)+1];
@ -481,7 +481,7 @@ void LUAh_ThinkFrame(void)
continue; continue;
if (cv_perfstats.value == 3) if (cv_perfstats.value == 3)
time_taken = I_GetTimeMicros(); time_taken = I_GetPreciseTime();
PushHook(gL, hookp); PushHook(gL, hookp);
if (lua_pcall(gL, 0, 0, 1)) { if (lua_pcall(gL, 0, 0, 1)) {
if (!hookp->error || cv_debug & DBG_LUA) if (!hookp->error || cv_debug & DBG_LUA)
@ -492,7 +492,7 @@ void LUAh_ThinkFrame(void)
if (cv_perfstats.value == 3) if (cv_perfstats.value == 3)
{ {
lua_Debug ar; lua_Debug ar;
time_taken = I_GetTimeMicros() - time_taken; time_taken = I_GetPreciseTime() - time_taken;
// we need the function, let's just retrieve it again // we need the function, let's just retrieve it again
PushHook(gL, hookp); PushHook(gL, hookp);
lua_getinfo(gL, ">S", &ar); lua_getinfo(gL, ">S", &ar);
@ -1754,7 +1754,6 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean
} }
// Hook for MT_NAMECHECK // Hook for MT_NAMECHECK
#ifdef SEENAMES
boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend)
{ {
hook_p hookp; hook_p hookp;
@ -1798,7 +1797,6 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend)
return hasSeenPlayer; return hasSeenPlayer;
} }
#endif // SEENAMES
boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname)
{ {
@ -1846,7 +1844,7 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname)
} }
// Hook for game quitting // Hook for game quitting
void LUAh_GameQuit(void) void LUAh_GameQuit(boolean quitting)
{ {
hook_p hookp; hook_p hookp;
if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8)))) if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8))))
@ -1860,7 +1858,8 @@ void LUAh_GameQuit(void)
continue; continue;
PushHook(gL, hookp); PushHook(gL, hookp);
if (lua_pcall(gL, 0, 0, 1)) { lua_pushboolean(gL, quitting);
if (lua_pcall(gL, 1, 0, 1)) {
if (!hookp->error || cv_debug & DBG_LUA) if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1); lua_pop(gL, 1);
@ -1971,4 +1970,4 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo
lua_settop(gL, 0); lua_settop(gL, 0);
newname[6] = 0; newname[6] = 0;
return hooked; return hooked;
} }

View File

@ -896,8 +896,10 @@ static int libd_getColormap(lua_State *L)
else if (lua_type(L, 1) == LUA_TNUMBER) // skin number else if (lua_type(L, 1) == LUA_TNUMBER) // skin number
{ {
skinnum = (INT32)luaL_checkinteger(L, 1); skinnum = (INT32)luaL_checkinteger(L, 1);
if (skinnum < TC_BLINK || skinnum >= MAXSKINS) if (skinnum >= MAXSKINS)
return luaL_error(L, "skin number %d is out of range (%d - %d)", skinnum, TC_BLINK, MAXSKINS-1); return luaL_error(L, "skin number %d is out of range (>%d)", skinnum, MAXSKINS-1);
else if (skinnum < 0 && skinnum > TC_DEFAULT)
return luaL_error(L, "translation colormap index is out of range");
} }
else // skin name else // skin name
{ {

View File

@ -39,6 +39,8 @@ extern lua_State *gL;
#define META_SKIN "SKIN_T*" #define META_SKIN "SKIN_T*"
#define META_POWERS "PLAYER_T*POWERS" #define META_POWERS "PLAYER_T*POWERS"
#define META_SOUNDSID "SKIN_T*SOUNDSID" #define META_SOUNDSID "SKIN_T*SOUNDSID"
#define META_SKINSPRITES "SKIN_T*SPRITES"
#define META_SKINSPRITESLIST "SKIN_T*SPRITES[]"
#define META_VERTEX "VERTEX_T*" #define META_VERTEX "VERTEX_T*"
#define META_LINE "LINE_T*" #define META_LINE "LINE_T*"

View File

@ -2181,6 +2181,8 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->levelflags); lua_pushinteger(L, header->levelflags);
else if (fastcmp(field,"menuflags")) else if (fastcmp(field,"menuflags"))
lua_pushinteger(L, header->menuflags); lua_pushinteger(L, header->menuflags);
else if (fastcmp(field,"selectheading"))
lua_pushstring(L, header->selectheading);
else if (fastcmp(field,"startrings")) else if (fastcmp(field,"startrings"))
lua_pushinteger(L, header->startrings); lua_pushinteger(L, header->startrings);
else if (fastcmp(field, "sstimer")) else if (fastcmp(field, "sstimer"))

View File

@ -192,18 +192,30 @@ static luaL_Reg lib[] = {
{"cos", lib_finecosine}, {"cos", lib_finecosine},
{"tan", lib_finetangent}, {"tan", lib_finetangent},
{"FixedAngle", lib_fixedangle}, {"FixedAngle", lib_fixedangle},
{"fixangle" , lib_fixedangle},
{"AngleFixed", lib_anglefixed}, {"AngleFixed", lib_anglefixed},
{"anglefix" , lib_anglefixed},
{"InvAngle", lib_invangle}, {"InvAngle", lib_invangle},
{"FixedMul", lib_fixedmul}, {"FixedMul", lib_fixedmul},
{"fixmul" , lib_fixedmul},
{"FixedInt", lib_fixedint}, {"FixedInt", lib_fixedint},
{"fixint" , lib_fixedint},
{"FixedDiv", lib_fixeddiv}, {"FixedDiv", lib_fixeddiv},
{"fixdiv" , lib_fixeddiv},
{"FixedRem", lib_fixedrem}, {"FixedRem", lib_fixedrem},
{"fixrem" , lib_fixedrem},
{"FixedSqrt", lib_fixedsqrt}, {"FixedSqrt", lib_fixedsqrt},
{"fixsqrt" , lib_fixedsqrt},
{"FixedHypot", lib_fixedhypot}, {"FixedHypot", lib_fixedhypot},
{"fixhypot" , lib_fixedhypot},
{"FixedFloor", lib_fixedfloor}, {"FixedFloor", lib_fixedfloor},
{"fixfloor" , lib_fixedfloor},
{"FixedTrunc", lib_fixedtrunc}, {"FixedTrunc", lib_fixedtrunc},
{"fixtrunc" , lib_fixedtrunc},
{"FixedCeil", lib_fixedceil}, {"FixedCeil", lib_fixedceil},
{"fixceil" , lib_fixedceil},
{"FixedRound", lib_fixedround}, {"FixedRound", lib_fixedround},
{"fixround" , lib_fixedround},
{"GetSecSpecial", lib_getsecspecial}, {"GetSecSpecial", lib_getsecspecial},
{"All7Emeralds", lib_all7emeralds}, {"All7Emeralds", lib_all7emeralds},
{"ColorOpposite", lib_coloropposite}, {"ColorOpposite", lib_coloropposite},

View File

@ -158,6 +158,10 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->flashpal); lua_pushinteger(L, plr->flashpal);
else if (fastcmp(field,"skincolor")) else if (fastcmp(field,"skincolor"))
lua_pushinteger(L, plr->skincolor); lua_pushinteger(L, plr->skincolor);
else if (fastcmp(field,"skin"))
lua_pushinteger(L, plr->skin);
else if (fastcmp(field,"availabilities"))
lua_pushinteger(L, plr->availabilities);
else if (fastcmp(field,"score")) else if (fastcmp(field,"score"))
lua_pushinteger(L, plr->score); lua_pushinteger(L, plr->score);
else if (fastcmp(field,"dashspeed")) else if (fastcmp(field,"dashspeed"))
@ -469,6 +473,10 @@ static int player_set(lua_State *L)
return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, numskincolors-1); return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, numskincolors-1);
plr->skincolor = newcolor; plr->skincolor = newcolor;
} }
else if (fastcmp(field,"skin"))
return NOSET;
else if (fastcmp(field,"availabilities"))
return NOSET;
else if (fastcmp(field,"score")) else if (fastcmp(field,"score"))
plr->score = (UINT32)luaL_checkinteger(L, 3); plr->score = (UINT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"dashspeed")) else if (fastcmp(field,"dashspeed"))

View File

@ -21,7 +21,6 @@
enum skin { enum skin {
skin_valid = 0, skin_valid = 0,
skin_name, skin_name,
skin_spritedef,
skin_wadnum, skin_wadnum,
skin_flags, skin_flags,
skin_realname, skin_realname,
@ -54,12 +53,12 @@ enum skin {
skin_contspeed, skin_contspeed,
skin_contangle, skin_contangle,
skin_soundsid, skin_soundsid,
skin_availability skin_availability,
skin_sprites
}; };
static const char *const skin_opt[] = { static const char *const skin_opt[] = {
"valid", "valid",
"name", "name",
"spritedef",
"wadnum", "wadnum",
"flags", "flags",
"realname", "realname",
@ -93,6 +92,7 @@ static const char *const skin_opt[] = {
"contangle", "contangle",
"soundsid", "soundsid",
"availability", "availability",
"sprites",
NULL}; NULL};
#define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field]) #define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field])
@ -113,8 +113,6 @@ static int skin_get(lua_State *L)
case skin_name: case skin_name:
lua_pushstring(L, skin->name); lua_pushstring(L, skin->name);
break; break;
case skin_spritedef:
return UNIMPLEMENTED;
case skin_wadnum: case skin_wadnum:
// !!WARNING!! May differ between clients due to music wads, therefore NOT NETWORK SAFE // !!WARNING!! May differ between clients due to music wads, therefore NOT NETWORK SAFE
return UNIMPLEMENTED; return UNIMPLEMENTED;
@ -214,6 +212,9 @@ static int skin_get(lua_State *L)
case skin_availability: case skin_availability:
lua_pushinteger(L, skin->availability); lua_pushinteger(L, skin->availability);
break; break;
case skin_sprites:
LUA_PushLightUserdata(L, skin->sprites, META_SKINSPRITES);
break;
} }
return 1; return 1;
} }
@ -324,6 +325,49 @@ static int soundsid_num(lua_State *L)
return 1; return 1;
} }
enum spritesopt {
numframes = 0
};
static const char *const sprites_opt[] = {
"numframes",
NULL};
// skin.sprites[i] -> sprites[i]
static int lib_getSkinSprite(lua_State *L)
{
spritedef_t *sprites = (spritedef_t *)luaL_checkudata(L, 1, META_SKINSPRITES);
playersprite_t i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMPLAYERSPRITES*2)
return luaL_error(L, LUA_QL("skin_t") " field 'sprites' index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1);
LUA_PushLightUserdata(L, &sprites[i], META_SKINSPRITESLIST);
return 1;
}
// #skin.sprites -> NUMPLAYERSPRITES*2
static int lib_numSkinsSprites(lua_State *L)
{
lua_pushinteger(L, NUMPLAYERSPRITES*2);
return 1;
}
static int sprite_get(lua_State *L)
{
spritedef_t *sprite = (spritedef_t *)luaL_checkudata(L, 1, META_SKINSPRITESLIST);
enum spritesopt field = luaL_checkoption(L, 2, NULL, sprites_opt);
switch (field)
{
case numframes:
lua_pushinteger(L, sprite->numframes);
break;
}
return 1;
}
int LUA_SkinLib(lua_State *L) int LUA_SkinLib(lua_State *L)
{ {
luaL_newmetatable(L, META_SKIN); luaL_newmetatable(L, META_SKIN);
@ -345,6 +389,19 @@ int LUA_SkinLib(lua_State *L)
lua_setfield(L, -2, "__len"); lua_setfield(L, -2, "__len");
lua_pop(L,1); lua_pop(L,1);
luaL_newmetatable(L, META_SKINSPRITES);
lua_pushcfunction(L, lib_getSkinSprite);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_numSkinsSprites);
lua_setfield(L, -2, "__len");
lua_pop(L,1);
luaL_newmetatable(L, META_SKINSPRITESLIST);
lua_pushcfunction(L, sprite_get);
lua_setfield(L, -2, "__index");
lua_pop(L,1);
lua_newuserdata(L, 0); lua_newuserdata(L, 0);
lua_createtable(L, 0, 2); lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getSkin); lua_pushcfunction(L, lib_getSkin);

View File

@ -18,7 +18,7 @@
#include "z_zone.h" #include "z_zone.h"
#include "v_video.h" #include "v_video.h"
#include "i_video.h" #include "i_video.h"
#include "i_system.h" // I_GetTimeMicros #include "i_system.h" // I_GetPreciseTime
#include "m_misc.h" #include "m_misc.h"
#include "st_stuff.h" // st_palette #include "st_stuff.h" // st_palette
@ -53,8 +53,8 @@ static RGBA_t *gif_framepalette = NULL;
static FILE *gif_out = NULL; static FILE *gif_out = NULL;
static INT32 gif_frames = 0; static INT32 gif_frames = 0;
static UINT32 gif_prevframeus = 0; // "us" is microseconds static precise_t gif_prevframetime = 0;
static UINT32 gif_delayus = 0; static UINT32 gif_delayus = 0; // "us" is microseconds
static UINT8 gif_writeover = 0; static UINT8 gif_writeover = 0;
@ -608,7 +608,7 @@ static void GIF_framewrite(void)
{ {
// golden's attempt at creating a "dynamic delay" // golden's attempt at creating a "dynamic delay"
UINT16 mingifdelay = 10; // minimum gif delay in milliseconds (keep at 10 because gifs can't get more precise). UINT16 mingifdelay = 10; // minimum gif delay in milliseconds (keep at 10 because gifs can't get more precise).
gif_delayus += (I_GetTimeMicros() - gif_prevframeus); // increase delay by how much time was spent between last measurement gif_delayus += I_PreciseToMicros(I_GetPreciseTime() - gif_prevframetime); // increase delay by how much time was spent between last measurement
if (gif_delayus/1000 >= mingifdelay) // delay is big enough to be able to effect gif frame delay? if (gif_delayus/1000 >= mingifdelay) // delay is big enough to be able to effect gif frame delay?
{ {
@ -621,7 +621,7 @@ static void GIF_framewrite(void)
{ {
float delayf = ceil(100.0f/NEWTICRATE); float delayf = ceil(100.0f/NEWTICRATE);
delay = (UINT16)((I_GetTimeMicros() - gif_prevframeus)/10/1000); delay = (UINT16)I_PreciseToMicros((I_GetPreciseTime() - gif_prevframetime))/10/1000;
if (delay < (UINT16)(delayf)) if (delay < (UINT16)(delayf))
delay = (UINT16)(delayf); delay = (UINT16)(delayf);
@ -711,7 +711,7 @@ static void GIF_framewrite(void)
} }
fwrite(gifframe_data, 1, (p - gifframe_data), gif_out); fwrite(gifframe_data, 1, (p - gifframe_data), gif_out);
++gif_frames; ++gif_frames;
gif_prevframeus = I_GetTimeMicros(); gif_prevframetime = I_GetPreciseTime();
} }
@ -739,7 +739,7 @@ INT32 GIF_open(const char *filename)
GIF_headwrite(); GIF_headwrite();
gif_frames = 0; gif_frames = 0;
gif_prevframeus = I_GetTimeMicros(); gif_prevframetime = I_GetPreciseTime();
gif_delayus = 0; gif_delayus = 0;
return 1; return 1;
} }

View File

@ -1356,9 +1356,7 @@ static menuitem_t OP_VideoOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Score/Time/Rings", &cv_timetic, 71}, {IT_STRING | IT_CVAR, NULL, "Score/Time/Rings", &cv_timetic, 71},
{IT_STRING | IT_CVAR, NULL, "Show Powerups", &cv_powerupdisplay, 76}, {IT_STRING | IT_CVAR, NULL, "Show Powerups", &cv_powerupdisplay, 76},
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 81}, // shows ping next to framerate if we want to. {IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 81}, // shows ping next to framerate if we want to.
#ifdef SEENAMES
{IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 86}, {IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 86},
#endif
{IT_HEADER, NULL, "Console", NULL, 95}, {IT_HEADER, NULL, "Console", NULL, 95},
{IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 101}, {IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 101},
@ -1551,18 +1549,19 @@ static menuitem_t OP_ScreenshotOptionsMenu[] =
{IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bits, 57}, {IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bits, 57},
{IT_HEADER, NULL, "Movie Mode (F9)", NULL, 64}, {IT_HEADER, NULL, "Movie Mode (F9)", NULL, 64},
{IT_STRING|IT_CVAR, NULL, "Storage Location", &cv_movie_option, 70}, {IT_STRING|IT_CVAR, NULL, "Storage Location", &cv_movie_option, 70},
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_movie_folder, 75}, {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_movie_folder, 75},
{IT_STRING|IT_CVAR, NULL, "Capture Mode", &cv_moviemode, 90}, {IT_STRING|IT_CVAR, NULL, "Capture Mode", &cv_moviemode, 90},
{IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 95}, {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 95},
{IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 100}, {IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 100},
{IT_STRING|IT_CVAR, NULL, "Local Color Table", &cv_gif_localcolortable, 105}, {IT_STRING|IT_CVAR, NULL, "Local Color Table", &cv_gif_localcolortable, 105},
{IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memorya, 95}, {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_apng_downscale, 95},
{IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 100}, {IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memorya, 100},
{IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategya, 105}, {IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 105},
{IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bitsa, 110}, {IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategya, 110},
{IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bitsa, 115},
}; };
enum enum
@ -1575,7 +1574,7 @@ enum
op_screenshot_gif_start = 13, op_screenshot_gif_start = 13,
op_screenshot_gif_end = 15, op_screenshot_gif_end = 15,
op_screenshot_apng_start = 16, op_screenshot_apng_start = 16,
op_screenshot_apng_end = 19, op_screenshot_apng_end = 20,
}; };
static menuitem_t OP_EraseDataMenu[] = static menuitem_t OP_EraseDataMenu[] =
@ -6937,8 +6936,7 @@ static void M_SelectableClearMenus(INT32 choice)
static void M_UltimateCheat(INT32 choice) static void M_UltimateCheat(INT32 choice)
{ {
(void)choice; (void)choice;
if (Playing()) LUAh_GameQuit(true);
LUAh_GameQuit();
I_Quit(); I_Quit();
} }
@ -8423,7 +8421,7 @@ static void M_DrawLoadGameData(void)
sprdef = &charbotskin->sprites[SPR2_SIGN]; sprdef = &charbotskin->sprites[SPR2_SIGN];
if (!sprdef->numframes) if (!sprdef->numframes)
goto skipbot; goto skipbot;
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin-1, charbotskin->prefcolor, 0); colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin-1, charbotskin->prefcolor, GTC_CACHE);
sprframe = &sprdef->spriteframes[0]; sprframe = &sprdef->spriteframes[0];
patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
@ -8433,8 +8431,6 @@ static void M_DrawLoadGameData(void)
charbotskin->highresscale, charbotskin->highresscale,
0, patch, colormap); 0, patch, colormap);
Z_Free(colormap);
tempx -= (20<<FRACBITS); tempx -= (20<<FRACBITS);
//flip = V_FLIP; //flip = V_FLIP;
} }
@ -8443,7 +8439,7 @@ skipbot:
if (!charskin) // shut up compiler if (!charskin) // shut up compiler
goto skipsign; goto skipsign;
sprdef = &charskin->sprites[SPR2_SIGN]; sprdef = &charskin->sprites[SPR2_SIGN];
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, 0); colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, GTC_CACHE);
if (!sprdef->numframes) if (!sprdef->numframes)
goto skipsign; goto skipsign;
sprframe = &sprdef->spriteframes[0]; sprframe = &sprdef->spriteframes[0];
@ -8483,8 +8479,6 @@ skipsign:
charskin->highresscale/2, charskin->highresscale/2,
0, patch, colormap); 0, patch, colormap);
skiplife: skiplife:
if (colormap)
Z_Free(colormap);
patch = W_CachePatchName("STLIVEX", PU_PATCH); patch = W_CachePatchName("STLIVEX", PU_PATCH);
@ -11755,7 +11749,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
goto faildraw; goto faildraw;
// ok, draw player sprite for sure now // ok, draw player sprite for sure now
colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor->color, 0); colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor->color, GTC_CACHE);
if (multi_frame >= sprdef->numframes) if (multi_frame >= sprdef->numframes)
multi_frame = 0; multi_frame = 0;
@ -11773,7 +11767,6 @@ static void M_DrawSetupMultiPlayerMenu(void)
FixedDiv(skins[setupm_fakeskin].highresscale, skins[setupm_fakeskin].shieldscale), FixedDiv(skins[setupm_fakeskin].highresscale, skins[setupm_fakeskin].shieldscale),
flags, patch, colormap); flags, patch, colormap);
Z_Free(colormap);
goto colordraw; goto colordraw;
faildraw: faildraw:
@ -13372,8 +13365,7 @@ void M_QuitResponse(INT32 ch)
if (ch != 'y' && ch != KEY_ENTER) if (ch != 'y' && ch != KEY_ENTER)
return; return;
if (Playing()) LUAh_GameQuit(true);
LUAh_GameQuit();
if (!(netgame || cv_debug)) if (!(netgame || cv_debug))
{ {
S_ResetCaptions(); S_ResetCaptions();

View File

@ -163,6 +163,9 @@ consvar_t cv_zlib_levela = CVAR_INIT ("apng_compress_level", "4", CV_SAVE, zlib_
consvar_t cv_zlib_strategya = CVAR_INIT ("apng_strategy", "RLE", CV_SAVE, zlib_strategy_t, NULL); consvar_t cv_zlib_strategya = CVAR_INIT ("apng_strategy", "RLE", CV_SAVE, zlib_strategy_t, NULL);
consvar_t cv_zlib_window_bitsa = CVAR_INIT ("apng_window_size", "32k", CV_SAVE, zlib_window_bits_t, NULL); consvar_t cv_zlib_window_bitsa = CVAR_INIT ("apng_window_size", "32k", CV_SAVE, zlib_window_bits_t, NULL);
consvar_t cv_apng_delay = CVAR_INIT ("apng_speed", "1x", CV_SAVE, apng_delay_t, NULL); consvar_t cv_apng_delay = CVAR_INIT ("apng_speed", "1x", CV_SAVE, apng_delay_t, NULL);
consvar_t cv_apng_downscale = CVAR_INIT ("apng_downscale", "On", CV_SAVE, CV_OnOff, NULL);
static boolean apng_downscale = false; // So nobody can do something dumb like changing cvars mid output
boolean takescreenshot = false; // Take a screenshot this tic boolean takescreenshot = false; // Take a screenshot this tic
@ -981,25 +984,38 @@ static inline boolean M_PNGLib(void)
static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep png_buf) static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep png_buf)
{ {
png_uint_16 downscale = apng_downscale ? vid.dupx : 1;
png_uint_32 pitch = png_get_rowbytes(png_ptr, png_info_ptr); png_uint_32 pitch = png_get_rowbytes(png_ptr, png_info_ptr);
PNG_CONST png_uint_32 height = vid.height; PNG_CONST png_uint_32 width = vid.width / downscale;
png_bytepp row_pointers = png_malloc(png_ptr, height* sizeof (png_bytep)); PNG_CONST png_uint_32 height = vid.height / downscale;
png_uint_32 y; png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep));
png_uint_32 x, y;
png_uint_16 framedelay = (png_uint_16)cv_apng_delay.value; png_uint_16 framedelay = (png_uint_16)cv_apng_delay.value;
apng_frames++; apng_frames++;
for (y = 0; y < height; y++) for (y = 0; y < height; y++)
{ {
row_pointers[y] = png_buf; row_pointers[y] = malloc(pitch * sizeof(png_byte));
png_buf += pitch; for (x = 0; x < width; x++)
row_pointers[y][x] = png_buf[x * downscale];
png_buf += pitch * (downscale * downscale);
} }
//for (x = 0; x < width; x++)
//{
// printf("%d", x);
// row_pointers[y][x] = 0;
//}
/* row_pointers[y] = calloc(1, sizeof(png_bytep));
png_buf += pitch * 2;
}*/
#ifndef PNG_STATIC #ifndef PNG_STATIC
if (aPNG_write_frame_head) if (aPNG_write_frame_head)
#endif #endif
aPNG_write_frame_head(apng_ptr, apng_info_ptr, row_pointers, aPNG_write_frame_head(apng_ptr, apng_info_ptr, row_pointers,
vid.width, /* width */ width, /* width */
height, /* height */ height, /* height */
0, /* x offset */ 0, /* x offset */
0, /* y offset */ 0, /* y offset */
@ -1030,6 +1046,12 @@ static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr,
static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal) static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
{ {
png_uint_16 downscale;
apng_downscale = (!!cv_apng_downscale.value);
downscale = apng_downscale ? vid.dupx : 1;
apng_FILE = fopen(filename,"wb+"); // + mode for reading apng_FILE = fopen(filename,"wb+"); // + mode for reading
if (!apng_FILE) if (!apng_FILE)
{ {
@ -1080,7 +1102,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
png_set_compression_strategy(apng_ptr, cv_zlib_strategya.value); png_set_compression_strategy(apng_ptr, cv_zlib_strategya.value);
png_set_compression_window_bits(apng_ptr, cv_zlib_window_bitsa.value); png_set_compression_window_bits(apng_ptr, cv_zlib_window_bitsa.value);
M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, pal); M_PNGhdr(apng_ptr, apng_info_ptr, vid.width / downscale, vid.height / downscale, pal);
M_PNGText(apng_ptr, apng_info_ptr, true); M_PNGText(apng_ptr, apng_info_ptr, true);

View File

@ -33,7 +33,7 @@ extern consvar_t cv_screenshot_option, cv_screenshot_folder, cv_screenshot_color
extern consvar_t cv_moviemode, cv_movie_folder, cv_movie_option; extern consvar_t cv_moviemode, cv_movie_folder, cv_movie_option;
extern consvar_t cv_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits; 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_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa;
extern consvar_t cv_apng_delay; extern consvar_t cv_apng_delay, cv_apng_downscale;
void M_StartMovie(void); void M_StartMovie(void);
void M_SaveFrame(void); void M_SaveFrame(void);

View File

@ -22,32 +22,37 @@
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
#endif #endif
int ps_tictime = 0; struct perfstatcol;
struct perfstatrow;
int ps_playerthink_time = 0; typedef struct perfstatcol perfstatcol_t;
int ps_thinkertime = 0; typedef struct perfstatrow perfstatrow_t;
int ps_thlist_times[NUM_THINKERLISTS]; struct perfstatcol {
static const char* thlist_names[] = { INT32 lores_x;
"Polyobjects: %d", INT32 hires_x;
"Main: %d", INT32 color;
"Mobjs: %d", perfstatrow_t * rows;
"Dynamic slopes: %d",
"Precipitation: %d",
NULL
}; };
static const char* thlist_shortnames[] = {
"plyobjs %d", struct perfstatrow {
"main %d", const char * lores_label;
"mobjs %d", const char * hires_label;
"dynslop %d", void * value;
"precip %d",
NULL
}; };
static precise_t ps_frametime = 0;
precise_t ps_tictime = 0;
precise_t ps_playerthink_time = 0;
precise_t ps_thinkertime = 0;
precise_t ps_thlist_times[NUM_THINKERLISTS];
int ps_checkposition_calls = 0; int ps_checkposition_calls = 0;
int ps_lua_thinkframe_time = 0; precise_t ps_lua_thinkframe_time = 0;
int ps_lua_mobjhooks = 0; int ps_lua_mobjhooks = 0;
// dynamically allocated resizeable array for thinkframe hook stats // dynamically allocated resizeable array for thinkframe hook stats
@ -55,6 +60,8 @@ ps_hookinfo_t *thinkframe_hooks = NULL;
int thinkframe_hooks_length = 0; int thinkframe_hooks_length = 0;
int thinkframe_hooks_capacity = 16; int thinkframe_hooks_capacity = 16;
static INT32 draw_row;
void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src) void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src)
{ {
if (!thinkframe_hooks) if (!thinkframe_hooks)
@ -76,379 +83,413 @@ void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src)
thinkframe_hooks_length = index + 1; thinkframe_hooks_length = index + 1;
} }
static void PS_SetFrameTime(void)
{
precise_t currenttime = I_GetPreciseTime();
ps_frametime = currenttime - ps_prevframetime;
ps_prevframetime = currenttime;
}
static boolean M_HighResolution(void)
{
return (vid.width >= 640 && vid.height >= 400);
}
enum {
PERF_TIME,
PERF_COUNT,
};
static void M_DrawPerfString(perfstatcol_t *col, int type)
{
const boolean hires = M_HighResolution();
INT32 draw_flags = V_MONOSPACE | col->color;
perfstatrow_t * row;
int value;
if (hires)
draw_flags |= V_ALLOWLOWERCASE;
for (row = col->rows; row->lores_label; ++row)
{
if (type == PERF_TIME)
value = I_PreciseToMicros(*(precise_t *)row->value);
else
value = *(int *)row->value;
if (hires)
{
V_DrawSmallString(col->hires_x, draw_row, draw_flags,
va("%s %d", row->hires_label, value));
draw_row += 5;
}
else
{
V_DrawThinString(col->lores_x, draw_row, draw_flags,
va("%s %d", row->lores_label, value));
draw_row += 8;
}
}
}
static void M_DrawPerfTiming(perfstatcol_t *col)
{
M_DrawPerfString(col, PERF_TIME);
}
static void M_DrawPerfCount(perfstatcol_t *col)
{
M_DrawPerfString(col, PERF_COUNT);
}
static void M_DrawRenderStats(void)
{
const boolean hires = M_HighResolution();
const int half_row = hires ? 5 : 4;
precise_t extrarendertime;
perfstatrow_t frametime_row[] = {
{"frmtime", "Frame time: ", &ps_frametime},
{0}
};
perfstatrow_t rendercalltime_row[] = {
{"drwtime", "3d rendering: ", &ps_rendercalltime},
{0}
};
perfstatrow_t opengltime_row[] = {
{"skybox ", "Skybox render: ", &ps_hw_skyboxtime},
{"bsptime", "RenderBSPNode: ", &ps_bsptime},
{"nodesrt", "Drwnode sort: ", &ps_hw_nodesorttime},
{"nodedrw", "Drwnode render:", &ps_hw_nodedrawtime},
{"sprsort", "Sprite sort: ", &ps_hw_spritesorttime},
{"sprdraw", "Sprite render: ", &ps_hw_spritedrawtime},
{"other ", "Other: ", &extrarendertime},
{0}
};
perfstatrow_t softwaretime_row[] = {
{"bsptime", "RenderBSPNode: ", &ps_bsptime},
{"sprclip", "R_ClipSprites: ", &ps_sw_spritecliptime},
{"portals", "Portals+Skybox:", &ps_sw_portaltime},
{"planes ", "R_DrawPlanes: ", &ps_sw_planetime},
{"masked ", "R_DrawMasked: ", &ps_sw_maskedtime},
{"other ", "Other: ", &extrarendertime},
{0}
};
perfstatrow_t uiswaptime_row[] = {
{"ui ", "UI render: ", &ps_uitime},
{"finupdt", "I_FinishUpdate:", &ps_swaptime},
{0}
};
perfstatrow_t tictime_row[] = {
{"logic ", "Game logic: ", &ps_tictime},
{0}
};
perfstatrow_t rendercalls_row[] = {
{"bspcall", "BSP calls: ", &ps_numbspcalls},
{"sprites", "Sprites: ", &ps_numsprites},
{"drwnode", "Drawnodes: ", &ps_numdrawnodes},
{"plyobjs", "Polyobjects: ", &ps_numpolyobjects},
{0}
};
perfstatrow_t batchtime_row[] = {
{"batsort", "Batch sort: ", &ps_hw_batchsorttime},
{"batdraw", "Batch render:", &ps_hw_batchdrawtime},
{0}
};
perfstatrow_t batchcount_row[] = {
{"polygon", "Polygons: ", &ps_hw_numpolys},
{"vertex ", "Vertices: ", &ps_hw_numverts},
{0}
};
perfstatrow_t batchcalls_row[] = {
{"drwcall", "Draw calls:", &ps_hw_numcalls},
{"shaders", "Shaders: ", &ps_hw_numshaders},
{"texture", "Textures: ", &ps_hw_numtextures},
{"polyflg", "Polyflags: ", &ps_hw_numpolyflags},
{"colors ", "Colors: ", &ps_hw_numcolors},
{0}
};
perfstatcol_t frametime_col = {20, 20, V_YELLOWMAP, frametime_row};
perfstatcol_t rendercalltime_col = {20, 20, V_YELLOWMAP, rendercalltime_row};
perfstatcol_t opengltime_col = {24, 24, V_YELLOWMAP, opengltime_row};
perfstatcol_t softwaretime_col = {24, 24, V_YELLOWMAP, softwaretime_row};
perfstatcol_t uiswaptime_col = {20, 20, V_YELLOWMAP, uiswaptime_row};
perfstatcol_t tictime_col = {20, 20, V_GRAYMAP, tictime_row};
perfstatcol_t rendercalls_col = {90, 115, V_BLUEMAP, rendercalls_row};
perfstatcol_t batchtime_col = {90, 115, V_REDMAP, batchtime_row};
perfstatcol_t batchcount_col = {155, 200, V_PURPLEMAP, batchcount_row};
perfstatcol_t batchcalls_col = {220, 200, V_PURPLEMAP, batchcalls_row};
boolean rendering = (
gamestate == GS_LEVEL ||
(gamestate == GS_TITLESCREEN && titlemapinaction)
);
draw_row = 10;
M_DrawPerfTiming(&frametime_col);
if (rendering)
{
M_DrawPerfTiming(&rendercalltime_col);
// Remember to update this calculation when adding more 3d rendering stats!
extrarendertime = ps_rendercalltime - ps_bsptime;
#ifdef HWRENDER
if (rendermode == render_opengl)
{
extrarendertime -=
ps_hw_skyboxtime +
ps_hw_nodesorttime +
ps_hw_nodedrawtime +
ps_hw_spritesorttime +
ps_hw_spritedrawtime;
if (cv_glbatching.value)
{
extrarendertime -=
ps_hw_batchsorttime +
ps_hw_batchdrawtime;
}
M_DrawPerfTiming(&opengltime_col);
}
else
#endif
{
extrarendertime -=
ps_sw_spritecliptime +
ps_sw_portaltime +
ps_sw_planetime +
ps_sw_maskedtime;
M_DrawPerfTiming(&softwaretime_col);
}
}
M_DrawPerfTiming(&uiswaptime_col);
draw_row += half_row;
M_DrawPerfTiming(&tictime_col);
if (rendering)
{
draw_row = 10;
M_DrawPerfCount(&rendercalls_col);
#ifdef HWRENDER
if (rendermode == render_opengl && cv_glbatching.value)
{
draw_row += half_row;
M_DrawPerfTiming(&batchtime_col);
draw_row = 10;
M_DrawPerfCount(&batchcount_col);
if (hires)
draw_row += half_row;
else
draw_row = 10;
M_DrawPerfCount(&batchcalls_col);
}
#endif
}
}
static void M_DrawTickStats(void)
{
int i = 0;
thinker_t *thinker;
int thinkercount = 0;
int polythcount = 0;
int mainthcount = 0;
int mobjcount = 0;
int nothinkcount = 0;
int scenerycount = 0;
int regularcount = 0;
int dynslopethcount = 0;
int precipcount = 0;
int removecount = 0;
precise_t extratime =
ps_tictime -
ps_playerthink_time -
ps_thinkertime -
ps_lua_thinkframe_time;
perfstatrow_t tictime_row[] = {
{"logic ", "Game logic: ", &ps_tictime},
{0}
};
perfstatrow_t thinker_time_row[] = {
{"plrthnk", "P_PlayerThink: ", &ps_playerthink_time},
{"thnkers", "P_RunThinkers: ", &ps_thinkertime},
{0}
};
perfstatrow_t detailed_thinker_time_row[] = {
{"plyobjs", "Polyobjects: ", &ps_thlist_times[THINK_POLYOBJ]},
{"main ", "Main: ", &ps_thlist_times[THINK_MAIN]},
{"mobjs ", "Mobjs: ", &ps_thlist_times[THINK_MOBJ]},
{"dynslop", "Dynamic slopes: ", &ps_thlist_times[THINK_DYNSLOPE]},
{"precip ", "Precipitation: ", &ps_thlist_times[THINK_PRECIP]},
{0}
};
perfstatrow_t extra_thinker_time_row[] = {
{"lthinkf", "LUAh_ThinkFrame:", &ps_lua_thinkframe_time},
{"other ", "Other: ", &extratime},
{0}
};
perfstatrow_t thinkercount_row[] = {
{"thnkers", "Thinkers: ", &thinkercount},
{0}
};
perfstatrow_t detailed_thinkercount_row[] = {
{"plyobjs", "Polyobjects: ", &polythcount},
{"main ", "Main: ", &mainthcount},
{"mobjs ", "Mobjs: ", &mobjcount},
{0}
};
perfstatrow_t mobjthinkercount_row[] = {
{"regular", "Regular: ", &regularcount},
{"scenery", "Scenery: ", &scenerycount},
{0}
};
perfstatrow_t nothinkcount_row[] = {
{"nothink", "Nothink: ", &nothinkcount},
{0}
};
perfstatrow_t detailed_thinkercount_row2[] = {
{"dynslop", "Dynamic slopes: ", &dynslopethcount},
{"precip ", "Precipitation: ", &precipcount},
{"remove ", "Pending removal:", &removecount},
{0}
};
perfstatrow_t misc_calls_row[] = {
{"lmhook", "Lua mobj hooks: ", &ps_lua_mobjhooks},
{"chkpos", "P_CheckPosition:", &ps_checkposition_calls},
{0}
};
perfstatcol_t tictime_col = {20, 20, V_YELLOWMAP, tictime_row};
perfstatcol_t thinker_time_col = {24, 24, V_YELLOWMAP, thinker_time_row};
perfstatcol_t detailed_thinker_time_col = {28, 28, V_YELLOWMAP, detailed_thinker_time_row};
perfstatcol_t extra_thinker_time_col = {24, 24, V_YELLOWMAP, extra_thinker_time_row};
perfstatcol_t thinkercount_col = {90, 115, V_BLUEMAP, thinkercount_row};
perfstatcol_t detailed_thinkercount_col = {94, 119, V_BLUEMAP, detailed_thinkercount_row};
perfstatcol_t mobjthinkercount_col = {98, 123, V_BLUEMAP, mobjthinkercount_row};
perfstatcol_t nothinkcount_col = {98, 123, V_BLUEMAP, nothinkcount_row};
perfstatcol_t detailed_thinkercount_col2 = {94, 119, V_BLUEMAP, detailed_thinkercount_row2};
perfstatcol_t misc_calls_col = {170, 216, V_PURPLEMAP, misc_calls_row};
for (i = 0; i < NUM_THINKERLISTS; i++)
{
for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next)
{
thinkercount++;
if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
removecount++;
else if (i == THINK_POLYOBJ)
polythcount++;
else if (i == THINK_MAIN)
mainthcount++;
else if (i == THINK_MOBJ)
{
if (thinker->function.acp1 == (actionf_p1)P_MobjThinker)
{
mobj_t *mobj = (mobj_t*)thinker;
mobjcount++;
if (mobj->flags & MF_NOTHINK)
nothinkcount++;
else if (mobj->flags & MF_SCENERY)
scenerycount++;
else
regularcount++;
}
}
else if (i == THINK_DYNSLOPE)
dynslopethcount++;
else if (i == THINK_PRECIP)
precipcount++;
}
}
draw_row = 10;
M_DrawPerfTiming(&tictime_col);
M_DrawPerfTiming(&thinker_time_col);
M_DrawPerfTiming(&detailed_thinker_time_col);
M_DrawPerfTiming(&extra_thinker_time_col);
draw_row = 10;
M_DrawPerfCount(&thinkercount_col);
M_DrawPerfCount(&detailed_thinkercount_col);
M_DrawPerfCount(&mobjthinkercount_col);
if (nothinkcount)
M_DrawPerfCount(&nothinkcount_col);
M_DrawPerfCount(&detailed_thinkercount_col2);
if (M_HighResolution())
{
V_DrawSmallString(212, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, "Calls:");
draw_row = 15;
}
else
{
draw_row = 10;
}
M_DrawPerfCount(&misc_calls_col);
}
void M_DrawPerfStats(void) void M_DrawPerfStats(void)
{ {
char s[100]; char s[100];
int currenttime = I_GetTimeMicros();
int frametime = currenttime - ps_prevframetime; PS_SetFrameTime();
ps_prevframetime = currenttime;
if (cv_perfstats.value == 1) // rendering if (cv_perfstats.value == 1) // rendering
{ {
if (vid.width < 640 || vid.height < 400) // low resolution M_DrawRenderStats();
{
snprintf(s, sizeof s - 1, "frmtime %d", frametime);
V_DrawThinString(20, 10, V_MONOSPACE | V_YELLOWMAP, s);
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)))
{
snprintf(s, sizeof s - 1, "ui %d", ps_uitime);
V_DrawThinString(20, 18, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "finupdt %d", ps_swaptime);
V_DrawThinString(20, 26, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "logic %d", ps_tictime);
V_DrawThinString(20, 38, V_MONOSPACE | V_GRAYMAP, s);
return;
}
snprintf(s, sizeof s - 1, "drwtime %d", ps_rendercalltime);
V_DrawThinString(20, 18, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "bspcall %d", ps_numbspcalls);
V_DrawThinString(90, 10, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "sprites %d", ps_numsprites);
V_DrawThinString(90, 18, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "drwnode %d", ps_numdrawnodes);
V_DrawThinString(90, 26, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "plyobjs %d", ps_numpolyobjects);
V_DrawThinString(90, 34, V_MONOSPACE | V_BLUEMAP, s);
#ifdef HWRENDER
if (rendermode == render_opengl) // OpenGL specific stats
{
snprintf(s, sizeof s - 1, "skybox %d", ps_hw_skyboxtime);
V_DrawThinString(24, 26, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "bsptime %d", ps_bsptime);
V_DrawThinString(24, 34, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "nodesrt %d", ps_hw_nodesorttime);
V_DrawThinString(24, 42, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "nodedrw %d", ps_hw_nodedrawtime);
V_DrawThinString(24, 50, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "sprsort %d", ps_hw_spritesorttime);
V_DrawThinString(24, 58, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "sprdraw %d", ps_hw_spritedrawtime);
V_DrawThinString(24, 66, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "other %d",
ps_rendercalltime - ps_hw_skyboxtime - ps_bsptime - ps_hw_nodesorttime
- ps_hw_nodedrawtime - ps_hw_spritesorttime - ps_hw_spritedrawtime
- ps_hw_batchsorttime - ps_hw_batchdrawtime);
V_DrawThinString(24, 74, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "ui %d", ps_uitime);
V_DrawThinString(20, 82, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "finupdt %d", ps_swaptime);
V_DrawThinString(20, 90, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "logic %d", ps_tictime);
V_DrawThinString(20, 102, V_MONOSPACE | V_GRAYMAP, s);
if (cv_glbatching.value)
{
snprintf(s, sizeof s - 1, "batsort %d", ps_hw_batchsorttime);
V_DrawThinString(90, 46, V_MONOSPACE | V_REDMAP, s);
snprintf(s, sizeof s - 1, "batdraw %d", ps_hw_batchdrawtime);
V_DrawThinString(90, 54, V_MONOSPACE | V_REDMAP, s);
snprintf(s, sizeof s - 1, "polygon %d", ps_hw_numpolys);
V_DrawThinString(155, 10, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "drwcall %d", ps_hw_numcalls);
V_DrawThinString(155, 18, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "shaders %d", ps_hw_numshaders);
V_DrawThinString(155, 26, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "vertex %d", ps_hw_numverts);
V_DrawThinString(155, 34, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "texture %d", ps_hw_numtextures);
V_DrawThinString(220, 10, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "polyflg %d", ps_hw_numpolyflags);
V_DrawThinString(220, 18, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "colors %d", ps_hw_numcolors);
V_DrawThinString(220, 26, V_MONOSPACE | V_PURPLEMAP, s);
}
else
{
// reset these vars so the "other" measurement isn't off
ps_hw_batchsorttime = 0;
ps_hw_batchdrawtime = 0;
}
}
else // software specific stats
#endif
{
snprintf(s, sizeof s - 1, "bsptime %d", ps_bsptime);
V_DrawThinString(24, 26, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "sprclip %d", ps_sw_spritecliptime);
V_DrawThinString(24, 34, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "portals %d", ps_sw_portaltime);
V_DrawThinString(24, 42, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "planes %d", ps_sw_planetime);
V_DrawThinString(24, 50, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "masked %d", ps_sw_maskedtime);
V_DrawThinString(24, 58, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "other %d",
ps_rendercalltime - ps_bsptime - ps_sw_spritecliptime
- ps_sw_portaltime - ps_sw_planetime - ps_sw_maskedtime);
V_DrawThinString(24, 66, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "ui %d", ps_uitime);
V_DrawThinString(20, 74, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "finupdt %d", ps_swaptime);
V_DrawThinString(20, 82, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "logic %d", ps_tictime);
V_DrawThinString(20, 94, V_MONOSPACE | V_GRAYMAP, s);
}
}
else // high resolution
{
snprintf(s, sizeof s - 1, "Frame time: %d", frametime);
V_DrawSmallString(20, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)))
{
snprintf(s, sizeof s - 1, "UI render: %d", ps_uitime);
V_DrawSmallString(20, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "I_FinishUpdate: %d", ps_swaptime);
V_DrawSmallString(20, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime);
V_DrawSmallString(20, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s);
return;
}
snprintf(s, sizeof s - 1, "3d rendering: %d", ps_rendercalltime);
V_DrawSmallString(20, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "BSP calls: %d", ps_numbspcalls);
V_DrawSmallString(115, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Sprites: %d", ps_numsprites);
V_DrawSmallString(115, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Drawnodes: %d", ps_numdrawnodes);
V_DrawSmallString(115, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Polyobjects: %d", ps_numpolyobjects);
V_DrawSmallString(115, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
#ifdef HWRENDER
if (rendermode == render_opengl) // OpenGL specific stats
{
snprintf(s, sizeof s - 1, "Skybox render: %d", ps_hw_skyboxtime);
V_DrawSmallString(24, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "RenderBSPNode: %d", ps_bsptime);
V_DrawSmallString(24, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "Drwnode sort: %d", ps_hw_nodesorttime);
V_DrawSmallString(24, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "Drwnode render: %d", ps_hw_nodedrawtime);
V_DrawSmallString(24, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "Sprite sort: %d", ps_hw_spritesorttime);
V_DrawSmallString(24, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "Sprite render: %d", ps_hw_spritedrawtime);
V_DrawSmallString(24, 45, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
// Remember to update this calculation when adding more 3d rendering stats!
snprintf(s, sizeof s - 1, "Other: %d",
ps_rendercalltime - ps_hw_skyboxtime - ps_bsptime - ps_hw_nodesorttime
- ps_hw_nodedrawtime - ps_hw_spritesorttime - ps_hw_spritedrawtime
- ps_hw_batchsorttime - ps_hw_batchdrawtime);
V_DrawSmallString(24, 50, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "UI render: %d", ps_uitime);
V_DrawSmallString(20, 55, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "I_FinishUpdate: %d", ps_swaptime);
V_DrawSmallString(20, 60, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime);
V_DrawSmallString(20, 70, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s);
if (cv_glbatching.value)
{
snprintf(s, sizeof s - 1, "Batch sort: %d", ps_hw_batchsorttime);
V_DrawSmallString(115, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_REDMAP, s);
snprintf(s, sizeof s - 1, "Batch render: %d", ps_hw_batchdrawtime);
V_DrawSmallString(115, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_REDMAP, s);
snprintf(s, sizeof s - 1, "Polygons: %d", ps_hw_numpolys);
V_DrawSmallString(200, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "Vertices: %d", ps_hw_numverts);
V_DrawSmallString(200, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "Draw calls: %d", ps_hw_numcalls);
V_DrawSmallString(200, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "Shaders: %d", ps_hw_numshaders);
V_DrawSmallString(200, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "Textures: %d", ps_hw_numtextures);
V_DrawSmallString(200, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "Polyflags: %d", ps_hw_numpolyflags);
V_DrawSmallString(200, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "Colors: %d", ps_hw_numcolors);
V_DrawSmallString(200, 45, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s);
}
else
{
// reset these vars so the "other" measurement isn't off
ps_hw_batchsorttime = 0;
ps_hw_batchdrawtime = 0;
}
}
else // software specific stats
#endif
{
snprintf(s, sizeof s - 1, "RenderBSPNode: %d", ps_bsptime);
V_DrawSmallString(24, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "R_ClipSprites: %d", ps_sw_spritecliptime);
V_DrawSmallString(24, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "Portals+Skybox: %d", ps_sw_portaltime);
V_DrawSmallString(24, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "R_DrawPlanes: %d", ps_sw_planetime);
V_DrawSmallString(24, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "R_DrawMasked: %d", ps_sw_maskedtime);
V_DrawSmallString(24, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
// Remember to update this calculation when adding more 3d rendering stats!
snprintf(s, sizeof s - 1, "Other: %d",
ps_rendercalltime - ps_bsptime - ps_sw_spritecliptime
- ps_sw_portaltime - ps_sw_planetime - ps_sw_maskedtime);
V_DrawSmallString(24, 45, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "UI render: %d", ps_uitime);
V_DrawSmallString(20, 50, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "I_FinishUpdate: %d", ps_swaptime);
V_DrawSmallString(20, 55, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime);
V_DrawSmallString(20, 65, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s);
}
}
} }
else if (cv_perfstats.value == 2) // logic else if (cv_perfstats.value == 2) // logic
{ {
int i = 0; M_DrawTickStats();
thinker_t *thinker;
int thinkercount = 0;
int polythcount = 0;
int mainthcount = 0;
int mobjcount = 0;
int nothinkcount = 0;
int scenerycount = 0;
int dynslopethcount = 0;
int precipcount = 0;
int removecount = 0;
// y offset for drawing columns
int yoffset1 = 0;
int yoffset2 = 0;
for (i = 0; i < NUM_THINKERLISTS; i++)
{
for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next)
{
thinkercount++;
if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
removecount++;
else if (i == THINK_POLYOBJ)
polythcount++;
else if (i == THINK_MAIN)
mainthcount++;
else if (i == THINK_MOBJ)
{
if (thinker->function.acp1 == (actionf_p1)P_MobjThinker)
{
mobj_t *mobj = (mobj_t*)thinker;
mobjcount++;
if (mobj->flags & MF_NOTHINK)
nothinkcount++;
else if (mobj->flags & MF_SCENERY)
scenerycount++;
}
}
else if (i == THINK_DYNSLOPE)
dynslopethcount++;
else if (i == THINK_PRECIP)
precipcount++;
}
}
if (vid.width < 640 || vid.height < 400) // low resolution
{
snprintf(s, sizeof s - 1, "logic %d", ps_tictime);
V_DrawThinString(20, 10, V_MONOSPACE | V_YELLOWMAP, s);
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)))
return;
snprintf(s, sizeof s - 1, "plrthnk %d", ps_playerthink_time);
V_DrawThinString(24, 18, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "thnkers %d", ps_thinkertime);
V_DrawThinString(24, 26, V_MONOSPACE | V_YELLOWMAP, s);
for (i = 0; i < NUM_THINKERLISTS; i++)
{
yoffset1 += 8;
snprintf(s, sizeof s - 1, thlist_shortnames[i], ps_thlist_times[i]);
V_DrawThinString(28, 26+yoffset1, V_MONOSPACE | V_YELLOWMAP, s);
}
snprintf(s, sizeof s - 1, "lthinkf %d", ps_lua_thinkframe_time);
V_DrawThinString(24, 34+yoffset1, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "other %d",
ps_tictime - ps_playerthink_time - ps_thinkertime - ps_lua_thinkframe_time);
V_DrawThinString(24, 42+yoffset1, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "thnkers %d", thinkercount);
V_DrawThinString(90, 10, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "plyobjs %d", polythcount);
V_DrawThinString(94, 18, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "main %d", mainthcount);
V_DrawThinString(94, 26, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "mobjs %d", mobjcount);
V_DrawThinString(94, 34, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "regular %d", mobjcount - scenerycount - nothinkcount);
V_DrawThinString(98, 42, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "scenery %d", scenerycount);
V_DrawThinString(98, 50, V_MONOSPACE | V_BLUEMAP, s);
if (nothinkcount)
{
snprintf(s, sizeof s - 1, "nothink %d", nothinkcount);
V_DrawThinString(98, 58, V_MONOSPACE | V_BLUEMAP, s);
yoffset2 += 8;
}
snprintf(s, sizeof s - 1, "dynslop %d", dynslopethcount);
V_DrawThinString(94, 58+yoffset2, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "precip %d", precipcount);
V_DrawThinString(94, 66+yoffset2, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "remove %d", removecount);
V_DrawThinString(94, 74+yoffset2, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "lmhooks %d", ps_lua_mobjhooks);
V_DrawThinString(170, 10, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "chkpos %d", ps_checkposition_calls);
V_DrawThinString(170, 18, V_MONOSPACE | V_PURPLEMAP, s);
}
else // high resolution
{
snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime);
V_DrawSmallString(20, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)))
return;
snprintf(s, sizeof s - 1, "P_PlayerThink: %d", ps_playerthink_time);
V_DrawSmallString(24, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "P_RunThinkers: %d", ps_thinkertime);
V_DrawSmallString(24, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
for (i = 0; i < NUM_THINKERLISTS; i++)
{
yoffset1 += 5;
snprintf(s, sizeof s - 1, thlist_names[i], ps_thlist_times[i]);
V_DrawSmallString(28, 20+yoffset1, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
}
snprintf(s, sizeof s - 1, "LUAh_ThinkFrame: %d", ps_lua_thinkframe_time);
V_DrawSmallString(24, 25+yoffset1, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "Other: %d",
ps_tictime - ps_playerthink_time - ps_thinkertime - ps_lua_thinkframe_time);
V_DrawSmallString(24, 30+yoffset1, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "Thinkers: %d", thinkercount);
V_DrawSmallString(115, 10+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Polyobjects: %d", polythcount);
V_DrawSmallString(119, 15+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Main: %d", mainthcount);
V_DrawSmallString(119, 20+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Mobjs: %d", mobjcount);
V_DrawSmallString(119, 25+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Regular: %d", mobjcount - scenerycount - nothinkcount);
V_DrawSmallString(123, 30+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Scenery: %d", scenerycount);
V_DrawSmallString(123, 35+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
if (nothinkcount)
{
snprintf(s, sizeof s - 1, "Nothink: %d", nothinkcount);
V_DrawSmallString(123, 40+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
yoffset2 += 5;
}
snprintf(s, sizeof s - 1, "Dynamic slopes: %d", dynslopethcount);
V_DrawSmallString(119, 40+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Precipitation: %d", precipcount);
V_DrawSmallString(119, 45+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Pending removal: %d", removecount);
V_DrawSmallString(119, 50+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "Calls:");
V_DrawSmallString(212, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "Lua mobj hooks: %d", ps_lua_mobjhooks);
V_DrawSmallString(216, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "P_CheckPosition: %d", ps_checkposition_calls);
V_DrawSmallString(216, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s);
}
} }
else if (cv_perfstats.value == 3) // lua thinkframe else if (cv_perfstats.value == 3) // lua thinkframe
{ {

View File

@ -16,17 +16,17 @@
#include "lua_script.h" #include "lua_script.h"
#include "p_local.h" #include "p_local.h"
extern int ps_tictime; extern precise_t ps_tictime;
extern int ps_playerthink_time; extern precise_t ps_playerthink_time;
extern int ps_thinkertime; extern precise_t ps_thinkertime;
extern int ps_thlist_times[]; extern precise_t ps_thlist_times[];
extern int ps_checkposition_calls; extern int ps_checkposition_calls;
extern int ps_lua_thinkframe_time; extern precise_t ps_lua_thinkframe_time;
extern int ps_lua_mobjhooks; extern int ps_lua_mobjhooks;
typedef struct typedef struct
{ {

View File

@ -1834,7 +1834,7 @@ void A_SnailerThink(mobj_t *actor)
fixed_t dist; fixed_t dist;
fixed_t dx, dy; fixed_t dx, dy;
dist = P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y); dist = R_PointToDist2(0, 0, actor->x - actor->target->x, actor->y - actor->target->y);
if (an > ANGLE_45 && an <= ANGLE_90) // fire at 45 degrees to the left if (an > ANGLE_45 && an <= ANGLE_90) // fire at 45 degrees to the left
{ {
@ -3924,6 +3924,10 @@ void A_BossDeath(mobj_t *mo)
} }
else else
{ {
// Initialize my junk
junk.tags.tags = NULL;
junk.tags.count = 0;
// Bring the egg trap up to the surface // Bring the egg trap up to the surface
// Incredibly shitty code ahead // Incredibly shitty code ahead
Tag_FSet(&junk.tags, LE_CAPSULE0); Tag_FSet(&junk.tags, LE_CAPSULE0);
@ -4053,6 +4057,10 @@ bossjustdie:
} }
case MT_KOOPA: case MT_KOOPA:
{ {
// Initialize my junk
junk.tags.tags = NULL;
junk.tags.count = 0;
Tag_FSet(&junk.tags, LE_KOOPA); Tag_FSet(&junk.tags, LE_KOOPA);
EV_DoCeiling(&junk, raiseToHighest); EV_DoCeiling(&junk, raiseToHighest);
return; return;

View File

@ -1064,9 +1064,7 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
case MT_HOOP: case MT_HOOP:
case MT_HOOPCOLLIDE: case MT_HOOPCOLLIDE:
case MT_NIGHTSCORE: case MT_NIGHTSCORE:
#ifdef SEENAMES
case MT_NAMECHECK: // DEFINITELY not this, because it is client-side. case MT_NAMECHECK: // DEFINITELY not this, because it is client-side.
#endif
continue; continue;
default: default:
break; break;

View File

@ -470,14 +470,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
{ {
fixed_t setmomz = -toucher->momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce fixed_t setmomz = -toucher->momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce
if (elementalpierce == 2) // Reset bubblewrap, part 1 if (elementalpierce == 2) // Reset bubblewrap, part 1
P_DoBubbleBounce(player); P_DoBubbleBounce(player);
toucher->momz = setmomz; toucher->momz = setmomz;
if (elementalpierce == 2) // Reset bubblewrap, part 2 if (elementalpierce == 2) // Reset bubblewrap, part 2
{ {
boolean underwater = toucher->eflags & MFE_UNDERWATER; boolean underwater = toucher->eflags & MFE_UNDERWATER;
if (underwater) if (underwater)
toucher->momz /= 2; toucher->momz /= 2;
toucher->momz -= (toucher->momz/(underwater ? 8 : 4)); // Cap the height! toucher->momz -= (toucher->momz/(underwater ? 8 : 4)); // Cap the height!
@ -1388,6 +1388,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (player->bot) if (player->bot)
return; return;
// Initialize my junk
junk.tags.tags = NULL;
junk.tags.count = 0;
Tag_FSet(&junk.tags, LE_AXE); Tag_FSet(&junk.tags, LE_AXE);
EV_DoElevator(&junk, bridgeFall, false); EV_DoElevator(&junk, bridgeFall, false);
@ -1613,7 +1617,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->tracer && !(special->tracer->flags2 & MF2_STRONGBOX)) if (special->tracer && !(special->tracer->flags2 & MF2_STRONGBOX))
macespin = true; macespin = true;
if (macespin ? (player->powers[pw_ignorelatch] & (1<<15)) : (player->powers[pw_ignorelatch])) if (macespin ? (player->powers[pw_ignorelatch] & (1<<15)) : (player->powers[pw_ignorelatch]))
return; return;

View File

@ -279,6 +279,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype);
void P_RespawnSpecials(void); void P_RespawnSpecials(void);
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
void P_SetMobjSpawnDefaults(mobj_t *mobj);
void P_RecalcPrecipInSector(sector_t *sector); void P_RecalcPrecipInSector(sector_t *sector);
void P_PrecipitationEffects(void); void P_PrecipitationEffects(void);
@ -326,9 +327,7 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za,
mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z, INT32 shiftingAngle); mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z, INT32 shiftingAngle);
mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype, UINT32 flags2); mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype, UINT32 flags2);
#define P_SpawnPlayerMissile(s,t,f) P_SPMAngle(s,t,s->angle,true,f) #define P_SpawnPlayerMissile(s,t,f) P_SPMAngle(s,t,s->angle,true,f)
#ifdef SEENAMES
#define P_SpawnNameFinder(s,t) P_SPMAngle(s,t,s->angle,true,0) #define P_SpawnNameFinder(s,t) P_SPMAngle(s,t,s->angle,true,0)
#endif
void P_ColorTeamMissile(mobj_t *missile, player_t *source); void P_ColorTeamMissile(mobj_t *missile, player_t *source);
SINT8 P_MobjFlip(mobj_t *mobj); SINT8 P_MobjFlip(mobj_t *mobj);
fixed_t P_GetMobjGravity(mobj_t *mo); fixed_t P_GetMobjGravity(mobj_t *mo);

View File

@ -727,9 +727,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
|| (thing->player && thing->player->spectator)) || (thing->player && thing->player->spectator))
return true; return true;
#ifdef SEENAMES // Do name checks all the way up here
// Do name checks all the way up here // So that NOTHING ELSE can see MT_NAMECHECK because it is client-side.
// So that NOTHING ELSE can see MT_NAMECHECK because it is client-side.
if (tmthing->type == MT_NAMECHECK) if (tmthing->type == MT_NAMECHECK)
{ {
// Ignore things that aren't players, ignore spectators, ignore yourself. // Ignore things that aren't players, ignore spectators, ignore yourself.
@ -753,7 +752,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
seenplayer = thing->player; seenplayer = thing->player;
return false; return false;
} }
#endif
// Metal Sonic destroys tiny baby objects. // Metal Sonic destroys tiny baby objects.
if (tmthing->type == MT_METALSONIC_RACE if (tmthing->type == MT_METALSONIC_RACE
@ -982,7 +980,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_SALOONDOOR && tmthing->player) if (thing->type == MT_SALOONDOOR && tmthing->player)
{ {
mobj_t *ref = (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)) ? tmthing->tracer : tmthing; mobj_t *ref = (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)) ? tmthing->tracer : tmthing;
if ((thing->flags2 & MF2_AMBUSH) || ref != tmthing) if (((thing->flags2 & MF2_AMBUSH) && (tmthing->z <= thing->z + thing->height) && (tmthing->z + tmthing->height >= thing->z))
|| ref != tmthing)
{ {
fixed_t dm = min(FixedHypot(ref->momx, ref->momy), 16*FRACUNIT); fixed_t dm = min(FixedHypot(ref->momx, ref->momy), 16*FRACUNIT);
angle_t ang = R_PointToAngle2(0, 0, ref->momx, ref->momy) - thing->angle; angle_t ang = R_PointToAngle2(0, 0, ref->momx, ref->momy) - thing->angle;
@ -995,7 +994,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_SALOONDOORCENTER && tmthing->player) if (thing->type == MT_SALOONDOORCENTER && tmthing->player)
{ {
if ((thing->flags2 & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer))) if (((thing->flags2 & MF2_AMBUSH) && (tmthing->z <= thing->z + thing->height) && (tmthing->z + tmthing->height >= thing->z))
|| (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)))
return true; return true;
} }
@ -1683,7 +1683,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
{ {
fixed_t setmomz = -*momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce fixed_t setmomz = -*momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce
if (elementalpierce == 2) // Reset bubblewrap, part 1 if (elementalpierce == 2) // Reset bubblewrap, part 1
P_DoBubbleBounce(player); P_DoBubbleBounce(player);
*momz = setmomz; // Therefore, you should be thrust in the opposite direction, vertically. *momz = setmomz; // Therefore, you should be thrust in the opposite direction, vertically.
@ -1692,7 +1692,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (elementalpierce == 2) // Reset bubblewrap, part 2 if (elementalpierce == 2) // Reset bubblewrap, part 2
{ {
boolean underwater = tmthing->eflags & MFE_UNDERWATER; boolean underwater = tmthing->eflags & MFE_UNDERWATER;
if (underwater) if (underwater)
*momz /= 2; *momz /= 2;
*momz -= (*momz/(underwater ? 8 : 4)); // Cap the height! *momz -= (*momz/(underwater ? 8 : 4)); // Cap the height!
@ -3443,9 +3443,17 @@ static boolean PTR_SlideTraverse(intercept_t *in)
P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector);
} }
if (slidemo->player && slidemo->player->charability == CA_GLIDEANDCLIMB if (slidemo->player)
&& (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing)) {
PTR_GlideClimbTraverse(li); if (slidemo->player->charability == CA_GLIDEANDCLIMB
&& (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing))
PTR_GlideClimbTraverse(li);
else
{
slidemo->player->lastsidehit = li->sidenum[P_PointOnLineSide(slidemo->x, slidemo->y, li)];
slidemo->player->lastlinehit = (INT16)(li - lines);
}
}
if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing))
{ {

View File

@ -3366,7 +3366,7 @@ void P_MobjCheckWater(mobj_t *mobj)
} }
// skipping stone! // skipping stone!
if (p && (p->charability2 == CA2_SPINDASH) && p->speed/2 > abs(mobj->momz) if (p && p->speed/2 > abs(mobj->momz)
&& ((p->pflags & (PF_SPINNING|PF_JUMPED)) == PF_SPINNING) && ((p->pflags & (PF_SPINNING|PF_JUMPED)) == PF_SPINNING)
&& ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop) && ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop)
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom))) || ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom)))
@ -5654,14 +5654,10 @@ static void P_Boss9Thinker(mobj_t *mobj)
if (P_RandomRange(1,(dist>>FRACBITS)/16) == 1) if (P_RandomRange(1,(dist>>FRACBITS)/16) == 1)
break; break;
} }
if (spawner) if (spawner && dist)
{ {
mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER); mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER);
missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy));
if (dist == 0)
missile->fuse = 0;
else
missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy));
if (missile->fuse > mobj->fuse) if (missile->fuse > mobj->fuse)
P_RemoveMobj(missile); P_RemoveMobj(missile);
@ -7937,7 +7933,7 @@ static boolean P_MobjPushableThink(mobj_t *mobj)
P_PushableThinker(mobj); P_PushableThinker(mobj);
// Extinguish fire objects in water. (Yes, it's extraordinarily rare to have a pushable flame object, but Brak uses such a case.) // Extinguish fire objects in water. (Yes, it's extraordinarily rare to have a pushable flame object, but Brak uses such a case.)
if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL if ((mobj->flags & MF_FIRE) && !(mobj->eflags & MFE_TOUCHLAVA)
&& (mobj->eflags & (MFE_UNDERWATER | MFE_TOUCHWATER))) && (mobj->eflags & (MFE_UNDERWATER | MFE_TOUCHWATER)))
{ {
P_KillMobj(mobj, NULL, NULL, 0); P_KillMobj(mobj, NULL, NULL, 0);
@ -9651,6 +9647,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
break; break;
} }
case MT_SALOONDOOR: case MT_SALOONDOOR:
if (!mobj->tracer) // Door center is gone or not spawned?
{
P_RemoveMobj(mobj); // Die
return false;
}
P_SaloonDoorThink(mobj); P_SaloonDoorThink(mobj);
break; break;
case MT_MINECARTSPAWNER: case MT_MINECARTSPAWNER:
@ -9705,7 +9707,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_MobjCheckWater(mobj); P_MobjCheckWater(mobj);
// Extinguish fire objects in water // Extinguish fire objects in water
if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL if ((mobj->flags & MF_FIRE) && !(mobj->eflags & MFE_TOUCHLAVA)
&& (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
{ {
P_KillMobj(mobj, NULL, NULL, 0); P_KillMobj(mobj, NULL, NULL, 0);
@ -9835,7 +9837,7 @@ static void P_FlagFuseThink(mobj_t *mobj)
if (mobj->type == MT_REDFLAG) if (mobj->type == MT_REDFLAG)
{ {
if (!(mobj->flags2 & MF2_JUSTATTACKED)) if (!(mobj->flags2 & MF2_JUSTATTACKED))
CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80); CONS_Printf(M_GetText("The \205Red flag\200 has returned to base.\n"));
// Assumedly in splitscreen players will be on opposing teams // Assumedly in splitscreen players will be on opposing teams
if (players[consoleplayer].ctfteam == 1 || splitscreen) if (players[consoleplayer].ctfteam == 1 || splitscreen)
@ -9848,7 +9850,7 @@ static void P_FlagFuseThink(mobj_t *mobj)
else // MT_BLUEFLAG else // MT_BLUEFLAG
{ {
if (!(mobj->flags2 & MF2_JUSTATTACKED)) if (!(mobj->flags2 & MF2_JUSTATTACKED))
CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80); CONS_Printf(M_GetText("The \204Blue flag\200 has returned to base.\n"));
// Assumedly in splitscreen players will be on opposing teams // Assumedly in splitscreen players will be on opposing teams
if (players[consoleplayer].ctfteam == 2 || splitscreen) if (players[consoleplayer].ctfteam == 2 || splitscreen)
@ -10438,52 +10440,12 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->x = x; mobj->x = x;
mobj->y = y; mobj->y = y;
mobj->radius = info->radius; P_SetMobjSpawnDefaults(mobj);
mobj->height = info->height;
mobj->flags = info->flags;
mobj->health = (info->spawnhealth ? info->spawnhealth : 1);
mobj->reactiontime = info->reactiontime;
mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer
// do not set the state with P_SetMobjState,
// because action routines can not be called yet
st = &states[info->spawnstate];
mobj->state = st;
mobj->tics = st->tics;
mobj->sprite = st->sprite;
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
P_SetupStateAnimation(mobj, st);
mobj->friction = ORIG_FRICTION;
mobj->movefactor = FRACUNIT;
// All mobjs are created at 100% scale.
mobj->scale = FRACUNIT;
mobj->destscale = mobj->scale;
mobj->scalespeed = FRACUNIT/12;
// TODO: Make this a special map header
if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN))
mobj->destscale = FRACUNIT/2;
// Sprite rendering
mobj->blendmode = AST_TRANSLUCENT;
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
mobj->spritexoffset = mobj->spriteyoffset = 0;
mobj->floorspriteslope = NULL;
// set subsector and/or block links // set subsector and/or block links
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
I_Assert(mobj->subsector != NULL); I_Assert(mobj->subsector != NULL);
// Make sure scale matches destscale immediately when spawned
P_SetScale(mobj, mobj->destscale);
mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y); mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y); mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
@ -10785,6 +10747,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->frame &= ~FF_FRAMEMASK; mobj->frame &= ~FF_FRAMEMASK;
} }
st = &states[info->spawnstate];
// Call action functions when the state is set // Call action functions when the state is set
if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC)) if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC))
{ {
@ -10815,6 +10779,52 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
return mobj; return mobj;
} }
void P_SetMobjSpawnDefaults(mobj_t *mobj)
{
const mobjinfo_t *info = mobj->info;
state_t *st = &states[info->spawnstate];
mobj->radius = info->radius;
mobj->height = info->height;
mobj->flags = info->flags;
mobj->health = (info->spawnhealth ? info->spawnhealth : 1);
mobj->reactiontime = info->reactiontime;
mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer
// do not set the state with P_SetMobjState,
// because action routines can not be called yet
mobj->state = st;
mobj->tics = st->tics;
mobj->sprite = st->sprite;
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
P_SetupStateAnimation(mobj, st);
mobj->friction = ORIG_FRICTION;
mobj->movefactor = FRACUNIT;
// All mobjs are created at 100% scale.
mobj->scale = FRACUNIT;
mobj->destscale = mobj->scale;
mobj->scalespeed = FRACUNIT/12;
// TODO: Make this a special map header
if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN))
mobj->destscale = FRACUNIT/2;
// Make sure scale matches destscale immediately when spawned
P_SetScale(mobj, mobj->destscale);
// Sprite rendering
mobj->blendmode = AST_TRANSLUCENT;
mobj->spritexscale = mobj->spriteyscale = FRACUNIT;
mobj->spritexoffset = mobj->spriteyoffset = 0;
mobj->floorspriteslope = NULL;
}
static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
{ {
state_t *st; state_t *st;
@ -11397,6 +11407,10 @@ void P_SpawnPlayer(INT32 playernum)
p->jumpfactor = skins[p->skin].jumpfactor; p->jumpfactor = skins[p->skin].jumpfactor;
} }
// Clear lastlinehit and lastsidehit
p->lastsidehit = -1;
p->lastlinehit = -1;
//awayview stuff //awayview stuff
p->awayviewmobj = NULL; p->awayviewmobj = NULL;
p->awayviewtics = 0; p->awayviewtics = 0;
@ -11792,7 +11806,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
if (!(G_CoopGametype() || (mthing->options & MTF_EXTRA))) if (!(G_CoopGametype() || (mthing->options & MTF_EXTRA)))
return false; // she doesn't hang out here return false; // she doesn't hang out here
if (!mariomode && !(netgame || multiplayer) && players[consoleplayer].skin == 3) if (!(netgame || multiplayer) && players[consoleplayer].skin == 3)
return false; // no doubles return false; // no doubles
break; break;

View File

@ -1506,7 +1506,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
{ {
const mobj_t *mobj = (const mobj_t *)th; const mobj_t *mobj = (const mobj_t *)th;
UINT32 diff; UINT32 diff;
UINT16 diff2; UINT32 diff2;
// Ignore stationary hoops - these will be respawned from mapthings. // Ignore stationary hoops - these will be respawned from mapthings.
if (mobj->type == MT_HOOP) if (mobj->type == MT_HOOP)
@ -1638,7 +1638,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_SHADOWSCALE; diff2 |= MD2_SHADOWSCALE;
if (mobj->renderflags) if (mobj->renderflags)
diff2 |= MD2_RENDERFLAGS; diff2 |= MD2_RENDERFLAGS;
if (mobj->renderflags) if (mobj->blendmode != AST_TRANSLUCENT)
diff2 |= MD2_BLENDMODE; diff2 |= MD2_BLENDMODE;
if (mobj->spritexscale != FRACUNIT) if (mobj->spritexscale != FRACUNIT)
diff2 |= MD2_SPRITEXSCALE; diff2 |= MD2_SPRITEXSCALE;
@ -1646,6 +1646,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_SPRITEYSCALE; diff2 |= MD2_SPRITEYSCALE;
if (mobj->spritexoffset) if (mobj->spritexoffset)
diff2 |= MD2_SPRITEXOFFSET; diff2 |= MD2_SPRITEXOFFSET;
if (mobj->spriteyoffset)
diff2 |= MD2_SPRITEYOFFSET;
if (mobj->floorspriteslope) if (mobj->floorspriteslope)
{ {
pslope_t *slope = mobj->floorspriteslope; pslope_t *slope = mobj->floorspriteslope;
@ -1667,7 +1669,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT8(save_p, type); WRITEUINT8(save_p, type);
WRITEUINT32(save_p, diff); WRITEUINT32(save_p, diff);
if (diff & MD_MORE) if (diff & MD_MORE)
WRITEUINT16(save_p, diff2); WRITEUINT32(save_p, diff2);
// save pointer, at load time we will search this pointer to reinitilize pointers // save pointer, at load time we will search this pointer to reinitilize pointers
WRITEUINT32(save_p, (size_t)mobj); WRITEUINT32(save_p, (size_t)mobj);
@ -2615,14 +2617,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
thinker_t *next; thinker_t *next;
mobj_t *mobj; mobj_t *mobj;
UINT32 diff; UINT32 diff;
UINT16 diff2; UINT32 diff2;
INT32 i; INT32 i;
fixed_t z, floorz, ceilingz; fixed_t z, floorz, ceilingz;
ffloor_t *floorrover = NULL, *ceilingrover = NULL; ffloor_t *floorrover = NULL, *ceilingrover = NULL;
diff = READUINT32(save_p); diff = READUINT32(save_p);
if (diff & MD_MORE) if (diff & MD_MORE)
diff2 = READUINT16(save_p); diff2 = READUINT32(save_p);
else else
diff2 = 0; diff2 = 0;
@ -2690,7 +2692,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
} }
mobj->type = i; mobj->type = i;
} }
mobj->info = &mobjinfo[mobj->type]; mobj->info = &mobjinfo[mobj->type];
P_SetMobjSpawnDefaults(mobj);
if (diff & MD_POS) if (diff & MD_POS)
{ {
mobj->x = READFIXED(save_p); mobj->x = READFIXED(save_p);
@ -2716,35 +2721,21 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
if (diff & MD_RADIUS) if (diff & MD_RADIUS)
mobj->radius = READFIXED(save_p); mobj->radius = READFIXED(save_p);
else
mobj->radius = mobj->info->radius;
if (diff & MD_HEIGHT) if (diff & MD_HEIGHT)
mobj->height = READFIXED(save_p); mobj->height = READFIXED(save_p);
else
mobj->height = mobj->info->height;
if (diff & MD_FLAGS) if (diff & MD_FLAGS)
mobj->flags = READUINT32(save_p); mobj->flags = READUINT32(save_p);
else
mobj->flags = mobj->info->flags;
if (diff & MD_FLAGS2) if (diff & MD_FLAGS2)
mobj->flags2 = READUINT32(save_p); mobj->flags2 = READUINT32(save_p);
if (diff & MD_HEALTH) if (diff & MD_HEALTH)
mobj->health = READINT32(save_p); mobj->health = READINT32(save_p);
else
mobj->health = mobj->info->spawnhealth;
if (diff & MD_RTIME) if (diff & MD_RTIME)
mobj->reactiontime = READINT32(save_p); mobj->reactiontime = READINT32(save_p);
else
mobj->reactiontime = mobj->info->reactiontime;
if (diff & MD_STATE) if (diff & MD_STATE)
mobj->state = &states[READUINT16(save_p)]; mobj->state = &states[READUINT16(save_p)];
else
mobj->state = &states[mobj->info->spawnstate];
if (diff & MD_TICS) if (diff & MD_TICS)
mobj->tics = READINT32(save_p); mobj->tics = READINT32(save_p);
else
mobj->tics = mobj->state->tics;
if (diff & MD_SPRITE) { if (diff & MD_SPRITE) {
mobj->sprite = READUINT16(save_p); mobj->sprite = READUINT16(save_p);
if (mobj->sprite == SPR_PLAY) if (mobj->sprite == SPR_PLAY)
@ -2760,11 +2751,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->frame = READUINT32(save_p); mobj->frame = READUINT32(save_p);
mobj->anim_duration = READUINT16(save_p); mobj->anim_duration = READUINT16(save_p);
} }
else
{
mobj->frame = mobj->state->frame;
mobj->anim_duration = (UINT16)mobj->state->var2;
}
if (diff & MD_EFLAGS) if (diff & MD_EFLAGS)
mobj->eflags = READUINT16(save_p); mobj->eflags = READUINT16(save_p);
if (diff & MD_PLAYER) if (diff & MD_PLAYER)
@ -2781,20 +2767,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->threshold = READINT32(save_p); mobj->threshold = READINT32(save_p);
if (diff & MD_LASTLOOK) if (diff & MD_LASTLOOK)
mobj->lastlook = READINT32(save_p); mobj->lastlook = READINT32(save_p);
else
mobj->lastlook = -1;
if (diff & MD_TARGET) if (diff & MD_TARGET)
mobj->target = (mobj_t *)(size_t)READUINT32(save_p); mobj->target = (mobj_t *)(size_t)READUINT32(save_p);
if (diff & MD_TRACER) if (diff & MD_TRACER)
mobj->tracer = (mobj_t *)(size_t)READUINT32(save_p); mobj->tracer = (mobj_t *)(size_t)READUINT32(save_p);
if (diff & MD_FRICTION) if (diff & MD_FRICTION)
mobj->friction = READFIXED(save_p); mobj->friction = READFIXED(save_p);
else
mobj->friction = ORIG_FRICTION;
if (diff & MD_MOVEFACTOR) if (diff & MD_MOVEFACTOR)
mobj->movefactor = READFIXED(save_p); mobj->movefactor = READFIXED(save_p);
else
mobj->movefactor = FRACUNIT;
if (diff & MD_FUSE) if (diff & MD_FUSE)
mobj->fuse = READINT32(save_p); mobj->fuse = READINT32(save_p);
if (diff & MD_WATERTOP) if (diff & MD_WATERTOP)
@ -2803,16 +2783,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->waterbottom = READFIXED(save_p); mobj->waterbottom = READFIXED(save_p);
if (diff & MD_SCALE) if (diff & MD_SCALE)
mobj->scale = READFIXED(save_p); mobj->scale = READFIXED(save_p);
else
mobj->scale = FRACUNIT;
if (diff & MD_DSCALE) if (diff & MD_DSCALE)
mobj->destscale = READFIXED(save_p); mobj->destscale = READFIXED(save_p);
else
mobj->destscale = mobj->scale;
if (diff2 & MD2_SCALESPEED) if (diff2 & MD2_SCALESPEED)
mobj->scalespeed = READFIXED(save_p); mobj->scalespeed = READFIXED(save_p);
else
mobj->scalespeed = FRACUNIT/12;
if (diff2 & MD2_CUSVAL) if (diff2 & MD2_CUSVAL)
mobj->cusval = READINT32(save_p); mobj->cusval = READINT32(save_p);
if (diff2 & MD2_CVMEM) if (diff2 & MD2_CVMEM)

View File

@ -1621,6 +1621,14 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val)
P_SetLinedefV1(i, atol(val)); P_SetLinedefV1(i, atol(val));
else if (fastcmp(param, "v2")) else if (fastcmp(param, "v2"))
P_SetLinedefV2(i, atol(val)); P_SetLinedefV2(i, atol(val));
else if (strlen(param) == 7 && fastncmp(param, "arg", 3) && fastncmp(param + 4, "str", 3))
{
size_t argnum = param[3] - '0';
if (argnum >= NUMLINESTRINGARGS)
return;
lines[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(lines[i].stringargs[argnum], val, strlen(val) + 1);
}
else if (fastncmp(param, "arg", 3) && strlen(param) > 3) else if (fastncmp(param, "arg", 3) && strlen(param) > 3)
{ {
size_t argnum = atol(param + 3); size_t argnum = atol(param + 3);
@ -1628,14 +1636,6 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val)
return; return;
lines[i].args[argnum] = atol(val); lines[i].args[argnum] = atol(val);
} }
else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9)
{
size_t argnum = param[9] - '0';
if (argnum >= NUMLINESTRINGARGS)
return;
lines[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(lines[i].stringargs[argnum], val, strlen(val) + 1);
}
else if (fastcmp(param, "sidefront")) else if (fastcmp(param, "sidefront"))
lines[i].sidenum[0] = atol(val); lines[i].sidenum[0] = atol(val);
else if (fastcmp(param, "sideback")) else if (fastcmp(param, "sideback"))
@ -1720,6 +1720,14 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
else if (fastcmp(param, "ambush") && fastcmp("true", val)) else if (fastcmp(param, "ambush") && fastcmp("true", val))
mapthings[i].options |= MTF_AMBUSH; mapthings[i].options |= MTF_AMBUSH;
else if (strlen(param) == 7 && fastncmp(param, "arg", 3) && fastncmp(param + 4, "str", 3))
{
size_t argnum = param[3] - '0';
if (argnum >= NUMMAPTHINGSTRINGARGS)
return;
mapthings[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(mapthings[i].stringargs[argnum], val, strlen(val) + 1);
}
else if (fastncmp(param, "arg", 3) && strlen(param) > 3) else if (fastncmp(param, "arg", 3) && strlen(param) > 3)
{ {
size_t argnum = atol(param + 3); size_t argnum = atol(param + 3);
@ -1727,14 +1735,6 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
return; return;
mapthings[i].args[argnum] = atol(val); mapthings[i].args[argnum] = atol(val);
} }
else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9)
{
size_t argnum = param[9] - '0';
if (argnum >= NUMMAPTHINGSTRINGARGS)
return;
mapthings[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(mapthings[i].stringargs[argnum], val, strlen(val) + 1);
}
} }
/** From a given position table, run a specified parser function through a {}-encapsuled text. /** From a given position table, run a specified parser function through a {}-encapsuled text.
@ -3171,7 +3171,7 @@ static void P_ConvertBinaryMap(void)
switch (mapthings[i].type) switch (mapthings[i].type)
{ {
case 750: case 750:
Tag_Add(&mapthings[i].tags, mapthings[i].angle); Tag_FSet(&mapthings[i].tags, mapthings[i].angle);
break; break;
case 760: case 760:
case 761: case 761:

View File

@ -4304,7 +4304,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
if (leveltime % (TICRATE/2) == 0 && player->rings > 0) if (leveltime % (TICRATE/2) == 0 && player->rings > 0)
{ {
player->rings--; player->rings--;
S_StartSound(player->mo, sfx_itemup); S_StartSound(player->mo, sfx_antiri);
} }
break; break;
case 11: // Special Stage Damage case 11: // Special Stage Damage
@ -4420,15 +4420,19 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
// clear the special so you can't push the button twice. // clear the special so you can't push the button twice.
sector->special = 0; sector->special = 0;
// Initialize my junk
junk.tags.tags = NULL;
junk.tags.count = 0;
// Move the button down // Move the button down
Tag_FSet(&junk.tags, 680); Tag_FSet(&junk.tags, LE_CAPSULE0);
EV_DoElevator(&junk, elevateDown, false); EV_DoElevator(&junk, elevateDown, false);
// Open the top FOF // Open the top FOF
Tag_FSet(&junk.tags, 681); Tag_FSet(&junk.tags, LE_CAPSULE1);
EV_DoFloor(&junk, raiseFloorToNearestFast); EV_DoFloor(&junk, raiseFloorToNearestFast);
// Open the bottom FOF // Open the bottom FOF
Tag_FSet(&junk.tags, 682); Tag_FSet(&junk.tags, LE_CAPSULE2);
EV_DoCeiling(&junk, lowerToLowestFast); EV_DoCeiling(&junk, lowerToLowestFast);
// Mark all players with the time to exit thingy! // Mark all players with the time to exit thingy!
@ -4503,7 +4507,7 @@ DoneSection2:
P_InstaThrust(player->mo, player->mo->angle, linespeed); P_InstaThrust(player->mo, player->mo->angle, linespeed);
if ((lines[i].flags & ML_EFFECT5) && (player->charability2 == CA2_SPINDASH)) // Roll! if (lines[i].flags & ML_EFFECT5) // Roll!
{ {
if (!(player->pflags & PF_SPINNING)) if (!(player->pflags & PF_SPINNING))
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
@ -4600,7 +4604,7 @@ DoneSection2:
HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE);
HU_SetCEchoDuration(5); HU_SetCEchoDuration(5);
HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sBLUE FLAG%s.\\\\\\\\"), "\x85", player_names[player-players], "\x80", "\x84", "\x80")); HU_DoCEcho(va(M_GetText("\205%s\200\\CAPTURED THE \204BLUE FLAG\200.\\\\\\\\"), player_names[player-players]));
if (splitscreen || players[consoleplayer].ctfteam == 1) if (splitscreen || players[consoleplayer].ctfteam == 1)
S_StartSound(NULL, sfx_flgcap); S_StartSound(NULL, sfx_flgcap);
@ -4633,7 +4637,7 @@ DoneSection2:
HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE);
HU_SetCEchoDuration(5); HU_SetCEchoDuration(5);
HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sRED FLAG%s.\\\\\\\\"), "\x84", player_names[player-players], "\x80", "\x85", "\x80")); HU_DoCEcho(va(M_GetText("\204%s\200\\CAPTURED THE \205RED FLAG\200.\\\\\\\\"), player_names[player-players]));
if (splitscreen || players[consoleplayer].ctfteam == 2) if (splitscreen || players[consoleplayer].ctfteam == 2)
S_StartSound(NULL, sfx_flgcap); S_StartSound(NULL, sfx_flgcap);
@ -4669,7 +4673,7 @@ DoneSection2:
break; break;
case 7: // Make player spin case 7: // Make player spin
if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH)) if (!(player->pflags & PF_SPINNING))
{ {
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
@ -4823,6 +4827,8 @@ DoneSection2:
if (player->laps >= (UINT8)cv_numlaps.value) if (player->laps >= (UINT8)cv_numlaps.value)
CONS_Printf(M_GetText("%s has finished the race.\n"), player_names[player-players]); CONS_Printf(M_GetText("%s has finished the race.\n"), player_names[player-players]);
else if (player->laps == (UINT8)cv_numlaps.value-1)
CONS_Printf(M_GetText("%s started the \205final lap\200!\n"), player_names[player-players]);
else else
CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1); CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1);

View File

@ -22,7 +22,7 @@
#include "lua_script.h" #include "lua_script.h"
#include "lua_hook.h" #include "lua_hook.h"
#include "m_perfstats.h" #include "m_perfstats.h"
#include "i_system.h" // I_GetTimeMicros #include "i_system.h" // I_GetPreciseTime
// Object place // Object place
#include "m_cheat.h" #include "m_cheat.h"
@ -323,7 +323,7 @@ static inline void P_RunThinkers(void)
size_t i; size_t i;
for (i = 0; i < NUM_THINKERLISTS; i++) for (i = 0; i < NUM_THINKERLISTS; i++)
{ {
ps_thlist_times[i] = I_GetTimeMicros(); ps_thlist_times[i] = I_GetPreciseTime();
for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = currentthinker->next) for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = currentthinker->next)
{ {
#ifdef PARANOIA #ifdef PARANOIA
@ -331,7 +331,7 @@ static inline void P_RunThinkers(void)
#endif #endif
currentthinker->function.acp1(currentthinker); currentthinker->function.acp1(currentthinker);
} }
ps_thlist_times[i] = I_GetTimeMicros() - ps_thlist_times[i]; ps_thlist_times[i] = I_GetPreciseTime() - ps_thlist_times[i];
} }
} }
@ -658,11 +658,11 @@ void P_Ticker(boolean run)
LUAh_PreThinkFrame(); LUAh_PreThinkFrame();
ps_playerthink_time = I_GetTimeMicros(); ps_playerthink_time = I_GetPreciseTime();
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
P_PlayerThink(&players[i]); P_PlayerThink(&players[i]);
ps_playerthink_time = I_GetTimeMicros() - ps_playerthink_time; ps_playerthink_time = I_GetPreciseTime() - ps_playerthink_time;
} }
// Keep track of how long they've been playing! // Keep track of how long they've been playing!
@ -677,18 +677,18 @@ void P_Ticker(boolean run)
if (run) if (run)
{ {
ps_thinkertime = I_GetTimeMicros(); ps_thinkertime = I_GetPreciseTime();
P_RunThinkers(); P_RunThinkers();
ps_thinkertime = I_GetTimeMicros() - ps_thinkertime; ps_thinkertime = I_GetPreciseTime() - ps_thinkertime;
// Run any "after all the other thinkers" stuff // Run any "after all the other thinkers" stuff
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
P_PlayerAfterThink(&players[i]); P_PlayerAfterThink(&players[i]);
ps_lua_thinkframe_time = I_GetTimeMicros(); ps_lua_thinkframe_time = I_GetPreciseTime();
LUAh_ThinkFrame(); LUAh_ThinkFrame();
ps_lua_thinkframe_time = I_GetTimeMicros() - ps_lua_thinkframe_time; ps_lua_thinkframe_time = I_GetPreciseTime() - ps_lua_thinkframe_time;
} }
// Run shield positioning // Run shield positioning

View File

@ -1341,7 +1341,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
// Transformation animation // Transformation animation
P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1);
if (giverings) if (giverings && player->rings < 50)
player->rings = 50; player->rings = 50;
// Just in case. // Just in case.
@ -1491,10 +1491,10 @@ void P_PlayLivesJingle(player_t *player)
if (player && !P_IsLocalPlayer(player)) if (player && !P_IsLocalPlayer(player))
return; return;
if (use1upSound || cv_1upsound.value) if (mariomode)
S_StartSound(NULL, sfx_oneup);
else if (mariomode)
S_StartSound(NULL, sfx_marioa); S_StartSound(NULL, sfx_marioa);
else if (use1upSound || cv_1upsound.value)
S_StartSound(NULL, sfx_oneup);
else else
{ {
P_PlayJingle(player, JT_1UP); P_PlayJingle(player, JT_1UP);
@ -2329,7 +2329,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
P_MobjCheckWater(player->mo); P_MobjCheckWater(player->mo);
if (player->pflags & PF_SPINNING) if (player->pflags & PF_SPINNING)
{ {
if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH)) if (!(player->pflags & PF_STARTDASH) && player->panim != PA_ROLL && player->panim != PA_ETC
&& player->panim != PA_ABILITY && player->panim != PA_ABILITY2)
{ {
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_spin); S_StartSound(player->mo, sfx_spin);
@ -2612,10 +2613,10 @@ static void P_CheckBustableBlocks(player_t *player)
if ((netgame || multiplayer) && player->spectator) if ((netgame || multiplayer) && player->spectator)
return; return;
oldx = player->mo->x; oldx = player->mo->x;
oldy = player->mo->y; oldy = player->mo->y;
if (!(player->pflags & PF_BOUNCING)) // Bouncers only get to break downwards, not sideways if (!(player->pflags & PF_BOUNCING)) // Bouncers only get to break downwards, not sideways
{ {
P_UnsetThingPosition(player->mo); P_UnsetThingPosition(player->mo);
@ -2634,7 +2635,7 @@ static void P_CheckBustableBlocks(player_t *player)
if (!node->m_sector->ffloors) if (!node->m_sector->ffloors)
continue; continue;
for (rover = node->m_sector->ffloors; rover; rover = rover->next) for (rover = node->m_sector->ffloors; rover; rover = rover->next)
{ {
if (!P_PlayerCanBust(player, rover)) if (!P_PlayerCanBust(player, rover))
@ -4525,6 +4526,9 @@ void P_DoJump(player_t *player, boolean soundandstate)
player->pflags |= P_GetJumpFlags(player);; player->pflags |= P_GetJumpFlags(player);;
if (player->charflags & SF_NOJUMPDAMAGE)
player->pflags &= ~PF_SPINNING;
if (soundandstate) if (soundandstate)
{ {
if (!player->spectator) if (!player->spectator)
@ -5020,7 +5024,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN) if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN)
&& ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted && ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted
{ {
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY))
{ {
if ((lockonshield = P_LookForEnemies(player, false, false))) if ((lockonshield = P_LookForEnemies(player, false, false)))
{ {
@ -5043,7 +5047,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
} }
} }
} }
if (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player)) // Spin button effects if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player))) // Spin button effects
{ {
// Force stop // Force stop
if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE)
@ -5491,7 +5495,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
break; break;
} }
} }
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super]) else if ((!(player->charflags & SF_NOSHIELDABILITY)) && ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super] && !LUAh_ShieldSpecial(player)))
P_DoJumpShield(player); P_DoJumpShield(player);
} }
@ -5920,7 +5924,7 @@ static void P_3dMovement(player_t *player)
player->rmomy = player->mo->momy - player->cmomy; player->rmomy = player->mo->momy - player->cmomy;
// Calculates player's speed based on distance-of-a-line formula // Calculates player's speed based on distance-of-a-line formula
player->speed = P_AproxDistance(player->rmomx, player->rmomy); player->speed = R_PointToDist2(0, 0, player->rmomx, player->rmomy);
// Monster Iestyn - 04-11-13 // Monster Iestyn - 04-11-13
// Quadrants are stupid, excessive and broken, let's do this a much simpler way! // Quadrants are stupid, excessive and broken, let's do this a much simpler way!
@ -7752,6 +7756,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale));
P_SetObjectMomZ(flame, 3*FRACUNIT, false); P_SetObjectMomZ(flame, 3*FRACUNIT, false);
if (!(gametyperules & GTR_FRIENDLY))
{
P_SetMobjState(flame, S_TEAM_SPINFIRE1);
flame->color = player->mo->color;
}
} }
#undef limitangle #undef limitangle
#undef numangles #undef numangles
@ -7779,6 +7788,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
flame->destscale = player->mo->scale; flame->destscale = player->mo->scale;
P_SetScale(flame, player->mo->scale); P_SetScale(flame, player->mo->scale);
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
if (!(gametyperules & GTR_FRIENDLY))
{
P_SetMobjState(flame, S_TEAM_SPINFIRE1);
flame->color = player->mo->color;
}
flame->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others flame->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others
P_XYMovement(flame); P_XYMovement(flame);
@ -8605,12 +8619,6 @@ void P_MovePlayer(player_t *player)
player->climbing--; player->climbing--;
} }
if (!player->climbing)
{
player->lastsidehit = -1;
player->lastlinehit = -1;
}
// Make sure you're not teetering when you shouldn't be. // Make sure you're not teetering when you shouldn't be.
if (player->panim == PA_EDGE if (player->panim == PA_EDGE
&& (player->mo->momx || player->mo->momy || player->mo->momz)) && (player->mo->momx || player->mo->momy || player->mo->momz))
@ -8635,6 +8643,7 @@ void P_MovePlayer(player_t *player)
P_DoFiring(player, cmd); P_DoFiring(player, cmd);
{ {
boolean atspinheight = false;
fixed_t oldheight = player->mo->height; fixed_t oldheight = player->mo->height;
// Less height while spinning. Good for spinning under things...? // Less height while spinning. Good for spinning under things...?
@ -8644,32 +8653,35 @@ void P_MovePlayer(player_t *player)
|| player->powers[pw_tailsfly] || player->pflags & PF_GLIDING || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING
|| (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING)
|| (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED))
{
player->mo->height = P_GetPlayerSpinHeight(player); player->mo->height = P_GetPlayerSpinHeight(player);
atspinheight = true;
}
else else
player->mo->height = P_GetPlayerHeight(player); player->mo->height = P_GetPlayerHeight(player);
if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling
player->mo->z -= player->mo->height - oldheight; player->mo->z -= player->mo->height - oldheight;
}
// Crush test... // Crush test...
if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) if ((player->mo->ceilingz - player->mo->floorz < player->mo->height)
&& !(player->mo->flags & MF_NOCLIP)) && !(player->mo->flags & MF_NOCLIP))
{
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SPINNING))
{ {
player->pflags |= PF_SPINNING; if (!atspinheight)
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); {
} player->pflags |= PF_SPINNING;
else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
{ }
if ((netgame || multiplayer) && player->spectator) else if (player->mo->ceilingz - player->mo->floorz < player->mo->height)
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators {
else if ((netgame || multiplayer) && player->spectator)
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED); P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators
else
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED);
if (player->playerstate == PST_DEAD) if (player->playerstate == PST_DEAD)
return; return;
}
} }
} }
@ -11482,7 +11494,6 @@ void P_PlayerThink(player_t *player)
} }
} }
#ifdef SEENAMES
if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5))) if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5)))
{ {
seenplayer = NULL; seenplayer = NULL;
@ -11507,7 +11518,6 @@ void P_PlayerThink(player_t *player)
} }
} }
} }
#endif
if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj))
{ {
@ -12578,13 +12588,16 @@ void P_PlayerAfterThink(player_t *player)
player->powers[pw_carry] = CR_NONE; player->powers[pw_carry] = CR_NONE;
else else
{ {
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true); if (tails->player)
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true);
else
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->angle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->angle, 4*FRACUNIT), true);
player->mo->momx = tails->momx; player->mo->momx = tails->momx;
player->mo->momy = tails->momy; player->mo->momy = tails->momy;
player->mo->momz = tails->momz; player->mo->momz = tails->momz;
} }
if (G_CoopGametype() && (!tails->player || tails->player->bot != 1)) if (G_CoopGametype() && tails->player && tails->player->bot != 1)
{ {
player->mo->angle = tails->angle; player->mo->angle = tails->angle;
@ -12599,7 +12612,7 @@ void P_PlayerAfterThink(player_t *player)
{ {
if (player->mo->state-states != S_PLAY_RIDE) if (player->mo->state-states != S_PLAY_RIDE)
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
if ((tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER)) if (tails->player && (tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER))
tails->player->powers[pw_tailsfly] = 0; tails->player->powers[pw_tailsfly] = 0;
} }
else else

View File

@ -106,13 +106,17 @@ extern lumpnum_t viewborderlump[8];
#define GTC_CACHE 1 #define GTC_CACHE 1
#define TC_DEFAULT -1 enum
#define TC_BOSS -2 {
#define TC_METALSONIC -3 // For Metal Sonic battle TC_BOSS = INT8_MIN,
#define TC_ALLWHITE -4 // For Cy-Brak-demon TC_METALSONIC, // For Metal Sonic battle
#define TC_RAINBOW -5 // For single colour TC_ALLWHITE, // For Cy-Brak-demon
#define TC_BLINK -6 // For item blinking, according to kart TC_RAINBOW, // For single colour
#define TC_DASHMODE -7 // For Metal Sonic's dashmode TC_BLINK, // For item blinking, according to kart
TC_DASHMODE, // For Metal Sonic's dashmode
TC_DEFAULT
};
// Custom player skin translation // Custom player skin translation
// Initialize color translation tables, for player rendering etc. // Initialize color translation tables, for player rendering etc.

View File

@ -34,7 +34,7 @@
#include "m_random.h" // quake camera shake #include "m_random.h" // quake camera shake
#include "r_portal.h" #include "r_portal.h"
#include "r_main.h" #include "r_main.h"
#include "i_system.h" // I_GetTimeMicros #include "i_system.h" // I_GetPreciseTime
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
@ -100,17 +100,17 @@ lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
extracolormap_t *extra_colormaps = NULL; extracolormap_t *extra_colormaps = NULL;
// Render stats // Render stats
int ps_prevframetime = 0; precise_t ps_prevframetime = 0;
int ps_rendercalltime = 0; precise_t ps_rendercalltime = 0;
int ps_uitime = 0; precise_t ps_uitime = 0;
int ps_swaptime = 0; precise_t ps_swaptime = 0;
int ps_bsptime = 0; precise_t ps_bsptime = 0;
int ps_sw_spritecliptime = 0; precise_t ps_sw_spritecliptime = 0;
int ps_sw_portaltime = 0; precise_t ps_sw_portaltime = 0;
int ps_sw_planetime = 0; precise_t ps_sw_planetime = 0;
int ps_sw_maskedtime = 0; precise_t ps_sw_maskedtime = 0;
int ps_numbspcalls = 0; int ps_numbspcalls = 0;
int ps_numsprites = 0; int ps_numsprites = 0;
@ -1498,9 +1498,9 @@ void R_RenderPlayerView(player_t *player)
ProfZeroTimer(); ProfZeroTimer();
#endif #endif
ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0; ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0;
ps_bsptime = I_GetTimeMicros(); ps_bsptime = I_GetPreciseTime();
R_RenderBSPNode((INT32)numnodes - 1); R_RenderBSPNode((INT32)numnodes - 1);
ps_bsptime = I_GetTimeMicros() - ps_bsptime; ps_bsptime = I_GetPreciseTime() - ps_bsptime;
ps_numsprites = visspritecount; ps_numsprites = visspritecount;
#ifdef TIMING #ifdef TIMING
RDMSR(0x10, &mycount); RDMSR(0x10, &mycount);
@ -1511,9 +1511,9 @@ void R_RenderPlayerView(player_t *player)
//profile stuff --------------------------------------------------------- //profile stuff ---------------------------------------------------------
Mask_Post(&masks[nummasks - 1]); Mask_Post(&masks[nummasks - 1]);
ps_sw_spritecliptime = I_GetTimeMicros(); ps_sw_spritecliptime = I_GetPreciseTime();
R_ClipSprites(drawsegs, NULL); R_ClipSprites(drawsegs, NULL);
ps_sw_spritecliptime = I_GetTimeMicros() - ps_sw_spritecliptime; ps_sw_spritecliptime = I_GetPreciseTime() - ps_sw_spritecliptime;
// Add skybox portals caused by sky visplanes. // Add skybox portals caused by sky visplanes.
@ -1521,7 +1521,7 @@ void R_RenderPlayerView(player_t *player)
Portal_AddSkyboxPortals(); Portal_AddSkyboxPortals();
// Portal rendering. Hijacks the BSP traversal. // Portal rendering. Hijacks the BSP traversal.
ps_sw_portaltime = I_GetTimeMicros(); ps_sw_portaltime = I_GetPreciseTime();
if (portal_base) if (portal_base)
{ {
portal_t *portal; portal_t *portal;
@ -1561,17 +1561,17 @@ void R_RenderPlayerView(player_t *player)
Portal_Remove(portal); Portal_Remove(portal);
} }
} }
ps_sw_portaltime = I_GetTimeMicros() - ps_sw_portaltime; ps_sw_portaltime = I_GetPreciseTime() - ps_sw_portaltime;
ps_sw_planetime = I_GetTimeMicros(); ps_sw_planetime = I_GetPreciseTime();
R_DrawPlanes(); R_DrawPlanes();
ps_sw_planetime = I_GetTimeMicros() - ps_sw_planetime; ps_sw_planetime = I_GetPreciseTime() - ps_sw_planetime;
// draw mid texture and sprite // draw mid texture and sprite
// And now 3D floors/sides! // And now 3D floors/sides!
ps_sw_maskedtime = I_GetTimeMicros(); ps_sw_maskedtime = I_GetPreciseTime();
R_DrawMasked(masks, nummasks); R_DrawMasked(masks, nummasks);
ps_sw_maskedtime = I_GetTimeMicros() - ps_sw_maskedtime; ps_sw_maskedtime = I_GetPreciseTime() - ps_sw_maskedtime;
free(masks); free(masks);
} }

View File

@ -78,17 +78,17 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe
// Render stats // Render stats
extern int ps_prevframetime;// time when previous frame was rendered extern precise_t ps_prevframetime;// time when previous frame was rendered
extern int ps_rendercalltime; extern precise_t ps_rendercalltime;
extern int ps_uitime; extern precise_t ps_uitime;
extern int ps_swaptime; extern precise_t ps_swaptime;
extern int ps_bsptime; extern precise_t ps_bsptime;
extern int ps_sw_spritecliptime; extern precise_t ps_sw_spritecliptime;
extern int ps_sw_portaltime; extern precise_t ps_sw_portaltime;
extern int ps_sw_planetime; extern precise_t ps_sw_planetime;
extern int ps_sw_maskedtime; extern precise_t ps_sw_maskedtime;
extern int ps_numbspcalls; extern int ps_numbspcalls;
extern int ps_numsprites; extern int ps_numsprites;

View File

@ -544,21 +544,22 @@ void *Picture_GetPatchPixel(
UINT16 *s16 = NULL; UINT16 *s16 = NULL;
UINT32 *s32 = NULL; UINT32 *s32 = NULL;
softwarepatch_t *doompatch = (softwarepatch_t *)patch; softwarepatch_t *doompatch = (softwarepatch_t *)patch;
boolean isdoompatch = Picture_IsDoomPatchFormat(informat);
INT16 width; INT16 width;
if (patch == NULL) if (patch == NULL)
I_Error("Picture_GetPatchPixel: patch == NULL"); I_Error("Picture_GetPatchPixel: patch == NULL");
width = (Picture_IsDoomPatchFormat(informat) ? patch->width : SHORT(patch->width)); width = (isdoompatch ? SHORT(doompatch->width) : patch->width);
if (x >= 0 && x < width) if (x >= 0 && x < width)
{ {
INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x; INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x;
INT32 topdelta, prevdelta = -1; INT32 topdelta, prevdelta = -1;
INT32 colofs = (Picture_IsDoomPatchFormat(informat) ? LONG(patch->columnofs[colx]) : patch->columnofs[colx]); INT32 colofs = (isdoompatch ? LONG(doompatch->columnofs[colx]) : patch->columnofs[colx]);
// Column offsets are pointers so no casting required // Column offsets are pointers, so no casting is required.
if (Picture_IsDoomPatchFormat(informat)) if (isdoompatch)
column = (column_t *)((UINT8 *)doompatch + colofs); column = (column_t *)((UINT8 *)doompatch + colofs);
else else
column = (column_t *)((UINT8 *)patch->columns + colofs); column = (column_t *)((UINT8 *)patch->columns + colofs);

View File

@ -607,6 +607,7 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
void R_DrawPlanes(void) void R_DrawPlanes(void)
{ {
visplane_t *pl; visplane_t *pl;
angle_t va = viewangle;
INT32 i; INT32 i;
R_UpdatePlaneRipple(); R_UpdatePlaneRipple();
@ -621,6 +622,8 @@ void R_DrawPlanes(void)
R_DrawSinglePlane(pl); R_DrawSinglePlane(pl);
} }
} }
viewangle = va;
} }
// R_DrawSkyPlane // R_DrawSkyPlane
@ -705,9 +708,9 @@ void R_CalculateSlopeVectors(pslope_t *slope, fixed_t planeviewx, fixed_t planev
n.z = -xscale * cos(ang); n.z = -xscale * cos(ang);
ang = ANG2RAD(planeangle); ang = ANG2RAD(planeangle);
temp = P_GetSlopeZAt(slope, planeviewx + yscale * FLOAT_TO_FIXED(sin(ang)), planeviewy + yscale * FLOAT_TO_FIXED(cos(ang))); temp = P_GetSlopeZAt(slope, planeviewx + FLOAT_TO_FIXED(yscale * sin(ang)), planeviewy + FLOAT_TO_FIXED(yscale * cos(ang)));
m.y = FIXED_TO_FLOAT(temp) - zeroheight; m.y = FIXED_TO_FLOAT(temp) - zeroheight;
temp = P_GetSlopeZAt(slope, planeviewx + xscale * FLOAT_TO_FIXED(cos(ang)), planeviewy - xscale * FLOAT_TO_FIXED(sin(ang))); temp = P_GetSlopeZAt(slope, planeviewx + FLOAT_TO_FIXED(xscale * cos(ang)), planeviewy - FLOAT_TO_FIXED(xscale * sin(ang)));
n.y = FIXED_TO_FLOAT(temp) - zeroheight; n.y = FIXED_TO_FLOAT(temp) - zeroheight;
if (ds_powersoftwo) if (ds_powersoftwo)
@ -788,7 +791,6 @@ void R_DrawSinglePlane(visplane_t *pl)
ffloor_t *rover; ffloor_t *rover;
int type; int type;
int spanfunctype = BASEDRAWFUNC; int spanfunctype = BASEDRAWFUNC;
angle_t viewang = viewangle;
if (!(pl->minx <= pl->maxx)) if (!(pl->minx <= pl->maxx))
return; return;
@ -1153,8 +1155,6 @@ using the palette colors.
} }
} }
#endif #endif
viewangle = viewang;
} }
void R_PlaneBounds(visplane_t *plane) void R_PlaneBounds(visplane_t *plane)

View File

@ -540,7 +540,7 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor)
// Polyobjects have no ffloors, and they're handled in the conditional above. // Polyobjects have no ffloors, and they're handled in the conditional above.
if (pfloor->ffloor != NULL) if (pfloor->ffloor != NULL)
return (pfloor->ffloor->flags & FF_TRANSLUCENT); return (pfloor->ffloor->flags & (FF_TRANSLUCENT|FF_FOG));
return false; return false;
} }
@ -1191,7 +1191,7 @@ static void R_RenderSegLoop (void)
// Lactozilla: Cull part of the column by the 3D floor if it can't be seen // Lactozilla: Cull part of the column by the 3D floor if it can't be seen
// "bottom" is the top pixel of the floor column // "bottom" is the top pixel of the floor column
if (ffbottom >= bottom-1 && R_FFloorCanClip(&ffloor[i])) if (ffbottom >= bottom-1 && R_FFloorCanClip(&ffloor[i]) && !curline->polyseg)
{ {
rw_floormarked = true; rw_floormarked = true;
floorclip[rw_x] = fftop; floorclip[rw_x] = fftop;
@ -1239,7 +1239,7 @@ static void R_RenderSegLoop (void)
// Lactozilla: Cull part of the column by the 3D floor if it can't be seen // Lactozilla: Cull part of the column by the 3D floor if it can't be seen
// "top" is the height of the ceiling column // "top" is the height of the ceiling column
if (fftop <= top+1 && R_FFloorCanClip(&ffloor[i])) if (fftop <= top+1 && R_FFloorCanClip(&ffloor[i]) && !curline->polyseg)
{ {
rw_ceilingmarked = true; rw_ceilingmarked = true;
ceilingclip[rw_x] = ffbottom; ceilingclip[rw_x] = ffbottom;

View File

@ -511,6 +511,10 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
GETFLAG(MULTIABILITY) GETFLAG(MULTIABILITY)
GETFLAG(NONIGHTSROTATION) GETFLAG(NONIGHTSROTATION)
GETFLAG(NONIGHTSSUPER) GETFLAG(NONIGHTSSUPER)
GETFLAG(NOSUPERSPRITES)
GETFLAG(NOSUPERJUMPBOOST)
GETFLAG(CANBUSTWALLS)
GETFLAG(NOSHIELDABILITY)
#undef GETFLAG #undef GETFLAG
else // let's check if it's a sound, otherwise error out else // let's check if it's a sound, otherwise error out

View File

@ -604,7 +604,7 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
levelflat->height = ds_flatheight = SHORT(patch->height); levelflat->height = ds_flatheight = SHORT(patch->height);
levelflat->picture = Z_Malloc(levelflat->width * levelflat->height, PU_LEVEL, NULL); levelflat->picture = Z_Malloc(levelflat->width * levelflat->height, PU_LEVEL, NULL);
converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, patch->topoffset, patch->leftoffset, 0); converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, SHORT(patch->topoffset), SHORT(patch->leftoffset), 0);
M_Memcpy(levelflat->picture, converted, size); M_Memcpy(levelflat->picture, converted, size);
Z_Free(converted); Z_Free(converted);
} }

View File

@ -2143,7 +2143,7 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst)
static lumpnum_t S_GetMusicLumpNum(const char *mname) static lumpnum_t S_GetMusicLumpNum(const char *mname)
{ {
boolean midipref = cv_musicpref.value; boolean midipref = cv_musicpref.value;
if (S_PrefAvailable(midipref, mname)) if (S_PrefAvailable(midipref, mname))
return W_GetNumForName(va(midipref ? "d_%s":"o_%s", mname)); return W_GetNumForName(va(midipref ? "d_%s":"o_%s", mname));
else if (S_PrefAvailable(!midipref, mname)) else if (S_PrefAvailable(!midipref, mname))
@ -2291,7 +2291,7 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32
I_FadeSong(0, prefadems, S_ChangeMusicToQueue); I_FadeSong(0, prefadems, S_ChangeMusicToQueue);
return; return;
} }
else if (strnicmp(music_name, newmusic, 6) || (mflags & MUSIC_FORCERESET) || else if (strnicmp(music_name, newmusic, 6) || (mflags & MUSIC_FORCERESET) ||
(midipref != currentmidi && S_PrefAvailable(midipref, newmusic))) (midipref != currentmidi && S_PrefAvailable(midipref, newmusic)))
{ {
CONS_Debug(DBG_DETAILED, "Now playing song %s\n", newmusic); CONS_Debug(DBG_DETAILED, "Now playing song %s\n", newmusic);

View File

@ -54,12 +54,6 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include <fcntl.h> #include <fcntl.h>
#endif #endif
#if defined (_WIN32)
DWORD TimeFunction(int requested_frequency);
#else
int TimeFunction(int requested_frequency);
#endif
#include <stdio.h> #include <stdio.h>
#ifdef _WIN32 #ifdef _WIN32
#include <conio.h> #include <conio.h>
@ -2044,112 +2038,36 @@ ticcmd_t *I_BaseTiccmd2(void)
return &emptycmd2; return &emptycmd2;
} }
#if defined (_WIN32)
static HMODULE winmm = NULL;
static DWORD starttickcount = 0; // hack for win2k time bug
static p_timeGetTime pfntimeGetTime = NULL;
// ---------
// I_GetTime
// Use the High Resolution Timer if available,
// else use the multimedia timer which has 1 millisecond precision on Windowz 95,
// but lower precision on Windows NT
// ---------
DWORD TimeFunction(int requested_frequency)
{
DWORD newtics = 0;
// this var acts as a multiplier if sub-millisecond precision is asked but is not available
int excess_frequency = requested_frequency / 1000;
if (!starttickcount) // high precision timer
{
LARGE_INTEGER currtime; // use only LowPart if high resolution counter is not available
static LARGE_INTEGER basetime = {{0, 0}};
// use this if High Resolution timer is found
static LARGE_INTEGER frequency;
if (!basetime.LowPart)
{
if (!QueryPerformanceFrequency(&frequency))
frequency.QuadPart = 0;
else
QueryPerformanceCounter(&basetime);
}
if (frequency.LowPart && QueryPerformanceCounter(&currtime))
{
newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * requested_frequency
/ frequency.QuadPart);
}
else if (pfntimeGetTime)
{
currtime.LowPart = pfntimeGetTime();
if (!basetime.LowPart)
basetime.LowPart = currtime.LowPart;
if (requested_frequency > 1000)
newtics = currtime.LowPart - basetime.LowPart * excess_frequency;
else
newtics = (currtime.LowPart - basetime.LowPart)/(1000/requested_frequency);
}
}
else
{
if (requested_frequency > 1000)
newtics = (GetTickCount() - starttickcount) * excess_frequency;
else
newtics = (GetTickCount() - starttickcount)/(1000/requested_frequency);
}
return newtics;
}
static void I_ShutdownTimer(void)
{
pfntimeGetTime = NULL;
if (winmm)
{
p_timeEndPeriod pfntimeEndPeriod = (p_timeEndPeriod)(LPVOID)GetProcAddress(winmm, "timeEndPeriod");
if (pfntimeEndPeriod)
pfntimeEndPeriod(1);
FreeLibrary(winmm);
winmm = NULL;
}
}
#else
// //
// I_GetTime // I_GetTime
// returns time in 1/TICRATE second tics // returns time in 1/TICRATE second tics
// //
// millisecond precision only static Uint64 timer_frequency;
int TimeFunction(int requested_frequency)
{
static Uint64 basetime = 0;
Uint64 ticks = SDL_GetTicks();
if (!basetime) static double tic_frequency;
basetime = ticks; static Uint64 tic_epoch;
ticks -= basetime;
ticks = (ticks*requested_frequency);
ticks = (ticks/1000);
return ticks;
}
#endif
tic_t I_GetTime(void) tic_t I_GetTime(void)
{ {
return TimeFunction(NEWTICRATE); static double elapsed;
const Uint64 now = SDL_GetPerformanceCounter();
elapsed += (now - tic_epoch) / tic_frequency;
tic_epoch = now; // moving epoch
return (tic_t)elapsed;
} }
int I_GetTimeMicros(void) precise_t I_GetPreciseTime(void)
{ {
return TimeFunction(1000000); return SDL_GetPerformanceCounter();
}
int I_PreciseToMicros(precise_t d)
{
return (int)(d / (timer_frequency / 1000000.0));
} }
// //
@ -2157,27 +2075,12 @@ int I_GetTimeMicros(void)
// //
void I_StartupTimer(void) void I_StartupTimer(void)
{ {
#ifdef _WIN32 timer_frequency = SDL_GetPerformanceFrequency();
// for win2k time bug tic_epoch = SDL_GetPerformanceCounter();
if (M_CheckParm("-gettickcount"))
{ tic_frequency = timer_frequency / (double)NEWTICRATE;
starttickcount = GetTickCount();
CONS_Printf("%s", M_GetText("Using GetTickCount()\n"));
}
winmm = LoadLibraryA("winmm.dll");
if (winmm)
{
p_timeEndPeriod pfntimeBeginPeriod = (p_timeEndPeriod)(LPVOID)GetProcAddress(winmm, "timeBeginPeriod");
if (pfntimeBeginPeriod)
pfntimeBeginPeriod(1);
pfntimeGetTime = (p_timeGetTime)(LPVOID)GetProcAddress(winmm, "timeGetTime");
}
I_AddExitFunc(I_ShutdownTimer);
#endif
} }
void I_Sleep(void) void I_Sleep(void)
{ {
if (cv_sleep.value != -1) if (cv_sleep.value != -1)

View File

@ -1057,8 +1057,7 @@ void I_GetEvent(void)
M_SetupJoystickMenu(0); M_SetupJoystickMenu(0);
break; break;
case SDL_QUIT: case SDL_QUIT:
if (Playing()) LUAh_GameQuit(true);
LUAh_GameQuit();
I_Quit(); I_Quit();
break; break;
} }

View File

@ -1298,6 +1298,10 @@ boolean I_PlaySong(boolean looping)
if (gme) if (gme)
{ {
gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
#if GME_VERSION >= 0x000603
if (looping)
gme_set_autoload_playback_limit(gme, 0);
#endif
gme_set_equalizer(gme, &eq); gme_set_equalizer(gme, &eq);
gme_start_track(gme, 0); gme_start_track(gme, 0);
current_track = 0; current_track = 0;

View File

@ -2751,7 +2751,6 @@ static void ST_overlayDrawer(void)
void ST_Drawer(void) void ST_Drawer(void)
{ {
#ifdef SEENAMES
if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo)
{ {
INT32 c = 0; INT32 c = 0;
@ -2775,7 +2774,6 @@ void ST_Drawer(void)
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2 + 15, V_HUDTRANSHALF|c, player_names[seenplayer-players]); V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2 + 15, V_HUDTRANSHALF|c, player_names[seenplayer-players]);
} }
#endif
// Doom's status bar only updated if necessary. // Doom's status bar only updated if necessary.
// However, ours updates every frame regardless, so the "refresh" param was removed // However, ours updates every frame regardless, so the "refresh" param was removed

View File

@ -66,6 +66,7 @@
#include "p_setup.h" // P_ScanThings #include "p_setup.h" // P_ScanThings
#endif #endif
#include "m_misc.h" // M_MapNumber #include "m_misc.h" // M_MapNumber
#include "g_game.h" // G_SetGameModified
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
@ -683,9 +684,9 @@ static UINT16 W_InitFileError (const char *filename, boolean exitworthy)
if (exitworthy) if (exitworthy)
{ {
#ifdef _DEBUG #ifdef _DEBUG
CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); CONS_Error(va("%s was not found or not valid.\nCheck the log for more details.\n", filename));
#else #else
I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); I_Error("%s was not found or not valid.\nCheck the log for more details.\n", filename);
#endif #endif
} }
else else
@ -716,7 +717,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
#endif #endif
size_t packetsize; size_t packetsize;
UINT8 md5sum[16]; UINT8 md5sum[16];
boolean important; int important;
if (!(refreshdirmenu & REFRESHDIR_ADDFILE)) if (!(refreshdirmenu & REFRESHDIR_ADDFILE))
refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier
@ -746,10 +747,18 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
if ((handle = W_OpenWadFile(&filename, true)) == NULL) if ((handle = W_OpenWadFile(&filename, true)) == NULL)
return W_InitFileError(filename, startup); return W_InitFileError(filename, startup);
important = W_VerifyNMUSlumps(filename, startup);
if (important == -1)
{
fclose(handle);
return INT16_MAX;
}
// Check if wad files will overflow fileneededbuffer. Only the filename part // Check if wad files will overflow fileneededbuffer. Only the filename part
// is send in the packet; cf. // is send in the packet; cf.
// see PutFileNeeded in d_netfil.c // see PutFileNeeded in d_netfil.c
if ((important = !W_VerifyNMUSlumps(filename))) if ((important = !important))
{ {
packetsize = packetsizetally + nameonlylength(filename) + 22; packetsize = packetsizetally + nameonlylength(filename) + 22;
@ -811,6 +820,9 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
return W_InitFileError(filename, startup); return W_InitFileError(filename, startup);
} }
if (important && !mainfile)
G_SetGameModified(true);
// //
// link wad file to search files // link wad file to search files
// //
@ -1735,6 +1747,9 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag)
void W_UnlockCachedPatch(void *patch) void W_UnlockCachedPatch(void *patch)
{ {
if (!patch)
return;
// The hardware code does its own memory management, as its patches // The hardware code does its own memory management, as its patches
// have different lifetimes from software's. // have different lifetimes from software's.
#ifdef HWRENDER #ifdef HWRENDER
@ -1919,8 +1934,16 @@ static lumpchecklist_t folderblacklist[] =
static int static int
W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
{ {
int verified = true;
zend_t zend; zend_t zend;
zentry_t zentry; zentry_t zentry;
zlentry_t zlentry;
long file_size;/* size of zip file */
long data_size;/* size of data inside zip file */
long old_position;
UINT16 numlumps; UINT16 numlumps;
size_t i; size_t i;
@ -1936,6 +1959,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
// Central directory bullshit // Central directory bullshit
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
if (!ResFindSignature(fp, pat_end, max(0, ftell(fp) - (22 + 65536)))) if (!ResFindSignature(fp, pat_end, max(0, ftell(fp) - (22 + 65536))))
return true; return true;
@ -1943,6 +1968,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
if (fread(&zend, 1, sizeof zend, fp) < sizeof zend) if (fread(&zend, 1, sizeof zend, fp) < sizeof zend)
return true; return true;
data_size = sizeof zend;
numlumps = zend.entries; numlumps = zend.entries;
fseek(fp, zend.cdiroffset, SEEK_SET); fseek(fp, zend.cdiroffset, SEEK_SET);
@ -1957,40 +1984,79 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
if (memcmp(zentry.signature, pat_central, 4)) if (memcmp(zentry.signature, pat_central, 4))
return true; return true;
fullname = malloc(zentry.namelen + 1); if (verified == true)
if (fgets(fullname, zentry.namelen + 1, fp) != fullname)
return true;
// Strip away file address and extension for the 8char name.
if ((trimname = strrchr(fullname, '/')) != 0)
trimname++;
else
trimname = fullname; // Care taken for root files.
if (*trimname) // Ignore directories, well kinda
{ {
if ((dotpos = strrchr(trimname, '.')) == 0) fullname = malloc(zentry.namelen + 1);
dotpos = fullname + strlen(fullname); // Watch for files without extension. if (fgets(fullname, zentry.namelen + 1, fp) != fullname)
return true;
memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary? // Strip away file address and extension for the 8char name.
strncpy(lumpname, trimname, min(8, dotpos - trimname)); if ((trimname = strrchr(fullname, '/')) != 0)
trimname++;
else
trimname = fullname; // Care taken for root files.
if (! W_VerifyName(lumpname, checklist, status)) if (*trimname) // Ignore directories, well kinda
return false; {
if ((dotpos = strrchr(trimname, '.')) == 0)
dotpos = fullname + strlen(fullname); // Watch for files without extension.
// Check for directories next, if it's blacklisted it will return false memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
if (W_VerifyName(fullname, folderblacklist, status)) strncpy(lumpname, trimname, min(8, dotpos - trimname));
return false;
if (! W_VerifyName(lumpname, checklist, status))
verified = false;
// Check for directories next, if it's blacklisted it will return false
else if (W_VerifyName(fullname, folderblacklist, status))
verified = false;
}
free(fullname);
// skip and ignore comments/extra fields
if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
return true;
}
else
{
if (fseek(fp, zentry.namelen + zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
return true;
} }
free(fullname); data_size +=
sizeof zentry + zentry.namelen + zentry.xtralen + zentry.commlen;
// skip and ignore comments/extra fields old_position = ftell(fp);
if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
if (fseek(fp, zentry.offset, SEEK_SET) != 0)
return true; return true;
if (fread(&zlentry, 1, sizeof(zlentry_t), fp) < sizeof (zlentry_t))
return true;
data_size +=
sizeof zlentry + zlentry.namelen + zlentry.xtralen + zlentry.compsize;
fseek(fp, old_position, SEEK_SET);
} }
return true; if (data_size < file_size)
{
const char * error = "ZIP file has holes (%ld extra bytes)\n";
CONS_Alert(CONS_ERROR, error, (file_size - data_size));
return -1;
}
else if (data_size > file_size)
{
const char * error = "Reported size of ZIP file contents exceeds file size (%ld extra bytes)\n";
CONS_Alert(CONS_ERROR, error, (data_size - file_size));
return -1;
}
else
{
return verified;
}
} }
// Note: This never opens lumps themselves and therefore doesn't have to // Note: This never opens lumps themselves and therefore doesn't have to
@ -2029,12 +2095,13 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
* be sent. * be sent.
* *
* \param filename Filename of the wad to check. * \param filename Filename of the wad to check.
* \param exit_on_error Whether to exit upon file error.
* \return 1 if file contains only music/sound lumps, 0 if it contains other * \return 1 if file contains only music/sound lumps, 0 if it contains other
* stuff (maps, sprites, dehacked lumps, and so on). -1 if there no * stuff (maps, sprites, dehacked lumps, and so on). -1 if there no
* file exists with that filename * file exists with that filename
* \author Alam Arias * \author Alam Arias
*/ */
int W_VerifyNMUSlumps(const char *filename) int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error)
{ {
// MIDI, MOD/S3M/IT/XM/OGG/MP3/WAV, WAVE SFX // MIDI, MOD/S3M/IT/XM/OGG/MP3/WAV, WAVE SFX
// ENDOOM text and palette lumps // ENDOOM text and palette lumps
@ -2080,7 +2147,7 @@ int W_VerifyNMUSlumps(const char *filename)
{"LT", 2}, // Titlecard changes {"LT", 2}, // Titlecard changes
{"SLID", 4}, // Continue {"SLID", 4}, // Continue
{"CONT", 4}, {"CONT", 4},
{"MINICAPS", 8}, // NiGHTS graphics here and below {"MINICAPS", 8}, // NiGHTS graphics here and below
{"BLUESTAT", 8}, // Sphere status {"BLUESTAT", 8}, // Sphere status
@ -2108,7 +2175,13 @@ int W_VerifyNMUSlumps(const char *filename)
{NULL, 0}, {NULL, 0},
}; };
return W_VerifyFile(filename, NMUSlist, false);
int status = W_VerifyFile(filename, NMUSlist, false);
if (status == -1)
W_InitFileError(filename, exit_on_error);
return status;
} }
/** \brief Generates a virtual resource used for level data loading. /** \brief Generates a virtual resource used for level data loading.

View File

@ -206,6 +206,6 @@ void W_UnlockCachedPatch(void *patch);
void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5);
int W_VerifyNMUSlumps(const char *filename); int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error);
#endif // __W_WAD__ #endif // __W_WAD__

View File

@ -56,14 +56,6 @@ ifndef GCC44
#OPTS+=-mms-bitfields #OPTS+=-mms-bitfields
endif endif
ifndef SDL
OPTS+=-D_WINDOWS
endif
ifndef SDL
LIBS+=-lmingw32 -mwindows -ldinput -ldxguid -lgdi32 -lwinmm
endif
LIBS+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 LIBS+=-ladvapi32 -lkernel32 -lmsvcrt -luser32
ifdef MINGW64 ifdef MINGW64
LIBS+=-lws2_32 LIBS+=-lws2_32
@ -76,11 +68,7 @@ endif
endif endif
# name of the exefile # name of the exefile
ifdef SDL
EXENAME?=srb2win.exe EXENAME?=srb2win.exe
else
EXENAME?=srb2dd.exe
endif
ifdef SDL ifdef SDL
i_system_o+=$(OBJDIR)/SRB2.res i_system_o+=$(OBJDIR)/SRB2.res
@ -88,22 +76,6 @@ ifdef SDL
ifndef NOHW ifndef NOHW
OPTS+=-DUSE_WGL_SWAP OPTS+=-DUSE_WGL_SWAP
endif endif
else
D_FILES+=$(D_DIR)/fmodex.dll
CFLAGS+=-I../libs/fmodex/inc
LDFLAGS+=-L../libs/fmodex/lib
ifdef MINGW64
LIBS+=-lfmodex64_vc
else
LIBS+=-lfmodex_vc
endif
i_cdmus_o=$(OBJDIR)/win_cd.o
i_net_o=$(OBJDIR)/win_net.o
i_system_o=$(OBJDIR)/win_sys.o $(OBJDIR)/SRB2.res
i_sound_o=$(OBJDIR)/win_snd.o
i_main_o=$(OBJDIR)/win_main.o
#i_main_o+=$(OBJDIR)/win_dbg.o
OBJS=$(OBJDIR)/dx_error.o $(OBJDIR)/fabdxlib.o $(OBJDIR)/win_vid.o $(OBJDIR)/win_dll.o
endif endif
@ -161,4 +133,4 @@ ifdef MINGW64
else else
CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl
endif #MINGW64 endif #MINGW64
endif endif

View File

@ -1229,7 +1229,10 @@ void Y_StartIntermission(void)
data.coop.tics = players[consoleplayer].realtime; data.coop.tics = players[consoleplayer].realtime;
for (i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH); {
if (strlen(data.coop.bonuses[i].patch))
data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH);
}
data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH); data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH);
// get act number // get act number
@ -1733,7 +1736,6 @@ static void Y_SetNullBonus(player_t *player, y_bonus_t *bstruct)
{ {
(void)player; (void)player;
memset(bstruct, 0, sizeof(y_bonus_t)); memset(bstruct, 0, sizeof(y_bonus_t));
strncpy(bstruct->patch, "MISSING", sizeof(bstruct->patch));
} }
// //

View File

@ -813,12 +813,12 @@ static void Command_Memfree_f(void)
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode == render_opengl) if (rendermode == render_opengl)
{ {
CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10)); CONS_Printf(M_GetText("Patch info headers : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10));
CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10)); CONS_Printf(M_GetText("Cached textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10));
CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); CONS_Printf(M_GetText("Texture colormaps : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10));
CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); CONS_Printf(M_GetText("Model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10));
CONS_Printf(M_GetText("HW model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10)); CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10));
CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10); CONS_Printf(M_GetText("All GPU textures : %7d KB\n"), HWR_GetTextureUsed()>>10);
} }
#endif #endif