diff --git a/src/Makefile b/src/Makefile index 0c1626fc9..1314161bd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,8 +13,7 @@ # -DHAVE_SDL -> use for the SDL interface # # Sets: -# Compile the DirectX/Mingw version with 'make MINGW=1' -# Compile the SDL/Mingw version with 'make MINGW=1 SDL=1' +# Compile the SDL/Mingw version with 'make MINGW=1' # Compile the SDL/Linux version with 'make LINUX=1' # Compile the SDL/Solaris version with 'make SOLARIS=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 MINGW=1 - SDL=1 WINDOWSHELL=1 else # if you on the *nix @@ -568,12 +566,6 @@ all: pre-build $(BIN)/$(PNDNAME) endif -ifdef MINGW -ifndef SDL -all: pre-build $(BIN)/$(EXENAME) dll -endif -endif - ifdef SDL all: pre-build $(BIN)/$(EXENAME) endif @@ -653,57 +645,6 @@ endif $(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 MINGW $(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 - #dependecy made by gcc itself ! $(OBJS): 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 -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 MINGW diff --git a/src/Makefile.cfg b/src/Makefile.cfg index db7230bb4..f081eacdf 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -420,14 +420,14 @@ ifdef CYGWIN32 BIN:=$(BIN)/Cygwin else ifdef MINGW64 - INTERFACE=win32 #NASMFORMAT=win64 + SDL=1 OBJDIR:=$(OBJDIR)/Mingw64 BIN:=$(BIN)/Mingw64 else ifdef MINGW - INTERFACE=win32 NASMFORMAT=win32 + SDL=1 OBJDIR:=$(OBJDIR)/Mingw BIN:=$(BIN)/Mingw endif diff --git a/src/blua/lcode.c b/src/blua/lcode.c index 5c7fed454..fd4aaff24 100644 --- a/src/blua/lcode.c +++ b/src/blua/lcode.c @@ -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, expdesc *e2) { 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) { - expdesc e2; - e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; switch (op) { - case OPR_MINUS: { - if (!isnumeral(e)) - 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_MINUS: codeunaryarith(fs, OP_UNM, e); break; + case OPR_BNOT: codeunaryarith(fs, OP_BNOT, e); break; case OPR_NOT: codenot(fs, e); break; - case OPR_LEN: { - luaK_exp2anyreg(fs, e); /* cannot operate on constants */ - codearith(fs, OP_LEN, e, &e2); - break; - } + case OPR_LEN: codeunaryarith(fs, OP_LEN, e); break; default: lua_assert(0); } } diff --git a/src/console.c b/src/console.c index b19b8818d..c7bfe0fe1 100644 --- a/src/console.c +++ b/src/console.c @@ -360,30 +360,48 @@ static void CON_SetupColormaps(void) for (i = 0; i < (256*15); i++, ++memorysrc) *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... -#define colset(map, a, b, c) \ - map[1] = (UINT8)a;\ - map[3] = (UINT8)b;\ - map[9] = (UINT8)c +#define colset(map, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \ + map[0x0] = (UINT8)a;\ + map[0x1] = (UINT8)b;\ + 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); - colset(yellowmap, 82, 73, 66); - colset(lgreenmap, 97, 98, 106); - colset(bluemap, 146, 147, 155); - colset(redmap, 210, 32, 39); - colset(graymap, 6, 8, 14); - colset(orangemap, 51, 52, 57); - colset(skymap, 129, 130, 133); - colset(purplemap, 160, 161, 163); - colset(aquamap, 120, 121, 123); - colset(peridotmap, 88, 188, 190); - colset(azuremap, 144, 145, 170); - colset(brownmap, 219, 221, 224); - colset(rosymap, 200, 201, 203); - colset(invertmap, 27, 26, 22); - invertmap[26] = (UINT8)3; + // Tried to keep the colors vanilla while adding some shades in between them ~SonicX8000 + + // 0x1 0x3 0x9 0xF + colset(magentamap, 177, 177, 178, 178, 178, 180, 180, 180, 182, 182, 182, 182, 184, 184, 184, 185); + colset(yellowmap, 82, 82, 73, 73, 73, 64, 64, 64, 66, 66, 66, 66, 67, 67, 67, 68); + colset(lgreenmap, 96, 96, 98, 98, 98, 101, 101, 101, 104, 104, 104, 104, 106, 106, 106, 107); + colset(bluemap, 146, 146, 147, 147, 147, 149, 149, 149, 152, 152, 152, 152, 155, 155, 155, 157); + colset(redmap, 32, 32, 33, 33, 33, 35, 35, 35, 39, 39, 39, 39, 42, 42, 42, 44); + colset(graymap, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23); + colset(orangemap, 50, 50, 52, 52, 52, 54, 54, 54, 56, 56, 56, 56, 59, 59, 59, 60); + colset(skymap, 129, 129, 130, 130, 130, 131, 131, 131, 133, 133, 133, 133, 135, 135, 135, 136); + colset(purplemap, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 163, 164, 164, 164, 165); + colset(aquamap, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125); + colset(peridotmap, 72, 72, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191, 191, 191, 94); + colset(azuremap, 144, 144, 145, 145, 145, 146, 146, 146, 170, 170, 170, 170, 171, 171, 171, 172); + 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 + // Yeah just straight up invert it like a normal person + for (i = 0x00; i <= 0x1F; i++) + invertmap[0x1F - i] = i; + // Init back colormap CON_SetupBackColormap(); } diff --git a/src/d_clisrv.c b/src/d_clisrv.c index b198011a0..4fdc7e7ee 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1595,9 +1595,7 @@ static void CL_ReloadReceivedSavegame(void) for (i = 0; i < MAXPLAYERS; i++) { -#ifdef HAVE_BLUA LUA_InvalidatePlayer(&players[i]); -#endif sprintf(player_names[i], "Player %d", i + 1); } @@ -2260,11 +2258,15 @@ void D_SaveBan(void) size_t i; banreason_t *reasonlist = reasonhead; const char *address, *mask; + const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt"); if (!reasonhead) + { + remove(path); return; + } - f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "w"); + f = fopen(path, "w"); if (!f) { @@ -2308,16 +2310,14 @@ static void Ban_Add(const char *reason) reasontail = reasonlist; } -static void Command_ClearBans(void) +static void Ban_Clear(void) { banreason_t *temp; - if (!I_ClearBans) - return; - I_ClearBans(); - D_SaveBan(); + reasontail = NULL; + while (reasonhead) { 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) { FILE *f; @@ -2334,6 +2343,9 @@ static void Ban_Load_File(boolean warning) const char *address, *mask; char buffer[MAX_WADPATH]; + if (!I_ClearBans) + return; + f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r"); if (!f) @@ -2343,13 +2355,7 @@ static void Ban_Load_File(boolean warning) return; } - if (I_ClearBans) - Command_ClearBans(); - else - { - fclose(f); - return; - } + Ban_Clear(); 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 (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); #ifdef DUMPCONSISTENCY if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); #endif @@ -3727,8 +3732,7 @@ static void HandleConnect(SINT8 node) static void HandleShutdown(SINT8 node) { (void)node; - if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -3743,8 +3747,7 @@ static void HandleShutdown(SINT8 node) static void HandleTimeout(SINT8 node) { (void)node; - if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -4847,14 +4850,14 @@ void TryRunTics(tic_t realtics) { DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); - ps_tictime = I_GetTimeMicros(); + ps_tictime = I_GetPreciseTime(); G_Ticker((gametic % NEWTICRATERATIO) == 0); ExtraDataTicker(); gametic++; 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. if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value) diff --git a/src/d_main.c b/src/d_main.c index 1045d4d99..a89f4ed2d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -413,7 +413,7 @@ static void D_Display(void) if (!automapactive && !dedicated && cv_renderview.value) { - ps_rendercalltime = I_GetTimeMicros(); + ps_rendercalltime = I_GetPreciseTime(); if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) { topleft = screens[0] + viewwindowy*vid.width + viewwindowx; @@ -460,7 +460,7 @@ static void D_Display(void) if (postimgtype2) V_DoPostProcessor(1, postimgtype2, postimgparam2); } - ps_rendercalltime = I_GetTimeMicros() - ps_rendercalltime; + ps_rendercalltime = I_GetPreciseTime() - ps_rendercalltime; } if (lastdraw) @@ -474,7 +474,7 @@ static void D_Display(void) lastdraw = false; } - ps_uitime = I_GetTimeMicros(); + ps_uitime = I_GetPreciseTime(); if (gamestate == GS_LEVEL) { @@ -487,7 +487,7 @@ static void D_Display(void) } else { - ps_uitime = I_GetTimeMicros(); + ps_uitime = I_GetPreciseTime(); } } @@ -529,7 +529,7 @@ static void D_Display(void) CON_Drawer(); - ps_uitime = I_GetTimeMicros() - ps_uitime; + ps_uitime = I_GetPreciseTime() - ps_uitime; // // wipe update @@ -615,9 +615,9 @@ static void D_Display(void) M_DrawPerfStats(); } - ps_swaptime = I_GetTimeMicros(); + ps_swaptime = I_GetPreciseTime(); 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) \ {\ const char *musicpath = va(pandf,srb2waddir,str);\ - int ms = W_VerifyNMUSlumps(musicpath); \ + int ms = W_VerifyNMUSlumps(musicpath, false); \ if (ms == 1) \ D_AddFile(startupwadfiles, musicpath); \ else if (ms == 0) \ @@ -1187,11 +1187,7 @@ void D_SRB2Main(void) const char *s = M_GetNextParm(); if (s) // Check for NULL? - { - if (!W_VerifyNMUSlumps(s)) - G_SetGameModified(true); D_AddFile(startuppwads, s); - } } } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 31c10f58a..0acbec928 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -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); -#ifdef SEENAMES 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_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR, CV_YesNo, NULL); -#endif // names 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_showping); -#ifdef SEENAMES - CV_RegisterVar(&cv_allowseenames); -#endif + CV_RegisterVar(&cv_allowseenames); CV_RegisterVar(&cv_dummyconsvar); } @@ -670,6 +666,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_zlib_strategya); CV_RegisterVar(&cv_zlib_window_bitsa); CV_RegisterVar(&cv_apng_delay); + CV_RegisterVar(&cv_apng_downscale); // GIF variables CV_RegisterVar(&cv_gif_optimize); CV_RegisterVar(&cv_gif_downscale); @@ -690,9 +687,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_defaultplayercolor2); CV_RegisterVar(&cv_defaultskin2); -#ifdef SEENAMES CV_RegisterVar(&cv_seenames); -#endif CV_RegisterVar(&cv_rollingdemos); CV_RegisterVar(&cv_netstat); CV_RegisterVar(&cv_netticbuffer); @@ -878,7 +873,7 @@ void D_RegisterClientCommands(void) // CV_RegisterVar(&cv_snapto); CV_RegisterVar(&cv_freedemocamera); - + // add cheat commands COM_AddCommand("noclip", Command_CheatNoClip_f); COM_AddCommand("god", Command_CheatGod_f); @@ -3294,7 +3289,13 @@ static void Command_Addfile(void) if (!isprint(fn[i]) || fn[i] == ';') return; - musiconly = W_VerifyNMUSlumps(fn); + musiconly = W_VerifyNMUSlumps(fn, false); + + if (musiconly == -1) + { + addedfiles[numfilesadded++] = fn; + continue; + } if (!musiconly) { @@ -3606,8 +3607,7 @@ static void Command_Playintro_f(void) */ FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void) { - if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(true); I_Quit(); } @@ -4269,8 +4269,7 @@ void Command_ExitGame_f(void) { INT32 i; - if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 98d8f1425..ac39626a4 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -31,9 +31,7 @@ extern consvar_t cv_defaultskin; extern consvar_t cv_defaultplayercolor2; extern consvar_t cv_defaultskin2; -#ifdef SEENAMES extern consvar_t cv_seenames, cv_allowseenames; -#endif extern consvar_t cv_usemouse; extern consvar_t cv_usejoystick; extern consvar_t cv_usejoystick2; diff --git a/src/d_player.h b/src/d_player.h index eb0372832..2e7afed88 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -51,7 +51,9 @@ typedef enum 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_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 } skinflags_t; diff --git a/src/deh_tables.c b/src/deh_tables.c index 5733d9b0e..3039bf7de 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1522,6 +1522,13 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_SPINFIRE5", "S_SPINFIRE6", + "S_TEAM_SPINFIRE1", + "S_TEAM_SPINFIRE2", + "S_TEAM_SPINFIRE3", + "S_TEAM_SPINFIRE4", + "S_TEAM_SPINFIRE5", + "S_TEAM_SPINFIRE6", + // Spikes "S_SPIKE1", "S_SPIKE2", @@ -3478,9 +3485,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_BLUEBRICKDEBRIS", "S_YELLOWBRICKDEBRIS", -#ifdef SEENAMES "S_NAMECHECK", -#endif }; // 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_YELLOWBRICKDEBRIS", -#ifdef SEENAMES "MT_NAMECHECK", -#endif }; const char *const MOBJFLAG_LIST[] = { @@ -4331,6 +4334,7 @@ const char *const MOBJFLAG2_LIST[] = { "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH "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) + "SPLAT", // Object is a splat NULL }; @@ -4794,6 +4798,7 @@ struct int_const_s const INT_CONST[] = { // fixed_t constants, from m_fixed.h {"FRACUNIT",FRACUNIT}, + {"FU" ,FRACUNIT}, {"FRACBITS",FRACBITS}, // doomdef.h constants @@ -4871,6 +4876,36 @@ struct int_const_s const INT_CONST[] = { {"tr_trans90",tr_trans90}, {"NUMTRANSMAPS",NUMTRANSMAPS}, + // Alpha styles (blend modes) + {"AST_COPY",AST_COPY}, + {"AST_TRANSLUCENT",AST_TRANSLUCENT}, + {"AST_ADD",AST_ADD}, + {"AST_SUBTRACT",AST_SUBTRACT}, + {"AST_REVERSESUBTRACT",AST_REVERSESUBTRACT}, + {"AST_MODULATE",AST_MODULATE}, + {"AST_OVERLAY",AST_OVERLAY}, + + // 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 {"LF_SCRIPTISFILE",LF_SCRIPTISFILE}, {"LF_SPEEDMUSIC",LF_SPEEDMUSIC}, @@ -4987,6 +5022,7 @@ struct int_const_s const INT_CONST[] = { {"SF_NOSUPERSPRITES",SF_NOSUPERSPRITES}, {"SF_NOSUPERJUMPBOOST",SF_NOSUPERJUMPBOOST}, {"SF_CANBUSTWALLS",SF_CANBUSTWALLS}, + {"SF_NOSHIELDABILITY",SF_NOSHIELDABILITY}, // Dashmode constants {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, diff --git a/src/dehacked.c b/src/dehacked.c index e98ff71cf..b42663267 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -59,6 +59,12 @@ ATTRINLINE static FUNCINLINE char myfget_color(MYFILE *f) if (c >= '0' && c <= '9') return 0x80+(c-'0'); + + c = tolower(c); + + if (c >= 'a' && c <= 'f') + return 0x80+10+(c-'a'); + return 0x80; // Unhandled -- default to no color } diff --git a/src/doomdef.h b/src/doomdef.h index d0b7ea0c2..52abc9597 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -582,9 +582,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Dumps the contents of a network save game upon consistency failure for debugging. //#define DUMPCONSISTENCY -/// See name of player in your crosshair -#define SEENAMES - /// Who put weights on my recycler? ... Inuyasha did. /// \note XMOD port. //#define WEIGHTEDRECYCLER diff --git a/src/doomtype.h b/src/doomtype.h index 08317c65a..950f50856 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -401,4 +401,8 @@ unset_bit_array (bitarray_t * const array, const int value) array[value >> 3] &= ~(1<<(value & 7)); } +#ifdef HAVE_SDL +typedef UINT64 precise_t; +#endif + #endif //__DOOMTYPE__ diff --git a/src/f_finale.c b/src/f_finale.c index 688cd4fc7..b23ab4f7a 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1074,6 +1074,7 @@ static const char *credits[] = { "\1Programming", "Alam \"GBC\" Arias", "Logan \"GBA\" Arias", + "Zolton \"Zippy_Zolton\" Auburn", "Colette \"fickleheart\" Bordelon", "Andrew \"orospakr\" Clunis", "Sally \"TehRealSalt\" Cochenour", @@ -1104,6 +1105,7 @@ static const char *credits[] = { "Sean \"Sryder13\" Ryder", "Ehab \"Wolfy\" Saeed", "Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible + "Riku \"Ors\" Salminen", // Demo consistency improvements "Jonas \"MascaraSnake\" Sauer", "Wessel \"sphere\" Smit", "\"SSNTails\"", diff --git a/src/g_demo.c b/src/g_demo.c index 9d3b86015..593fd7723 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1956,9 +1956,7 @@ void G_DoPlayDemo(char *defdemoname) // Set skin SetPlayerSkin(0, skin); -#ifdef HAVE_BLUA LUAh_MapChange(gamemap); -#endif displayplayer = consoleplayer = 0; memset(playeringame,0,sizeof(playeringame)); playeringame[0] = true; diff --git a/src/g_game.c b/src/g_game.c index 283113bbe..6171c7b72 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -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_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 -#endif // now automatically allocated in D_RegisterClientCommands // 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. if (marathonmode && gamemap == spmarathon_start && !players[consoleplayer].starposttime) { + player_t *p = &players[consoleplayer]; marathonmode |= MA_INIT; 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) players[consoleplayer].lives -= 1; diff --git a/src/g_game.h b/src/g_game.h index 2bcf444c2..744d6755a 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -25,9 +25,7 @@ extern char timeattackfolder[64]; extern char customversionstring[32]; #define GAMEDATASIZE (4*8192) -#ifdef SEENAMES extern player_t *seenplayer; -#endif extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; extern INT32 player_name_changes[MAXPLAYERS]; diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 5ea9f55d4..fb3417158 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -248,12 +248,12 @@ void HWR_RenderBatches(void) } // sort polygons - ps_hw_batchsorttime = I_GetTimeMicros(); + ps_hw_batchsorttime = I_GetPreciseTime(); if (cv_glshaders.value && gl_shadersavailable) qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons); else 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 // 1. shader // 2. texture @@ -261,7 +261,7 @@ void HWR_RenderBatches(void) // 4. colors + light level // 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; currentTexture = polygonArray[polygonIndexArray[0]].texture; @@ -446,7 +446,7 @@ void HWR_RenderBatches(void) polygonArraySize = 0; unsortedVertexArraySize = 0; - ps_hw_batchdrawtime = I_GetTimeMicros() - ps_hw_batchdrawtime; + ps_hw_batchdrawtime = I_GetPreciseTime() - ps_hw_batchdrawtime; } diff --git a/src/hardware/hw_batching.h b/src/hardware/hw_batching.h index 3d22324ac..42291a0df 100644 --- a/src/hardware/hw_batching.h +++ b/src/hardware/hw_batching.h @@ -16,7 +16,7 @@ #include "hw_data.h" #include "hw_drv.h" -typedef struct +typedef struct { FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused unsigned int vertsIndex;// location of verts in unsortedVertexArray diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index b4fa7ec6c..43fdc89f0 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -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 if (mipmap->colormap) - texel = mipmap->colormap[texel]; + texel = mipmap->colormap->data[texel]; // 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 ?) @@ -218,7 +218,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, //Hurdler: 25/04/2000: now support colormap in hardware mode if (mipmap->colormap) - texel = mipmap->colormap[texel]; + texel = mipmap->colormap->data[texel]; // 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 ?) @@ -659,7 +659,10 @@ void HWR_FreeTextureColormaps(patch_t *patch) // Free image data from memory. if (next->data) Z_Free(next->data); + if (next->colormap) + Z_Free(next->colormap); next->data = NULL; + next->colormap = NULL; HWD.pfnDeleteTexture(next); // 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) { - INT32 i; + boolean (*callback)(void *mem) = FreeTextureCallback; - for (i = 0; i < numwadfiles; i++) - { - INT32 j = 0; - for (; j < wadfiles[i]->numlumps; j++) - (freeall ? HWR_FreeTexture : HWR_FreeTextureColormaps)(wadfiles[i]->patchcache[j]); - } + if (!freeall) + callback = FreeColormapsCallback; + + Z_IterateTags(PU_PATCH, PU_PATCH_ROTATED, callback); + Z_IterateTags(PU_SPRITE, PU_HUDGFX, callback); } // 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); } +// ----------------------+ +// 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) { @@ -1006,14 +1042,20 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap) return; } - // search for the mimmap + // search for the mipmap // skip the first (no colormap translated) for (grMipmap = grPatch->mipmap; 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; } } @@ -1029,7 +1071,10 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap) I_Error("%s: Out of memory", "HWR_GetMappedPatch"); 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); } diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index 3ae4ef8bc..11e41b18a 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -39,6 +39,15 @@ typedef enum GLTextureFormat_e GL_TEXFMT_ALPHA_INTENSITY_88 = 0x22, } 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 // NULL if the texture is not in Doom heap cache. struct GLMipmap_s @@ -53,7 +62,7 @@ struct GLMipmap_s UINT32 downloaded; // The GPU has this texture. struct GLMipmap_s *nextcolormap; - const UINT8 *colormap; + struct GLColormap_s *colormap; struct GLMipmap_s *nextmipmap; // Linked list of all textures }; @@ -77,7 +86,7 @@ struct GLPatch_s { float max_s,max_t; GLMipmap_t *mipmap; -} ATTRPACK; +}; typedef struct GLPatch_s GLPatch_t; #endif //_HWR_DATA_ diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index b9cb288e9..c5d362520 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -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; 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 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; 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 v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t; diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 987d70c69..93c61f4e7 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -253,6 +253,7 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_SIGN &lspr[NOLIGHT], // SPR_SPIK &lspr[NOLIGHT], // SPR_SFLM + &lspr[NOLIGHT], // SPR_TFLM &lspr[NOLIGHT], // SPR_USPK &lspr[NOLIGHT], // SPR_WSPK &lspr[NOLIGHT], // SPR_WSPB diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5dd2727bc..a7e37d231 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -147,11 +147,11 @@ static angle_t gl_aimingangle; static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); // Render stats -int ps_hw_skyboxtime = 0; -int ps_hw_nodesorttime = 0; -int ps_hw_nodedrawtime = 0; -int ps_hw_spritesorttime = 0; -int ps_hw_spritedrawtime = 0; +precise_t ps_hw_skyboxtime = 0; +precise_t ps_hw_nodesorttime = 0; +precise_t ps_hw_nodedrawtime = 0; +precise_t ps_hw_spritesorttime = 0; +precise_t ps_hw_spritedrawtime = 0; // Render stats for batching int ps_hw_numpolys = 0; @@ -161,8 +161,8 @@ int ps_hw_numshaders = 0; int ps_hw_numtextures = 0; int ps_hw_numpolyflags = 0; int ps_hw_numcolors = 0; -int ps_hw_batchsorttime = 0; -int ps_hw_batchdrawtime = 0; +precise_t ps_hw_batchsorttime = 0; +precise_t ps_hw_batchdrawtime = 0; boolean gl_init = 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. 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++) { @@ -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! 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; 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); } else - vis->colormap = colormaps; + vis->colormap = NULL; // set top/bottom coords vis->gzt = gzt; @@ -5396,7 +5396,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->flip = flip; vis->mobj = (mobj_t *)thing; - vis->colormap = colormaps; + vis->colormap = NULL; // set top/bottom coords 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 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 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)? @@ -6132,7 +6132,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) ps_numbspcalls = 0; ps_numpolyobjects = 0; - ps_bsptime = I_GetTimeMicros(); + ps_bsptime = I_GetPreciseTime(); validcount++; @@ -6170,7 +6170,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) } #endif - ps_bsptime = I_GetTimeMicros() - ps_bsptime; + ps_bsptime = I_GetPreciseTime() - ps_bsptime; if (cv_glbatching.value) HWR_RenderBatches(); @@ -6186,12 +6186,12 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // Draw MD2 and sprites ps_numsprites = gl_visspritecount; - ps_hw_spritesorttime = I_GetTimeMicros(); + ps_hw_spritesorttime = I_GetPreciseTime(); HWR_SortVisSprites(); - ps_hw_spritesorttime = I_GetTimeMicros() - ps_hw_spritesorttime; - ps_hw_spritedrawtime = I_GetTimeMicros(); + ps_hw_spritesorttime = I_GetPreciseTime() - ps_hw_spritesorttime; + ps_hw_spritedrawtime = I_GetPreciseTime(); HWR_DrawSprites(); - ps_hw_spritedrawtime = I_GetTimeMicros() - ps_hw_spritedrawtime; + ps_hw_spritedrawtime = I_GetPreciseTime() - ps_hw_spritedrawtime; #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 2ce918408..4ad09aa3d 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -116,11 +116,11 @@ extern FTransform atransform; // Render stats -extern int ps_hw_skyboxtime; -extern int ps_hw_nodesorttime; -extern int ps_hw_nodedrawtime; -extern int ps_hw_spritesorttime; -extern int ps_hw_spritedrawtime; +extern precise_t ps_hw_skyboxtime; +extern precise_t ps_hw_nodesorttime; +extern precise_t ps_hw_nodedrawtime; +extern precise_t ps_hw_spritesorttime; +extern precise_t ps_hw_spritedrawtime; // Render stats for batching extern int ps_hw_numpolys; @@ -130,8 +130,8 @@ extern int ps_hw_numshaders; extern int ps_hw_numtextures; extern int ps_hw_numpolyflags; extern int ps_hw_numcolors; -extern int ps_hw_batchsorttime; -extern int ps_hw_batchdrawtime; +extern precise_t ps_hw_batchsorttime; +extern precise_t ps_hw_batchdrawtime; extern boolean gl_init; extern boolean gl_maploaded; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9c786e67e..2e944d3e6 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1106,11 +1106,19 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; ) { grMipmap = grMipmap->nextcolormap; - if (grMipmap->colormap == colormap) + if (grMipmap->colormap && grMipmap->colormap->source == colormap) { 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); return; } @@ -1128,7 +1136,10 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski if (newMipmap == NULL) I_Error("%s: Out of memory", "HWR_GetBlendedTexture"); 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); diff --git a/src/i_system.h b/src/i_system.h index dd0b65f6d..12f0d751d 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -46,7 +46,13 @@ UINT32 I_GetFreeMem(UINT32 *total); */ 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 diff --git a/src/i_tcp.c b/src/i_tcp.c index 5180869a5..ab8a69a9f 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -20,127 +20,121 @@ #endif #ifndef NO_IPV6 -#define HAVE_IPV6 + #define HAVE_IPV6 #endif #ifdef _WIN32 -#define USE_WINSOCK -#if defined (_WIN64) || defined (HAVE_IPV6) -#define USE_WINSOCK2 -#else //_WIN64/HAVE_IPV6 -#define USE_WINSOCK1 -#endif + #define USE_WINSOCK + #if defined (_WIN64) || defined (HAVE_IPV6) + #define USE_WINSOCK2 + #else //_WIN64/HAVE_IPV6 + #define USE_WINSOCK1 + #endif #endif //WIN32 OS #ifdef USE_WINSOCK2 -#include + #include #endif #include "doomdef.h" #if defined (NOMD5) && !defined (NONET) -//#define NONET + //#define NONET #endif #ifdef NONET -#undef HAVE_MINIUPNPC + #undef HAVE_MINIUPNPC #else -#ifdef USE_WINSOCK1 -#include -#elif !defined (SCOUW2) && !defined (SCOUW7) -#ifndef USE_WINSOCK -#include -#endif //normal BSD API + #ifdef USE_WINSOCK1 + #include + #else + #ifndef USE_WINSOCK + #include + #ifdef __APPLE_CC__ + #ifndef _BSD_SOCKLEN_T_ + #define _BSD_SOCKLEN_T_ + #endif //_BSD_SOCKLEN_T_ + #endif //__APPLE_CC__ + #include + #include + #include + #include + #endif //normal BSD API -#ifndef USE_WINSOCK -#ifdef __APPLE_CC__ -#ifndef _BSD_SOCKLEN_T_ -#define _BSD_SOCKLEN_T_ -#endif //_BSD_SOCKLEN_T_ -#endif //__APPLE_CC__ -#include -#include -#endif //normal BSD API + #include + #include -#ifndef USE_WINSOCK -#include -#include -#endif //normal BSD API + #if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) + #include + #endif // UNIXCOMMON + #endif -#include -#include + #ifdef USE_WINSOCK + // 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) - #include -#endif // UNIXCOMMON -#endif // !NONET + #ifdef __DJGPP__ + #ifdef WATTCP // Alam_GBC: Wattcp may need this + #include + #define strerror strerror_s + #else // wattcp + #include + #endif // libsocket + #endif // djgpp -#ifdef USE_WINSOCK - // 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 + typedef union + { + struct sockaddr any; + struct sockaddr_in ip4; + #ifdef HAVE_IPV6 + struct sockaddr_in6 ip6; #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 + } mysockaddr_t; -#ifdef __DJGPP__ -#ifdef WATTCP // Alam_GBC: Wattcp may need this -#include -#define strerror strerror_s -#else // wattcp -#include -#endif // libsocket -#endif // djgpp - -typedef union -{ - 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 + #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 // HAVE_MINIUPNC #endif // !NONET @@ -177,32 +171,32 @@ static UINT8 UPNP_support = TRUE; #define DEFAULTPORT "5029" #if defined (USE_WINSOCK) && !defined (NONET) -typedef SOCKET SOCKET_TYPE; -#define ERRSOCKET (SOCKET_ERROR) + typedef SOCKET SOCKET_TYPE; + #define ERRSOCKET (SOCKET_ERROR) #else -#if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) -typedef int SOCKET_TYPE; -#else -typedef unsigned long SOCKET_TYPE; -#endif -#define ERRSOCKET (-1) -#endif - -#if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) -typedef int socklen_t; + #if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) + typedef int SOCKET_TYPE; + #else + typedef unsigned long SOCKET_TYPE; + #endif + #define ERRSOCKET (-1) #endif #ifndef NONET -static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET}; -static size_t mysocketses = 0; -static int myfamily[MAXNETNODES+1] = {0}; -static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {ERRSOCKET}; -static mysockaddr_t clientaddress[MAXNETNODES+1]; -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]; + // define socklen_t in DOS/Windows if it is not already defined + #if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) + typedef int socklen_t; + #endif + static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET}; + static size_t mysocketses = 0; + static int myfamily[MAXNETNODES+1] = {0}; + static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {ERRSOCKET}; + static mysockaddr_t clientaddress[MAXNETNODES+1]; + 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 static size_t numbans = 0; diff --git a/src/info.c b/src/info.c index 29a79b1d6..ee836a372 100644 --- a/src/info.c +++ b/src/info.c @@ -150,6 +150,7 @@ char sprnames[NUMSPRITES + 1][5] = "SIGN", // Level end sign "SPIK", // Spike Ball "SFLM", // Spin fire + "TFLM", // Spin fire (team) "USPK", // Floor spike "WSPK", // Wall spike "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|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 {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 @@ -3291,18 +3299,18 @@ state_t states[NUMSTATES] = {SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_RANDOMANIM, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP // Spindash dust - {SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1 - {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_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, 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_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, 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_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4 + {SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1 + {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_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, 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_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4 + {SPR_FPRT, FF_FULLBRIGHT|0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1 + {SPR_FPRT, FF_FULLBRIGHT|0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2 + {SPR_FPRT, FF_FULLBRIGHT|FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3 + {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 @@ -3924,9 +3932,7 @@ state_t states[NUMSTATES] = {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 -#ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK -#endif }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = @@ -6458,8 +6464,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_fizzle, // deathsound 10*FRACUNIT, // speed - 48*FRACUNIT, // radius - 160*FRACUNIT, // height + 24*FRACUNIT, // radius + 80*FRACUNIT, // height 0, // display offset DMG_ELECTRIC, // mass 1, // damage @@ -21653,7 +21659,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, -#ifdef SEENAMES { // MT_NAMECHECK -1, // doomednum S_NAMECHECK, // spawnstate @@ -21680,7 +21685,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_NOSECTOR, // flags S_NULL // raisestate }, -#endif }; skincolor_t skincolors[MAXSKINCOLORS] = { diff --git a/src/info.h b/src/info.h index 604922beb..60e970246 100644 --- a/src/info.h +++ b/src/info.h @@ -684,6 +684,7 @@ typedef enum sprite SPR_SIGN, // Level end sign SPR_SPIK, // Spike Ball SPR_SFLM, // Spin fire + SPR_TFLM, // Spin fire (team) SPR_USPK, // Floor spike SPR_WSPK, // Wall spike SPR_WSPB, // Wall spike base @@ -2324,6 +2325,13 @@ typedef enum state S_SPINFIRE5, S_SPINFIRE6, + S_TEAM_SPINFIRE1, + S_TEAM_SPINFIRE2, + S_TEAM_SPINFIRE3, + S_TEAM_SPINFIRE4, + S_TEAM_SPINFIRE5, + S_TEAM_SPINFIRE6, + // Spikes S_SPIKE1, S_SPIKE2, @@ -4280,9 +4288,7 @@ typedef enum state S_BLUEBRICKDEBRIS, // for CEZ3 S_YELLOWBRICKDEBRIS, // for CEZ3 -#ifdef SEENAMES S_NAMECHECK, -#endif S_FIRSTFREESLOT, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, @@ -5082,9 +5088,7 @@ typedef enum mobj_type MT_BLUEBRICKDEBRIS, // for CEZ3 MT_YELLOWBRICKDEBRIS, // for CEZ3 -#ifdef SEENAMES MT_NAMECHECK, -#endif MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 59c1d411b..c5f847be6 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -165,6 +165,8 @@ static const struct { {META_SKIN, "skin_t"}, {META_POWERS, "player_t.powers"}, {META_SOUNDSID, "skin_t.soundsid"}, + {META_SKINSPRITES, "skin_t.sprites"}, + {META_SKINSPRITESLIST, "skin_t.sprites[]"}, {META_VERTEX, "vertex_t"}, {META_LINE, "line_t"}, diff --git a/src/lua_hook.h b/src/lua_hook.h index 796f3a9d2..5cfcb8360 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -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 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 -#ifdef SEENAMES 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 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_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes \ No newline at end of file +boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 117aa48a3..29c15a4de 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -25,7 +25,7 @@ #include "m_perfstats.h" #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]; @@ -481,7 +481,7 @@ void LUAh_ThinkFrame(void) continue; if (cv_perfstats.value == 3) - time_taken = I_GetTimeMicros(); + time_taken = I_GetPreciseTime(); PushHook(gL, hookp); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -492,7 +492,7 @@ void LUAh_ThinkFrame(void) if (cv_perfstats.value == 3) { 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 PushHook(gL, hookp); lua_getinfo(gL, ">S", &ar); @@ -1754,7 +1754,6 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean } // Hook for MT_NAMECHECK -#ifdef SEENAMES boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) { hook_p hookp; @@ -1798,7 +1797,6 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) return hasSeenPlayer; } -#endif // SEENAMES 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 -void LUAh_GameQuit(void) +void LUAh_GameQuit(boolean quitting) { hook_p hookp; if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8)))) @@ -1860,7 +1858,8 @@ void LUAh_GameQuit(void) continue; 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) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(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); newname[6] = 0; return hooked; -} \ No newline at end of file +} diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 684e47c38..e58cd4a58 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -896,8 +896,10 @@ static int libd_getColormap(lua_State *L) else if (lua_type(L, 1) == LUA_TNUMBER) // skin number { skinnum = (INT32)luaL_checkinteger(L, 1); - if (skinnum < TC_BLINK || skinnum >= MAXSKINS) - return luaL_error(L, "skin number %d is out of range (%d - %d)", skinnum, TC_BLINK, MAXSKINS-1); + if (skinnum >= MAXSKINS) + 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 { diff --git a/src/lua_libs.h b/src/lua_libs.h index e7f4ae253..fbe8d4878 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -39,6 +39,8 @@ extern lua_State *gL; #define META_SKIN "SKIN_T*" #define META_POWERS "PLAYER_T*POWERS" #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_LINE "LINE_T*" diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 3520cdbda..6a9091cc9 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2181,6 +2181,8 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->levelflags); else if (fastcmp(field,"menuflags")) lua_pushinteger(L, header->menuflags); + else if (fastcmp(field,"selectheading")) + lua_pushstring(L, header->selectheading); else if (fastcmp(field,"startrings")) lua_pushinteger(L, header->startrings); else if (fastcmp(field, "sstimer")) diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 7cbe7a6cc..10ba42ee0 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -192,18 +192,30 @@ static luaL_Reg lib[] = { {"cos", lib_finecosine}, {"tan", lib_finetangent}, {"FixedAngle", lib_fixedangle}, + {"fixangle" , lib_fixedangle}, {"AngleFixed", lib_anglefixed}, + {"anglefix" , lib_anglefixed}, {"InvAngle", lib_invangle}, {"FixedMul", lib_fixedmul}, + {"fixmul" , lib_fixedmul}, {"FixedInt", lib_fixedint}, + {"fixint" , lib_fixedint}, {"FixedDiv", lib_fixeddiv}, + {"fixdiv" , lib_fixeddiv}, {"FixedRem", lib_fixedrem}, + {"fixrem" , lib_fixedrem}, {"FixedSqrt", lib_fixedsqrt}, + {"fixsqrt" , lib_fixedsqrt}, {"FixedHypot", lib_fixedhypot}, + {"fixhypot" , lib_fixedhypot}, {"FixedFloor", lib_fixedfloor}, + {"fixfloor" , lib_fixedfloor}, {"FixedTrunc", lib_fixedtrunc}, + {"fixtrunc" , lib_fixedtrunc}, {"FixedCeil", lib_fixedceil}, + {"fixceil" , lib_fixedceil}, {"FixedRound", lib_fixedround}, + {"fixround" , lib_fixedround}, {"GetSecSpecial", lib_getsecspecial}, {"All7Emeralds", lib_all7emeralds}, {"ColorOpposite", lib_coloropposite}, diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 412dc3eff..0eb54808f 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -158,6 +158,10 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->flashpal); else if (fastcmp(field,"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")) lua_pushinteger(L, plr->score); 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); plr->skincolor = newcolor; } + else if (fastcmp(field,"skin")) + return NOSET; + else if (fastcmp(field,"availabilities")) + return NOSET; else if (fastcmp(field,"score")) plr->score = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"dashspeed")) diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 3e4ddb9f0..56be6bf4f 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -21,7 +21,6 @@ enum skin { skin_valid = 0, skin_name, - skin_spritedef, skin_wadnum, skin_flags, skin_realname, @@ -54,12 +53,12 @@ enum skin { skin_contspeed, skin_contangle, skin_soundsid, - skin_availability + skin_availability, + skin_sprites }; static const char *const skin_opt[] = { "valid", "name", - "spritedef", "wadnum", "flags", "realname", @@ -93,6 +92,7 @@ static const char *const skin_opt[] = { "contangle", "soundsid", "availability", + "sprites", 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]) @@ -113,8 +113,6 @@ static int skin_get(lua_State *L) case skin_name: lua_pushstring(L, skin->name); break; - case skin_spritedef: - return UNIMPLEMENTED; case skin_wadnum: // !!WARNING!! May differ between clients due to music wads, therefore NOT NETWORK SAFE return UNIMPLEMENTED; @@ -214,6 +212,9 @@ static int skin_get(lua_State *L) case skin_availability: lua_pushinteger(L, skin->availability); break; + case skin_sprites: + LUA_PushLightUserdata(L, skin->sprites, META_SKINSPRITES); + break; } return 1; } @@ -324,6 +325,49 @@ static int soundsid_num(lua_State *L) 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) { luaL_newmetatable(L, META_SKIN); @@ -345,6 +389,19 @@ int LUA_SkinLib(lua_State *L) lua_setfield(L, -2, "__len"); 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_createtable(L, 0, 2); lua_pushcfunction(L, lib_getSkin); diff --git a/src/m_anigif.c b/src/m_anigif.c index dbc8d3422..41f99254e 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -18,7 +18,7 @@ #include "z_zone.h" #include "v_video.h" #include "i_video.h" -#include "i_system.h" // I_GetTimeMicros +#include "i_system.h" // I_GetPreciseTime #include "m_misc.h" #include "st_stuff.h" // st_palette @@ -53,8 +53,8 @@ static RGBA_t *gif_framepalette = NULL; static FILE *gif_out = NULL; static INT32 gif_frames = 0; -static UINT32 gif_prevframeus = 0; // "us" is microseconds -static UINT32 gif_delayus = 0; +static precise_t gif_prevframetime = 0; +static UINT32 gif_delayus = 0; // "us" is microseconds static UINT8 gif_writeover = 0; @@ -608,7 +608,7 @@ static void GIF_framewrite(void) { // 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). - 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? { @@ -621,7 +621,7 @@ static void GIF_framewrite(void) { 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)) delay = (UINT16)(delayf); @@ -711,7 +711,7 @@ static void GIF_framewrite(void) } fwrite(gifframe_data, 1, (p - gifframe_data), gif_out); ++gif_frames; - gif_prevframeus = I_GetTimeMicros(); + gif_prevframetime = I_GetPreciseTime(); } @@ -739,7 +739,7 @@ INT32 GIF_open(const char *filename) GIF_headwrite(); gif_frames = 0; - gif_prevframeus = I_GetTimeMicros(); + gif_prevframetime = I_GetPreciseTime(); gif_delayus = 0; return 1; } diff --git a/src/m_menu.c b/src/m_menu.c index 77648f877..05c819c37 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -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, "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. -#ifdef SEENAMES {IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 86}, -#endif {IT_HEADER, NULL, "Console", NULL, 95}, {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_HEADER, NULL, "Movie Mode (F9)", NULL, 64}, - {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, NULL, "Capture Mode", &cv_moviemode, 90}, + {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, 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, 100}, + {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 95}, + {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, "Memory Level", &cv_zlib_memorya, 95}, - {IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 100}, - {IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategya, 105}, - {IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bitsa, 110}, + {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_apng_downscale, 95}, + {IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memorya, 100}, + {IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 105}, + {IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategya, 110}, + {IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bitsa, 115}, }; enum @@ -1575,7 +1574,7 @@ enum op_screenshot_gif_start = 13, op_screenshot_gif_end = 15, op_screenshot_apng_start = 16, - op_screenshot_apng_end = 19, + op_screenshot_apng_end = 20, }; static menuitem_t OP_EraseDataMenu[] = @@ -6937,8 +6936,7 @@ static void M_SelectableClearMenus(INT32 choice) static void M_UltimateCheat(INT32 choice) { (void)choice; - if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(true); I_Quit(); } @@ -8423,7 +8421,7 @@ static void M_DrawLoadGameData(void) sprdef = &charbotskin->sprites[SPR2_SIGN]; if (!sprdef->numframes) 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]; patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); @@ -8433,8 +8431,6 @@ static void M_DrawLoadGameData(void) charbotskin->highresscale, 0, patch, colormap); - Z_Free(colormap); - tempx -= (20<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) goto skipsign; sprframe = &sprdef->spriteframes[0]; @@ -8483,8 +8479,6 @@ skipsign: charskin->highresscale/2, 0, patch, colormap); skiplife: - if (colormap) - Z_Free(colormap); patch = W_CachePatchName("STLIVEX", PU_PATCH); @@ -11755,7 +11749,7 @@ static void M_DrawSetupMultiPlayerMenu(void) goto faildraw; // 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) multi_frame = 0; @@ -11773,7 +11767,6 @@ static void M_DrawSetupMultiPlayerMenu(void) FixedDiv(skins[setupm_fakeskin].highresscale, skins[setupm_fakeskin].shieldscale), flags, patch, colormap); - Z_Free(colormap); goto colordraw; faildraw: @@ -13372,8 +13365,7 @@ void M_QuitResponse(INT32 ch) if (ch != 'y' && ch != KEY_ENTER) return; - if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(true); if (!(netgame || cv_debug)) { S_ResetCaptions(); diff --git a/src/m_misc.c b/src/m_misc.c index d97d8f94b..ad2d133ab 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -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_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_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 @@ -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) { + png_uint_16 downscale = apng_downscale ? vid.dupx : 1; + png_uint_32 pitch = png_get_rowbytes(png_ptr, png_info_ptr); - PNG_CONST png_uint_32 height = vid.height; - png_bytepp row_pointers = png_malloc(png_ptr, height* sizeof (png_bytep)); - png_uint_32 y; + PNG_CONST png_uint_32 width = vid.width / downscale; + PNG_CONST png_uint_32 height = vid.height / downscale; + 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; apng_frames++; for (y = 0; y < height; y++) { - row_pointers[y] = png_buf; - png_buf += pitch; + row_pointers[y] = malloc(pitch * sizeof(png_byte)); + 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 if (aPNG_write_frame_head) #endif aPNG_write_frame_head(apng_ptr, apng_info_ptr, row_pointers, - vid.width, /* width */ + width, /* width */ height, /* height */ 0, /* x 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) { + png_uint_16 downscale; + + apng_downscale = (!!cv_apng_downscale.value); + + downscale = apng_downscale ? vid.dupx : 1; + apng_FILE = fopen(filename,"wb+"); // + mode for reading 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_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); diff --git a/src/m_misc.h b/src/m_misc.h index dbded37d0..c5ef9f9f2 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -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_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits; extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa; -extern consvar_t cv_apng_delay; +extern consvar_t cv_apng_delay, cv_apng_downscale; void M_StartMovie(void); void M_SaveFrame(void); diff --git a/src/m_perfstats.c b/src/m_perfstats.c index 085adda80..1596a87e5 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -22,32 +22,37 @@ #include "hardware/hw_main.h" #endif -int ps_tictime = 0; +struct perfstatcol; +struct perfstatrow; -int ps_playerthink_time = 0; -int ps_thinkertime = 0; +typedef struct perfstatcol perfstatcol_t; +typedef struct perfstatrow perfstatrow_t; -int ps_thlist_times[NUM_THINKERLISTS]; -static const char* thlist_names[] = { - "Polyobjects: %d", - "Main: %d", - "Mobjs: %d", - "Dynamic slopes: %d", - "Precipitation: %d", - NULL +struct perfstatcol { + INT32 lores_x; + INT32 hires_x; + INT32 color; + perfstatrow_t * rows; }; -static const char* thlist_shortnames[] = { - "plyobjs %d", - "main %d", - "mobjs %d", - "dynslop %d", - "precip %d", - NULL + +struct perfstatrow { + const char * lores_label; + const char * hires_label; + void * value; }; +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_lua_thinkframe_time = 0; +precise_t ps_lua_thinkframe_time = 0; int ps_lua_mobjhooks = 0; // 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_capacity = 16; +static INT32 draw_row; + void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src) { if (!thinkframe_hooks) @@ -76,379 +83,413 @@ void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src) 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: ", ®ularcount}, + {"scenery", "Scenery: ", &scenerycount}, + {0} + }; + + perfstatrow_t nothinkcount_row[] = { + {"nothink", "Nothink: ", ¬hinkcount}, + {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(¬hinkcount_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) { char s[100]; - int currenttime = I_GetTimeMicros(); - int frametime = currenttime - ps_prevframetime; - ps_prevframetime = currenttime; + + PS_SetFrameTime(); if (cv_perfstats.value == 1) // rendering { - if (vid.width < 640 || vid.height < 400) // low resolution - { - 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); - } - } + M_DrawRenderStats(); } else if (cv_perfstats.value == 2) // logic { - 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 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); - } + M_DrawTickStats(); } else if (cv_perfstats.value == 3) // lua thinkframe { diff --git a/src/m_perfstats.h b/src/m_perfstats.h index 01a818c1c..132bea38c 100644 --- a/src/m_perfstats.h +++ b/src/m_perfstats.h @@ -16,17 +16,17 @@ #include "lua_script.h" #include "p_local.h" -extern int ps_tictime; +extern precise_t ps_tictime; -extern int ps_playerthink_time; -extern int ps_thinkertime; +extern precise_t ps_playerthink_time; +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 int ps_lua_mobjhooks; +extern precise_t ps_lua_thinkframe_time; +extern int ps_lua_mobjhooks; typedef struct { diff --git a/src/p_enemy.c b/src/p_enemy.c index 22de9bc67..203e04af1 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1834,7 +1834,7 @@ void A_SnailerThink(mobj_t *actor) fixed_t dist; 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 { @@ -3924,6 +3924,10 @@ void A_BossDeath(mobj_t *mo) } else { + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; + // Bring the egg trap up to the surface // Incredibly shitty code ahead Tag_FSet(&junk.tags, LE_CAPSULE0); @@ -4053,6 +4057,10 @@ bossjustdie: } case MT_KOOPA: { + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; + Tag_FSet(&junk.tags, LE_KOOPA); EV_DoCeiling(&junk, raiseToHighest); return; diff --git a/src/p_floor.c b/src/p_floor.c index ed49b03a3..7c26065b5 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1064,9 +1064,7 @@ static mobj_t *SearchMarioNode(msecnode_t *node) case MT_HOOP: case MT_HOOPCOLLIDE: case MT_NIGHTSCORE: -#ifdef SEENAMES case MT_NAMECHECK: // DEFINITELY not this, because it is client-side. -#endif continue; default: break; diff --git a/src/p_inter.c b/src/p_inter.c index 415c679e4..e9a16a3dd 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -470,14 +470,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) 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 - + if (elementalpierce == 2) // Reset bubblewrap, part 1 P_DoBubbleBounce(player); toucher->momz = setmomz; if (elementalpierce == 2) // Reset bubblewrap, part 2 { boolean underwater = toucher->eflags & MFE_UNDERWATER; - + if (underwater) toucher->momz /= 2; 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) return; + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; + Tag_FSet(&junk.tags, LE_AXE); 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)) macespin = true; - + if (macespin ? (player->powers[pw_ignorelatch] & (1<<15)) : (player->powers[pw_ignorelatch])) return; diff --git a/src/p_local.h b/src/p_local.h index 8a5084962..9359290fa 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -279,6 +279,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype); void P_RespawnSpecials(void); 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_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_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) -#ifdef SEENAMES #define P_SpawnNameFinder(s,t) P_SPMAngle(s,t,s->angle,true,0) -#endif void P_ColorTeamMissile(mobj_t *missile, player_t *source); SINT8 P_MobjFlip(mobj_t *mobj); fixed_t P_GetMobjGravity(mobj_t *mo); diff --git a/src/p_map.c b/src/p_map.c index 922c0d9ec..b934e3255 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -727,9 +727,8 @@ static boolean PIT_CheckThing(mobj_t *thing) || (thing->player && thing->player->spectator)) return true; -#ifdef SEENAMES - // Do name checks all the way up here - // So that NOTHING ELSE can see MT_NAMECHECK because it is client-side. + // Do name checks all the way up here + // So that NOTHING ELSE can see MT_NAMECHECK because it is client-side. if (tmthing->type == MT_NAMECHECK) { // Ignore things that aren't players, ignore spectators, ignore yourself. @@ -753,7 +752,6 @@ static boolean PIT_CheckThing(mobj_t *thing) seenplayer = thing->player; return false; } -#endif // Metal Sonic destroys tiny baby objects. if (tmthing->type == MT_METALSONIC_RACE @@ -982,7 +980,8 @@ static boolean PIT_CheckThing(mobj_t *thing) 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; - 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); 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->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; } @@ -1683,7 +1683,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) { fixed_t setmomz = -*momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce - + if (elementalpierce == 2) // Reset bubblewrap, part 1 P_DoBubbleBounce(player); *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 { boolean underwater = tmthing->eflags & MFE_UNDERWATER; - + if (underwater) *momz /= 2; *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); } - if (slidemo->player && slidemo->player->charability == CA_GLIDEANDCLIMB - && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing)) - PTR_GlideClimbTraverse(li); + if (slidemo->player) + { + 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)) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 7ba6d1fad..58124fb9b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3366,7 +3366,7 @@ void P_MobjCheckWater(mobj_t *mobj) } // 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) && ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop) || ((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) break; } - if (spawner) + if (spawner && dist) { mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER); - - if (dist == 0) - missile->fuse = 0; - else - missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy)); + missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy)); if (missile->fuse > mobj->fuse) P_RemoveMobj(missile); @@ -7937,7 +7933,7 @@ static boolean P_MobjPushableThink(mobj_t *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.) - 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))) { P_KillMobj(mobj, NULL, NULL, 0); @@ -9651,6 +9647,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; } case MT_SALOONDOOR: + if (!mobj->tracer) // Door center is gone or not spawned? + { + P_RemoveMobj(mobj); // Die + return false; + } + P_SaloonDoorThink(mobj); break; case MT_MINECARTSPAWNER: @@ -9705,7 +9707,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_MobjCheckWater(mobj); // 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))) { P_KillMobj(mobj, NULL, NULL, 0); @@ -9835,7 +9837,7 @@ static void P_FlagFuseThink(mobj_t *mobj) if (mobj->type == MT_REDFLAG) { 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 if (players[consoleplayer].ctfteam == 1 || splitscreen) @@ -9848,7 +9850,7 @@ static void P_FlagFuseThink(mobj_t *mobj) else // MT_BLUEFLAG { 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 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->y = y; - 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 - 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; + P_SetMobjSpawnDefaults(mobj); // set subsector and/or block links P_SetThingPosition(mobj); 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->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; } + st = &states[info->spawnstate]; + // Call action functions when the state is set 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; } +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) { state_t *st; @@ -11397,6 +11407,10 @@ void P_SpawnPlayer(INT32 playernum) p->jumpfactor = skins[p->skin].jumpfactor; } + // Clear lastlinehit and lastsidehit + p->lastsidehit = -1; + p->lastlinehit = -1; + //awayview stuff p->awayviewmobj = NULL; p->awayviewtics = 0; @@ -11792,7 +11806,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) if (!(G_CoopGametype() || (mthing->options & MTF_EXTRA))) 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 break; diff --git a/src/p_saveg.c b/src/p_saveg.c index adedea049..c1364e08f 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1506,7 +1506,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) { const mobj_t *mobj = (const mobj_t *)th; UINT32 diff; - UINT16 diff2; + UINT32 diff2; // Ignore stationary hoops - these will be respawned from mapthings. if (mobj->type == MT_HOOP) @@ -1638,7 +1638,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_SHADOWSCALE; if (mobj->renderflags) diff2 |= MD2_RENDERFLAGS; - if (mobj->renderflags) + if (mobj->blendmode != AST_TRANSLUCENT) diff2 |= MD2_BLENDMODE; if (mobj->spritexscale != FRACUNIT) diff2 |= MD2_SPRITEXSCALE; @@ -1646,6 +1646,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_SPRITEYSCALE; if (mobj->spritexoffset) diff2 |= MD2_SPRITEXOFFSET; + if (mobj->spriteyoffset) + diff2 |= MD2_SPRITEYOFFSET; if (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); WRITEUINT32(save_p, diff); 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 WRITEUINT32(save_p, (size_t)mobj); @@ -2615,14 +2617,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) thinker_t *next; mobj_t *mobj; UINT32 diff; - UINT16 diff2; + UINT32 diff2; INT32 i; fixed_t z, floorz, ceilingz; ffloor_t *floorrover = NULL, *ceilingrover = NULL; diff = READUINT32(save_p); if (diff & MD_MORE) - diff2 = READUINT16(save_p); + diff2 = READUINT32(save_p); else diff2 = 0; @@ -2690,7 +2692,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) } mobj->type = i; } + mobj->info = &mobjinfo[mobj->type]; + P_SetMobjSpawnDefaults(mobj); + if (diff & MD_POS) { mobj->x = READFIXED(save_p); @@ -2716,35 +2721,21 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff & MD_RADIUS) mobj->radius = READFIXED(save_p); - else - mobj->radius = mobj->info->radius; if (diff & MD_HEIGHT) mobj->height = READFIXED(save_p); - else - mobj->height = mobj->info->height; if (diff & MD_FLAGS) mobj->flags = READUINT32(save_p); - else - mobj->flags = mobj->info->flags; if (diff & MD_FLAGS2) mobj->flags2 = READUINT32(save_p); if (diff & MD_HEALTH) mobj->health = READINT32(save_p); - else - mobj->health = mobj->info->spawnhealth; if (diff & MD_RTIME) mobj->reactiontime = READINT32(save_p); - else - mobj->reactiontime = mobj->info->reactiontime; if (diff & MD_STATE) mobj->state = &states[READUINT16(save_p)]; - else - mobj->state = &states[mobj->info->spawnstate]; if (diff & MD_TICS) mobj->tics = READINT32(save_p); - else - mobj->tics = mobj->state->tics; if (diff & MD_SPRITE) { mobj->sprite = READUINT16(save_p); if (mobj->sprite == SPR_PLAY) @@ -2760,11 +2751,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->frame = READUINT32(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) mobj->eflags = READUINT16(save_p); if (diff & MD_PLAYER) @@ -2781,20 +2767,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->threshold = READINT32(save_p); if (diff & MD_LASTLOOK) mobj->lastlook = READINT32(save_p); - else - mobj->lastlook = -1; if (diff & MD_TARGET) mobj->target = (mobj_t *)(size_t)READUINT32(save_p); if (diff & MD_TRACER) mobj->tracer = (mobj_t *)(size_t)READUINT32(save_p); if (diff & MD_FRICTION) mobj->friction = READFIXED(save_p); - else - mobj->friction = ORIG_FRICTION; if (diff & MD_MOVEFACTOR) mobj->movefactor = READFIXED(save_p); - else - mobj->movefactor = FRACUNIT; if (diff & MD_FUSE) mobj->fuse = READINT32(save_p); if (diff & MD_WATERTOP) @@ -2803,16 +2783,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->waterbottom = READFIXED(save_p); if (diff & MD_SCALE) mobj->scale = READFIXED(save_p); - else - mobj->scale = FRACUNIT; if (diff & MD_DSCALE) mobj->destscale = READFIXED(save_p); - else - mobj->destscale = mobj->scale; if (diff2 & MD2_SCALESPEED) mobj->scalespeed = READFIXED(save_p); - else - mobj->scalespeed = FRACUNIT/12; if (diff2 & MD2_CUSVAL) mobj->cusval = READINT32(save_p); if (diff2 & MD2_CVMEM) diff --git a/src/p_setup.c b/src/p_setup.c index 918ffbd4e..66243fb0e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1621,6 +1621,14 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val) P_SetLinedefV1(i, atol(val)); else if (fastcmp(param, "v2")) 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) { size_t argnum = atol(param + 3); @@ -1628,14 +1636,6 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val) return; 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")) lines[i].sidenum[0] = atol(val); 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)) 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) { size_t argnum = atol(param + 3); @@ -1727,14 +1735,6 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val) return; 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. @@ -3171,7 +3171,7 @@ static void P_ConvertBinaryMap(void) switch (mapthings[i].type) { case 750: - Tag_Add(&mapthings[i].tags, mapthings[i].angle); + Tag_FSet(&mapthings[i].tags, mapthings[i].angle); break; case 760: case 761: diff --git a/src/p_spec.c b/src/p_spec.c index a1afdd00d..226e58d15 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4304,7 +4304,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers if (leveltime % (TICRATE/2) == 0 && player->rings > 0) { player->rings--; - S_StartSound(player->mo, sfx_itemup); + S_StartSound(player->mo, sfx_antiri); } break; 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. sector->special = 0; + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; + // Move the button down - Tag_FSet(&junk.tags, 680); + Tag_FSet(&junk.tags, LE_CAPSULE0); EV_DoElevator(&junk, elevateDown, false); // Open the top FOF - Tag_FSet(&junk.tags, 681); + Tag_FSet(&junk.tags, LE_CAPSULE1); EV_DoFloor(&junk, raiseFloorToNearestFast); // Open the bottom FOF - Tag_FSet(&junk.tags, 682); + Tag_FSet(&junk.tags, LE_CAPSULE2); EV_DoCeiling(&junk, lowerToLowestFast); // Mark all players with the time to exit thingy! @@ -4503,7 +4507,7 @@ DoneSection2: 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)) player->pflags |= PF_SPINNING; @@ -4600,7 +4604,7 @@ DoneSection2: HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); 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) S_StartSound(NULL, sfx_flgcap); @@ -4633,7 +4637,7 @@ DoneSection2: HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); 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) S_StartSound(NULL, sfx_flgcap); @@ -4669,7 +4673,7 @@ DoneSection2: break; 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; P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); @@ -4823,6 +4827,8 @@ DoneSection2: if (player->laps >= (UINT8)cv_numlaps.value) 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 CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1); diff --git a/src/p_tick.c b/src/p_tick.c index da2a980c4..c0a1c5700 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -22,7 +22,7 @@ #include "lua_script.h" #include "lua_hook.h" #include "m_perfstats.h" -#include "i_system.h" // I_GetTimeMicros +#include "i_system.h" // I_GetPreciseTime // Object place #include "m_cheat.h" @@ -323,7 +323,7 @@ static inline void P_RunThinkers(void) size_t 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) { #ifdef PARANOIA @@ -331,7 +331,7 @@ static inline void P_RunThinkers(void) #endif 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(); - ps_playerthink_time = I_GetTimeMicros(); + ps_playerthink_time = I_GetPreciseTime(); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) 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! @@ -677,18 +677,18 @@ void P_Ticker(boolean run) if (run) { - ps_thinkertime = I_GetTimeMicros(); + ps_thinkertime = I_GetPreciseTime(); P_RunThinkers(); - ps_thinkertime = I_GetTimeMicros() - ps_thinkertime; + ps_thinkertime = I_GetPreciseTime() - ps_thinkertime; // Run any "after all the other thinkers" stuff for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); - ps_lua_thinkframe_time = I_GetTimeMicros(); + ps_lua_thinkframe_time = I_GetPreciseTime(); 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 diff --git a/src/p_user.c b/src/p_user.c index c5f919c78..a70dceb8b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1341,7 +1341,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) // Transformation animation P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); - if (giverings) + if (giverings && player->rings < 50) player->rings = 50; // Just in case. @@ -1491,10 +1491,10 @@ void P_PlayLivesJingle(player_t *player) if (player && !P_IsLocalPlayer(player)) return; - if (use1upSound || cv_1upsound.value) - S_StartSound(NULL, sfx_oneup); - else if (mariomode) + if (mariomode) S_StartSound(NULL, sfx_marioa); + else if (use1upSound || cv_1upsound.value) + S_StartSound(NULL, sfx_oneup); else { P_PlayJingle(player, JT_1UP); @@ -2329,7 +2329,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) P_MobjCheckWater(player->mo); 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); S_StartSound(player->mo, sfx_spin); @@ -2612,10 +2613,10 @@ static void P_CheckBustableBlocks(player_t *player) if ((netgame || multiplayer) && player->spectator) return; - + oldx = player->mo->x; oldy = player->mo->y; - + if (!(player->pflags & PF_BOUNCING)) // Bouncers only get to break downwards, not sideways { P_UnsetThingPosition(player->mo); @@ -2634,7 +2635,7 @@ static void P_CheckBustableBlocks(player_t *player) if (!node->m_sector->ffloors) continue; - + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { if (!P_PlayerCanBust(player, rover)) @@ -4525,6 +4526,9 @@ void P_DoJump(player_t *player, boolean soundandstate) player->pflags |= P_GetJumpFlags(player);; + if (player->charflags & SF_NOJUMPDAMAGE) + player->pflags &= ~PF_SPINNING; + if (soundandstate) { 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) && ((!(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))) { @@ -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 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; } } - 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); } @@ -5920,7 +5924,7 @@ static void P_3dMovement(player_t *player) player->rmomy = player->mo->momy - player->cmomy; // 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 // 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); P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); P_SetObjectMomZ(flame, 3*FRACUNIT, false); + if (!(gametyperules & GTR_FRIENDLY)) + { + P_SetMobjState(flame, S_TEAM_SPINFIRE1); + flame->color = player->mo->color; + } } #undef limitangle #undef numangles @@ -7779,6 +7788,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle) flame->destscale = player->mo->scale; P_SetScale(flame, player->mo->scale); 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 P_XYMovement(flame); @@ -8605,12 +8619,6 @@ void P_MovePlayer(player_t *player) player->climbing--; } - if (!player->climbing) - { - player->lastsidehit = -1; - player->lastlinehit = -1; - } - // Make sure you're not teetering when you shouldn't be. if (player->panim == PA_EDGE && (player->mo->momx || player->mo->momy || player->mo->momz)) @@ -8635,6 +8643,7 @@ void P_MovePlayer(player_t *player) P_DoFiring(player, cmd); { + boolean atspinheight = false; fixed_t oldheight = player->mo->height; // 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->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) + { player->mo->height = P_GetPlayerSpinHeight(player); + atspinheight = true; + } else 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 player->mo->z -= player->mo->height - oldheight; - } - // Crush test... - if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) - && !(player->mo->flags & MF_NOCLIP)) - { - if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SPINNING)) + // Crush test... + if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) + && !(player->mo->flags & MF_NOCLIP)) { - player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); - } - else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) - { - if ((netgame || multiplayer) && player->spectator) - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators - else - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED); + if (!atspinheight) + { + player->pflags |= PF_SPINNING; + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + } + else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) + { + if ((netgame || multiplayer) && player->spectator) + 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) - return; + if (player->playerstate == PST_DEAD) + return; + } } } @@ -11482,7 +11494,6 @@ void P_PlayerThink(player_t *player) } } -#ifdef SEENAMES if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5))) { seenplayer = NULL; @@ -11507,7 +11518,6 @@ void P_PlayerThink(player_t *player) } } } -#endif if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) { @@ -12578,13 +12588,16 @@ void P_PlayerAfterThink(player_t *player) player->powers[pw_carry] = CR_NONE; 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->momy = tails->momy; 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; @@ -12599,7 +12612,7 @@ void P_PlayerAfterThink(player_t *player) { if (player->mo->state-states != 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; } else diff --git a/src/r_draw.h b/src/r_draw.h index 9957541ca..d1eb83033 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -106,13 +106,17 @@ extern lumpnum_t viewborderlump[8]; #define GTC_CACHE 1 -#define TC_DEFAULT -1 -#define TC_BOSS -2 -#define TC_METALSONIC -3 // For Metal Sonic battle -#define TC_ALLWHITE -4 // For Cy-Brak-demon -#define TC_RAINBOW -5 // For single colour -#define TC_BLINK -6 // For item blinking, according to kart -#define TC_DASHMODE -7 // For Metal Sonic's dashmode +enum +{ + TC_BOSS = INT8_MIN, + TC_METALSONIC, // For Metal Sonic battle + TC_ALLWHITE, // For Cy-Brak-demon + TC_RAINBOW, // For single colour + TC_BLINK, // For item blinking, according to kart + TC_DASHMODE, // For Metal Sonic's dashmode + + TC_DEFAULT +}; // Custom player skin translation // Initialize color translation tables, for player rendering etc. diff --git a/src/r_main.c b/src/r_main.c index 165f74a79..f82fb589e 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -34,7 +34,7 @@ #include "m_random.h" // quake camera shake #include "r_portal.h" #include "r_main.h" -#include "i_system.h" // I_GetTimeMicros +#include "i_system.h" // I_GetPreciseTime #ifdef HWRENDER #include "hardware/hw_main.h" @@ -100,17 +100,17 @@ lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; extracolormap_t *extra_colormaps = NULL; // Render stats -int ps_prevframetime = 0; -int ps_rendercalltime = 0; -int ps_uitime = 0; -int ps_swaptime = 0; +precise_t ps_prevframetime = 0; +precise_t ps_rendercalltime = 0; +precise_t ps_uitime = 0; +precise_t ps_swaptime = 0; -int ps_bsptime = 0; +precise_t ps_bsptime = 0; -int ps_sw_spritecliptime = 0; -int ps_sw_portaltime = 0; -int ps_sw_planetime = 0; -int ps_sw_maskedtime = 0; +precise_t ps_sw_spritecliptime = 0; +precise_t ps_sw_portaltime = 0; +precise_t ps_sw_planetime = 0; +precise_t ps_sw_maskedtime = 0; int ps_numbspcalls = 0; int ps_numsprites = 0; @@ -1498,9 +1498,9 @@ void R_RenderPlayerView(player_t *player) ProfZeroTimer(); #endif ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0; - ps_bsptime = I_GetTimeMicros(); + ps_bsptime = I_GetPreciseTime(); R_RenderBSPNode((INT32)numnodes - 1); - ps_bsptime = I_GetTimeMicros() - ps_bsptime; + ps_bsptime = I_GetPreciseTime() - ps_bsptime; ps_numsprites = visspritecount; #ifdef TIMING RDMSR(0x10, &mycount); @@ -1511,9 +1511,9 @@ void R_RenderPlayerView(player_t *player) //profile stuff --------------------------------------------------------- Mask_Post(&masks[nummasks - 1]); - ps_sw_spritecliptime = I_GetTimeMicros(); + ps_sw_spritecliptime = I_GetPreciseTime(); 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. @@ -1521,7 +1521,7 @@ void R_RenderPlayerView(player_t *player) Portal_AddSkyboxPortals(); // Portal rendering. Hijacks the BSP traversal. - ps_sw_portaltime = I_GetTimeMicros(); + ps_sw_portaltime = I_GetPreciseTime(); if (portal_base) { portal_t *portal; @@ -1561,17 +1561,17 @@ void R_RenderPlayerView(player_t *player) 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(); - ps_sw_planetime = I_GetTimeMicros() - ps_sw_planetime; + ps_sw_planetime = I_GetPreciseTime() - ps_sw_planetime; // draw mid texture and sprite // And now 3D floors/sides! - ps_sw_maskedtime = I_GetTimeMicros(); + ps_sw_maskedtime = I_GetPreciseTime(); R_DrawMasked(masks, nummasks); - ps_sw_maskedtime = I_GetTimeMicros() - ps_sw_maskedtime; + ps_sw_maskedtime = I_GetPreciseTime() - ps_sw_maskedtime; free(masks); } diff --git a/src/r_main.h b/src/r_main.h index f1cc9621f..2ac6abf5a 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -78,17 +78,17 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe // Render stats -extern int ps_prevframetime;// time when previous frame was rendered -extern int ps_rendercalltime; -extern int ps_uitime; -extern int ps_swaptime; +extern precise_t ps_prevframetime;// time when previous frame was rendered +extern precise_t ps_rendercalltime; +extern precise_t ps_uitime; +extern precise_t ps_swaptime; -extern int ps_bsptime; +extern precise_t ps_bsptime; -extern int ps_sw_spritecliptime; -extern int ps_sw_portaltime; -extern int ps_sw_planetime; -extern int ps_sw_maskedtime; +extern precise_t ps_sw_spritecliptime; +extern precise_t ps_sw_portaltime; +extern precise_t ps_sw_planetime; +extern precise_t ps_sw_maskedtime; extern int ps_numbspcalls; extern int ps_numsprites; diff --git a/src/r_picformats.c b/src/r_picformats.c index 02f1de4ab..f87362c76 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -544,21 +544,22 @@ void *Picture_GetPatchPixel( UINT16 *s16 = NULL; UINT32 *s32 = NULL; softwarepatch_t *doompatch = (softwarepatch_t *)patch; + boolean isdoompatch = Picture_IsDoomPatchFormat(informat); INT16 width; if (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) { INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x; 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 - if (Picture_IsDoomPatchFormat(informat)) + // Column offsets are pointers, so no casting is required. + if (isdoompatch) column = (column_t *)((UINT8 *)doompatch + colofs); else column = (column_t *)((UINT8 *)patch->columns + colofs); diff --git a/src/r_plane.c b/src/r_plane.c index c54b32382..45d635213 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -607,6 +607,7 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) void R_DrawPlanes(void) { visplane_t *pl; + angle_t va = viewangle; INT32 i; R_UpdatePlaneRipple(); @@ -621,6 +622,8 @@ void R_DrawPlanes(void) R_DrawSinglePlane(pl); } } + + viewangle = va; } // R_DrawSkyPlane @@ -705,9 +708,9 @@ void R_CalculateSlopeVectors(pslope_t *slope, fixed_t planeviewx, fixed_t planev n.z = -xscale * cos(ang); 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; - 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; if (ds_powersoftwo) @@ -788,7 +791,6 @@ void R_DrawSinglePlane(visplane_t *pl) ffloor_t *rover; int type; int spanfunctype = BASEDRAWFUNC; - angle_t viewang = viewangle; if (!(pl->minx <= pl->maxx)) return; @@ -1153,8 +1155,6 @@ using the palette colors. } } #endif - - viewangle = viewang; } void R_PlaneBounds(visplane_t *plane) diff --git a/src/r_segs.c b/src/r_segs.c index 1ed1f0285..c79071e9b 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -540,7 +540,7 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor) // Polyobjects have no ffloors, and they're handled in the conditional above. if (pfloor->ffloor != NULL) - return (pfloor->ffloor->flags & FF_TRANSLUCENT); + return (pfloor->ffloor->flags & (FF_TRANSLUCENT|FF_FOG)); 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 // "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; 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 // "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; ceilingclip[rw_x] = ffbottom; diff --git a/src/r_skins.c b/src/r_skins.c index 25904e95e..6f150f234 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -511,6 +511,10 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) GETFLAG(MULTIABILITY) GETFLAG(NONIGHTSROTATION) GETFLAG(NONIGHTSSUPER) + GETFLAG(NOSUPERSPRITES) + GETFLAG(NOSUPERJUMPBOOST) + GETFLAG(CANBUSTWALLS) + GETFLAG(NOSHIELDABILITY) #undef GETFLAG else // let's check if it's a sound, otherwise error out diff --git a/src/r_textures.c b/src/r_textures.c index 9de9649e2..a006d739f 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -604,7 +604,7 @@ void *R_GetLevelFlat(levelflat_t *levelflat) levelflat->height = ds_flatheight = SHORT(patch->height); 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); Z_Free(converted); } diff --git a/src/s_sound.c b/src/s_sound.c index 36bd454c1..392a5b453 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2143,7 +2143,7 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst) static lumpnum_t S_GetMusicLumpNum(const char *mname) { boolean midipref = cv_musicpref.value; - + if (S_PrefAvailable(midipref, mname)) return W_GetNumForName(va(midipref ? "d_%s":"o_%s", 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); 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))) { CONS_Debug(DBG_DETAILED, "Now playing song %s\n", newmusic); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 10c0747bf..d2c819c37 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -54,12 +54,6 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include #endif -#if defined (_WIN32) -DWORD TimeFunction(int requested_frequency); -#else -int TimeFunction(int requested_frequency); -#endif - #include #ifdef _WIN32 #include @@ -2044,112 +2038,36 @@ ticcmd_t *I_BaseTiccmd2(void) 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 // returns time in 1/TICRATE second tics // -// millisecond precision only -int TimeFunction(int requested_frequency) -{ - static Uint64 basetime = 0; - Uint64 ticks = SDL_GetTicks(); +static Uint64 timer_frequency; - if (!basetime) - basetime = ticks; - - ticks -= basetime; - - ticks = (ticks*requested_frequency); - - ticks = (ticks/1000); - - return ticks; -} -#endif +static double tic_frequency; +static Uint64 tic_epoch; 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) { -#ifdef _WIN32 - // for win2k time bug - if (M_CheckParm("-gettickcount")) - { - 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 + timer_frequency = SDL_GetPerformanceFrequency(); + tic_epoch = SDL_GetPerformanceCounter(); + + tic_frequency = timer_frequency / (double)NEWTICRATE; } - - void I_Sleep(void) { if (cv_sleep.value != -1) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index b8b3b9d34..5ebff8700 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1057,8 +1057,7 @@ void I_GetEvent(void) M_SetupJoystickMenu(0); break; case SDL_QUIT: - if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(true); I_Quit(); break; } diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index c64164caa..5cae48077 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -1298,6 +1298,10 @@ boolean I_PlaySong(boolean looping) if (gme) { 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_start_track(gme, 0); current_track = 0; diff --git a/src/st_stuff.c b/src/st_stuff.c index b25538d88..649644620 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2751,7 +2751,6 @@ static void ST_overlayDrawer(void) void ST_Drawer(void) { -#ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) { 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]); } -#endif // Doom's status bar only updated if necessary. // However, ours updates every frame regardless, so the "refresh" param was removed diff --git a/src/w_wad.c b/src/w_wad.c index aca530fa5..6566800c0 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -66,6 +66,7 @@ #include "p_setup.h" // P_ScanThings #endif #include "m_misc.h" // M_MapNumber +#include "g_game.h" // G_SetGameModified #ifdef HWRENDER #include "hardware/hw_main.h" @@ -683,9 +684,9 @@ static UINT16 W_InitFileError (const char *filename, boolean exitworthy) if (exitworthy) { #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 - 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 } else @@ -716,7 +717,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) #endif size_t packetsize; UINT8 md5sum[16]; - boolean important; + int important; if (!(refreshdirmenu & REFRESHDIR_ADDFILE)) 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) 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 // is send in the packet; cf. // see PutFileNeeded in d_netfil.c - if ((important = !W_VerifyNMUSlumps(filename))) + if ((important = !important)) { packetsize = packetsizetally + nameonlylength(filename) + 22; @@ -811,6 +820,9 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) return W_InitFileError(filename, startup); } + if (important && !mainfile) + G_SetGameModified(true); + // // link wad file to search files // @@ -1735,6 +1747,9 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag) void W_UnlockCachedPatch(void *patch) { + if (!patch) + return; + // The hardware code does its own memory management, as its patches // have different lifetimes from software's. #ifdef HWRENDER @@ -1919,8 +1934,16 @@ static lumpchecklist_t folderblacklist[] = static int W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) { + int verified = true; + zend_t zend; 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; size_t i; @@ -1936,6 +1959,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) // Central directory bullshit fseek(fp, 0, SEEK_END); + file_size = ftell(fp); + if (!ResFindSignature(fp, pat_end, max(0, ftell(fp) - (22 + 65536)))) return true; @@ -1943,6 +1968,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) if (fread(&zend, 1, sizeof zend, fp) < sizeof zend) return true; + data_size = sizeof zend; + numlumps = zend.entries; 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)) return true; - fullname = malloc(zentry.namelen + 1); - 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 (verified == true) { - if ((dotpos = strrchr(trimname, '.')) == 0) - dotpos = fullname + strlen(fullname); // Watch for files without extension. + fullname = malloc(zentry.namelen + 1); + if (fgets(fullname, zentry.namelen + 1, fp) != fullname) + return true; - memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary? - strncpy(lumpname, trimname, min(8, dotpos - trimname)); + // 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 (! W_VerifyName(lumpname, checklist, status)) - return false; + if (*trimname) // Ignore directories, well kinda + { + 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 - if (W_VerifyName(fullname, folderblacklist, status)) - return false; + memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary? + strncpy(lumpname, trimname, min(8, dotpos - trimname)); + + 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 - if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0) + old_position = ftell(fp); + + if (fseek(fp, zentry.offset, SEEK_SET) != 0) 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 @@ -2029,12 +2095,13 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist, * be sent. * * \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 * stuff (maps, sprites, dehacked lumps, and so on). -1 if there no * file exists with that filename * \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 // ENDOOM text and palette lumps @@ -2080,7 +2147,7 @@ int W_VerifyNMUSlumps(const char *filename) {"LT", 2}, // Titlecard changes {"SLID", 4}, // Continue - {"CONT", 4}, + {"CONT", 4}, {"MINICAPS", 8}, // NiGHTS graphics here and below {"BLUESTAT", 8}, // Sphere status @@ -2108,7 +2175,13 @@ int W_VerifyNMUSlumps(const char *filename) {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. diff --git a/src/w_wad.h b/src/w_wad.h index 1e86eea5a..d0a86bcb4 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -206,6 +206,6 @@ void W_UnlockCachedPatch(void *patch); 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__ diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index 486616f2d..702ae3765 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -56,14 +56,6 @@ ifndef GCC44 #OPTS+=-mms-bitfields endif -ifndef SDL - OPTS+=-D_WINDOWS -endif - -ifndef SDL - LIBS+=-lmingw32 -mwindows -ldinput -ldxguid -lgdi32 -lwinmm -endif - LIBS+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 ifdef MINGW64 LIBS+=-lws2_32 @@ -76,11 +68,7 @@ endif endif # name of the exefile -ifdef SDL EXENAME?=srb2win.exe -else - EXENAME?=srb2dd.exe -endif ifdef SDL i_system_o+=$(OBJDIR)/SRB2.res @@ -88,22 +76,6 @@ ifdef SDL ifndef NOHW OPTS+=-DUSE_WGL_SWAP 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 @@ -161,4 +133,4 @@ ifdef MINGW64 else CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl endif #MINGW64 -endif \ No newline at end of file +endif diff --git a/src/y_inter.c b/src/y_inter.c index 061cbb5e1..bd3b557d7 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1229,7 +1229,10 @@ void Y_StartIntermission(void) data.coop.tics = players[consoleplayer].realtime; 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); // get act number @@ -1733,7 +1736,6 @@ static void Y_SetNullBonus(player_t *player, y_bonus_t *bstruct) { (void)player; memset(bstruct, 0, sizeof(y_bonus_t)); - strncpy(bstruct->patch, "MISSING", sizeof(bstruct->patch)); } // diff --git a/src/z_zone.c b/src/z_zone.c index ad64a3a07..d7da17e51 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -813,12 +813,12 @@ static void Command_Memfree_f(void) #ifdef HWRENDER if (rendermode == render_opengl) { - 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("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); - CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); - CONS_Printf(M_GetText("HW model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10)); - CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10); + CONS_Printf(M_GetText("Patch info headers : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10)); + CONS_Printf(M_GetText("Cached textures : %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("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("All GPU textures : %7d KB\n"), HWR_GetTextureUsed()>>10); } #endif