From 7851bef929947017ab6ef0c18db80f88b0733516 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 25 Dec 2019 14:22:01 -0500 Subject: [PATCH 001/168] Port of Jimita's shader stuff + my lighting shader Co-Authored-By: Jaime Passos --- src/command.c | 8 +- src/dehacked.c | 8 +- src/doomdata.h | 2 +- src/doomdef.h | 13 +- src/f_finale.c | 12 +- src/f_finale.h | 4 +- src/f_wipe.c | 4 +- src/hardware/hw_clip.c | 14 +- src/hardware/hw_clip.h | 2 +- src/hardware/hw_defs.h | 68 +- src/hardware/hw_dll.h | 5 +- src/hardware/hw_draw.c | 184 ++-- src/hardware/hw_drv.h | 32 +- src/hardware/hw_glob.h | 6 +- src/hardware/hw_light.c | 50 +- src/hardware/hw_main.c | 1601 +++++++++++------------------- src/hardware/hw_main.h | 8 +- src/hardware/hw_md2.c | 24 +- src/hardware/r_opengl/ogl_win.c | 42 +- src/hardware/r_opengl/r_opengl.c | 870 +++++++++++++--- src/hardware/r_opengl/r_opengl.h | 36 +- src/m_fixed.c | 2 +- src/m_fixed.h | 2 +- src/p_enemy.c | 58 +- src/p_floor.c | 4 +- src/p_inter.c | 2 +- src/p_local.h | 2 +- src/p_mobj.c | 10 +- src/p_setup.c | 10 +- src/p_spec.c | 2 +- src/p_user.c | 6 +- src/r_main.c | 28 +- src/s_sound.c | 8 +- src/sdl/hwsym_sdl.c | 13 +- src/sdl/i_video.c | 31 +- src/sdl/ogl_sdl.c | 45 +- src/sounds.c | 8 +- src/sounds.h | 8 +- src/v_video.c | 25 +- src/w_wad.c | 12 +- src/z_zone.c | 2 +- 41 files changed, 1711 insertions(+), 1560 deletions(-) diff --git a/src/command.c b/src/command.c index 33d8ead96..cf0fa5e7d 100644 --- a/src/command.c +++ b/src/command.c @@ -2056,15 +2056,15 @@ void CV_SaveVariables(FILE *f) for (cvar = consvar_vars; cvar; cvar = cvar->next) if (cvar->flags & CV_SAVE) { - char stringtowrite[MAXTEXTCMD+1]; + char stringtrite[MAXTEXTCMD+1]; // Silly hack for Min/Max vars if (!strcmp(cvar->string, "MAX") || !strcmp(cvar->string, "MIN")) - sprintf(stringtowrite, "%d", cvar->value); + sprintf(stringtrite, "%d", cvar->value); else - strcpy(stringtowrite, cvar->string); + strcpy(stringtrite, cvar->string); - fprintf(f, "%s \"%s\"\n", cvar->name, stringtowrite); + fprintf(f, "%s \"%s\"\n", cvar->name, stringtrite); } } diff --git a/src/dehacked.c b/src/dehacked.c index 938699516..b782a5a6c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4110,8 +4110,8 @@ static void readwipes(MYFILE *f) else if (fastncmp(word, "SPECLEVEL_", 10)) { pword = word + 10; - if (fastcmp(pword, "TOWHITE")) - wipeoffset = wipe_speclevel_towhite; + if (fastcmp(pword, "tHITE")) + wipeoffset = wipe_speclevel_thite; } if (wipeoffset < 0) @@ -4121,10 +4121,10 @@ static void readwipes(MYFILE *f) } if (value == UINT8_MAX - && (wipeoffset <= wipe_level_toblack || wipeoffset >= wipe_speclevel_towhite)) + && (wipeoffset <= wipe_level_toblack || wipeoffset >= wipe_speclevel_thite)) { // Cannot disable non-toblack wipes - // (or the level toblack wipe, or the special towhite wipe) + // (or the level toblack wipe, or the special thite wipe) deh_warning("Wipes: can't disable wipe of type '%s'", word); continue; } diff --git a/src/doomdata.h b/src/doomdata.h index f6e7cb584..fdd7c291a 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -76,7 +76,7 @@ typedef struct { INT16 textureoffset, rowoffset; char toptexture[8], bottomtexture[8], midtexture[8]; - // Front sector, towards viewer. + // Front sector, tards viewer. INT16 sector; } ATTRPACK mapsidedef_t; diff --git a/src/doomdef.h b/src/doomdef.h index 6c4f1fef3..815716433 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -495,6 +495,9 @@ extern INT32 cv_debug; extern UINT8 shiftdown, ctrldown, altdown; extern boolean capslock; +// WARNING: a should be unsigned but to add with 2048, it isn't! +#define AIMINGTODY(a) (FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160) + // if we ever make our alloc stuff... #define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL) #define ZZ_Calloc(x) Z_Calloc(x, PU_STATIC, NULL) @@ -612,17 +615,13 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP +/// Hardware renderer: OpenGL +#define GL_SHADERS + /// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink. /// \note Required for proper collision with moving sloped surfaces that have sector specials on them. #define SECTORSPECIALSAFTERTHINK -/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up -/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down) -/// on the bright side it fixes some weird issues with translucent walls -/// \note SRB2CB port. -/// SRB2CB itself ported this from PrBoom+ -#define NEWCLIP - /// Sprite rotation #define ROTSPRITE #define ROTANGLES 24 // Needs to be a divisor of 360 (45, 60, 90, 120...) diff --git a/src/f_finale.c b/src/f_finale.c index 424fc7f39..c7e2e4d5f 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -233,7 +233,7 @@ static tic_t cutscene_lasttextwrite = 0; // static UINT8 F_WriteText(void) { - INT32 numtowrite = 1; + INT32 numtrite = 1; const char *c; tic_t ltw = I_GetTime(); @@ -244,7 +244,7 @@ static UINT8 F_WriteText(void) if (cutscene_boostspeed) { // for custom cutscene speedup mode - numtowrite = 8; + numtrite = 8; } else { @@ -253,10 +253,10 @@ static UINT8 F_WriteText(void) return 1; if (cutscene_textspeed < 7) - numtowrite = 8 - cutscene_textspeed; + numtrite = 8 - cutscene_textspeed; } - for (;numtowrite > 0;++cutscene_baseptr) + for (;numtrite > 0;++cutscene_baseptr) { c = &cutscene_basetext[cutscene_baseptr]; if (!c || !*c || *c=='#') @@ -272,7 +272,7 @@ static UINT8 F_WriteText(void) else if ((UINT8)*c >= 0xB0 && (UINT8)*c <= (0xB0+TICRATE-1)) { cutscene_textcount = (INT32)((UINT8)*c - 0xAF); - numtowrite = 0; + numtrite = 0; continue; } @@ -280,7 +280,7 @@ static UINT8 F_WriteText(void) // Ignore other control codes (color) if ((UINT8)*c < 0x80) - --numtowrite; + --numtrite; } // Reset textcount for next tic based on speed // if it wasn't already set by a delay. diff --git a/src/f_finale.h b/src/f_finale.h index 1636f1967..74532ebf0 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -154,7 +154,7 @@ typedef enum { WSF_FADEOUT = 1, WSF_FADEIN = 1<<1, - WSF_TOWHITE = 1<<2, + WSF_tHITE = 1<<2, WSF_CROSSFADE = 1<<3, } wipestyleflags_t; extern wipestyleflags_t wipestyleflags; @@ -199,7 +199,7 @@ enum // custom intermissions wipe_specinter_toblack, wipe_multinter_toblack, - wipe_speclevel_towhite, + wipe_speclevel_thite, wipe_level_final, wipe_intermission_final, diff --git a/src/f_wipe.c b/src/f_wipe.c index b0982a957..6e8ba31a9 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -68,7 +68,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = { 0, // wipe_specinter_toblack 0, // wipe_multinter_toblack - 0, // wipe_speclevel_towhite + 0, // wipe_speclevel_thite 0, // wipe_level_final 0, // wipe_intermission_final @@ -298,7 +298,7 @@ static void F_DoWipe(fademask_t *fademask) int nmask; UINT8 *fade = fadecolormap; - if (wipestyleflags & WSF_TOWHITE) + if (wipestyleflags & WSF_tHITE) fade = fadecolormap + (FADECOLORMAPROWS * 256); nmask = *mask; diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c index 4bdc753ec..95426f8d4 100644 --- a/src/hardware/hw_clip.c +++ b/src/hardware/hw_clip.c @@ -77,8 +77,8 @@ #include "r_opengl/r_opengl.h" #ifdef HAVE_SPHEREFRUSTRUM -static GLfloat viewMatrix[16]; -static GLfloat projMatrix[16]; +static GLdouble viewMatrix[16]; +static GLdouble projMatrix[16]; float frustum[6][4]; #endif @@ -319,12 +319,12 @@ void gld_clipper_Clear(void) #define RMUL (1.6f/1.333333f) -angle_t gld_FrustumAngle(void) +angle_t gld_FrustumAngle(angle_t tiltangle) { double floatangle; angle_t a1; - float tilt = (float)fabs(((double)(int)aimingangle) / ANG1); + float tilt = (float)fabs(((double)(int)tiltangle) / ANG1); // NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function @@ -338,7 +338,7 @@ angle_t gld_FrustumAngle(void) } // If the pitch is larger than this you can look all around at a FOV of 90 - if (abs((signed)aimingangle) > 46 * ANG1) + if (abs((signed)tiltangle) > 46 * ANG1) return 0xffffffff; // ok, this is a gross hack that barely works... @@ -351,7 +351,7 @@ angle_t gld_FrustumAngle(void) } // SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either -// compiler complains about (p)glGetDoublev anyway, in case anyone wants this +// compiler complains about (p)glGetFloatv anyway, in case anyone wants this // only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks // btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h #ifdef HAVE_SPHEREFRUSTRUM @@ -380,7 +380,7 @@ void gld_FrustrumSetup(void) float t; float clip[16]; - pglGeFloatv(GL_PROJECTION_MATRIX, projMatrix); + pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); pglGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix); clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12); diff --git a/src/hardware/hw_clip.h b/src/hardware/hw_clip.h index 3ba26e5e5..27a2ed1ef 100644 --- a/src/hardware/hw_clip.h +++ b/src/hardware/hw_clip.h @@ -17,7 +17,7 @@ boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); void gld_clipper_Clear(void); -angle_t gld_FrustumAngle(void); +angle_t gld_FrustumAngle(angle_t tiltangle); #ifdef HAVE_SPHEREFRUSTRUM void gld_FrustrumSetup(void); boolean gld_SphereInFrustum(float x, float y, float z, float radius); diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 5f2d907bd..313c62eec 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -19,6 +19,7 @@ #ifndef _HWR_DEFS_ #define _HWR_DEFS_ #include "../doomtype.h" +#include "../r_defs.h" #define ZCLIP_PLANE 4.0f // Used for the actual game drawing #define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures @@ -79,19 +80,15 @@ typedef struct FLOAT x,y; } F2DCoord, v2d_t; -// Simple 3D vector -typedef struct FVector -{ - FLOAT x,y,z; -} FVector; +// ====================== +// wallVert3D +// ---------------------- +// :crab: IS GONE! :crab: +// ====================== -// 3D model vector (coords + texture coords) -typedef struct -{ - //FVector Point; - FLOAT x,y,z; - FLOAT s,t,w; // texture coordinates -} v3d_t, wallVert3D; +// ----------- +// structures +// ----------- //Hurdler: Transform (coords + angles) //BP: transform order : scale(rotation_x(rotation_y(translation(v)))) @@ -125,15 +122,16 @@ typedef struct #ifdef USE_FTRANSFORM_MIRROR boolean mirror; // SRB2Kart: Encore Mode #endif + boolean shearing; // 14042019 + angle_t viewaiming; // 17052019 } FTransform; // Transformed vector, as passed to HWR API typedef struct { FLOAT x,y,z; - FUINT argb; // flat-shaded color - FLOAT sow; // s texture ordinate (s over w) - FLOAT tow; // t texture ordinate (t over w) + FLOAT s; // s texture ordinate (s over w) + FLOAT t; // t texture ordinate (t over w) } FOutVector; @@ -164,10 +162,10 @@ enum EPolyFlags PF_Invisible = 0x00000400, // Disable write to color buffer PF_Decal = 0x00000800, // Enable polygon offset PF_Modulated = 0x00001000, // Modulation (multiply output with constant ARGB) - // When set, pass the color constant into the FSurfaceInfo -> FlatColor + // When set, pass the color constant into the FSurfaceInfo -> PolyColor PF_NoTexture = 0x00002000, // Use the small white texture PF_Corona = 0x00004000, // Tell the rendrer we are drawing a corona - PF_Unused = 0x00008000, // Unused + PF_Ripple = 0x00008000, // Water shader effect PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y PF_ForceWrapX = 0x00020000, // Force repeat texture on X PF_ForceWrapY = 0x00040000, // Force repeat texture on Y @@ -180,7 +178,6 @@ enum EPolyFlags enum ESurfFlags { SF_DYNLIGHT = 0x00000001, - }; enum ETextureFlags @@ -192,31 +189,31 @@ enum ETextureFlags TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0 }; -#ifdef TODO -struct FTextureInfo -{ - FUINT Width; // Pixels - FUINT Height; // Pixels - FUBYTE *TextureData; // Image data - FUINT Format; // FORMAT_RGB, ALPHA ... - FBITFIELD Flags; // Flags to tell driver about texture (see ETextureFlags) - void DriverExtra; // (OpenGL texture object nr, ...) - // chromakey enabled,... - - struct FTextureInfo *Next; // Manage list of downloaded textures. -}; -#else typedef struct GLMipmap_s FTextureInfo; -#endif + +// jimita 14032019 +struct FLightInfo +{ + FUINT light_level; + FUINT fade_start; + FUINT fade_end; +}; +typedef struct FLightInfo FLightInfo; // Description of a renderable surface struct FSurfaceInfo { - FUINT PolyFlags; // Surface flags -- UNUSED YET -- - RGBA_t FlatColor; // Flat-shaded color used with PF_Modulated mode + FUINT PolyFlags; + RGBA_t PolyColor; + RGBA_t TintColor; + RGBA_t FadeColor; + FLightInfo LightInfo; // jimita 14032019 }; typedef struct FSurfaceInfo FSurfaceInfo; +#define GL_DEFAULTMIX 0x00000000 +#define GL_DEFAULTFOG 0xFF000000 + //Hurdler: added for backward compatibility enum hwdsetspecialstate { @@ -224,6 +221,7 @@ enum hwdsetspecialstate HWD_SET_FOG_MODE, HWD_SET_FOG_COLOR, HWD_SET_FOG_DENSITY, + HWD_SET_SHADERS, HWD_SET_TEXTUREFILTERMODE, HWD_SET_TEXTUREANISOTROPICMODE, HWD_NUMSTATE diff --git a/src/hardware/hw_dll.h b/src/hardware/hw_dll.h index 3fa5852d8..43dfbcf0b 100644 --- a/src/hardware/hw_dll.h +++ b/src/hardware/hw_dll.h @@ -54,8 +54,6 @@ #endif #endif -typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR; - // ========================================================================== // MATHS // ========================================================================== @@ -63,7 +61,8 @@ typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR; // Constants #define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360 -void DBG_Printf(const char *lpFmt, ...) /*FUNCPRINTF*/; +void GL_DBG_Printf(const char *format, ...) /*FUNCPRINTF*/; +#define GL_DBG_Printf GL_DBG_Printf #ifdef _WINDOWS BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 4519e1280..f93b52590 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1,17 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- /// \file /// \brief miscellaneous drawing (mainly 2d) @@ -23,6 +18,7 @@ #include "../doomdef.h" #ifdef HWRENDER +#include "hw_main.h" #include "hw_glob.h" #include "hw_drv.h" @@ -43,9 +39,6 @@ #define O_BINARY 0 #endif -float gr_patch_scalex; -float gr_patch_scaley; - #if defined(_MSC_VER) #pragma pack(1) #endif @@ -65,9 +58,6 @@ typedef struct #if defined(_MSC_VER) #pragma pack() #endif -typedef UINT8 GLRGB[3]; - -#define BLENDMODE PF_Translucent static UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229,255}; static UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255}; @@ -121,12 +111,12 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = gpatch->max_s; - v[0].tow = v[1].tow = 0.0f; - v[2].tow = v[3].tow = gpatch->max_t; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = gpatch->max_s; + v[0].t = v[1].t = 0.0f; + v[2].t = v[3].t = gpatch->max_t; - flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; + flags = PF_Translucent|PF_NoDepthTest; if (option & V_WRAPX) flags |= PF_ForceWrapX; @@ -356,19 +346,19 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t if (option & V_FLIP) { - v[0].sow = v[3].sow = gpatch->max_s; - v[2].sow = v[1].sow = 0.0f; + v[0].s = v[3].s = gpatch->max_s; + v[2].s = v[1].s = 0.0f; } else { - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = gpatch->max_s; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = gpatch->max_s; } - v[0].tow = v[1].tow = 0.0f; - v[2].tow = v[3].tow = gpatch->max_t; + v[0].t = v[1].t = 0.0f; + v[2].t = v[3].t = gpatch->max_t; - flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; + flags = PF_Translucent|PF_NoDepthTest; if (option & V_WRAPX) flags |= PF_ForceWrapX; @@ -379,11 +369,11 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t if (alphalevel) { FSurfaceInfo Surf; - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; - if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[st_translucency]; - else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[st_translucency]; - else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[st_translucency]; - else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel]; + Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff; + if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value]; + else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[cv_translucenthud.value]; + else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value]; + else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; HWD.pfnDrawPolygon(&Surf, v, 4, flags); } @@ -514,19 +504,19 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = ((sx )/(float)SHORT(gpatch->width) )*gpatch->max_s; + v[0].s = v[3].s = ((sx )/(float)SHORT(gpatch->width) )*gpatch->max_s; if (sx + w > SHORT(gpatch->width)) - v[2].sow = v[1].sow = gpatch->max_s; + v[2].s = v[1].s = gpatch->max_s; else - v[2].sow = v[1].sow = ((sx+w)/(float)SHORT(gpatch->width) )*gpatch->max_s; + v[2].s = v[1].s = ((sx+w)/(float)SHORT(gpatch->width) )*gpatch->max_s; - v[0].tow = v[1].tow = ((sy )/(float)SHORT(gpatch->height))*gpatch->max_t; + v[0].t = v[1].t = ((sy )/(float)SHORT(gpatch->height))*gpatch->max_t; if (sy + h > SHORT(gpatch->height)) - v[2].tow = v[3].tow = gpatch->max_t; + v[2].t = v[3].t = gpatch->max_t; else - v[2].tow = v[3].tow = ((sy+h)/(float)SHORT(gpatch->height))*gpatch->max_t; + v[2].t = v[3].t = ((sy+h)/(float)SHORT(gpatch->height))*gpatch->max_t; - flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; + flags = PF_Translucent|PF_NoDepthTest; if (option & V_WRAPX) flags |= PF_ForceWrapX; @@ -537,11 +527,11 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal if (alphalevel) { FSurfaceInfo Surf; - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; - if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[st_translucency]; - else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[st_translucency]; - else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[st_translucency]; - else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel]; + Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff; + if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value]; + else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[cv_translucenthud.value]; + else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value]; + else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; HWD.pfnDrawPolygon(&Surf, v, 4, flags); } @@ -569,10 +559,10 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum) v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0; - v[2].sow = v[1].sow = patch->max_s; - v[0].tow = v[1].tow = 0; - v[2].tow = v[3].tow = patch->max_t; + v[0].s = v[3].s = 0; + v[2].s = v[1].s = patch->max_s; + v[0].t = v[1].t = 0; + v[2].t = v[3].t = patch->max_t; //Hurdler: Boris, the same comment as above... but maybe for pics @@ -581,7 +571,7 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum) // But then, the question is: why not 0 instead of PF_Masked ? // or maybe PF_Environment ??? (like what I said above) // BP: PF_Environment don't change anything ! and 0 is undifined - HWD.pfnDrawPolygon(NULL, v, 4, BLENDMODE | PF_NoDepthTest | PF_Clip | PF_NoZClip); + HWD.pfnDrawPolygon(NULL, v, 4, PF_Translucent | PF_NoDepthTest | PF_Clip | PF_NoZClip); } // ========================================================================== @@ -644,10 +634,10 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; // flat is 64x64 lod and texture offsets are [0.0, 1.0] - v[0].sow = v[3].sow = (float)((x & flatflag)/dflatsize); - v[2].sow = v[1].sow = (float)(v[0].sow + w/dflatsize); - v[0].tow = v[1].tow = (float)((y & flatflag)/dflatsize); - v[2].tow = v[3].tow = (float)(v[0].tow + h/dflatsize); + v[0].s = v[3].s = (float)((x & flatflag)/dflatsize); + v[2].s = v[1].s = (float)(v[0].s + w/dflatsize); + v[0].t = v[1].t = (float)((y & flatflag)/dflatsize); + v[2].t = v[3].t = (float)(v[0].t + h/dflatsize); HWR_LiterallyGetFlat(flatlumpnum); @@ -679,20 +669,20 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) v[2].y = v[3].y = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 1.0f; - v[2].tow = v[3].tow = 0.0f; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 1.0f; + v[2].t = v[3].t = 0.0f; if (color & 0xFF00) // Do COLORMAP fade. { - Surf.FlatColor.rgba = UINT2RGBA(0x01010160); - Surf.FlatColor.s.alpha = (strength*8); + Surf.PolyColor.rgba = UINT2RGBA(0x01010160); + Surf.PolyColor.s.alpha = (strength*8); } else // Do TRANSMAP** fade. { - Surf.FlatColor.rgba = V_GetColor(color).rgba; - Surf.FlatColor.s.alpha = softwaretranstogl[strength]; + Surf.PolyColor.rgba = V_GetColor(color).rgba; + Surf.PolyColor.s.alpha = softwaretranstogl[strength]; } HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } @@ -850,24 +840,22 @@ void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 ac v[0].y = v[1].y = fy; v[2].y = v[3].y = fy - fh; - //Hurdler: do we still use this argb color? if not, we should remove it - v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 0.0f; - v[2].tow = v[3].tow = 1.0f; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 0.0f; + v[2].t = v[3].t = 1.0f; if (actualcolor & 0xFF00) // Do COLORMAP fade. { - Surf.FlatColor.rgba = UINT2RGBA(0x01010160); - Surf.FlatColor.s.alpha = (strength*8); + Surf.PolyColor.rgba = UINT2RGBA(0x01010160); + Surf.PolyColor.s.alpha = (strength*8); } else // Do TRANSMAP** fade. { - Surf.FlatColor.rgba = V_GetColor(actualcolor).rgba; - Surf.FlatColor.s.alpha = softwaretranstogl[strength]; + Surf.PolyColor.rgba = V_GetColor(actualcolor).rgba; + Surf.PolyColor.s.alpha = softwaretranstogl[strength]; } HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } @@ -888,13 +876,13 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height) v[2].y = v[3].y = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 1.0f; - v[2].tow = v[3].tow = 0.0f; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 1.0f; + v[2].t = v[3].t = 0.0f; - Surf.FlatColor.rgba = UINT2RGBA(color); - Surf.FlatColor.s.alpha = 0x80; + Surf.PolyColor.rgba = UINT2RGBA(color); + Surf.PolyColor.s.alpha = 0x80; HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } @@ -914,13 +902,13 @@ void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight) v[2].y = v[3].y = -1.0f+((height<<1)/(float)vid.height); v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 1.0f; - v[2].tow = v[3].tow = 0.0f; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 1.0f; + v[2].t = v[3].t = 0.0f; - Surf.FlatColor.rgba = UINT2RGBA(color); - Surf.FlatColor.s.alpha = (color == 0 ? 0xC0 : 0x80); // make black darker, like software + Surf.PolyColor.rgba = UINT2RGBA(color); + Surf.PolyColor.s.alpha = (color == 0 ? 0xC0 : 0x80); // make black darker, like software HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } @@ -1232,17 +1220,15 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32 v[0].y = v[1].y = fy; v[2].y = v[3].y = fy - fh; - //Hurdler: do we still use this argb color? if not, we should remove it - v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 0.0f; - v[2].tow = v[3].tow = 1.0f; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 0.0f; + v[2].t = v[3].t = 1.0f; - Surf.FlatColor.rgba = UINT2RGBA(actualcolor); - Surf.FlatColor.s.alpha = 0x80; + Surf.PolyColor.rgba = UINT2RGBA(actualcolor); + Surf.PolyColor.s.alpha = 0x80; HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } @@ -1412,16 +1398,14 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) v[0].y = v[1].y = fy; v[2].y = v[3].y = fy - fh; - //Hurdler: do we still use this argb color? if not, we should remove it - v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 0.0f; - v[2].tow = v[3].tow = 1.0f; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 0.0f; + v[2].t = v[3].t = 1.0f; - Surf.FlatColor = V_GetColor(color); + Surf.PolyColor = V_GetColor(color); HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_NoTexture|PF_NoDepthTest); diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 3314fb015..400034bb2 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -32,7 +32,7 @@ // STANDARD DLL EXPORTS // ========================================================================== -EXPORT boolean HWRAPI(Init) (I_Error_t ErrorFunction); +EXPORT boolean HWRAPI(Init) (void); #ifndef HAVE_SDL EXPORT void HWRAPI(Shutdown) (void); #endif @@ -55,14 +55,11 @@ EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); //Hurdler: added for new development -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color); +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface); EXPORT void HWRAPI(CreateModelVBOs) (model_t *model); EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); -EXPORT INT32 HWRAPI(GetRenderVersion) (void); -#define SCREENVERTS 10 -EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); EXPORT void HWRAPI(FlushScreenTextures) (void); EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(EndScreenWipe) (void); @@ -71,6 +68,19 @@ EXPORT void HWRAPI(DrawIntermissionBG) (void); EXPORT void HWRAPI(MakeScreenTexture) (void); EXPORT void HWRAPI(MakeScreenFinalTexture) (void); EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height); + +#define SCREENVERTS 10 +EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); + +// jimita +EXPORT void HWRAPI(LoadShaders) (void); +EXPORT void HWRAPI(KillShaders) (void); +EXPORT void HWRAPI(SetShader) (int shader); +EXPORT void HWRAPI(UnSetShader) (void); + +EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment); +EXPORT void HWRAPI(InitCustomShaders) (void); + // ========================================================================== // HWR DRIVER OBJECT, FOR CLIENT PROGRAM // ========================================================================== @@ -96,7 +106,6 @@ struct hwdriver_s CreateModelVBOs pfnCreateModelVBOs; SetTransform pfnSetTransform; GetTextureUsed pfnGetTextureUsed; - GetRenderVersion pfnGetRenderVersion; #ifdef _WINDOWS GetModeList pfnGetModeList; #endif @@ -112,13 +121,18 @@ struct hwdriver_s MakeScreenTexture pfnMakeScreenTexture; MakeScreenFinalTexture pfnMakeScreenFinalTexture; DrawScreenFinalTexture pfnDrawScreenFinalTexture; + + LoadShaders pfnLoadShaders; + KillShaders pfnKillShaders; + SetShader pfnSetShader; + UnSetShader pfnUnSetShader; + + LoadCustomShader pfnLoadCustomShader; + InitCustomShaders pfnInitCustomShaders; }; extern struct hwdriver_s hwdriver; -//Hurdler: 16/10/99: added for OpenGL gamma correction -//extern RGBA_t gamma_correction; - #define HWD hwdriver #endif //not defined _CREATE_DLL_ diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index cf98e7317..49a72c1b9 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -118,12 +118,12 @@ GLPatch_t *HWR_GetCachedGLRotSprite(aatree_t *hwrcache, UINT16 rollangle, patch_ #endif void HWR_GetFadeMask(lumpnum_t fademasklumpnum); +// hardware driver +extern INT32 gl_leveltime; + // -------- // hw_draw.c // -------- -extern float gr_patch_scalex; -extern float gr_patch_scaley; - extern consvar_t cv_grrounddown; // on/off extern INT32 patchformat; diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 4df71d145..3feb4d52e 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -877,19 +877,19 @@ void HWR_WallLighting(FOutVector *wlVerts) #endif for (i = 0; i < 4; i++) { - wlVerts[i].sow = (float)(0.5f + d[i]*s); - wlVerts[i].tow = (float)(0.5f + (wlVerts[i].y-LIGHT_POS(j).y)*s*1.2f); + wlVerts[i].s = (float)(0.5f + d[i]*s); + wlVerts[i].t = (float)(0.5f + (wlVerts[i].y-LIGHT_POS(j).y)*s*1.2f); } HWR_SetLight(); - Surf.FlatColor.rgba = LONG(dynlights->p_lspr[j]->dynamic_color); + Surf.PolyColor.rgba = LONG(dynlights->p_lspr[j]->dynamic_color); #ifdef DL_HIGH_QUALITY - Surf.FlatColor.s.alpha = (UINT8)((1-dist_p2d/DL_SQRRADIUS(j))*Surf.FlatColor.s.alpha); + Surf.PolyColor.s.alpha = (UINT8)((1-dist_p2d/DL_SQRRADIUS(j))*Surf.PolyColor.s.alpha); #endif // next state is null so fade out with alpha if (dynlights->mo[j]->state->nextstate == S_NULL) - Surf.FlatColor.s.alpha = (UINT8)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha); + Surf.PolyColor.s.alpha = (UINT8)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.PolyColor.s.alpha); HWD.pfnDrawPolygon (&Surf, wlVerts, 4, LIGHTMAPFLAGS); @@ -946,19 +946,19 @@ void HWR_PlaneLighting(FOutVector *clVerts, int nrClipVerts) #endif for (i = 0; i < nrClipVerts; i++) { - clVerts[i].sow = 0.5f + (clVerts[i].x-LIGHT_POS(j).x)*s; - clVerts[i].tow = 0.5f + (clVerts[i].z-LIGHT_POS(j).z)*s*1.2f; + clVerts[i].s = 0.5f + (clVerts[i].x-LIGHT_POS(j).x)*s; + clVerts[i].t = 0.5f + (clVerts[i].z-LIGHT_POS(j).z)*s*1.2f; } HWR_SetLight(); - Surf.FlatColor.rgba = LONG(dynlights->p_lspr[j]->dynamic_color); + Surf.PolyColor.rgba = LONG(dynlights->p_lspr[j]->dynamic_color); #ifdef DL_HIGH_QUALITY - Surf.FlatColor.s.alpha = (unsigned char)((1 - dist_p2d/DL_SQRRADIUS(j))*Surf.FlatColor.s.alpha); + Surf.PolyColor.s.alpha = (unsigned char)((1 - dist_p2d/DL_SQRRADIUS(j))*Surf.PolyColor.s.alpha); #endif // next state is null so fade out with alpha if ((dynlights->mo[j]->state->nextstate == S_NULL)) - Surf.FlatColor.s.alpha = (unsigned char)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha); + Surf.PolyColor.s.alpha = (unsigned char)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.PolyColor.s.alpha); HWD.pfnDrawPolygon (&Surf, clVerts, nrClipVerts, LIGHTMAPFLAGS); @@ -1025,11 +1025,11 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr) // more realistique corona ! if (cz >= 255*8+250) return; - Surf.FlatColor.rgba = p_lspr->corona_color; + Surf.PolyColor.rgba = p_lspr->corona_color; if (cz > 250.0f) - Surf.FlatColor.s.alpha = 0xff-((int)cz-250)/8; + Surf.PolyColor.s.alpha = 0xff-((int)cz-250)/8; else - Surf.FlatColor.s.alpha = 0xff; + Surf.PolyColor.s.alpha = 0xff; // do not be hide by sprite of the light itself ! cz = cz - 2.0f; @@ -1041,19 +1041,19 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr) // car comme l'offset est minime sa ce voit pas ! light[0].x = cx-size; light[0].z = cz; light[0].y = cy-size*1.33f+p_lspr->light_yoffset; - light[0].sow = 0.0f; light[0].tow = 0.0f; + light[0].s = 0.0f; light[0].t = 0.0f; light[1].x = cx+size; light[1].z = cz; light[1].y = cy-size*1.33f+p_lspr->light_yoffset; - light[1].sow = 1.0f; light[1].tow = 0.0f; + light[1].s = 1.0f; light[1].t = 0.0f; light[2].x = cx+size; light[2].z = cz; light[2].y = cy+size*1.33f+p_lspr->light_yoffset; - light[2].sow = 1.0f; light[2].tow = 1.0f; + light[2].s = 1.0f; light[2].t = 1.0f; light[3].x = cx-size; light[3].z = cz; light[3].y = cy+size*1.33f+p_lspr->light_yoffset; - light[3].sow = 0.0f; light[3].tow = 1.0f; + light[3].s = 0.0f; light[3].t = 1.0f; HWR_GetPic(coronalumpnum); /// \todo use different coronas @@ -1099,11 +1099,11 @@ void HWR_DrawCoronas(void) // more realistique corona ! if (cz >= 255*8+250) continue; - Surf.FlatColor.rgba = p_lspr->corona_color; + Surf.PolyColor.rgba = p_lspr->corona_color; if (cz > 250.0f) - Surf.FlatColor.s.alpha = (UINT8)(0xff-(UINT8)(((int)cz-250)/8)); + Surf.PolyColor.s.alpha = (UINT8)(0xff-(UINT8)(((int)cz-250)/8)); else - Surf.FlatColor.s.alpha = 0xff; + Surf.PolyColor.s.alpha = 0xff; switch (p_lspr->type) { @@ -1111,7 +1111,7 @@ void HWR_DrawCoronas(void) size = p_lspr->corona_radius * ((cz+120.0f)/950.0f); // d'ou vienne ces constante ? break; case ROCKET_SPR: - Surf.FlatColor.s.alpha = (UINT8)((M_RandomByte()>>1)&0xff); + Surf.PolyColor.s.alpha = (UINT8)((M_RandomByte()>>1)&0xff); // don't need a break case CORONA_SPR: size = p_lspr->corona_radius * ((cz+60.0f)/100.0f); // d'ou vienne ces constante ? @@ -1131,19 +1131,19 @@ void HWR_DrawCoronas(void) light[0].x = cx-size; light[0].z = cz; light[0].y = cy-size*1.33f; - light[0].sow = 0.0f; light[0].tow = 0.0f; + light[0].s = 0.0f; light[0].t = 0.0f; light[1].x = cx+size; light[1].z = cz; light[1].y = cy-size*1.33f; - light[1].sow = 1.0f; light[1].tow = 0.0f; + light[1].s = 1.0f; light[1].t = 0.0f; light[2].x = cx+size; light[2].z = cz; light[2].y = cy+size*1.33f; - light[2].sow = 1.0f; light[2].tow = 1.0f; + light[2].s = 1.0f; light[2].t = 1.0f; light[3].x = cx-size; light[3].z = cz; light[3].y = cy+size*1.33f; - light[3].sow = 0.0f; light[3].tow = 1.0f; + light[3].s = 0.0f; light[3].t = 1.0f; HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Clip | PF_NoDepthTest | PF_Corona); } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6ef48f222..b33b930aa 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -52,7 +52,6 @@ #define R_FAKEFLOORS #define HWPRECIP -#define SORTING //#define POLYSKY // ========================================================================== @@ -71,175 +70,15 @@ static void HWR_ProjectSprite(mobj_t *thing); static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); #endif -#ifdef SORTING -void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, - INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); +void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); -#else -static void HWR_Add3DWater(levelflat_t *levelflat, extrasubsector_t *xsub, fixed_t fixedheight, - INT32 lightlevel, INT32 alpha, sector_t *FOFSector); -static void HWR_Render3DWater(void); -static void HWR_RenderTransparentWalls(void); -#endif + static void HWR_FoggingOn(void); static UINT32 atohex(const char *s); boolean drawsky = true; -/* - * lookuptable for lightvalues - * calculated as follow: - * floatlight = (1.0-exp((light^3)*gamma)) / (1.0-exp(1.0*gamma)); - * gamma=-0,2;-2,0;-4,0;-6,0;-8,0 - * light = 0,0 .. 1,0 - */ -static const float lighttable[5][256] = -{ - { - 0.00000f,0.00000f,0.00000f,0.00000f,0.00000f,0.00001f,0.00001f,0.00002f,0.00003f,0.00004f, - 0.00006f,0.00008f,0.00010f,0.00013f,0.00017f,0.00020f,0.00025f,0.00030f,0.00035f,0.00041f, - 0.00048f,0.00056f,0.00064f,0.00073f,0.00083f,0.00094f,0.00106f,0.00119f,0.00132f,0.00147f, - 0.00163f,0.00180f,0.00198f,0.00217f,0.00237f,0.00259f,0.00281f,0.00305f,0.00331f,0.00358f, - 0.00386f,0.00416f,0.00447f,0.00479f,0.00514f,0.00550f,0.00587f,0.00626f,0.00667f,0.00710f, - 0.00754f,0.00800f,0.00848f,0.00898f,0.00950f,0.01003f,0.01059f,0.01117f,0.01177f,0.01239f, - 0.01303f,0.01369f,0.01437f,0.01508f,0.01581f,0.01656f,0.01734f,0.01814f,0.01896f,0.01981f, - 0.02069f,0.02159f,0.02251f,0.02346f,0.02444f,0.02544f,0.02647f,0.02753f,0.02862f,0.02973f, - 0.03088f,0.03205f,0.03325f,0.03448f,0.03575f,0.03704f,0.03836f,0.03971f,0.04110f,0.04252f, - 0.04396f,0.04545f,0.04696f,0.04851f,0.05009f,0.05171f,0.05336f,0.05504f,0.05676f,0.05852f, - 0.06031f,0.06214f,0.06400f,0.06590f,0.06784f,0.06981f,0.07183f,0.07388f,0.07597f,0.07810f, - 0.08027f,0.08248f,0.08473f,0.08702f,0.08935f,0.09172f,0.09414f,0.09659f,0.09909f,0.10163f, - 0.10421f,0.10684f,0.10951f,0.11223f,0.11499f,0.11779f,0.12064f,0.12354f,0.12648f,0.12946f, - 0.13250f,0.13558f,0.13871f,0.14188f,0.14511f,0.14838f,0.15170f,0.15507f,0.15850f,0.16197f, - 0.16549f,0.16906f,0.17268f,0.17635f,0.18008f,0.18386f,0.18769f,0.19157f,0.19551f,0.19950f, - 0.20354f,0.20764f,0.21179f,0.21600f,0.22026f,0.22458f,0.22896f,0.23339f,0.23788f,0.24242f, - 0.24702f,0.25168f,0.25640f,0.26118f,0.26602f,0.27091f,0.27587f,0.28089f,0.28596f,0.29110f, - 0.29630f,0.30156f,0.30688f,0.31226f,0.31771f,0.32322f,0.32879f,0.33443f,0.34013f,0.34589f, - 0.35172f,0.35761f,0.36357f,0.36960f,0.37569f,0.38185f,0.38808f,0.39437f,0.40073f,0.40716f, - 0.41366f,0.42022f,0.42686f,0.43356f,0.44034f,0.44718f,0.45410f,0.46108f,0.46814f,0.47527f, - 0.48247f,0.48974f,0.49709f,0.50451f,0.51200f,0.51957f,0.52721f,0.53492f,0.54271f,0.55058f, - 0.55852f,0.56654f,0.57463f,0.58280f,0.59105f,0.59937f,0.60777f,0.61625f,0.62481f,0.63345f, - 0.64217f,0.65096f,0.65984f,0.66880f,0.67783f,0.68695f,0.69615f,0.70544f,0.71480f,0.72425f, - 0.73378f,0.74339f,0.75308f,0.76286f,0.77273f,0.78268f,0.79271f,0.80283f,0.81304f,0.82333f, - 0.83371f,0.84417f,0.85472f,0.86536f,0.87609f,0.88691f,0.89781f,0.90880f,0.91989f,0.93106f, - 0.94232f,0.95368f,0.96512f,0.97665f,0.98828f,1.00000f - }, - { - 0.00000f,0.00000f,0.00000f,0.00000f,0.00001f,0.00002f,0.00003f,0.00005f,0.00007f,0.00010f, - 0.00014f,0.00019f,0.00024f,0.00031f,0.00038f,0.00047f,0.00057f,0.00069f,0.00081f,0.00096f, - 0.00112f,0.00129f,0.00148f,0.00170f,0.00193f,0.00218f,0.00245f,0.00274f,0.00306f,0.00340f, - 0.00376f,0.00415f,0.00456f,0.00500f,0.00547f,0.00597f,0.00649f,0.00704f,0.00763f,0.00825f, - 0.00889f,0.00957f,0.01029f,0.01104f,0.01182f,0.01264f,0.01350f,0.01439f,0.01532f,0.01630f, - 0.01731f,0.01836f,0.01945f,0.02058f,0.02176f,0.02298f,0.02424f,0.02555f,0.02690f,0.02830f, - 0.02974f,0.03123f,0.03277f,0.03436f,0.03600f,0.03768f,0.03942f,0.04120f,0.04304f,0.04493f, - 0.04687f,0.04886f,0.05091f,0.05301f,0.05517f,0.05738f,0.05964f,0.06196f,0.06434f,0.06677f, - 0.06926f,0.07181f,0.07441f,0.07707f,0.07979f,0.08257f,0.08541f,0.08831f,0.09126f,0.09428f, - 0.09735f,0.10048f,0.10368f,0.10693f,0.11025f,0.11362f,0.11706f,0.12056f,0.12411f,0.12773f, - 0.13141f,0.13515f,0.13895f,0.14281f,0.14673f,0.15072f,0.15476f,0.15886f,0.16303f,0.16725f, - 0.17153f,0.17587f,0.18028f,0.18474f,0.18926f,0.19383f,0.19847f,0.20316f,0.20791f,0.21272f, - 0.21759f,0.22251f,0.22748f,0.23251f,0.23760f,0.24274f,0.24793f,0.25318f,0.25848f,0.26383f, - 0.26923f,0.27468f,0.28018f,0.28573f,0.29133f,0.29697f,0.30266f,0.30840f,0.31418f,0.32001f, - 0.32588f,0.33179f,0.33774f,0.34374f,0.34977f,0.35585f,0.36196f,0.36810f,0.37428f,0.38050f, - 0.38675f,0.39304f,0.39935f,0.40570f,0.41207f,0.41847f,0.42490f,0.43136f,0.43784f,0.44434f, - 0.45087f,0.45741f,0.46398f,0.47057f,0.47717f,0.48379f,0.49042f,0.49707f,0.50373f,0.51041f, - 0.51709f,0.52378f,0.53048f,0.53718f,0.54389f,0.55061f,0.55732f,0.56404f,0.57075f,0.57747f, - 0.58418f,0.59089f,0.59759f,0.60429f,0.61097f,0.61765f,0.62432f,0.63098f,0.63762f,0.64425f, - 0.65086f,0.65746f,0.66404f,0.67060f,0.67714f,0.68365f,0.69015f,0.69662f,0.70307f,0.70948f, - 0.71588f,0.72224f,0.72857f,0.73488f,0.74115f,0.74739f,0.75359f,0.75976f,0.76589f,0.77199f, - 0.77805f,0.78407f,0.79005f,0.79599f,0.80189f,0.80774f,0.81355f,0.81932f,0.82504f,0.83072f, - 0.83635f,0.84194f,0.84747f,0.85296f,0.85840f,0.86378f,0.86912f,0.87441f,0.87964f,0.88482f, - 0.88995f,0.89503f,0.90005f,0.90502f,0.90993f,0.91479f,0.91959f,0.92434f,0.92903f,0.93366f, - 0.93824f,0.94276f,0.94723f,0.95163f,0.95598f,0.96027f,0.96451f,0.96868f,0.97280f,0.97686f, - 0.98086f,0.98481f,0.98869f,0.99252f,0.99629f,1.00000f - }, - { - 0.00000f,0.00000f,0.00000f,0.00001f,0.00002f,0.00003f,0.00005f,0.00008f,0.00013f,0.00018f, - 0.00025f,0.00033f,0.00042f,0.00054f,0.00067f,0.00083f,0.00101f,0.00121f,0.00143f,0.00168f, - 0.00196f,0.00227f,0.00261f,0.00299f,0.00339f,0.00383f,0.00431f,0.00483f,0.00538f,0.00598f, - 0.00661f,0.00729f,0.00802f,0.00879f,0.00961f,0.01048f,0.01140f,0.01237f,0.01340f,0.01447f, - 0.01561f,0.01680f,0.01804f,0.01935f,0.02072f,0.02215f,0.02364f,0.02520f,0.02682f,0.02850f, - 0.03026f,0.03208f,0.03397f,0.03594f,0.03797f,0.04007f,0.04225f,0.04451f,0.04684f,0.04924f, - 0.05172f,0.05428f,0.05691f,0.05963f,0.06242f,0.06530f,0.06825f,0.07129f,0.07441f,0.07761f, - 0.08089f,0.08426f,0.08771f,0.09125f,0.09487f,0.09857f,0.10236f,0.10623f,0.11019f,0.11423f, - 0.11836f,0.12257f,0.12687f,0.13125f,0.13571f,0.14027f,0.14490f,0.14962f,0.15442f,0.15931f, - 0.16427f,0.16932f,0.17445f,0.17966f,0.18496f,0.19033f,0.19578f,0.20130f,0.20691f,0.21259f, - 0.21834f,0.22417f,0.23007f,0.23605f,0.24209f,0.24820f,0.25438f,0.26063f,0.26694f,0.27332f, - 0.27976f,0.28626f,0.29282f,0.29944f,0.30611f,0.31284f,0.31962f,0.32646f,0.33334f,0.34027f, - 0.34724f,0.35426f,0.36132f,0.36842f,0.37556f,0.38273f,0.38994f,0.39718f,0.40445f,0.41174f, - 0.41907f,0.42641f,0.43378f,0.44116f,0.44856f,0.45598f,0.46340f,0.47084f,0.47828f,0.48573f, - 0.49319f,0.50064f,0.50809f,0.51554f,0.52298f,0.53042f,0.53784f,0.54525f,0.55265f,0.56002f, - 0.56738f,0.57472f,0.58203f,0.58932f,0.59658f,0.60381f,0.61101f,0.61817f,0.62529f,0.63238f, - 0.63943f,0.64643f,0.65339f,0.66031f,0.66717f,0.67399f,0.68075f,0.68746f,0.69412f,0.70072f, - 0.70726f,0.71375f,0.72017f,0.72653f,0.73282f,0.73905f,0.74522f,0.75131f,0.75734f,0.76330f, - 0.76918f,0.77500f,0.78074f,0.78640f,0.79199f,0.79751f,0.80295f,0.80831f,0.81359f,0.81880f, - 0.82393f,0.82898f,0.83394f,0.83883f,0.84364f,0.84836f,0.85301f,0.85758f,0.86206f,0.86646f, - 0.87078f,0.87502f,0.87918f,0.88326f,0.88726f,0.89118f,0.89501f,0.89877f,0.90245f,0.90605f, - 0.90957f,0.91301f,0.91638f,0.91966f,0.92288f,0.92601f,0.92908f,0.93206f,0.93498f,0.93782f, - 0.94059f,0.94329f,0.94592f,0.94848f,0.95097f,0.95339f,0.95575f,0.95804f,0.96027f,0.96244f, - 0.96454f,0.96658f,0.96856f,0.97049f,0.97235f,0.97416f,0.97591f,0.97760f,0.97924f,0.98083f, - 0.98237f,0.98386f,0.98530f,0.98669f,0.98803f,0.98933f,0.99058f,0.99179f,0.99295f,0.99408f, - 0.99516f,0.99620f,0.99721f,0.99817f,0.99910f,1.00000f - }, - { - 0.00000f,0.00000f,0.00000f,0.00001f,0.00002f,0.00005f,0.00008f,0.00012f,0.00019f,0.00026f, - 0.00036f,0.00048f,0.00063f,0.00080f,0.00099f,0.00122f,0.00148f,0.00178f,0.00211f,0.00249f, - 0.00290f,0.00335f,0.00386f,0.00440f,0.00500f,0.00565f,0.00636f,0.00711f,0.00793f,0.00881f, - 0.00975f,0.01075f,0.01182f,0.01295f,0.01416f,0.01543f,0.01678f,0.01821f,0.01971f,0.02129f, - 0.02295f,0.02469f,0.02652f,0.02843f,0.03043f,0.03252f,0.03469f,0.03696f,0.03933f,0.04178f, - 0.04433f,0.04698f,0.04973f,0.05258f,0.05552f,0.05857f,0.06172f,0.06498f,0.06834f,0.07180f, - 0.07537f,0.07905f,0.08283f,0.08672f,0.09072f,0.09483f,0.09905f,0.10337f,0.10781f,0.11236f, - 0.11701f,0.12178f,0.12665f,0.13163f,0.13673f,0.14193f,0.14724f,0.15265f,0.15817f,0.16380f, - 0.16954f,0.17538f,0.18132f,0.18737f,0.19351f,0.19976f,0.20610f,0.21255f,0.21908f,0.22572f, - 0.23244f,0.23926f,0.24616f,0.25316f,0.26023f,0.26739f,0.27464f,0.28196f,0.28935f,0.29683f, - 0.30437f,0.31198f,0.31966f,0.32740f,0.33521f,0.34307f,0.35099f,0.35896f,0.36699f,0.37506f, - 0.38317f,0.39133f,0.39952f,0.40775f,0.41601f,0.42429f,0.43261f,0.44094f,0.44929f,0.45766f, - 0.46604f,0.47443f,0.48283f,0.49122f,0.49962f,0.50801f,0.51639f,0.52476f,0.53312f,0.54146f, - 0.54978f,0.55807f,0.56633f,0.57457f,0.58277f,0.59093f,0.59905f,0.60713f,0.61516f,0.62314f, - 0.63107f,0.63895f,0.64676f,0.65452f,0.66221f,0.66984f,0.67739f,0.68488f,0.69229f,0.69963f, - 0.70689f,0.71407f,0.72117f,0.72818f,0.73511f,0.74195f,0.74870f,0.75536f,0.76192f,0.76839f, - 0.77477f,0.78105f,0.78723f,0.79331f,0.79930f,0.80518f,0.81096f,0.81664f,0.82221f,0.82768f, - 0.83305f,0.83832f,0.84347f,0.84853f,0.85348f,0.85832f,0.86306f,0.86770f,0.87223f,0.87666f, - 0.88098f,0.88521f,0.88933f,0.89334f,0.89726f,0.90108f,0.90480f,0.90842f,0.91194f,0.91537f, - 0.91870f,0.92193f,0.92508f,0.92813f,0.93109f,0.93396f,0.93675f,0.93945f,0.94206f,0.94459f, - 0.94704f,0.94941f,0.95169f,0.95391f,0.95604f,0.95810f,0.96009f,0.96201f,0.96386f,0.96564f, - 0.96735f,0.96900f,0.97059f,0.97212f,0.97358f,0.97499f,0.97634f,0.97764f,0.97888f,0.98007f, - 0.98122f,0.98231f,0.98336f,0.98436f,0.98531f,0.98623f,0.98710f,0.98793f,0.98873f,0.98949f, - 0.99021f,0.99090f,0.99155f,0.99218f,0.99277f,0.99333f,0.99387f,0.99437f,0.99486f,0.99531f, - 0.99575f,0.99616f,0.99654f,0.99691f,0.99726f,0.99759f,0.99790f,0.99819f,0.99847f,0.99873f, - 0.99897f,0.99920f,0.99942f,0.99963f,0.99982f,1.00000f - }, - { - 0.00000f,0.00000f,0.00000f,0.00001f,0.00003f,0.00006f,0.00010f,0.00017f,0.00025f,0.00035f, - 0.00048f,0.00064f,0.00083f,0.00106f,0.00132f,0.00163f,0.00197f,0.00237f,0.00281f,0.00330f, - 0.00385f,0.00446f,0.00513f,0.00585f,0.00665f,0.00751f,0.00845f,0.00945f,0.01054f,0.01170f, - 0.01295f,0.01428f,0.01569f,0.01719f,0.01879f,0.02048f,0.02227f,0.02415f,0.02614f,0.02822f, - 0.03042f,0.03272f,0.03513f,0.03765f,0.04028f,0.04303f,0.04589f,0.04887f,0.05198f,0.05520f, - 0.05855f,0.06202f,0.06561f,0.06933f,0.07318f,0.07716f,0.08127f,0.08550f,0.08987f,0.09437f, - 0.09900f,0.10376f,0.10866f,0.11369f,0.11884f,0.12414f,0.12956f,0.13512f,0.14080f,0.14662f, - 0.15257f,0.15865f,0.16485f,0.17118f,0.17764f,0.18423f,0.19093f,0.19776f,0.20471f,0.21177f, - 0.21895f,0.22625f,0.23365f,0.24117f,0.24879f,0.25652f,0.26435f,0.27228f,0.28030f,0.28842f, - 0.29662f,0.30492f,0.31329f,0.32175f,0.33028f,0.33889f,0.34756f,0.35630f,0.36510f,0.37396f, - 0.38287f,0.39183f,0.40084f,0.40989f,0.41897f,0.42809f,0.43723f,0.44640f,0.45559f,0.46479f, - 0.47401f,0.48323f,0.49245f,0.50167f,0.51088f,0.52008f,0.52927f,0.53843f,0.54757f,0.55668f, - 0.56575f,0.57479f,0.58379f,0.59274f,0.60164f,0.61048f,0.61927f,0.62799f,0.63665f,0.64524f, - 0.65376f,0.66220f,0.67056f,0.67883f,0.68702f,0.69511f,0.70312f,0.71103f,0.71884f,0.72655f, - 0.73415f,0.74165f,0.74904f,0.75632f,0.76348f,0.77053f,0.77747f,0.78428f,0.79098f,0.79756f, - 0.80401f,0.81035f,0.81655f,0.82264f,0.82859f,0.83443f,0.84013f,0.84571f,0.85117f,0.85649f, - 0.86169f,0.86677f,0.87172f,0.87654f,0.88124f,0.88581f,0.89026f,0.89459f,0.89880f,0.90289f, - 0.90686f,0.91071f,0.91445f,0.91807f,0.92157f,0.92497f,0.92826f,0.93143f,0.93450f,0.93747f, - 0.94034f,0.94310f,0.94577f,0.94833f,0.95081f,0.95319f,0.95548f,0.95768f,0.95980f,0.96183f, - 0.96378f,0.96565f,0.96744f,0.96916f,0.97081f,0.97238f,0.97388f,0.97532f,0.97669f,0.97801f, - 0.97926f,0.98045f,0.98158f,0.98266f,0.98369f,0.98467f,0.98560f,0.98648f,0.98732f,0.98811f, - 0.98886f,0.98958f,0.99025f,0.99089f,0.99149f,0.99206f,0.99260f,0.99311f,0.99359f,0.99404f, - 0.99446f,0.99486f,0.99523f,0.99559f,0.99592f,0.99623f,0.99652f,0.99679f,0.99705f,0.99729f, - 0.99751f,0.99772f,0.99792f,0.99810f,0.99827f,0.99843f,0.99857f,0.99871f,0.99884f,0.99896f, - 0.99907f,0.99917f,0.99926f,0.99935f,0.99943f,0.99951f,0.99958f,0.99964f,0.99970f,0.99975f, - 0.99980f,0.99985f,0.99989f,0.99993f,0.99997f,1.00000f - } -}; - -#define gld_CalcLightLevel(lightlevel) (lighttable[1][max(min((lightlevel),255),0)]) - // ========================================================================== // VIEW GLOBALS // ========================================================================== @@ -309,147 +148,83 @@ static float gr_viewx, gr_viewy, gr_viewz; static float gr_viewsin, gr_viewcos; // Maybe not necessary with the new T&L code (needs to be checked!) +static angle_t gr_aimingangle; static float gr_viewludsin, gr_viewludcos; // look up down kik test static float gr_fovlud; // ========================================================================== -// LIGHT stuffs +// Lighting // ========================================================================== -static UINT8 lightleveltonumlut[256]; - -// added to SRB2's sector lightlevel to make things a bit brighter (sprites/walls/planes) -FUNCMATH UINT8 LightLevelToLum(INT32 l) -{ - return (UINT8)(255*gld_CalcLightLevel(l)); -} - -static inline void InitLumLut(void) -{ - INT32 i, k = 0; - for (i = 0; i < 256; i++) - { - if (i > 128) - k += 2; - else - k = 1; - lightleveltonumlut[i] = (UINT8)(k); - } -} - -//#define FOGFACTOR 300 //was 600 >> Covered by cv_grfogdensity -#define NORMALFOG 0x00000000 -#define FADEFOG 0x19000000 -#define CALCFOGDENSITY(x) ((float)((5220.0f*(1.0f/((x)/41.0f+1.0f)))-(5220.0f*(1.0f/(255.0f/41.0f+1.0f))))) // Approximate fog calculation based off of software walls -#define CALCFOGDENSITYFLOOR(x) ((float)((40227.0f*(1.0f/((x)/11.0f+1.0f)))-(40227.0f*(1.0f/(255.0f/11.0f+1.0f))))) // Approximate fog calculation based off of software floors #define CALCLIGHT(x,y) ((float)(x)*((y)/255.0f)) -UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane) + +void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap) { - RGBA_t realcolor, fogcolor, surfcolor; - INT32 alpha, fogalpha; + RGBA_t poly_color, tint_color, fade_color; - (void)fogblockpoly; + poly_color.rgba = 0xFFFFFFFF; + tint_color.rgba = (colormap != NULL) ? (UINT32)colormap->rgba : GL_DEFAULTMIX; + fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : GL_DEFAULTFOG; - // Don't go out of bounds - if (light < 0) - light = 0; - else if (light > 255) - light = 255; - - realcolor.rgba = color; - fogcolor.rgba = fadecolor; - - alpha = (realcolor.s.alpha*255)/25; - fogalpha = (fogcolor.s.alpha*255)/25; - - if (cv_grfog.value && cv_grsoftwarefog.value) // Only do this when fog is on, software fog mode is on, and the poly is not from a fog block + // Crappy backup coloring if you can't do shaders + if (!cv_grshaders.value) { - // Modulate the colors by alpha. - realcolor.s.red = (UINT8)(CALCLIGHT(alpha,realcolor.s.red)); - realcolor.s.green = (UINT8)(CALCLIGHT(alpha,realcolor.s.green)); - realcolor.s.blue = (UINT8)(CALCLIGHT(alpha,realcolor.s.blue)); + // be careful, this may get negative for high lightlevel values. + float tint_alpha, fade_alpha; + float red, green, blue; - // Set the surface colors and further modulate the colors by light. - surfcolor.s.red = (UINT8)(CALCLIGHT((0xFF-alpha),255)+CALCLIGHT(realcolor.s.red,255)); - surfcolor.s.green = (UINT8)(CALCLIGHT((0xFF-alpha),255)+CALCLIGHT(realcolor.s.green,255)); - surfcolor.s.blue = (UINT8)(CALCLIGHT((0xFF-alpha),255)+CALCLIGHT(realcolor.s.blue,255)); - surfcolor.s.alpha = 0xFF; + red = (float)poly_color.s.red; + green = (float)poly_color.s.green; + blue = (float)poly_color.s.blue; - // Modulate the colors by alpha. - fogcolor.s.red = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.red)); - fogcolor.s.green = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.green)); - fogcolor.s.blue = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.blue)); - } - else - { - // Modulate the colors by alpha. - realcolor.s.red = (UINT8)(CALCLIGHT(alpha,realcolor.s.red)); - realcolor.s.green = (UINT8)(CALCLIGHT(alpha,realcolor.s.green)); - realcolor.s.blue = (UINT8)(CALCLIGHT(alpha,realcolor.s.blue)); + // 48 is just an arbritrary value that looked relatively okay. + tint_alpha = (float)(sqrt(tint_color.s.alpha) * 48) / 255.0f; - // Set the surface colors and further modulate the colors by light. - surfcolor.s.red = (UINT8)(CALCLIGHT((0xFF-alpha),light)+CALCLIGHT(realcolor.s.red,light)); - surfcolor.s.green = (UINT8)(CALCLIGHT((0xFF-alpha),light)+CALCLIGHT(realcolor.s.green,light)); - surfcolor.s.blue = (UINT8)(CALCLIGHT((0xFF-alpha),light)+CALCLIGHT(realcolor.s.blue,light)); + // 8 is roughly the brightness of the "close" color in Software, and 16 the brightness of the "far" color. + // 8 is too bright for dark levels, and 16 is too dark for bright levels. + // 12 is the compromise value. It doesn't look especially good anywhere, but it's the most balanced. + // (Also, as far as I can tell, fade_color's alpha is actually not used in Software, so we only use light level.) + fade_alpha = (float)(sqrt(255-light_level) * 12) / 255.0f; - // Modulate the colors by alpha. - fogcolor.s.red = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.red)); - fogcolor.s.green = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.green)); - fogcolor.s.blue = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.blue)); + // Clamp the alpha values + tint_alpha = min(max(tint_alpha, 0.0f), 1.0f); + fade_alpha = min(max(fade_alpha, 0.0f), 1.0f); - // Set the surface colors and further modulate the colors by light. - surfcolor.s.red = surfcolor.s.red+((UINT8)(CALCLIGHT((0xFF-fogalpha),(255-light))+CALCLIGHT(fogcolor.s.red,(255-light)))); - surfcolor.s.green = surfcolor.s.green+((UINT8)(CALCLIGHT((0xFF-fogalpha),(255-light))+CALCLIGHT(fogcolor.s.green,(255-light)))); - surfcolor.s.blue = surfcolor.s.blue+((UINT8)(CALCLIGHT((0xFF-fogalpha),(255-light))+CALCLIGHT(fogcolor.s.blue,(255-light)))); - surfcolor.s.alpha = 0xFF; + red = (tint_color.s.red * tint_alpha) + (red * (1.0f - tint_alpha)); + green = (tint_color.s.green * tint_alpha) + (green * (1.0f - tint_alpha)); + blue = (tint_color.s.blue * tint_alpha) + (blue * (1.0f - tint_alpha)); + + red = (fade_color.s.red * fade_alpha) + (red * (1.0f - fade_alpha)); + green = (fade_color.s.green * fade_alpha) + (green * (1.0f - fade_alpha)); + blue = (fade_color.s.blue * fade_alpha) + (blue * (1.0f - fade_alpha)); + + poly_color.s.red = (UINT8)red; + poly_color.s.green = (UINT8)green; + poly_color.s.blue = (UINT8)blue; } - if(cv_grfog.value) - { - if (cv_grsoftwarefog.value) - { - fogcolor.s.red = (UINT8)((CALCLIGHT(fogcolor.s.red,(255-light)))+(CALCLIGHT(realcolor.s.red,light))); - fogcolor.s.green = (UINT8)((CALCLIGHT(fogcolor.s.green,(255-light)))+(CALCLIGHT(realcolor.s.green,light))); - fogcolor.s.blue = (UINT8)((CALCLIGHT(fogcolor.s.blue,(255-light)))+(CALCLIGHT(realcolor.s.blue,light))); - - // Set the fog options. - if (cv_grsoftwarefog.value == 1 && plane) // With floors, software draws them way darker for their distance - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, (INT32)(CALCFOGDENSITYFLOOR(light))); - else // everything else is drawn like walls - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, (INT32)(CALCFOGDENSITY(light))); - } - else - { - fogcolor.s.red = (UINT8)((CALCLIGHT(fogcolor.s.red,(255-light)))+(CALCLIGHT(realcolor.s.red,light))); - fogcolor.s.green = (UINT8)((CALCLIGHT(fogcolor.s.green,(255-light)))+(CALCLIGHT(realcolor.s.green,light))); - fogcolor.s.blue = (UINT8)((CALCLIGHT(fogcolor.s.blue,(255-light)))+(CALCLIGHT(realcolor.s.blue,light))); - - fogalpha = (UINT8)((CALCLIGHT(fogalpha,(255-light)))+(CALCLIGHT(alpha,light))); - - // Set the fog options. - light = (UINT8)(CALCLIGHT(light,(255-fogalpha))); - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, (INT32)(cv_grfogdensity.value-(cv_grfogdensity.value*(float)light/255.0f))); - } - - HWD.pfnSetSpecialState(HWD_SET_FOG_COLOR, (fogcolor.s.red*0x10000)+(fogcolor.s.green*0x100)+fogcolor.s.blue); - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 1); - } - return surfcolor.rgba; + Surface->PolyColor.rgba = poly_color.rgba; + Surface->TintColor.rgba = tint_color.rgba; + Surface->FadeColor.rgba = fade_color.rgba; + Surface->LightInfo.light_level = light_level; + Surface->LightInfo.fade_start = (colormap != NULL) ? colormap->fadestart : 0; + Surface->LightInfo.fade_end = (colormap != NULL) ? colormap->fadeend : 31; } - -static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this can work +UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work { RGBA_t realcolor, surfcolor; INT32 alpha; + light = light - (255 - light); + // Don't go out of bounds if (light < 0) light = 0; else if (light > 255) light = 255; - realcolor.rgba = color; + realcolor.rgba = (colormap != NULL) ? colormap->rgba : GL_DEFAULTMIX; alpha = (realcolor.s.alpha*255)/25; @@ -465,11 +240,9 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this c #ifdef DOPLANES -// -----------------+ -// HWR_RenderPlane : Render a floor or ceiling convex polygon -// -----------------+ -static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, - FBITFIELD PolyFlags, INT32 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap) +// HWR_RenderPlane +// Render a floor or ceiling convex polygon +static void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) { polyvertex_t * pv; float height; //constant y for all points on the convex flat polygon @@ -492,8 +265,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; - (void)sector; ///@TODO remove shitty unused variable - // no convex poly were generated for this subsector if (!xsub->planepoly) return; @@ -528,13 +299,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (nrPlaneVerts < 3) //not even a triangle ? return; - // This check is so inconsistent between functions, it hurts. - if (nrPlaneVerts > INT16_MAX) // FIXME: exceeds plVerts size - { - CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, INT16_MAX); - return; - } - // Allocate plane-vertex buffer if we need to if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts) { @@ -625,9 +389,18 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is } } + if (angle) // Only needs to be done if there's an altered angle { - angle = InvAngle(angle)>>ANGLETOFINESHIFT; + + angle = (InvAngle(angle)+ANGLE_180)>>ANGLETOFINESHIFT; + + // This needs to be done so that it scrolls in a different direction after rotation like software + /*tempxsow = FLOAT_TO_FIXED(scrollx); + tempytow = FLOAT_TO_FIXED(scrolly); + scrollx = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); + scrolly = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));*/ + // This needs to be done so everything aligns after rotation // It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does tempxsow = FLOAT_TO_FIXED(flatxref); @@ -636,33 +409,34 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is flatyref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); } + for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++) { // Hurdler: add scrolling texture on floor/ceiling if (texflat) { - v3d->sow = (float)(pv->x / fflatwidth) + scrollx; - v3d->tow = -(float)(pv->y / fflatheight) + scrolly; + v3d->s = (float)(pv->x / fflatwidth) + scrollx; + v3d->t = -(float)(pv->y / fflatheight) + scrolly; } else { - v3d->sow = (float)((pv->x / fflatwidth) - flatxref + scrollx); - v3d->tow = (float)(flatyref - (pv->y / fflatheight) + scrolly); + v3d->s = (float)((pv->x / fflatwidth) - flatxref + scrollx); + v3d->t = (float)(flatyref - (pv->y / fflatheight) + scrolly); } // Need to rotate before translate if (angle) // Only needs to be done if there's an altered angle { - tempxsow = FLOAT_TO_FIXED(v3d->sow); - tempytow = FLOAT_TO_FIXED(v3d->tow); + tempxsow = FLOAT_TO_FIXED(v3d->s); + tempytow = FLOAT_TO_FIXED(v3d->t); if (texflat) tempytow = -tempytow; - v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - v3d->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); + v3d->s = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); + v3d->t = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); } - //v3d->sow = (float)(v3d->sow - flatxref + scrollx); - //v3d->tow = (float)(flatyref - v3d->tow + scrolly); + //v3d->s = (float)(v3d->s - flatxref + scrollx); + //v3d->t = (float)(flatyref - v3d->t + scrolly); v3d->x = pv->x; v3d->y = height; @@ -677,69 +451,22 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is #endif } - // only useful for flat coloured triangles - //Surf.FlatColor = 0xff804020; - - // use different light tables - // for horizontal / vertical / diagonal - // note: try to get the same visual feel as the original - Surf.FlatColor.s.red = Surf.FlatColor.s.green = - Surf.FlatColor.s.blue = LightLevelToLum(lightlevel); // Don't take from the frontsector, or the game will crash - -#if 0 // no colormap test - // colormap test - if (gr_frontsector) - { - sector_t *psector = gr_frontsector; - -#ifdef ESLOPE - if (slope) - fixedheight = P_GetZAt(slope, psector->soundorg.x, psector->soundorg.y); -#endif - - if (psector->ffloors) - { - ffloor_t *caster = psector->lightlist[R_GetPlaneLight(psector, fixedheight, false)].caster; - psector = caster ? §ors[caster->secnum] : psector; - - if (caster) - { - lightlevel = psector->lightlevel; - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = LightLevelToLum(lightlevel); - } - } - if (psector->extra_colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel,psector->extra_colormap->rgba,psector->extra_colormap->fadergba, false, true); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel,NORMALFOG,FADEFOG, false, true); - } - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel,NORMALFOG,FADEFOG, false, true); - -#endif // NOPE - - if (planecolormap) - { - if (fogplane) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, planecolormap->rgba, planecolormap->fadergba, true, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, planecolormap->rgba, planecolormap->fadergba, false, true); - } - else - { - if (fogplane) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, true, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, true); - } + HWR_Lighting(&Surf, lightlevel, planecolormap); if (PolyFlags & (PF_Translucent|PF_Fog)) { - Surf.FlatColor.s.alpha = (UINT8)alpha; - PolyFlags |= PF_Modulated|PF_Clip; + Surf.PolyColor.s.alpha = (UINT8)alpha; + PolyFlags |= PF_Modulated; } else - PolyFlags |= PF_Masked|PF_Modulated|PF_Clip; + PolyFlags |= PF_Masked|PF_Modulated; + + if (PolyFlags & PF_Fog) + HWD.pfnSetShader(6); // fog shader + else if (PolyFlags & PF_Ripple) + HWD.pfnSetShader(5); // water shader + else + HWD.pfnSetShader(1); // floor shader HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags); @@ -782,8 +509,8 @@ static void HWR_RenderSkyPlane(extrasubsector_t *xsub, fixed_t fixedheight) v3d = planeVerts; for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++) { - v3d->sow = 0.0f; - v3d->tow = 0.0f; + v3d->s = 0.0f; + v3d->t = 0.0f; v3d->x = pv->x; v3d->y = height; v3d->z = pv->y; @@ -806,13 +533,10 @@ static void HWR_RenderSkyPlane(extrasubsector_t *xsub, fixed_t fixedheight) #ifdef WALLSPLATS static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) { - FOutVector trVerts[4], *wv; - wallVert3D wallVerts[4]; - wallVert3D *pwallVerts; + FOutVector wallVerts[4]; wallsplat_t *splat; GLPatch_t *gpatch; fixed_t i; - FSurfaceInfo pSurf2; // seg bbox fixed_t segbbox[4]; @@ -850,141 +574,65 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) wallVerts[3].s = wallVerts[3].t = wallVerts[2].s = wallVerts[0].t = 0.0f; wallVerts[1].s = wallVerts[1].t = wallVerts[2].t = wallVerts[0].s = 1.0f; - // transform - wv = trVerts; - pwallVerts = wallVerts; - for (i = 0; i < 4; i++,wv++,pwallVerts++) - { - wv->x = pwallVerts->x; - wv->z = pwallVerts->z; - wv->y = pwallVerts->y; - - // Kalaron: TOW and SOW needed to be switched - wv->sow = pwallVerts->t; - wv->tow = pwallVerts->s; - } - M_Memcpy(&pSurf2,pSurf,sizeof (FSurfaceInfo)); switch (splat->flags & SPLATDRAWMODE_MASK) { case SPLATDRAWMODE_OPAQUE : - pSurf2.FlatColor.s.alpha = 0xff; + pSurf.PolyColor.s.alpha = 0xff; i = PF_Translucent; break; case SPLATDRAWMODE_TRANS : - pSurf2.FlatColor.s.alpha = 128; + pSurf.PolyColor.s.alpha = 128; i = PF_Translucent; break; case SPLATDRAWMODE_SHADE : - pSurf2.FlatColor.s.alpha = 0xff; + pSurf.PolyColor.s.alpha = 0xff; i = PF_Substractive; break; } - HWD.pfnDrawPolygon(&pSurf2, trVerts, 4, i|PF_Modulated|PF_Clip|PF_Decal); + HWD.pfnSetShader(2); // wall shader + HWD.pfnDrawPolygon(&pSurf, wallVerts, 4, i|PF_Modulated|PF_Decal); } } #endif -// ========================================================================== -// WALL GENERATION FROM SUBSECTOR SEGS -// ========================================================================== - - FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf) { switch (transtablenum) { - case tr_trans10 : pSurf->FlatColor.s.alpha = 0xe6;return PF_Translucent; - case tr_trans20 : pSurf->FlatColor.s.alpha = 0xcc;return PF_Translucent; - case tr_trans30 : pSurf->FlatColor.s.alpha = 0xb3;return PF_Translucent; - case tr_trans40 : pSurf->FlatColor.s.alpha = 0x99;return PF_Translucent; - case tr_trans50 : pSurf->FlatColor.s.alpha = 0x80;return PF_Translucent; - case tr_trans60 : pSurf->FlatColor.s.alpha = 0x66;return PF_Translucent; - case tr_trans70 : pSurf->FlatColor.s.alpha = 0x4c;return PF_Translucent; - case tr_trans80 : pSurf->FlatColor.s.alpha = 0x33;return PF_Translucent; - case tr_trans90 : pSurf->FlatColor.s.alpha = 0x19;return PF_Translucent; + case tr_trans10 : pSurf->PolyColor.s.alpha = 0xe6;return PF_Translucent; + case tr_trans20 : pSurf->PolyColor.s.alpha = 0xcc;return PF_Translucent; + case tr_trans30 : pSurf->PolyColor.s.alpha = 0xb3;return PF_Translucent; + case tr_trans40 : pSurf->PolyColor.s.alpha = 0x99;return PF_Translucent; + case tr_trans50 : pSurf->PolyColor.s.alpha = 0x80;return PF_Translucent; + case tr_trans60 : pSurf->PolyColor.s.alpha = 0x66;return PF_Translucent; + case tr_trans70 : pSurf->PolyColor.s.alpha = 0x4c;return PF_Translucent; + case tr_trans80 : pSurf->PolyColor.s.alpha = 0x33;return PF_Translucent; + case tr_trans90 : pSurf->PolyColor.s.alpha = 0x19;return PF_Translucent; } return PF_Translucent; } -// v1,v2 : the start & end vertices along the original wall segment, that may have been -// clipped so that only a visible portion of the wall seg is drawn. -// floorheight, ceilingheight : depend on wall upper/lower/middle, comes from the sectors. +static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); -static void HWR_AddTransparentWall(wallVert3D *wallVerts, FSurfaceInfo * pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); +// ========================================================================== +// Wall generation from subsector segs +// ========================================================================== -// -----------------+ -// HWR_ProjectWall : -// -----------------+ -/* - wallVerts order is : - 3--2 - | /| - |/ | - 0--1 -*/ -static void HWR_ProjectWall(wallVert3D * wallVerts, - FSurfaceInfo * pSurf, - FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap) +// +// HWR_ProjectWall +// +static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap) { - FOutVector trVerts[4]; - FOutVector *wv; + HWR_Lighting(pSurf, lightlevel, wallcolormap); - // transform - wv = trVerts; - // it sounds really stupid to do this conversion with the new T&L code - // we should directly put the right information in the right structure - // wallVerts3D seems ok, doesn't need FOutVector - // also remove the light copy - - // More messy to unwrap, but it's also quicker, uses less memory. - wv->sow = wallVerts->s; - wv->tow = wallVerts->t; - wv->x = wallVerts->x; - wv->y = wallVerts->y; - wv->z = wallVerts->z; - wv++; wallVerts++; - wv->sow = wallVerts->s; - wv->tow = wallVerts->t; - wv->x = wallVerts->x; - wv->y = wallVerts->y; - wv->z = wallVerts->z; - wv++; wallVerts++; - wv->sow = wallVerts->s; - wv->tow = wallVerts->t; - wv->x = wallVerts->x; - wv->y = wallVerts->y; - wv->z = wallVerts->z; - wv++; wallVerts++; - wv->sow = wallVerts->s; - wv->tow = wallVerts->t; - wv->x = wallVerts->x; - wv->y = wallVerts->y; - wv->z = wallVerts->z; - - if (wallcolormap) - { - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, wallcolormap->rgba, wallcolormap->fadergba, false, false); - } - else - { - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); - } - - HWD.pfnDrawPolygon(pSurf, trVerts, 4, blendmode|PF_Modulated|PF_Occlude|PF_Clip); + HWD.pfnSetShader(2); // wall shader + HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude); #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) HWR_DrawSegsSplats(pSurf); #endif -#ifdef ALAM_LIGHTING - //Hurdler: TDOD: do static lighting using gr_curline->lm - HWR_WallLighting(trVerts); - - //Hurdler: for better dynamic light in dark area, we should draw the light first - // and then the wall all that with the right blending func - //HWD.pfnDrawPolygon(pSurf, trVerts, 4, PF_Additive|PF_Modulated|PF_Occlude|PF_Clip); -#endif } // ========================================================================== @@ -1029,7 +677,7 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) // // HWR_SplitWall // -static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor) +static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor) { /* SoM: split up and light walls according to the lightlist. This may also include leaving out parts @@ -1055,7 +703,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, INT32 solid, i; lightlist_t * list = sector->lightlist; - const UINT8 alpha = Surf->FlatColor.s.alpha; + const UINT8 alpha = Surf->PolyColor.s.alpha; FUINT lightnum = sector->lightlevel; extracolormap_t *colormap = NULL; @@ -1076,12 +724,11 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, for (i = 0; i < sector->numlights; i++) { #ifdef ESLOPE - if (endtop < endrealbot) + if (endtop < endrealbot) #endif if (top < realbot) return; - // There's a compiler warning here if this comment isn't here because of indentation if (!(list[i].flags & FF_NOSHADE)) { if (pfloor && (pfloor->flags & FF_FOG)) @@ -1201,7 +848,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (endbot < endrealbot) endbot = endrealbot; #endif - Surf->FlatColor.s.alpha = alpha; + Surf->PolyColor.s.alpha = alpha; #ifdef ESLOPE wallVerts[3].t = pegt + ((realtop - top) * pegmul); @@ -1244,7 +891,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (top <= realbot) return; - Surf->FlatColor.s.alpha = alpha; + Surf->PolyColor.s.alpha = alpha; #ifdef ESLOPE wallVerts[3].t = pegt + ((realtop - top) * pegmul); @@ -1258,12 +905,12 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = bot; wallVerts[1].y = endbot; #else - wallVerts[3].t = wallVerts[2].t = pegt + ((realtop - top) * pegmul); - wallVerts[0].t = wallVerts[1].t = pegt + ((realtop - bot) * pegmul); + wallVerts[3].t = wallVerts[2].t = pegt + ((realtop - top) * pegmul); + wallVerts[0].t = wallVerts[1].t = pegt + ((realtop - bot) * pegmul); - // set top/bottom coords - wallVerts[2].y = wallVerts[3].y = top; - wallVerts[0].y = wallVerts[1].y = bot; + // set top/bottom coords + wallVerts[2].y = wallVerts[3].y = top; + wallVerts[0].y = wallVerts[1].y = bot; #endif if (cutflag & FF_FOG) @@ -1276,7 +923,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, // HWR_DrawSkyWall // Draw walls into the depth buffer so that anything behind is culled properly -static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf) +static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top) { HWD.pfnSetTexture(NULL); // no texture @@ -1284,27 +931,25 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf) wallVerts[0].t = wallVerts[1].t = 0; wallVerts[0].s = wallVerts[3].s = 0; wallVerts[2].s = wallVerts[1].s = 0; - // this no longer sets top/bottom coords, this should be done before caling the function - HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_Clip|PF_NoTexture, 255, NULL); + // set top/bottom coords + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(top); // No real way to find the correct height of this + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(bottom); // worldlow/bottom because it needs to cover up the lower thok barrier wall + HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_NoTexture, 255, NULL); // PF_Invisible so it's not drawn into the colour buffer // PF_NoTexture for no texture // PF_Occlude is set in HWR_ProjectWall to draw into the depth buffer } // -// HWR_StoreWallRange +// HWR_ProcessSeg // A portion or all of a wall segment will be drawn, from startfrac to endfrac, // where 0 is the start of the segment, 1 the end of the segment // Anything between means the wall segment has been clipped with solidsegs, // reducing wall overdraw to a minimum // -#ifdef NEWCLIP static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom -#else -static void HWR_StoreWallRange(double startfrac, double endfrac) -#endif { - wallVert3D wallVerts[4]; + FOutVector wallVerts[4]; v2d_t vs, ve; // start, end vertices of 2d line (view from above) fixed_t worldtop, worldbottom; @@ -1327,11 +972,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) extracolormap_t *colormap; FSurfaceInfo Surf; -#ifndef NEWCLIP - if (startfrac > endfrac) - return; -#endif - gr_sidedef = gr_curline->sidedef; gr_linedef = gr_curline->linedef; @@ -1373,42 +1013,24 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) wallVerts[0].z = wallVerts[3].z = vs.y; wallVerts[2].x = wallVerts[1].x = ve.x; wallVerts[2].z = wallVerts[1].z = ve.y; - wallVerts[0].w = wallVerts[1].w = wallVerts[2].w = wallVerts[3].w = 1.0f; + // x offset the texture { - // x offset the texture fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset; - -#ifndef NEWCLIP - // clip texture s start/end coords with solidsegs - if (startfrac > 0.0f && startfrac < 1.0f) - cliplow = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * startfrac); - else -#endif - cliplow = (float)texturehpeg; - -#ifndef NEWCLIP - if (endfrac > 0.0f && endfrac < 1.0f) - cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * endfrac); - else -#endif - cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT)); + cliplow = (float)texturehpeg; + cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT)); } lightnum = gr_frontsector->lightlevel; colormap = gr_frontsector->extra_colormap; if (gr_frontsector) - { - Surf.FlatColor.s.alpha = 255; - } + Surf.PolyColor.s.alpha = 255; if (gr_backsector) { - INT32 gr_toptexture = 0, gr_bottomtexture = 0; + INT32 gr_toptexture, gr_bottomtexture; // two sided line - boolean bothceilingssky = false; // turned on if both back and front ceilings are sky - boolean bothfloorssky = false; // likewise, but for floors #ifdef ESLOPE SLOPEPARAMS(gr_backsector->c_slope, worldhigh, worldhighslope, gr_backsector->ceilingheight) @@ -1421,23 +1043,17 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // hack to allow height changes in outdoor areas // This is what gets rid of the upper textures if there should be sky - if (gr_frontsector->ceilingpic == skyflatnum - && gr_backsector->ceilingpic == skyflatnum) + if (gr_frontsector->ceilingpic == skyflatnum && + gr_backsector->ceilingpic == skyflatnum) { - bothceilingssky = true; + worldtop = worldhigh; +#ifdef ESLOPE + worldtopslope = worldhighslope; +#endif } - // likewise, but for floors and upper textures - if (gr_frontsector->floorpic == skyflatnum - && gr_backsector->floorpic == skyflatnum) - { - bothfloorssky = true; - } - - if (!bothceilingssky) - gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); - if (!bothfloorssky) - gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); + gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); + gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); // check TOP TEXTURE if (( @@ -1848,7 +1464,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { if (gr_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn { - Surf.FlatColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode + Surf.PolyColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode blendmode = PF_Masked; } else @@ -1869,57 +1485,93 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, blendmode, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap); - - // If there is a colormap change, remove it. -/* if (!(Surf.FlatColor.s.red + Surf.FlatColor.s.green + Surf.FlatColor.s.blue == Surf.FlatColor.s.red/3) - { - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; - Surf.FlatColor.rgba = 0xffffffff; - }*/ } -#if 1 - // Sky culling - // No longer so much a mess as before! + // Isn't this just the most lovely mess if (!gr_curline->polyseg) // Don't do it for polyobjects { - if (gr_frontsector->ceilingpic == skyflatnum) + if (gr_frontsector->ceilingpic == skyflatnum || gr_backsector->ceilingpic == skyflatnum) { - if (gr_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky + fixed_t depthwallheight; + + if (!gr_sidedef->toptexture || (gr_frontsector->ceilingpic == skyflatnum && gr_backsector->ceilingpic == skyflatnum)) // when both sectors are sky, the top texture isn't drawn + depthwallheight = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; + else + depthwallheight = gr_frontsector->ceilingheight > gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; + + if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier { - wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space -#ifdef ESLOPE - wallVerts[0].y = FIXED_TO_FLOAT(worldtop); - wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); -#else - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); -#endif - HWR_DrawSkyWall(wallVerts, &Surf); + if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier + { + if (!gr_sidedef->bottomtexture) // Only extend further down if there's no texture + HWR_DrawSkyWall(wallVerts, &Surf, worldbottom < worldlow ? worldbottom : worldlow, INT32_MAX); + else + HWR_DrawSkyWall(wallVerts, &Surf, worldbottom > worldlow ? worldbottom : worldlow, INT32_MAX); + } + // behind sector is not a thok barrier + else if (gr_backsector->ceilingheight <= gr_frontsector->ceilingheight) // behind sector ceiling is lower or equal to current sector + HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); + // gr_front/backsector heights need to be used here because of the worldtop being set to worldhigh earlier on + } + else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not + { + if (gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier ceiling height is equal to or greater than current sector ceiling height + || gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier ceiling height is equal to or less than current sector floor height + || gr_backsector->ceilingpic != skyflatnum) // thok barrier is not a sky + HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); + } + else // neither sectors are thok barriers + { + if ((gr_backsector->ceilingheight < gr_frontsector->ceilingheight && !gr_sidedef->toptexture) // no top texture and sector behind is lower + || gr_backsector->ceilingpic != skyflatnum) // behind sector is not a sky + HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); } } - - if (gr_frontsector->floorpic == skyflatnum) + // And now for sky floors! + if (gr_frontsector->floorpic == skyflatnum || gr_backsector->floorpic == skyflatnum) { - if (gr_backsector->floorpic != skyflatnum) // don't cull if back sector is also sky + fixed_t depthwallheight; + + if (!gr_sidedef->bottomtexture) + depthwallheight = worldbottom > worldlow ? worldbottom : worldlow; + else + depthwallheight = worldbottom < worldlow ? worldbottom : worldlow; + + if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier { -#ifdef ESLOPE - wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); - wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); -#else - wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); -#endif - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space - HWR_DrawSkyWall(wallVerts, &Surf); + if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier + { + if (!gr_sidedef->toptexture) // Only extend up if there's no texture + HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop > worldhigh ? worldtop : worldhigh); + else + HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop < worldhigh ? worldtop : worldhigh); + } + // behind sector is not a thok barrier + else if (gr_backsector->floorheight >= gr_frontsector->floorheight) // behind sector floor is greater or equal to current sector + HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); + } + else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not + { + if (gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier floor height is equal to or less than current sector floor height + || gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier floor height is equal to or greater than current sector ceiling height + || gr_backsector->floorpic != skyflatnum) // thok barrier is not a sky + HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); + } + else // neither sectors are thok barriers + { + if (((gr_backsector->floorheight > gr_frontsector->floorheight && !gr_sidedef->bottomtexture) // no bottom texture and sector behind is higher + || gr_backsector->floorpic != skyflatnum) // behind sector is not a sky + && ABS(gr_backsector->floorheight - gr_frontsector->floorheight) > FRACUNIT*3/2) // don't draw sky walls for VERY thin differences, this makes for horrible looking slopes sometimes! + HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); } } } -#endif } else { // Single sided line... Deal only with the middletexture (if one exists) gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture); - if (gr_midtexture && gr_linedef->special != HORIZONSPECIAL) // Ignore horizon line for OGL + if (gr_midtexture && gr_linedef->special != 41) // (Ignore horizon line for OGL) { { fixed_t texturevpeg; @@ -1969,9 +1621,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldtop); wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldbottom); #endif - // I don't think that solid walls can use translucent linedef types... + if (gr_frontsector->numlights) HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTLEVEL, NULL); + // I don't think that solid walls can use translucent linedef types... else { if (grTex->mipmap.flags & TF_TRANSPARENT) @@ -1984,33 +1637,14 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (!gr_curline->polyseg) { if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector - { - wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space -#ifdef ESLOPE - wallVerts[0].y = FIXED_TO_FLOAT(worldtop); - wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); -#else - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); -#endif - HWR_DrawSkyWall(wallVerts, &Surf); - } + HWR_DrawSkyWall(wallVerts, &Surf, worldtop, INT32_MAX); if (gr_frontsector->floorpic == skyflatnum) - { -#ifdef ESLOPE - wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); - wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); -#else - wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); -#endif - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space - HWR_DrawSkyWall(wallVerts, &Surf); - } + HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldbottom); } } //Hurdler: 3d-floors test -#ifdef R_FAKEFLOORS if (gr_frontsector && gr_backsector && gr_frontsector->tag != gr_backsector->tag && (gr_backsector->ffloors || gr_frontsector->ffloors)) { ffloor_t * rover; @@ -2153,15 +1787,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) lightnum = rover->master->frontsector->lightlevel; colormap = rover->master->frontsector->extra_colormap; - if (rover->master->frontsector->extra_colormap) - { - - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba); - } - else - { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG); - } + Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); if (gr_frontsector->numlights) HWR_SplitWall(gr_frontsector, wallVerts, 0, &Surf, rover->flags, rover); @@ -2175,7 +1801,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { blendmode = PF_Translucent; - Surf.FlatColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; + Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; } if (gr_frontsector->numlights) @@ -2273,14 +1899,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) lightnum = rover->master->frontsector->lightlevel; colormap = rover->master->frontsector->extra_colormap; - if (rover->master->frontsector->extra_colormap) - { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba); - } - else - { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG); - } + Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); if (gr_backsector->numlights) HWR_SplitWall(gr_backsector, wallVerts, 0, &Surf, rover->flags, rover); @@ -2294,7 +1913,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { blendmode = PF_Translucent; - Surf.FlatColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; + Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; } if (gr_backsector->numlights) @@ -2310,7 +1929,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } } } -#endif //Hurdler: end of 3d-floors test } @@ -3146,7 +2764,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, float scrollx = 0.0f, scrolly = 0.0f; angle_t angle = 0; FSurfaceInfo Surf; - fixed_t tempxsow, tempytow; + fixed_t tempxs, tempyt; size_t nrPlaneVerts; static FOutVector *planeVerts = NULL; @@ -3258,17 +2876,17 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, if (angle) // Only needs to be done if there's an altered angle { // This needs to be done so that it scrolls in a different direction after rotation like software - tempxsow = FLOAT_TO_FIXED(scrollx); - tempytow = FLOAT_TO_FIXED(scrolly); - scrollx = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - scrolly = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); + tempxs = FLOAT_TO_FIXED(scrollx); + tempyt = FLOAT_TO_FIXED(scrolly); + scrollx = (FIXED_TO_FLOAT(FixedMul(tempxs, FINECOSINE(angle)) - FixedMul(tempyt, FINESINE(angle)))); + scrolly = (FIXED_TO_FLOAT(FixedMul(tempxs, FINESINE(angle)) + FixedMul(tempyt, FINECOSINE(angle)))); // This needs to be done so everything aligns after rotation // It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does - tempxsow = FLOAT_TO_FIXED(flatxref); - tempytow = FLOAT_TO_FIXED(flatyref); - flatxref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - flatyref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); + tempxs = FLOAT_TO_FIXED(flatxref); + tempyt = FLOAT_TO_FIXED(flatyref); + flatxref = (FIXED_TO_FLOAT(FixedMul(tempxs, FINECOSINE(angle)) - FixedMul(tempyt, FINESINE(angle)))); + flatyref = (FIXED_TO_FLOAT(FixedMul(tempxs, FINESINE(angle)) + FixedMul(tempyt, FINECOSINE(angle)))); } for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++) @@ -3277,24 +2895,24 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, // Means the flat is offset based on the original vertex locations if (texflat) { - v3d->sow = (float)(FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) + scrollx; - v3d->tow = -(float)(FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly; + v3d->s = (float)(FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) + scrollx; + v3d->t = -(float)(FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly; } else { - v3d->sow = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx); - v3d->tow = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly); + v3d->s = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx); + v3d->t = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly); } // Need to rotate before translate if (angle) // Only needs to be done if there's an altered angle { - tempxsow = FLOAT_TO_FIXED(v3d->sow); - tempytow = FLOAT_TO_FIXED(v3d->tow); + tempxs = FLOAT_TO_FIXED(v3d->s); + tempyt = FLOAT_TO_FIXED(v3d->t); if (texflat) - tempytow = -tempytow; - v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - v3d->tow = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle)))); + tempyt = -tempyt; + v3d->s = (FIXED_TO_FLOAT(FixedMul(tempxs, FINECOSINE(angle)) - FixedMul(tempyt, FINESINE(angle)))); + v3d->t = (FIXED_TO_FLOAT(-FixedMul(tempxs, FINESINE(angle)) - FixedMul(tempyt, FINECOSINE(angle)))); } v3d->x = FIXED_TO_FLOAT(polysector->vertices[i]->x); @@ -3303,19 +2921,17 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, } - if (planecolormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, planecolormap->rgba, planecolormap->fadergba, false, true); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, true); + HWR_Lighting(&Surf, lightlevel, planecolormap); if (blendmode & PF_Translucent) { - Surf.FlatColor.s.alpha = (UINT8)alpha; + Surf.PolyColor.s.alpha = (UINT8)alpha; blendmode |= PF_Modulated|PF_Occlude|PF_Clip; } else blendmode |= PF_Masked|PF_Modulated|PF_Clip; + HWD.pfnSetShader(1); // floor shader HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode); } @@ -3350,7 +2966,7 @@ static void HWR_AddPolyObjectPlanes(void) memset(&Surf, 0x00, sizeof(Surf)); blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); HWR_AddTransparentPolyobjectFloor(&levelflats[polyobjsector->floorpic], po_ptrs[i], false, polyobjsector->floorheight, - (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.FlatColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); + (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.PolyColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } else { @@ -3373,7 +2989,7 @@ static void HWR_AddPolyObjectPlanes(void) memset(&Surf, 0x00, sizeof(Surf)); blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); HWR_AddTransparentPolyobjectFloor(&levelflats[polyobjsector->ceilingpic], po_ptrs[i], true, polyobjsector->ceilingheight, - (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.FlatColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); + (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.PolyColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } else { @@ -3531,11 +3147,11 @@ static void HWR_Subsector(size_t num) if (sub->validcount != validcount) { HWR_GetLevelFlat(&levelflats[gr_frontsector->floorpic]); - HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], false, + HWR_RenderPlane(&extrasubsectors[num], false, // Hack to make things continue to work around slopes. locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, floorlightlevel, &levelflats[gr_frontsector->floorpic], NULL, 255, false, floorcolormap); + PF_Occlude, floorlightlevel, &levelflats[gr_frontsector->floorpic], NULL, 255, floorcolormap); } } else @@ -3553,11 +3169,11 @@ static void HWR_Subsector(size_t num) if (sub->validcount != validcount) { HWR_GetLevelFlat(&levelflats[gr_frontsector->ceilingpic]); - HWR_RenderPlane(NULL, &extrasubsectors[num], true, + HWR_RenderPlane(&extrasubsectors[num], true, // Hack to make things continue to work around slopes. locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, ceilinglightlevel, &levelflats[gr_frontsector->ceilingpic], NULL, 255, false, ceilingcolormap); + PF_Occlude, ceilinglightlevel, &levelflats[gr_frontsector->ceilingpic], NULL, 255, ceilingcolormap); } } else @@ -3610,13 +3226,9 @@ static void HWR_Subsector(size_t num) UINT8 alpha; light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); - if (rover->master->frontsector->extra_colormap) - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba); - else - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); - - HWR_AddTransparentFloor(NULL, + HWR_AddTransparentFloor(0, &extrasubsectors[num], false, *rover->bottomheight, @@ -3627,28 +3239,21 @@ static void HWR_Subsector(size_t num) else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) // SoM: Flags are more efficient { light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); -#ifndef SORTING - HWR_Add3DWater(&levelflats[*rover->bottompic], - &extrasubsectors[num], - *rover->bottomheight, - *gr_frontsector->lightlist[light].lightlevel, - rover->alpha-1, rover->master->frontsector); -#else + HWR_AddTransparentFloor(&levelflats[*rover->bottompic], &extrasubsectors[num], false, *rover->bottomheight, *gr_frontsector->lightlist[light].lightlevel, - rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent, + rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Translucent, false, *gr_frontsector->lightlist[light].extra_colormap); -#endif } else { HWR_GetLevelFlat(&levelflats[*rover->bottompic]); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); - HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic], - rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap); + HWR_RenderPlane(&extrasubsectors[num], false, *rover->bottomheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic], + rover->master->frontsector, 255, *gr_frontsector->lightlist[light].extra_colormap); } } @@ -3673,13 +3278,9 @@ static void HWR_Subsector(size_t num) UINT8 alpha; light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); - if (rover->master->frontsector->extra_colormap) - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba); - else - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); - - HWR_AddTransparentFloor(NULL, + HWR_AddTransparentFloor(0, &extrasubsectors[num], true, *rover->topheight, @@ -3690,29 +3291,21 @@ static void HWR_Subsector(size_t num) else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); -#ifndef SORTING - HWR_Add3DWater(&levelflats[*rover->toppic], - &extrasubsectors[num], - *rover->topheight, - *gr_frontsector->lightlist[light].lightlevel, - rover->alpha-1, rover->master->frontsector); -#else + HWR_AddTransparentFloor(&levelflats[*rover->toppic], &extrasubsectors[num], true, *rover->topheight, *gr_frontsector->lightlist[light].lightlevel, - rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent, + rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Translucent, false, *gr_frontsector->lightlist[light].extra_colormap); -#endif - } else { HWR_GetLevelFlat(&levelflats[*rover->toppic]); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); - HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic], - rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap); + HWR_RenderPlane(&extrasubsectors[num], true, *rover->topheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic], + rover->master->frontsector, 255, *gr_frontsector->lightlist[light].extra_colormap); } } } @@ -3826,7 +3419,7 @@ static void HWR_RenderBSPNode(INT32 bspnum) // Decide which side the view point is on INT32 side = R_PointOnSide(dup_viewx, dup_viewy, bsp); - // Recursively divide front space (toward the viewer) + // Recursively divide front space (tard the viewer) HWR_RenderBSPNode(bsp->children[side]); // Possibly divide back space (away from viewer) @@ -4188,30 +3781,30 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t if (spr->flip) { - swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s; - swallVerts[2].sow = swallVerts[1].sow = 0; + swallVerts[0].s = swallVerts[3].s = gpatch->max_s; + swallVerts[2].s = swallVerts[1].s = 0; } else { - swallVerts[0].sow = swallVerts[3].sow = 0; - swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s; + swallVerts[0].s = swallVerts[3].s = 0; + swallVerts[2].s = swallVerts[1].s = gpatch->max_s; } // flip the texture coords (look familiar?) if (spr->vflip) { - swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t; - swallVerts[0].tow = swallVerts[1].tow = 0; + swallVerts[3].t = swallVerts[2].t = gpatch->max_t; + swallVerts[0].t = swallVerts[1].t = 0; } else { - swallVerts[3].tow = swallVerts[2].tow = 0; - swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t; + swallVerts[3].t = swallVerts[2].t = 0; + swallVerts[0].t = swallVerts[1].t = gpatch->max_t; } - sSurf.FlatColor.s.red = 0x00; - sSurf.FlatColor.s.blue = 0x00; - sSurf.FlatColor.s.green = 0x00; + sSurf.PolyColor.s.red = 0x00; + sSurf.PolyColor.s.blue = 0x00; + sSurf.PolyColor.s.green = 0x00; /*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW) { @@ -4238,27 +3831,28 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t } if (colormap) - sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true); + sSurf.PolyColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true); else - sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true); + sSurf.PolyColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true); }*/ // shadow is always half as translucent as the sprite itself if (!cv_translucency.value) // use default translucency (main sprite won't have any translucency) - sSurf.FlatColor.s.alpha = 0x80; // default + sSurf.PolyColor.s.alpha = 0x80; // default else if (spr->mobj->flags2 & MF2_SHADOW) - sSurf.FlatColor.s.alpha = 0x20; + sSurf.PolyColor.s.alpha = 0x20; else if (spr->mobj->frame & FF_TRANSMASK) { HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf); - sSurf.FlatColor.s.alpha /= 2; //cut alpha in half! + sSurf.PolyColor.s.alpha /= 2; //cut alpha in half! } else - sSurf.FlatColor.s.alpha = 0x80; // default + sSurf.PolyColor.s.alpha = 0x80; // default - if (sSurf.FlatColor.s.alpha > floorheight/4) + if (sSurf.PolyColor.s.alpha > floorheight/4) { - sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4); + sSurf.PolyColor.s.alpha = (UINT8)(sSurf.PolyColor.s.alpha - floorheight/4); + HWD.pfnSetShader(1); // floor shader HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); } } @@ -4313,7 +3907,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) INT32 i; float realtop, realbot, top, bot; - float towtop, towbot, towmult; + float ttop, tbot, tmult; float bheight; float realheight, heightmult; const sector_t *sector = spr->mobj->subsector->sector; @@ -4374,28 +3968,28 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (spr->flip) { - baseWallVerts[0].sow = baseWallVerts[3].sow = gpatch->max_s; - baseWallVerts[2].sow = baseWallVerts[1].sow = 0; + baseWallVerts[0].s = baseWallVerts[3].s = gpatch->max_s; + baseWallVerts[2].s = baseWallVerts[1].s = 0; } else { - baseWallVerts[0].sow = baseWallVerts[3].sow = 0; - baseWallVerts[2].sow = baseWallVerts[1].sow = gpatch->max_s; + baseWallVerts[0].s = baseWallVerts[3].s = 0; + baseWallVerts[2].s = baseWallVerts[1].s = gpatch->max_s; } // flip the texture coords (look familiar?) if (spr->vflip) { - baseWallVerts[3].tow = baseWallVerts[2].tow = gpatch->max_t; - baseWallVerts[0].tow = baseWallVerts[1].tow = 0; + baseWallVerts[3].t = baseWallVerts[2].t = gpatch->max_t; + baseWallVerts[0].t = baseWallVerts[1].t = 0; } else { - baseWallVerts[3].tow = baseWallVerts[2].tow = 0; - baseWallVerts[0].tow = baseWallVerts[1].tow = gpatch->max_t; + baseWallVerts[3].t = baseWallVerts[2].t = 0; + baseWallVerts[0].t = baseWallVerts[1].t = gpatch->max_t; } - // if it has a dispoffset, push it a little towards the camera + // if it has a dispoffset, push it a little tards the camera if (spr->dispoffset) { float co = -gr_viewcos*(0.05f*spr->dispoffset); float si = -gr_viewsin*(0.05f*spr->dispoffset); @@ -4410,9 +4004,9 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) realtop = top = baseWallVerts[3].y; realbot = bot = baseWallVerts[0].y; - towtop = baseWallVerts[3].tow; - towbot = baseWallVerts[0].tow; - towmult = (towbot - towtop) / (top - bot); + ttop = baseWallVerts[3].t; + tbot = baseWallVerts[0].t; + tmult = (tbot - ttop) / (top - bot); #ifdef ESLOPE endrealtop = endtop = baseWallVerts[2].y; @@ -4426,12 +4020,12 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (!cv_translucency.value) // translucency disabled { - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; blend = PF_Translucent|PF_Occlude; } else if (spr->mobj->flags2 & MF2_SHADOW) { - Surf.FlatColor.s.alpha = 0x40; + Surf.PolyColor.s.alpha = 0x40; blend = PF_Translucent; } else if (spr->mobj->frame & FF_TRANSMASK) @@ -4442,11 +4036,11 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) // work properly under glide nor with fogcolor to ffffff :( // Hurdler: PF_Environement would be cool, but we need to fix // the issue with the fog before - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; blend = PF_Translucent|PF_Occlude; } - alpha = Surf.FlatColor.s.alpha; + alpha = Surf.PolyColor.s.alpha; // Start with the lightlevel and colormap from the top of the sprite lightlevel = *list[sector->numlights - 1].lightlevel; @@ -4541,10 +4135,10 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) #endif #ifdef ESLOPE - wallVerts[3].tow = towtop + ((realtop - top) * towmult); - wallVerts[2].tow = towtop + ((endrealtop - endtop) * towmult); - wallVerts[0].tow = towtop + ((realtop - bot) * towmult); - wallVerts[1].tow = towtop + ((endrealtop - endbot) * towmult); + wallVerts[3].t = ttop + ((realtop - top) * tmult); + wallVerts[2].t = ttop + ((endrealtop - endtop) * tmult); + wallVerts[0].t = ttop + ((realtop - bot) * tmult); + wallVerts[1].t = ttop + ((endrealtop - endbot) * tmult); wallVerts[3].y = top; wallVerts[2].y = endtop; @@ -4575,8 +4169,8 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) wallVerts[1].z = baseWallVerts[2].z + (baseWallVerts[2].z - baseWallVerts[1].z) * heightmult; } #else - wallVerts[3].tow = wallVerts[2].tow = towtop + ((realtop - top) * towmult); - wallVerts[0].tow = wallVerts[1].tow = towtop + ((realtop - bot) * towmult); + wallVerts[3].t = wallVerts[2].t = ttop + ((realtop - top) * tmult); + wallVerts[0].t = wallVerts[1].t = ttop + ((realtop - bot) * tmult); wallVerts[2].y = wallVerts[3].y = top; wallVerts[0].y = wallVerts[1].y = bot; @@ -4601,13 +4195,11 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) } #endif - if (colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + HWR_Lighting(&Surf, lightlevel, colormap); - Surf.FlatColor.s.alpha = alpha; + Surf.PolyColor.s.alpha = alpha; + HWD.pfnSetShader(3); // sprite shader HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); top = bot; @@ -4626,30 +4218,28 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) // If we're ever down here, somehow the above loop hasn't draw all the light levels of sprite #ifdef ESLOPE - wallVerts[3].tow = towtop + ((realtop - top) * towmult); - wallVerts[2].tow = towtop + ((endrealtop - endtop) * towmult); - wallVerts[0].tow = towtop + ((realtop - bot) * towmult); - wallVerts[1].tow = towtop + ((endrealtop - endbot) * towmult); + wallVerts[3].t = ttop + ((realtop - top) * tmult); + wallVerts[2].t = ttop + ((endrealtop - endtop) * tmult); + wallVerts[0].t = ttop + ((realtop - bot) * tmult); + wallVerts[1].t = ttop + ((endrealtop - endbot) * tmult); wallVerts[3].y = top; wallVerts[2].y = endtop; wallVerts[0].y = bot; wallVerts[1].y = endbot; #else - wallVerts[3].tow = wallVerts[2].tow = towtop + ((realtop - top) * towmult); - wallVerts[0].tow = wallVerts[1].tow = towtop + ((realtop - bot) * towmult); + wallVerts[3].t = wallVerts[2].t = ttop + ((realtop - top) * tmult); + wallVerts[0].t = wallVerts[1].t = ttop + ((realtop - bot) * tmult); wallVerts[2].y = wallVerts[3].y = top; wallVerts[0].y = wallVerts[1].y = bot; #endif - if (colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + HWR_Lighting(&Surf, lightlevel, colormap); - Surf.FlatColor.s.alpha = alpha; + Surf.PolyColor.s.alpha = alpha; + HWD.pfnSetShader(3); // sprite shader HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); } @@ -4720,21 +4310,21 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) if (spr->flip) { - wallVerts[0].sow = wallVerts[3].sow = gpatch->max_s; - wallVerts[2].sow = wallVerts[1].sow = 0; + wallVerts[0].s = wallVerts[3].s = gpatch->max_s; + wallVerts[2].s = wallVerts[1].s = 0; }else{ - wallVerts[0].sow = wallVerts[3].sow = 0; - wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; + wallVerts[0].s = wallVerts[3].s = 0; + wallVerts[2].s = wallVerts[1].s = gpatch->max_s; } // flip the texture coords (look familiar?) if (spr->vflip) { - wallVerts[3].tow = wallVerts[2].tow = gpatch->max_t; - wallVerts[0].tow = wallVerts[1].tow = 0; + wallVerts[3].t = wallVerts[2].t = gpatch->max_t; + wallVerts[0].t = wallVerts[1].t = 0; }else{ - wallVerts[3].tow = wallVerts[2].tow = 0; - wallVerts[0].tow = wallVerts[1].tow = gpatch->max_t; + wallVerts[3].t = wallVerts[2].t = 0; + wallVerts[0].t = wallVerts[1].t = gpatch->max_t; } // cache the patch in the graphics card memory @@ -4760,7 +4350,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) } #endif //#ifdef GLBADSHADOWS - // if it has a dispoffset, push it a little towards the camera + // if it has a dispoffset, push it a little tards the camera if (spr->dispoffset) { float co = -gr_viewcos*(0.05f*spr->dispoffset); float si = -gr_viewsin*(0.05f*spr->dispoffset); @@ -4786,22 +4376,19 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = sector->lightlevel; - if (colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + HWR_Lighting(&Surf, lightlevel, colormap); } { FBITFIELD blend = 0; if (!cv_translucency.value) // translucency disabled { - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; blend = PF_Translucent|PF_Occlude; } else if (spr->mobj->flags2 & MF2_SHADOW) { - Surf.FlatColor.s.alpha = 0x40; + Surf.PolyColor.s.alpha = 0x40; blend = PF_Translucent; } else if (spr->mobj->frame & FF_TRANSMASK) @@ -4812,10 +4399,11 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // work properly under glide nor with fogcolor to ffffff :( // Hurdler: PF_Environement would be cool, but we need to fix // the issue with the fog before - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; blend = PF_Translucent|PF_Occlude; } + HWD.pfnSetShader(3); // sprite shader HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); } } @@ -4857,11 +4445,11 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) // Let dispoffset work first since this adjust each vertex HWR_RotateSpritePolyToAim(spr, wallVerts); - wallVerts[0].sow = wallVerts[3].sow = 0; - wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; + wallVerts[0].s = wallVerts[3].s = 0; + wallVerts[2].s = wallVerts[1].s = gpatch->max_s; - wallVerts[3].tow = wallVerts[2].tow = 0; - wallVerts[0].tow = wallVerts[1].tow = gpatch->max_t; + wallVerts[3].t = wallVerts[2].t = 0; + wallVerts[0].t = wallVerts[1].t = gpatch->max_t; // cache the patch in the graphics card memory //12/12/99: Hurdler: same comment as above (for md2) @@ -4895,15 +4483,12 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) colormap = sector->extra_colormap; } - if (colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + HWR_Lighting(&Surf, lightlevel, colormap); } if (spr->mobj->flags2 & MF2_SHADOW) { - Surf.FlatColor.s.alpha = 0x40; + Surf.PolyColor.s.alpha = 0x40; blend = PF_Translucent; } else if (spr->mobj->frame & FF_TRANSMASK) @@ -4914,10 +4499,11 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) // work properly under glide nor with fogcolor to ffffff :( // Hurdler: PF_Environement would be cool, but we need to fix // the issue with the fog before - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; blend = PF_Translucent|PF_Occlude; } + HWD.pfnSetShader(3); // sprite shader HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); } #endif @@ -5021,14 +4607,11 @@ static void HWR_SortVisSprites(void) // middle texture. This is used for sorting with sprites. typedef struct { - wallVert3D wallVerts[4]; + FOutVector wallVerts[4]; FSurfaceInfo Surf; INT32 texnum; FBITFIELD blend; INT32 drawcount; -#ifndef SORTING - fixed_t fixedheight; -#endif boolean fogwall; INT32 lightlevel; extracolormap_t *wallcolormap; // Doing the lighting in HWR_RenderWall now for correct fog after sorting @@ -5037,7 +4620,7 @@ typedef struct static wallinfo_t *wallinfo = NULL; static size_t numwalls = 0; // a list of transparent walls to be drawn -static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); +void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); #define MAX_TRANSPARENTWALL 256 @@ -5076,9 +4659,6 @@ typedef struct static size_t numpolyplanes = 0; // a list of transparent poyobject floors to be drawn static polyplaneinfo_t *polyplaneinfo = NULL; -#ifndef SORTING -size_t numfloors = 0; -#else //Hurdler: 3D water sutffs typedef struct gr_drawnode_s { @@ -5096,8 +4676,7 @@ static INT32 drawcount = 0; #define MAX_TRANSPARENTFLOOR 512 // This will likely turn into a copy of HWR_Add3DWater and replace it. -void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, - fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) +void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) { static size_t allocedplanes = 0; @@ -5128,8 +4707,7 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo // Adding this for now until I can create extrasubsector info for polyobjects // When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane -void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, - fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap) +void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap) { static size_t allocedpolyplanes = 0; @@ -5298,8 +4876,10 @@ static void HWR_CreateDrawNodes(void) } //i++ } // loop++ - HWD.pfnSetTransform(&atransform); // Okay! Let's draw it all! Woo! + HWD.pfnSetTransform(&atransform); + HWD.pfnSetShader(0); + for (i = 0; i < p; i++) { if (sortnode[sortindex[i]].plane) @@ -5309,8 +4889,8 @@ static void HWR_CreateDrawNodes(void) if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture)) HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat); - HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, - sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap); + HWR_RenderPlane(sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, + sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->planecolormap); } else if (sortnode[sortindex[i]].polyplane) { @@ -5340,12 +4920,10 @@ static void HWR_CreateDrawNodes(void) Z_Free(sortindex); } -#endif - // -------------------------------------------------------------------------- // Draw all vissprites // -------------------------------------------------------------------------- -#ifdef SORTING + // added the stransform so they can be switched as drawing happenes so MD2s and sprites are sorted correctly with each other static void HWR_DrawSprites(void) { @@ -5386,7 +4964,6 @@ static void HWR_DrawSprites(void) } } } -#endif // -------------------------------------------------------------------------- // HWR_AddSprites @@ -5963,8 +5540,8 @@ static void HWR_DrawSkyBackground(player_t *player) dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); - v[0].sow = v[3].sow = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left - v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f) + v[0].s = v[3].s = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left + v[2].s = v[1].s = v[0].s + (1.0f/dimensionmultiply); // right (or left + 1.0f) // use +angle and -1.0f above instead if you wanted old backwards behavior // Y @@ -5982,13 +5559,13 @@ static void HWR_DrawSkyBackground(player_t *player) if (atransform.flip) { // During vertical flip the sky should be flipped and it's y movement should also be flipped obviously - v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); // top - v[0].tow = v[1].tow = v[3].tow - (1.0f/dimensionmultiply); // bottom (or top - 1.0f) + v[3].t = v[2].t = -(0.5f-(0.5f/dimensionmultiply)); // top + v[0].t = v[1].t = v[3].t - (1.0f/dimensionmultiply); // bottom (or top - 1.0f) } else { - v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); // bottom - v[3].tow = v[2].tow = v[0].tow - (1.0f/dimensionmultiply); // top (or bottom - 1.0f) + v[0].t = v[1].t = -(0.5f-(0.5f/dimensionmultiply)); // bottom + v[3].t = v[2].t = v[0].t - (1.0f/dimensionmultiply); // top (or bottom - 1.0f) } angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply; @@ -5996,16 +5573,18 @@ static void HWR_DrawSkyBackground(player_t *player) if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa { angle = InvAngle(angle); - v[3].tow = v[2].tow += ((float) angle / angleturn); - v[0].tow = v[1].tow += ((float) angle / angleturn); + v[3].t = v[2].t += ((float) angle / angleturn); + v[0].t = v[1].t += ((float) angle / angleturn); } else { - v[3].tow = v[2].tow -= ((float) angle / angleturn); - v[0].tow = v[1].tow -= ((float) angle / angleturn); + v[3].t = v[2].t -= ((float) angle / angleturn); + v[0].t = v[1].t -= ((float) angle / angleturn); } + HWD.pfnSetShader(7); // sky shader HWD.pfnDrawPolygon(NULL, v, 4, 0); + HWD.pfnSetShader(0); } } @@ -6142,6 +5721,18 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) atransform.scalex = 1; atransform.scaley = (float)vid.width/vid.height; atransform.scalez = 1; + + // 14042019 + gr_aimingangle = aimingangle; + atransform.shearing = false; + atransform.viewaiming = aimingangle; + + if (cv_grshearing.value) + { + gr_aimingangle = 0; + atransform.shearing = true; + } + atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails atransform.splitscreen = splitscreen; @@ -6167,13 +5758,12 @@ if (0) HWR_ClearSprites(); -#ifdef SORTING drawcount = 0; -#endif + #ifdef NEWCLIP if (rendermode == render_opengl) { - angle_t a1 = gld_FrustumAngle(); + angle_t a1 = gld_FrustumAngle(gr_aimingangle); gld_clipper_Clear(); gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); #ifdef HAVE_SPHEREFRUSTRUM @@ -6188,6 +5778,10 @@ if (0) // Actually it only works on Walls and Planes HWD.pfnSetTransform(&atransform); + // Reset the shader state. + HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_grshaders.value); + HWD.pfnSetShader(0); + validcount++; HWR_RenderBSPNode((INT32)numnodes-1); @@ -6231,35 +5825,21 @@ if (0) #endif // Draw MD2 and sprites -#ifdef SORTING HWR_SortVisSprites(); -#endif - -#ifdef SORTING HWR_DrawSprites(); -#endif + #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? HWR_DrawCoronas(); #endif -#ifdef SORTING if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything { HWR_CreateDrawNodes(); } -#else - if (numfloors || numwalls) - { - HWD.pfnSetTransform(&atransform); - if (numfloors) - HWR_Render3DWater(); - if (numwalls) - HWR_RenderTransparentWalls(); - } -#endif HWD.pfnSetTransform(NULL); + HWD.pfnUnSetShader(); // put it off for menus etc if (cv_grfog.value) @@ -6362,6 +5942,18 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) atransform.scalex = 1; atransform.scaley = (float)vid.width/vid.height; atransform.scalez = 1; + + // 14042019 + gr_aimingangle = aimingangle; + atransform.shearing = false; + atransform.viewaiming = aimingangle; + + if (cv_grshearing.value) + { + gr_aimingangle = 0; + atransform.shearing = true; + } + atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails atransform.splitscreen = splitscreen; @@ -6387,13 +5979,12 @@ if (0) HWR_ClearSprites(); -#ifdef SORTING drawcount = 0; -#endif + #ifdef NEWCLIP if (rendermode == render_opengl) { - angle_t a1 = gld_FrustumAngle(); + angle_t a1 = gld_FrustumAngle(gr_aimingangle); gld_clipper_Clear(); gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); #ifdef HAVE_SPHEREFRUSTRUM @@ -6408,6 +5999,10 @@ if (0) // Actually it only works on Walls and Planes HWD.pfnSetTransform(&atransform); + // Reset the shader state. + HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_grshaders.value); + HWD.pfnSetShader(0); + validcount++; HWR_RenderBSPNode((INT32)numnodes-1); @@ -6451,35 +6046,21 @@ if (0) #endif // Draw MD2 and sprites -#ifdef SORTING HWR_SortVisSprites(); -#endif - -#ifdef SORTING HWR_DrawSprites(); -#endif + #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? HWR_DrawCoronas(); #endif -#ifdef SORTING if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything { HWR_CreateDrawNodes(); } -#else - if (numfloors || numpolyplanes || numwalls) - { - HWD.pfnSetTransform(&atransform); - if (numfloors) - HWR_Render3DWater(); - if (numwalls) - HWR_RenderTransparentWalls(); - } -#endif HWD.pfnSetTransform(NULL); + HWD.pfnUnSetShader(); // put it off for menus etc if (cv_grfog.value) @@ -6560,8 +6141,9 @@ static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA {0, NULL}}; CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; +consvar_t cv_grshaders = {"gr_shaders", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grfog = {"gr_fog", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6576,6 +6158,7 @@ consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, N consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_grmodellighting_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grshearing = {"gr_shearing", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6647,6 +6230,9 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grskydome); CV_RegisterVar(&cv_grspritebillboarding); + CV_RegisterVar(&cv_grshearing); + CV_RegisterVar(&cv_grshaders); + CV_RegisterVar(&cv_grfiltermode); CV_RegisterVar(&cv_grrounddown); CV_RegisterVar(&cv_grcorrecttricks); @@ -6669,13 +6255,6 @@ void HWR_Startup(void) { static boolean startupdone = false; - // setup GLPatch_t scaling - gr_patch_scalex = (float)(1.0f / vid.width); - gr_patch_scaley = (float)(1.0f / vid.height); - - // initalze light lut translation - InitLumLut(); - // do this once if (!startupdone) { @@ -6693,6 +6272,10 @@ void HWR_Startup(void) textureformat = patchformat = GR_RGBA; startupdone = true; + + // jimita + HWD.pfnKillShaders(); + HWD.pfnLoadShaders(); } @@ -6732,106 +6315,7 @@ void transform(float *cx, float *cy, float *cz) *cx *= gr_fovlud; } - -//Hurdler: 3D Water stuff -#ifndef SORTING - -#define MAX_3DWATER 512 - -static void HWR_Add3DWater(levelflat_t *levelflat, extrasubsector_t *xsub, - fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector) -{ - static size_t allocedplanes = 0; - - // Force realloc if buffer has been freed - if (!planeinfo) - allocedplanes = 0; - - if (allocedplanes < numfloors + 1) - { - allocedplanes += MAX_3DWATER; - Z_Realloc(planeinfo, allocedplanes * sizeof (*planeinfo), PU_LEVEL, &planeinfo); - } - planeinfo[numfloors].fixedheight = fixedheight; - planeinfo[numfloors].lightlevel = lightlevel; - planeinfo[numfloors].levelflat = levelflat; - planeinfo[numfloors].xsub = xsub; - planeinfo[numfloors].alpha = alpha; - planeinfo[numfloors].FOFSector = FOFSector; - numfloors++; -} - -#define DIST_PLANE(i) ABS(planeinfo[(i)].fixedheight-dup_viewz) - -static void HWR_QuickSortPlane(INT32 start, INT32 finish) -{ - INT32 left = start; - INT32 right = finish; - INT32 starterval = (INT32)((right+left)/2); //pick a starter - - planeinfo_t temp; - - //'sort of sort' the two halves of the data list about starterval - while (right > left); - { - while (DIST_PLANE(left) < DIST_PLANE(starterval)) left++; //attempt to find a bigger value on the left - while (DIST_PLANE(right) > DIST_PLANE(starterval)) right--; //attempt to find a smaller value on the right - - if (left < right) //if we haven't gone too far - { - //switch them - M_Memcpy(&temp, &planeinfo[left], sizeof (planeinfo_t)); - M_Memcpy(&planeinfo[left], &planeinfo[right], sizeof (planeinfo_t)); - M_Memcpy(&planeinfo[right], &temp, sizeof (planeinfo_t)); - //move the bounds - left++; - right--; - } - } - - if (start < right) HWR_QuickSortPlane(start, right); - if (left < finish) HWR_QuickSortPlane(left, finish); -} - -static void HWR_Render3DWater(void) -{ - size_t i; - - //bubble sort 3D Water for correct alpha blending - { - boolean permut = true; - while (permut) - { - size_t j; - for (j = 0, permut= false; j < numfloors-1; j++) - { - if (ABS(planeinfo[j].fixedheight-dup_viewz) < ABS(planeinfo[j+1].fixedheight-dup_viewz)) - { - planeinfo_t temp; - M_Memcpy(&temp, &planeinfo[j+1], sizeof (planeinfo_t)); - M_Memcpy(&planeinfo[j+1], &planeinfo[j], sizeof (planeinfo_t)); - M_Memcpy(&planeinfo[j], &temp, sizeof (planeinfo_t)); - permut = true; - } - } - } - } -#if 0 //thanks epat, but it's goes looping forever on CTF map Silver Cascade Zone - HWR_QuickSortPlane(0, numplanes-1); -#endif - - gr_frontsector = NULL; //Hurdler: gr_fronsector is no longer valid - for (i = 0; i < numfloors; i++) - { - HWR_GetLevelFlat(planeinfo[i].levelflat); - HWR_RenderPlane(NULL, planeinfo[i].xsub, planeinfo[i].isceiling, planeinfo[i].fixedheight, PF_Translucent, planeinfo[i].lightlevel, planeinfo[i].levelflat, - planeinfo[i].FOFSector, planeinfo[i].alpha, planeinfo[i].fogplane, planeinfo[i].planecolormap); - } - numfloors = 0; -} -#endif - -static void HWR_AddTransparentWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) +void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) { static size_t allocedwalls = 0; @@ -6849,103 +6333,41 @@ static void HWR_AddTransparentWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, I M_Memcpy(&wallinfo[numwalls].Surf, pSurf, sizeof (FSurfaceInfo)); wallinfo[numwalls].texnum = texnum; wallinfo[numwalls].blend = blend; -#ifdef SORTING wallinfo[numwalls].drawcount = drawcount++; -#endif wallinfo[numwalls].fogwall = fogwall; wallinfo[numwalls].lightlevel = lightlevel; wallinfo[numwalls].wallcolormap = wallcolormap; numwalls++; } -#ifndef SORTING -static void HWR_RenderTransparentWalls(void) +void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) { - size_t i; - - /*{ // sorting is disbale for now, do it! - INT32 permut = 1; - while (permut) - { - INT32 j; - for (j = 0, permut = 0; j < numwalls-1; j++) - { - if (ABS(wallinfo[j].fixedheight-dup_viewz) < ABS(wallinfo[j+1].fixedheight-dup_viewz)) - { - wallinfo_t temp; - M_Memcpy(&temp, &wallinfo[j+1], sizeof (wallinfo_t)); - M_Memcpy(&wallinfo[j+1], &wallinfo[j], sizeof (wallinfo_t)); - M_Memcpy(&wallinfo[j], &temp, sizeof (wallinfo_t)); - permut = 1; - } - } - } - }*/ - - for (i = 0; i < numwalls; i++) - { - HWR_GetTexture(wallinfo[i].texnum); - HWR_RenderWall(wallinfo[i].wallVerts, &wallinfo[i].Surf, wallinfo[i].blend, wallinfo[i].wall->fogwall, wallinfo[i].wall->lightlevel, wallinfo[i].wall->wallcolormap); - } - numwalls = 0; -} -#endif - -static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) -{ - FOutVector trVerts[4]; - UINT8 i; - FOutVector *wv; - UINT8 alpha; - - // transform - wv = trVerts; - // it sounds really stupid to do this conversion with the new T&L code - // we should directly put the right information in the right structure - // wallVerts3D seems ok, doesn't need FOutVector - // also remove the light copy - for (i = 0; i < 4; i++, wv++, wallVerts++) - { - wv->sow = wallVerts->s; - wv->tow = wallVerts->t; - wv->x = wallVerts->x; - wv->y = wallVerts->y; - wv->z = wallVerts->z; - } - - alpha = pSurf->FlatColor.s.alpha; // retain the alpha + FBITFIELD blendmode = blend; + UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha // Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting - if (wallcolormap) - { - if (fogwall) - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, wallcolormap->rgba, wallcolormap->fadergba, true, false); - else - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, wallcolormap->rgba, wallcolormap->fadergba, false, false); - } - else - { - if (fogwall) - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, true, false); - else - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); - } + HWR_Lighting(pSurf, lightlevel, wallcolormap); - pSurf->FlatColor.s.alpha = alpha; // put the alpha back after lighting + pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting + + HWD.pfnSetShader(2); // wall shader if (blend & PF_Environment) - HWD.pfnDrawPolygon(pSurf, trVerts, 4, blend|PF_Modulated|PF_Clip|PF_Occlude); // PF_Occlude must be used for solid objects - else - HWD.pfnDrawPolygon(pSurf, trVerts, 4, blend|PF_Modulated|PF_Clip); // No PF_Occlude means overlapping (incorrect) transparency + blendmode |= PF_Occlude; // PF_Occlude must be used for solid objects + + if (fogwall) + { + blendmode |= PF_Fog; + HWD.pfnSetShader(6); // fog shader + } + + blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency + + HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode); #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) HWR_DrawSegsSplats(pSurf); - -#ifdef ALAM_LIGHTING - //Hurdler: TODO: do static lighting using gr_curline->lm - HWR_WallLighting(trVerts); -#endif #endif } @@ -6958,6 +6380,8 @@ void HWR_DoPostProcessor(player_t *player) { postimg_t *type; + HWD.pfnUnSetShader(); + if (splitscreen && player == &players[secondarydisplayplayer]) type = &postimgtype2; else @@ -6977,13 +6401,13 @@ void HWR_DoPostProcessor(player_t *player) // This won't change if the flash palettes are changed unfortunately, but it works for its purpose if (player->flashpal == PAL_NUKE) { - Surf.FlatColor.s.red = 0xff; - Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0x7F; // The nuke palette is kind of pink-ish + Surf.PolyColor.s.red = 0xff; + Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0x7F; // The nuke palette is kind of pink-ish } else - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; + Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff; - Surf.FlatColor.s.alpha = 0xc0; // match software mode + Surf.PolyColor.s.alpha = 0xc0; // match software mode HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Additive|PF_NoTexture|PF_NoDepthTest|PF_Clip|PF_NoZClip); } @@ -7117,4 +6541,161 @@ void HWR_DrawScreenFinalTexture(int width, int height) HWD.pfnDrawScreenFinalTexture(width, height); } +// jimita 18032019 +typedef struct +{ + char type[16]; + INT32 id; +} shaderxlat_t; + +static inline UINT16 HWR_CheckShader(UINT16 wadnum) +{ + UINT16 i; + lumpinfo_t *lump_p; + + lump_p = wadfiles[wadnum]->lumpinfo; + for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lump_p++) + if (memcmp(lump_p->name, "SHADERS", 7) == 0) + return i; + + return INT16_MAX; +} + +void HWR_LoadShaders(UINT16 wadnum, boolean PK3) +{ + UINT16 lump; + char *shaderdef, *line; + char *stoken; + char *value; + size_t size; + int linenum = 1; + int shadertype = 0; + int i; + + #define SHADER_TYPES 7 + shaderxlat_t shaderxlat[SHADER_TYPES] = + { + {"Flat", 1}, + {"WallTexture", 2}, + {"Sprite", 3}, + {"Model", 4}, + {"WaterRipple", 5}, + {"Fog", 6}, + {"Sky", 7}, + }; + + lump = HWR_CheckShader(wadnum); + if (lump == INT16_MAX) + return; + + shaderdef = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); + size = W_LumpLengthPwad(wadnum, lump); + + line = Z_Malloc(size+1, PU_STATIC, NULL); + if (!line) + I_Error("HWR_LoadShaders: No more free memory\n"); + + M_Memcpy(line, shaderdef, size); + line[size] = '\0'; + + stoken = strtok(line, "\r\n "); + while (stoken) + { + if ((stoken[0] == '/' && stoken[1] == '/') + || (stoken[0] == '#'))// skip comments + { + stoken = strtok(NULL, "\r\n"); + goto skip_field; + } + + if (!stricmp(stoken, "GLSL")) + { + value = strtok(NULL, "\r\n "); + if (!value) + { + CONS_Alert(CONS_WARNING, "HWR_LoadShaders: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + stoken = strtok(NULL, "\r\n"); // skip end of line + goto skip_lump; + } + + if (!stricmp(value, "VERTEX")) + shadertype = 1; + else if (!stricmp(value, "FRAGMENT")) + shadertype = 2; + +skip_lump: + stoken = strtok(NULL, "\r\n "); + linenum++; + } + else + { + value = strtok(NULL, "\r\n= "); + if (!value) + { + CONS_Alert(CONS_WARNING, "HWR_LoadShaders: Missing shader target (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + stoken = strtok(NULL, "\r\n"); // skip end of line + goto skip_field; + } + + if (!shadertype) + { + CONS_Alert(CONS_ERROR, "HWR_LoadShaders: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + Z_Free(line); + return; + } + + for (i = 0; i < SHADER_TYPES; i++) + { + if (!stricmp(shaderxlat[i].type, stoken)) + { + size_t shader_size; + char *shader_source; + char *shader_lumpname; + UINT16 shader_lumpnum; + + if (PK3) + { + shader_lumpname = Z_Malloc(strlen(value) + 12, PU_STATIC, NULL); + strcpy(shader_lumpname, "Shaders/sh_"); + strcat(shader_lumpname, value); + shader_lumpnum = W_CheckNumForFullNamePK3(shader_lumpname, wadnum, 0); + } + else + { + shader_lumpname = Z_Malloc(strlen(value) + 4, PU_STATIC, NULL); + strcpy(shader_lumpname, "SH_"); + strcat(shader_lumpname, value); + shader_lumpnum = W_CheckNumForNamePwad(shader_lumpname, wadnum, 0); + } + + if (shader_lumpnum == INT16_MAX) + { + CONS_Alert(CONS_ERROR, "HWR_LoadShaders: Missing shader source %s (file %s, line %d)\n", shader_lumpname, wadfiles[wadnum]->filename, linenum); + Z_Free(shader_lumpname); + continue; + } + + shader_size = W_LumpLengthPwad(wadnum, shader_lumpnum); + shader_source = Z_Malloc(shader_size, PU_STATIC, NULL); + W_ReadLumpPwad(wadnum, shader_lumpnum, shader_source); + + HWD.pfnLoadCustomShader(shaderxlat[i].id, shader_source, shader_size, (shadertype == 2)); + + Z_Free(shader_source); + Z_Free(shader_lumpname); + } + } + +skip_field: + stoken = strtok(NULL, "\r\n= "); + linenum++; + } + } + + HWD.pfnInitCustomShaders(); + + Z_Free(line); + return; +} + #endif // HWRENDER diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index e46aa9801..2b008a3ca 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -72,8 +72,10 @@ void HWR_MakeScreenFinalTexture(void); void HWR_DrawScreenFinalTexture(int width, int height); // This stuff is put here so MD2's can use them -UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane); -FUNCMATH UINT8 LightLevelToLum(INT32 l); +void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap); +UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work + +void HWR_LoadShaders(UINT16 wadnum, boolean PK3); extern CV_PossibleValue_t granisotropicmode_cons_t[]; @@ -83,6 +85,7 @@ extern consvar_t cv_grstaticlighting; extern consvar_t cv_grcoronas; extern consvar_t cv_grcoronasize; #endif +extern consvar_t cv_grshaders; extern consvar_t cv_grfov; extern consvar_t cv_grmodels; extern consvar_t cv_grmodelinterpolation; @@ -96,6 +99,7 @@ extern consvar_t cv_granisotropicmode; extern consvar_t cv_grcorrecttricks; extern consvar_t cv_grfovchange; extern consvar_t cv_grsolvetjoin; +extern consvar_t cv_grshearing; extern consvar_t cv_grspritebillboarding; extern consvar_t cv_grskydome; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 13ba007ee..83df59627 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1084,15 +1084,14 @@ static UINT8 HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t boolean HWR_DrawModel(gr_vissprite_t *spr) { - FSurfaceInfo Surf; + md2_t *md2; char filename[64]; INT32 frame = 0; INT32 nextFrame = -1; UINT8 spr2 = 0; FTransform p; - md2_t *md2; - UINT8 color[4]; + FSurfaceInfo Surf; if (!cv_grmodels.value) return false; @@ -1131,13 +1130,10 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) colormap = sector->extra_colormap; } - if (colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + HWR_Lighting(&Surf, lightlevel, colormap); } else - Surf.FlatColor.rgba = 0xFFFFFFFF; + Surf.PolyColor.rgba = 0xFFFFFFFF; // Look at HWR_ProjectSprite for more { @@ -1160,11 +1156,11 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) //durs = tics; if (spr->mobj->flags2 & MF2_SHADOW) - Surf.FlatColor.s.alpha = 0x40; + Surf.PolyColor.s.alpha = 0x40; else if (spr->mobj->frame & FF_TRANSMASK) HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); else - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; // dont forget to enabled the depth test because we can't do this like // before: polygons models are not sorted @@ -1428,11 +1424,6 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) } #endif - color[0] = Surf.FlatColor.s.red; - color[1] = Surf.FlatColor.s.green; - color[2] = Surf.FlatColor.s.blue; - color[3] = Surf.FlatColor.s.alpha; - // SRB2CBTODO: MD2 scaling support finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); @@ -1441,7 +1432,8 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) p.mirror = atransform.mirror; // from Kart #endif - HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color); + HWD.pfnSetShader(4); // model shader + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, &Surf); } return true; diff --git a/src/hardware/r_opengl/ogl_win.c b/src/hardware/r_opengl/ogl_win.c index e4a71734b..c9bf60144 100644 --- a/src/hardware/r_opengl/ogl_win.c +++ b/src/hardware/r_opengl/ogl_win.c @@ -206,7 +206,7 @@ int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepth if (iLastPFD) { - DBG_Printf("WARNING : SetPixelFormat() called twise not supported by all drivers !\n"); + GL_DBG_Printf("WARNING : SetPixelFormat() called twise not supported by all drivers !\n"); } // set the pixel format only if different than the current @@ -215,17 +215,17 @@ int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepth else iLastPFD = iPFD; - DBG_Printf("SetupPixelFormat() - %d ColorBits - %d StencilBits - %d DepthBits\n", + GL_DBG_Printf("SetupPixelFormat() - %d ColorBits - %d StencilBits - %d DepthBits\n", WantColorBits, WantStencilBits, WantDepthBits); nPixelFormat = ChoosePixelFormat(hDC, &pfd); if (nPixelFormat == 0) - DBG_Printf("ChoosePixelFormat() FAILED\n"); + GL_DBG_Printf("ChoosePixelFormat() FAILED\n"); if (SetPixelFormat(hDC, nPixelFormat, &pfd) == 0) { - DBG_Printf("SetPixelFormat() FAILED\n"); + GL_DBG_Printf("SetPixelFormat() FAILED\n"); return 0; } @@ -243,7 +243,7 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode) BOOL WantFullScreen = !(lvid->u.windowed); //(lvid->u.windowed ? 0 : CDS_FULLSCREEN); UNREFERENCED_PARAMETER(pcurrentmode); - DBG_Printf ("SetMode(): %dx%d %d bits (%s)\n", + GL_DBG_Printf ("SetMode(): %dx%d %d bits (%s)\n", lvid->width, lvid->height, lvid->bpp*8, WantFullScreen ? "fullscreen" : "windowed"); @@ -301,7 +301,7 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode) hDC = GetDC(hWnd); if (!hDC) { - DBG_Printf("GetDC() FAILED\n"); + GL_DBG_Printf("GetDC() FAILED\n"); return 0; } @@ -321,12 +321,12 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode) hGLRC = pwglCreateContext(hDC); if (!hGLRC) { - DBG_Printf("pwglCreateContext() FAILED\n"); + GL_DBG_Printf("pwglCreateContext() FAILED\n"); return 0; } if (!pwglMakeCurrent(hDC, hGLRC)) { - DBG_Printf("wglMakeCurrent() FAILED\n"); + GL_DBG_Printf("wglMakeCurrent() FAILED\n"); return 0; } } @@ -337,15 +337,15 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode) //BP: why don't we make it earlier ? //Hurdler: we cannot do that before intialising gl context renderer = (LPCSTR)pglGetString(GL_RENDERER); - DBG_Printf("Vendor : %s\n", pglGetString(GL_VENDOR)); - DBG_Printf("Renderer : %s\n", renderer); - DBG_Printf("Version : %s\n", pglGetString(GL_VERSION)); - DBG_Printf("Extensions : %s\n", gl_extensions); + GL_DBG_Printf("Vendor : %s\n", pglGetString(GL_VENDOR)); + GL_DBG_Printf("Renderer : %s\n", renderer); + GL_DBG_Printf("Version : %s\n", pglGetString(GL_VERSION)); + GL_DBG_Printf("Extensions : %s\n", gl_extensions); // BP: disable advenced feature that don't work on somes hardware // Hurdler: Now works on G400 with bios 1.6 and certified drivers 6.04 if (strstr(renderer, "810")) oglflags |= GLF_NOZBUFREAD; - DBG_Printf("oglflags : 0x%X\n", oglflags); + GL_DBG_Printf("oglflags : 0x%X\n", oglflags); #ifdef USE_WGL_SWAP if (isExtAvailable("WGL_EXT_swap_control",gl_extensions)) @@ -386,7 +386,7 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode) // -----------------+ static void UnSetRes(void) { - DBG_Printf("UnSetRes()\n"); + GL_DBG_Printf("UnSetRes()\n"); pwglMakeCurrent(hDC, NULL); pwglDeleteContext(hGLRC); @@ -437,7 +437,7 @@ EXPORT void HWRAPI(GetModeList) (vmode_t** pvidmodes, INT32 *numvidmodes) video_modes[iMode].misc = 0; video_modes[iMode].name = malloc(12 * sizeof (CHAR)); sprintf(video_modes[iMode].name, "%dx%d", (INT32)Tmp.dmPelsWidth, (INT32)Tmp.dmPelsHeight); - DBG_Printf ("Mode: %s\n", video_modes[iMode].name); + GL_DBG_Printf ("Mode: %s\n", video_modes[iMode].name); video_modes[iMode].width = Tmp.dmPelsWidth; video_modes[iMode].height = Tmp.dmPelsHeight; video_modes[iMode].bytesperpixel = Tmp.dmBitsPerPel/8; @@ -474,7 +474,7 @@ EXPORT void HWRAPI(GetModeList) (vmode_t** pvidmodes, INT32 *numvidmodes) HDC bpphdc; INT32 iBitsPerPel; - DBG_Printf ("HWRAPI GetModeList()\n"); + GL_DBG_Printf ("HWRAPI GetModeList()\n"); bpphdc = GetDC(NULL); // on obtient le bpp actuel iBitsPerPel = GetDeviceCaps(bpphdc, BITSPIXEL); @@ -490,7 +490,7 @@ EXPORT void HWRAPI(GetModeList) (vmode_t** pvidmodes, INT32 *numvidmodes) video_modes[i].misc = 0; video_modes[i].name = malloc(12 * sizeof (CHAR)); sprintf(video_modes[i].name, "%dx%d", res[i][0], res[i][1]); - DBG_Printf ("Mode: %s\n", video_modes[i].name); + GL_DBG_Printf ("Mode: %s\n", video_modes[i].name); video_modes[i].width = res[i][0]; video_modes[i].height = res[i][1]; video_modes[i].bytesperpixel = iBitsPerPel/8; @@ -511,9 +511,9 @@ EXPORT void HWRAPI(Shutdown) (void) #ifdef DEBUG_TO_FILE long nb_centiemes; - DBG_Printf ("HWRAPI Shutdown()\n"); + GL_DBG_Printf ("HWRAPI Shutdown()\n"); nb_centiemes = ((clock()-my_clock)*100)/CLOCKS_PER_SEC; - DBG_Printf("Nb frames: %li; Nb sec: %2.2f -> %2.1f fps\n", + GL_DBG_Printf("Nb frames: %li; Nb sec: %2.2f -> %2.1f fps\n", nb_frames, nb_centiemes/100.0f, (100*nb_frames)/(double)nb_centiemes); #endif @@ -530,7 +530,7 @@ EXPORT void HWRAPI(Shutdown) (void) } FreeLibrary(GLU32); FreeLibrary(OGL32); - DBG_Printf ("HWRAPI Shutdown(DONE)\n"); + GL_DBG_Printf ("HWRAPI Shutdown(DONE)\n"); } // -----------------+ @@ -543,7 +543,7 @@ EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl) #else UNREFERENCED_PARAMETER(waitvbl); #endif - // DBG_Printf ("FinishUpdate()\n"); + // GL_DBG_Printf ("FinishUpdate()\n"); #ifdef DEBUG_TO_FILE if ((++nb_frames)==2) // on ne commence pas � la premi�re frame my_clock = clock(); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 129bf5678..6997ebcfe 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -49,7 +49,7 @@ static const GLubyte white[4] = { 255, 255, 255, 255 }; // ========================================================================== // With OpenGL 1.1+, the first texture should be 1 -#define NOTEXTURE_NUM 1 // small white texture +#define NOTEXTURE_NUM 0 // small white texture #define FIRST_TEX_AVAIL (NOTEXTURE_NUM + 1) #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) @@ -66,10 +66,6 @@ static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; static GLuint NextTexAvail = FIRST_TEX_AVAIL; static GLuint tex_downloaded = 0; static GLfloat fov = 90.0f; -#if 0 -static GLuint pal_col = 0; -static FRGBAFloat const_pal_col; -#endif static FBITFIELD CurrentPolyFlags; static FTextureInfo* gr_cachetail = NULL; @@ -87,12 +83,19 @@ static GLint mag_filter = GL_LINEAR; static GLint anisotropic_filter = 0; static boolean model_lighting = true; +const GLubyte *gl_version = NULL; +const GLubyte *gl_renderer = NULL; const GLubyte *gl_extensions = NULL; //Hurdler: 04/10/2000: added for the kick ass coronas as Boris wanted;-) -static GLfloat modelMatrix[16]; -static GLfloat projMatrix[16]; -static GLint viewport[4]; +static GLfloat modelMatrix[16]; +static GLfloat projMatrix[16]; +static GLint viewport[4]; + +#ifdef USE_PALETTED_TEXTURE + PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL; + GLubyte palette_tex[256*3]; +#endif // Yay for arbitrary numbers! NextTexAvail is buggy for some reason. // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing @@ -108,9 +111,6 @@ static GLuint screentexture = 0; static GLuint startScreenWipe = 0; static GLuint endScreenWipe = 0; static GLuint finalScreenTexture = 0; -#if 0 -GLuint screentexture = FIRST_TEX_AVAIL; -#endif // shortcut for ((float)1/i) static const GLfloat byte2float[256] = { @@ -148,31 +148,32 @@ static const GLfloat byte2float[256] = { 0.972549f, 0.976471f, 0.980392f, 0.984314f, 0.988235f, 0.992157f, 0.996078f, 1.000000f }; -float byteasfloat(UINT8 fbyte) -{ - return (float)(byte2float[fbyte]*2.0f); -} - -static I_Error_t I_Error_GL = NULL; - // -----------------+ -// DBG_Printf : Output error messages to debug log if DEBUG_TO_FILE is defined, +// GL_DBG_Printf : Output debug messages to debug log if DEBUG_TO_FILE is defined, // : else do nothing // Returns : // -----------------+ -FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) + +#ifdef DEBUG_TO_FILE +FILE *gllogstream; +#endif + +FUNCPRINTF void GL_DBG_Printf(const char *format, ...) { #ifdef DEBUG_TO_FILE - char str[4096] = ""; + char str[4096] = ""; va_list arglist; - va_start (arglist, lpFmt); - vsnprintf (str, 4096, lpFmt, arglist); - va_end (arglist); - if (gllogstream) - fwrite(str, strlen(str), 1, gllogstream); + if (!gllogstream) + gllogstream = fopen("ogllog.txt", "w"); + + va_start(arglist, format); + vsnprintf(str, 4096, format, arglist); + va_end(arglist); + + fwrite(str, strlen(str), 1, gllogstream); #else - (void)lpFmt; + (void)format; #endif } @@ -227,6 +228,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglLightfv glLightfv #define pglLightModelfv glLightModelfv #define pglMaterialfv glMaterialfv +#define pglMateriali glMateriali /* Raster functions */ #define pglPixelStorei glPixelStorei @@ -243,6 +245,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) /* 1.1 functions */ /* texture objects */ //GL_EXT_texture_object +#define pglGenTextures glGenTextures #define pglDeleteTextures glDeleteTextures #define pglBindTexture glBindTexture /* texture mapping */ //GL_EXT_copy_texture @@ -255,7 +258,6 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) /* Miscellaneous */ typedef void (APIENTRY * PFNglClearColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); static PFNglClearColor pglClearColor; -//glClear typedef void (APIENTRY * PFNglColorMask) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); static PFNglColorMask pglColorMask; typedef void (APIENTRY * PFNglAlphaFunc) (GLenum func, GLclampf ref); @@ -274,8 +276,6 @@ typedef void (APIENTRY * PFNglDisable) (GLenum cap); static PFNglDisable pglDisable; typedef void (APIENTRY * PFNglGetFloatv) (GLenum pname, GLfloat *params); static PFNglGetFloatv pglGetFloatv; -//glGetIntegerv -//glGetString /* Depth Buffer */ typedef void (APIENTRY * PFNglClearDepth) (GLclampd depth); @@ -336,6 +336,8 @@ typedef void (APIENTRY * PFNglLightModelfv) (GLenum pname, GLfloat *params); static PFNglLightModelfv pglLightModelfv; typedef void (APIENTRY * PFNglMaterialfv) (GLint face, GLenum pname, GLfloat *params); static PFNglMaterialfv pglMaterialfv; +typedef void (APIENTRY * PFNglMateriali) (GLint face, GLenum pname, GLint param); +static PFNglMateriali pglMateriali; /* Raster functions */ typedef void (APIENTRY * PFNglPixelStorei) (GLenum pname, GLint param); @@ -359,6 +361,8 @@ static PFNglFogfv pglFogfv; /* 1.1 functions */ /* texture objects */ //GL_EXT_texture_object +typedef void (APIENTRY * PFNglGenTextures) (GLsizei n, const GLuint *textures); +static PFNglGenTextures pglGenTextures; typedef void (APIENTRY * PFNglDeleteTextures) (GLsizei n, const GLuint *textures); static PFNglDeleteTextures pglDeleteTextures; typedef void (APIENTRY * PFNglBindTexture) (GLenum target, GLuint texture); @@ -429,7 +433,7 @@ boolean SetupGLfunc(void) func = GetGLFunc(#proc); \ if (!func) \ { \ - DBG_Printf("failed to get OpenGL function: %s", #proc); \ + GL_DBG_Printf("failed to get OpenGL function: %s", #proc); \ } \ GETOPENGLFUNC(pglClearColor, glClearColor) @@ -447,22 +451,23 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglGetIntegerv, glGetIntegerv) GETOPENGLFUNC(pglGetString, glGetString) - GETOPENGLFUNC(pglClearDepth , glClearDepth) - GETOPENGLFUNC(pglDepthFunc , glDepthFunc) - GETOPENGLFUNC(pglDepthMask , glDepthMask) - GETOPENGLFUNC(pglDepthRange , glDepthRange) + GETOPENGLFUNC(pglClearDepth, glClearDepth) + GETOPENGLFUNC(pglDepthFunc, glDepthFunc) + GETOPENGLFUNC(pglDepthMask, glDepthMask) + GETOPENGLFUNC(pglDepthRange, glDepthRange) - GETOPENGLFUNC(pglMatrixMode , glMatrixMode) - GETOPENGLFUNC(pglViewport , glViewport) - GETOPENGLFUNC(pglPushMatrix , glPushMatrix) - GETOPENGLFUNC(pglPopMatrix , glPopMatrix) - GETOPENGLFUNC(pglLoadIdentity , glLoadIdentity) - GETOPENGLFUNC(pglMultMatrixf , glMultMatrixf) - GETOPENGLFUNC(pglRotatef , glRotatef) - GETOPENGLFUNC(pglScalef , glScalef) - GETOPENGLFUNC(pglTranslatef , glTranslatef) + GETOPENGLFUNC(pglMatrixMode, glMatrixMode) + GETOPENGLFUNC(pglViewport, glViewport) + GETOPENGLFUNC(pglPushMatrix, glPushMatrix) + GETOPENGLFUNC(pglPopMatrix, glPopMatrix) + GETOPENGLFUNC(pglLoadIdentity, glLoadIdentity) + GETOPENGLFUNC(pglMultMatrixf, glMultMatrixf) + GETOPENGLFUNC(pglRotatef, glRotatef) + GETOPENGLFUNC(pglScalef, glScalef) + GETOPENGLFUNC(pglTranslatef, glTranslatef) GETOPENGLFUNC(pglColor4ubv, glColor4ubv) + GETOPENGLFUNC(pglVertexPointer, glVertexPointer) GETOPENGLFUNC(pglNormalPointer, glNormalPointer) GETOPENGLFUNC(pglTexCoordPointer, glTexCoordPointer) @@ -472,38 +477,288 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglEnableClientState, glEnableClientState) GETOPENGLFUNC(pglDisableClientState, glDisableClientState) - GETOPENGLFUNC(pglShadeModel , glShadeModel) + GETOPENGLFUNC(pglShadeModel, glShadeModel) GETOPENGLFUNC(pglLightfv, glLightfv) - GETOPENGLFUNC(pglLightModelfv , glLightModelfv) - GETOPENGLFUNC(pglMaterialfv , glMaterialfv) + GETOPENGLFUNC(pglLightModelfv, glLightModelfv) + GETOPENGLFUNC(pglMaterialfv, glMaterialfv) + GETOPENGLFUNC(pglMateriali, glMateriali) - GETOPENGLFUNC(pglPixelStorei , glPixelStorei) - GETOPENGLFUNC(pglReadPixels , glReadPixels) + GETOPENGLFUNC(pglPixelStorei, glPixelStorei) + GETOPENGLFUNC(pglReadPixels, glReadPixels) - GETOPENGLFUNC(pglTexEnvi , glTexEnvi) - GETOPENGLFUNC(pglTexParameteri , glTexParameteri) - GETOPENGLFUNC(pglTexImage2D , glTexImage2D) + GETOPENGLFUNC(pglTexEnvi, glTexEnvi) + GETOPENGLFUNC(pglTexParameteri, glTexParameteri) + GETOPENGLFUNC(pglTexImage2D, glTexImage2D) - GETOPENGLFUNC(pglFogf , glFogf) - GETOPENGLFUNC(pglFogfv , glFogfv) + GETOPENGLFUNC(pglFogf, glFogf) + GETOPENGLFUNC(pglFogfv, glFogfv) - GETOPENGLFUNC(pglDeleteTextures , glDeleteTextures) - GETOPENGLFUNC(pglBindTexture , glBindTexture) + GETOPENGLFUNC(pglGenTextures, glGenTextures) + GETOPENGLFUNC(pglDeleteTextures, glDeleteTextures) + GETOPENGLFUNC(pglBindTexture, glBindTexture) - GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D) - GETOPENGLFUNC(pglCopyTexSubImage2D , glCopyTexSubImage2D) + GETOPENGLFUNC(pglCopyTexImage2D, glCopyTexImage2D) + GETOPENGLFUNC(pglCopyTexSubImage2D, glCopyTexSubImage2D) #undef GETOPENGLFUNC - pgluBuild2DMipmaps = GetGLFunc("gluBuild2DMipmaps"); - #endif return true; } -// This has to be done after the context is created so the version number can be obtained -// This is stupid -- even some of the oldest usable OpenGL hardware today supports 1.3-level featureset. -boolean SetupGLFunc13(void) +INT32 gl_leveltime = 0; + +#ifdef GL_SHADERS +typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum); +typedef void (APIENTRY *PFNglShaderSource) (GLuint, GLsizei, const GLchar**, GLint*); +typedef void (APIENTRY *PFNglCompileShader) (GLuint); +typedef void (APIENTRY *PFNglGetShaderiv) (GLuint, GLenum, GLint*); +typedef void (APIENTRY *PFNglGetShaderInfoLog) (GLuint, GLsizei, GLsizei*, GLchar*); +typedef void (APIENTRY *PFNglDeleteShader) (GLuint); +typedef GLuint (APIENTRY *PFNglCreateProgram) (void); +typedef void (APIENTRY *PFNglAttachShader) (GLuint, GLuint); +typedef void (APIENTRY *PFNglLinkProgram) (GLuint); +typedef void (APIENTRY *PFNglGetProgramiv) (GLuint, GLenum, GLint*); +typedef void (APIENTRY *PFNglUseProgram) (GLuint); +typedef void (APIENTRY *PFNglUniform1i) (GLint, GLint); +typedef void (APIENTRY *PFNglUniform1f) (GLint, GLfloat); +typedef void (APIENTRY *PFNglUniform2f) (GLint, GLfloat, GLfloat); +typedef void (APIENTRY *PFNglUniform3f) (GLint, GLfloat, GLfloat, GLfloat); +typedef void (APIENTRY *PFNglUniform4f) (GLint, GLfloat, GLfloat, GLfloat, GLfloat); +typedef void (APIENTRY *PFNglUniform1fv) (GLint, GLsizei, const GLfloat*); +typedef void (APIENTRY *PFNglUniform2fv) (GLint, GLsizei, const GLfloat*); +typedef void (APIENTRY *PFNglUniform3fv) (GLint, GLsizei, const GLfloat*); +typedef GLint (APIENTRY *PFNglGetUniformLocation) (GLuint, const GLchar*); + +static PFNglCreateShader pglCreateShader; +static PFNglShaderSource pglShaderSource; +static PFNglCompileShader pglCompileShader; +static PFNglGetShaderiv pglGetShaderiv; +static PFNglGetShaderInfoLog pglGetShaderInfoLog; +static PFNglDeleteShader pglDeleteShader; +static PFNglCreateProgram pglCreateProgram; +static PFNglAttachShader pglAttachShader; +static PFNglLinkProgram pglLinkProgram; +static PFNglGetProgramiv pglGetProgramiv; +static PFNglUseProgram pglUseProgram; +static PFNglUniform1i pglUniform1i; +static PFNglUniform1f pglUniform1f; +static PFNglUniform2f pglUniform2f; +static PFNglUniform3f pglUniform3f; +static PFNglUniform4f pglUniform4f; +static PFNglUniform1fv pglUniform1fv; +static PFNglUniform2fv pglUniform2fv; +static PFNglUniform3fv pglUniform3fv; +static PFNglGetUniformLocation pglGetUniformLocation; + +#define MAXSHADERS 16 +#define MAXSHADERPROGRAMS 16 + +// 18032019 +static char *gl_customvertexshaders[MAXSHADERS]; +static char *gl_customfragmentshaders[MAXSHADERS]; + +static boolean gl_allowshaders = false; +static boolean gl_shadersenabled = false; +static GLuint gl_currentshaderprogram = 0; + +// 13062019 +typedef enum +{ + // lighting + gluniform_poly_color, + gluniform_tint_color, + gluniform_fade_color, + gluniform_lighting, + gluniform_fade_start, + gluniform_fade_end, + + // misc. (custom shaders) + gluniform_leveltime, + + gluniform_max, +} gluniform_t; + +typedef struct gl_shaderprogram_s +{ + GLuint program; + boolean custom; + GLint uniforms[gluniform_max+1]; +} gl_shaderprogram_t; +static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; + +// ======================== +// Fragment shader macros +// ======================== + +// +// GLSL Software fragment shader +// + + +#if 0 +// Old ZDoom style +#define GLSL_DOOM_COLORMAP \ + "float R_DoomColormap(float light, float z)\n" \ + "{\n" \ + "float vis = min(29.0 / z, 24.0 / 32.0);\n" \ + "float shade = 2.0 - (light + 12.0) / 128.0;\n" \ + "float lightscale = shade - vis;\n" \ + "return lightscale * 31.0;\n" \ + "}\n" +#else +// TODO: This is R_PlaneColormap, need a way to get polygon normal to add R_WallColormap +#define GLSL_DOOM_COLORMAP \ + "float R_DoomColormap(float light, float z)\n" \ + "{\n" \ + "float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \ + "float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \ + "float startmap = (15.0 - lightnum) * 4.0;\n" \ + "float scale = 160.0 / (lightz + 1.0);\n" \ + "return startmap - scale * 0.5;\n" \ + "}\n" +#endif + +#define GLSL_DOOM_LIGHT_EQUATION \ + "float R_DoomLightingEquation(float light)\n" \ + "{\n" \ + "float z = gl_FragCoord.z / gl_FragCoord.w;\n" \ + "float colormap = floor(R_DoomColormap(light, z)) + 0.5;\n" \ + "return clamp(colormap, 0.0, 31.0) / 32.0;\n" \ + "}\n" + +#define GLSL_SOFTWARE_TINT_EQUATION \ + "if (tint_color.a > 0.0) {\n" \ + "float color_bright = sqrt((base_color.r * base_color.r) + (base_color.g * base_color.g) + (base_color.b * base_color.b));\n" \ + "float strength = sqrt(9.0 * tint_color.a);\n" \ + "final_color.r = clamp((color_bright * (tint_color.r * strength)) + (base_color.r * (1.0 - strength)), 0.0, 1.0);\n" \ + "final_color.g = clamp((color_bright * (tint_color.g * strength)) + (base_color.g * (1.0 - strength)), 0.0, 1.0);\n" \ + "final_color.b = clamp((color_bright * (tint_color.b * strength)) + (base_color.b * (1.0 - strength)), 0.0, 1.0);\n" \ + "}\n" + +#define GLSL_SOFTWARE_FADE_EQUATION \ + "float darkness = R_DoomLightingEquation(lighting);\n" \ + "if (fade_start != 0.0 || fade_end != 31.0) {\n" \ + "float fs = fade_start / 31.0;\n" \ + "float fe = fade_end / 31.0;\n" \ + "float fd = fe - fs;\n" \ + "darkness = clamp((darkness - fs) * (1.0 / fd), 0.0, 1.0);\n" \ + "}\n" \ + "final_color = mix(final_color, fade_color, darkness);\n" + +#define GLSL_SOFTWARE_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform vec4 poly_color;\n" \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ + "vec4 base_color = texel * poly_color;\n" \ + "vec4 final_color = base_color;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "final_color.a = texel.a * poly_color.a;\n" \ + "gl_FragColor = final_color;\n" \ + "}\0" + + +// +// GLSL generic fragment shader +// + +#define GLSL_DEFAULT_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform vec4 poly_color;\n" \ + "void main(void) {\n" \ + "gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * poly_color;\n" \ + "}\0" + +static const char *fragment_shaders[] = { + // Default fragment shader + GLSL_DEFAULT_FRAGMENT_SHADER, + + // Floor fragment shader + GLSL_SOFTWARE_FRAGMENT_SHADER, + + // Wall fragment shader + GLSL_SOFTWARE_FRAGMENT_SHADER, + + // Sprite fragment shader + GLSL_SOFTWARE_FRAGMENT_SHADER, + + // Model fragment shader + GLSL_SOFTWARE_FRAGMENT_SHADER, + + // Water fragment shader + GLSL_SOFTWARE_FRAGMENT_SHADER, + + // Fog fragment shader + "void main(void) {\n" + "gl_FragColor = gl_Color;\n" + "}\0", + + // Sky fragment shader + "uniform sampler2D tex;\n" + "void main(void) {\n" + "gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n" \ + "}\0", + + NULL, +}; + +// ====================== +// Vertex shader macros +// ====================== + +// +// GLSL generic vertex shader +// + +#define GLSL_DEFAULT_VERTEX_SHADER \ + "void main()\n" \ + "{\n" \ + "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ + "gl_FrontColor = gl_Color;\n" \ + "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ + "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ + "}\0" + +static const char *vertex_shaders[] = { + // Default vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Floor vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Wall vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Sprite vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Model vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Water vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Fog vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Sky vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + NULL, +}; + +#endif // GL_SHADERS + +void SetupGLFunc4(void) { pglActiveTexture = GetGLFunc("glActiveTexture"); pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f"); @@ -516,7 +771,199 @@ boolean SetupGLFunc13(void) pglBufferData = GetGLFunc("glBufferData"); pglDeleteBuffers = GetGLFunc("glDeleteBuffers"); - return true; +#ifdef GL_SHADERS + pglCreateShader = GetGLFunc("glCreateShader"); + pglShaderSource = GetGLFunc("glShaderSource"); + pglCompileShader = GetGLFunc("glCompileShader"); + pglGetShaderiv = GetGLFunc("glGetShaderiv"); + pglGetShaderInfoLog = GetGLFunc("glGetShaderInfoLog"); + pglDeleteShader = GetGLFunc("glDeleteShader"); + pglCreateProgram = GetGLFunc("glCreateProgram"); + pglAttachShader = GetGLFunc("glAttachShader"); + pglLinkProgram = GetGLFunc("glLinkProgram"); + pglGetProgramiv = GetGLFunc("glGetProgramiv"); + pglUseProgram = GetGLFunc("glUseProgram"); + pglUniform1i = GetGLFunc("glUniform1i"); + pglUniform1f = GetGLFunc("glUniform1f"); + pglUniform2f = GetGLFunc("glUniform2f"); + pglUniform3f = GetGLFunc("glUniform3f"); + pglUniform4f = GetGLFunc("glUniform4f"); + pglUniform1fv = GetGLFunc("glUniform1fv"); + pglUniform2fv = GetGLFunc("glUniform2fv"); + pglUniform3fv = GetGLFunc("glUniform3fv"); + pglGetUniformLocation = GetGLFunc("glGetUniformLocation"); +#endif + + // GLU + pgluBuild2DMipmaps = GetGLFunc("gluBuild2DMipmaps"); +} + +// jimita +EXPORT void HWRAPI(LoadShaders) (void) +{ +#ifdef GL_SHADERS + GLuint gl_vertShader, gl_fragShader; + GLint i, result; + + gl_customvertexshaders[0] = NULL; + gl_customfragmentshaders[0] = NULL; + + for (i = 0; vertex_shaders[i] && fragment_shaders[i]; i++) + { + gl_shaderprogram_t *shader; + const GLchar* vert_shader = vertex_shaders[i]; + const GLchar* frag_shader = fragment_shaders[i]; + boolean custom = ((gl_customvertexshaders[i] || gl_customfragmentshaders[i]) && (i > 0)); + + // 18032019 + if (gl_customvertexshaders[i]) + vert_shader = gl_customvertexshaders[i]; + if (gl_customfragmentshaders[i]) + frag_shader = gl_customfragmentshaders[i]; + + if (i >= MAXSHADERS) + break; + if (i >= MAXSHADERPROGRAMS) + break; + + // + // Load and compile vertex shader + // + gl_vertShader = pglCreateShader(GL_VERTEX_SHADER); + if (!gl_vertShader) + I_Error("Hardware driver: Error creating vertex shader %d", i); + + pglShaderSource(gl_vertShader, 1, &vert_shader, NULL); + pglCompileShader(gl_vertShader); + + // check for compile errors + pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) + { + GLchar* infoLog; + GLint logLength; + + pglGetShaderiv(gl_vertShader, GL_INFO_LOG_LENGTH, &logLength); + + infoLog = malloc(logLength); + pglGetShaderInfoLog(gl_vertShader, logLength, NULL, infoLog); + + I_Error("Hardware driver: Error compiling vertex shader %d\n%s", i, infoLog); + } + + // + // Load and compile fragment shader + // + gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER); + if (!gl_fragShader) + I_Error("Hardware driver: Error creating fragment shader %d", i); + + pglShaderSource(gl_fragShader, 1, &frag_shader, NULL); + pglCompileShader(gl_fragShader); + + // check for compile errors + pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) + { + GLchar* infoLog; + GLint logLength; + + pglGetShaderiv(gl_fragShader, GL_INFO_LOG_LENGTH, &logLength); + + infoLog = malloc(logLength); + pglGetShaderInfoLog(gl_fragShader, logLength, NULL, infoLog); + + I_Error("Hardware driver: Error compiling fragment shader %d\n%s", i, infoLog); + } + + shader = &gl_shaderprograms[i]; + shader->program = pglCreateProgram(); + shader->custom = custom; + pglAttachShader(shader->program, gl_vertShader); + pglAttachShader(shader->program, gl_fragShader); + pglLinkProgram(shader->program); + + // check link status + pglGetProgramiv(shader->program, GL_LINK_STATUS, &result); + if (result != GL_TRUE) + I_Error("Hardware driver: Error linking shader program %d", i); + + // delete the shader objects + pglDeleteShader(gl_vertShader); + pglDeleteShader(gl_fragShader); + + // 13062019 +#define GETUNI(uniform) pglGetUniformLocation(shader->program, uniform); + + // lighting + shader->uniforms[gluniform_poly_color] = GETUNI("poly_color"); + shader->uniforms[gluniform_tint_color] = GETUNI("tint_color"); + shader->uniforms[gluniform_fade_color] = GETUNI("fade_color"); + shader->uniforms[gluniform_lighting] = GETUNI("lighting"); + shader->uniforms[gluniform_fade_start] = GETUNI("fade_start"); + shader->uniforms[gluniform_fade_end] = GETUNI("fade_end"); + + // misc. (custom shaders) + shader->uniforms[gluniform_leveltime] = GETUNI("leveltime"); + +#undef GETUNI + } +#endif +} + +EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment) +{ +#ifdef GL_SHADERS + if (number < 1 || number > MAXSHADERS) + I_Error("LoadCustomShader(): cannot load shader %d (max %d)", number, MAXSHADERS); + + if (fragment) + { + gl_customfragmentshaders[number] = malloc(size+1); + strncpy(gl_customfragmentshaders[number], shader, size); + gl_customfragmentshaders[number][size] = 0; + } + else + { + gl_customvertexshaders[number] = malloc(size+1); + strncpy(gl_customvertexshaders[number], shader, size); + gl_customvertexshaders[number][size] = 0; + } +#endif +} + +EXPORT void HWRAPI(InitCustomShaders) (void) +{ +#ifdef GL_SHADERS + KillShaders(); + LoadShaders(); +#endif +} + +EXPORT void HWRAPI(SetShader) (int shader) +{ +#ifdef GL_SHADERS + if (gl_allowshaders) + { + gl_shadersenabled = true; + gl_currentshaderprogram = shader; + } + else +#endif + gl_shadersenabled = false; +} + +EXPORT void HWRAPI(UnSetShader) (void) +{ +#ifdef GL_SHADERS + gl_shadersenabled = false; + gl_currentshaderprogram = 0; +#endif +} + +EXPORT void HWRAPI(KillShaders) (void) +{ + // unused......................... } // -----------------+ @@ -524,7 +971,7 @@ boolean SetupGLFunc13(void) // -----------------+ static void SetNoTexture(void) { - // Set small white texture. + // Disable texture. if (tex_downloaded != NOTEXTURE_NUM) { pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM); @@ -544,7 +991,7 @@ static void GLPerspective(GLfloat fovy, GLfloat aspect) const GLfloat zNear = NEAR_CLIPPING_PLANE; const GLfloat zFar = FAR_CLIPPING_PLANE; const GLfloat radians = (GLfloat)(fovy / 2.0f * M_PIl / 180.0f); - const GLfloat sine = sinf(radians); + const GLfloat sine = sin(radians); const GLfloat deltaZ = zFar - zNear; GLfloat cotangent; @@ -607,7 +1054,7 @@ static void GLProject(GLfloat objX, GLfloat objY, GLfloat objZ, // -----------------+ void SetModelView(GLint w, GLint h) { -// DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); +// GL_DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); // The screen textures need to be flushed if the width or height change so that they be remade for the correct size if (screen_width != w || screen_height != h) @@ -650,7 +1097,7 @@ void SetStates(void) GLfloat LightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; #endif -// DBG_Printf("SetStates()\n"); +// GL_DBG_Printf("SetStates()\n"); // Hurdler: not necessary, is it? pglShadeModel(GL_SMOOTH); // iterate vertice colors @@ -675,7 +1122,7 @@ void SetStates(void) pglDepthRange(0.0f, 1.0f); pglDepthFunc(GL_LEQUAL); - // this set CurrentPolyFlags to the acctual configuration + // this set CurrentPolyFlags to the actual configuration CurrentPolyFlags = 0xffffffff; SetBlend(0); @@ -719,7 +1166,7 @@ void SetStates(void) // -----------------+ void Flush(void) { - //DBG_Printf ("HWR_Flush()\n"); + //GL_DBG_Printf ("HWR_Flush()\n"); while (gr_cachehead) { @@ -787,10 +1234,8 @@ INT32 isExtAvailable(const char *extension, const GLubyte *start) // Init : Initialise the OpenGL interface API // Returns : // -----------------+ -EXPORT boolean HWRAPI(Init) (I_Error_t FatalErrorFunction) +EXPORT boolean HWRAPI(Init) (void) { - I_Error_GL = FatalErrorFunction; - DBG_Printf ("%s %s\n", DRIVER_STRING, VERSIONSTRING); return LoadGL(); } @@ -800,7 +1245,7 @@ EXPORT boolean HWRAPI(Init) (I_Error_t FatalErrorFunction) // -----------------+ EXPORT void HWRAPI(ClearMipMapCache) (void) { - // DBG_Printf ("HWR_Flush(exe)\n"); + // GL_DBG_Printf ("HWR_Flush(exe)\n"); Flush(); } @@ -814,7 +1259,7 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 * dst_data) { INT32 i; - // DBG_Printf ("ReadRect()\n"); + // GL_DBG_Printf ("ReadRect()\n"); if (dst_stride == width*3) { GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (height - 1); @@ -862,7 +1307,7 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, // -----------------+ EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip) { - // DBG_Printf ("GClipRect(%d, %d, %d, %d)\n", minx, miny, maxx, maxy); + // GL_DBG_Printf ("GClipRect(%d, %d, %d, %d)\n", minx, miny, maxx, maxy); pglViewport(minx, screen_height-maxy, maxx-minx, maxy-miny); NEAR_CLIPPING_PLANE = nearclip; @@ -886,7 +1331,7 @@ EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat * ClearColor) { - // DBG_Printf ("ClearBuffer(%d)\n", alpha); + // GL_DBG_Printf ("ClearBuffer(%d)\n", alpha); GLbitfield ClearMask = 0; if (ColorMask) @@ -921,7 +1366,7 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, F2DCoord * v2, RGBA_t Color) { - // DBG_Printf ("DrawLine() (%f %f %f) %d\n", v1->x, -v1->y, -v1->z, v1->argb); + // GL_DBG_Printf ("DrawLine() (%f %f %f) %d\n", v1->x, -v1->y, -v1->z, v1->argb); GLfloat p[12]; GLfloat dx, dy; GLfloat angle; @@ -1064,7 +1509,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) else #endif if (PolyFlags & PF_Modulated) - { // mix texture colour with Surface->FlatColor + { // mix texture colour with Surface->PolyColor pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else @@ -1129,11 +1574,21 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) const GLvoid *ptex = tex; INT32 w, h; - //DBG_Printf ("DownloadMipmap %d %x\n",NextTexAvail,pTexInfo->grInfo.data); + //GL_DBG_Printf ("DownloadMipmap %d %x\n",NextTexAvail,pTexInfo->grInfo.data); w = pTexInfo->width; h = pTexInfo->height; +#ifdef USE_PALETTED_TEXTURE + if (glColorTableEXT && + (pTexInfo->grInfo.format == GR_TEXFMT_P_8) && + !(pTexInfo->flags & TF_CHROMAKEYED)) + { + // do nothing here. + // Not a problem with MiniGL since we don't use paletted texture + } + else +#endif if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) || (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)) { @@ -1215,7 +1670,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } } else - DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); + GL_DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); pTexInfo->downloaded = NextTexAvail++; tex_downloaded = pTexInfo->downloaded; @@ -1233,6 +1688,17 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); } +#ifdef USE_PALETTED_TEXTURE + //Hurdler: not really supported and not tested recently + if (glColorTableEXT && + (pTexInfo->grInfo.format == GR_TEXFMT_P_8) && + !(pTexInfo->flags & TF_CHROMAKEYED)) + { + glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex); + pglTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, w, h, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, pTexInfo->grInfo.data); + } + else +#endif if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) { //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); @@ -1305,32 +1771,116 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } } +static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade) +{ +#ifdef GL_SHADERS + if (gl_shadersenabled) + { + gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram]; + if (shader->program) + { + boolean custom = (gl_shaderprograms[gl_currentshaderprogram].custom); + // 13062019 + // Check for fog + //if (changed) + { + pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program); + } + + // set uniforms + { + #define UNIFORM_1(uniform, a, function) \ + if (uniform != -1) \ + function (uniform, a); + + #define UNIFORM_2(uniform, a, b, function) \ + if (uniform != -1) \ + function (uniform, a, b); + + #define UNIFORM_3(uniform, a, b, c, function) \ + if (uniform != -1) \ + function (uniform, a, b, c); + + #define UNIFORM_4(uniform, a, b, c, d, function) \ + if (uniform != -1) \ + function (uniform, a, b, c, d); + + // polygon + UNIFORM_4(shader->uniforms[gluniform_poly_color], poly->red, poly->green, poly->blue, poly->alpha, pglUniform4f); + UNIFORM_4(shader->uniforms[gluniform_tint_color], tint->red, tint->green, tint->blue, tint->alpha, pglUniform4f); + UNIFORM_4(shader->uniforms[gluniform_fade_color], fade->red, fade->green, fade->blue, fade->alpha, pglUniform4f); + UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f); + + // Custom shader uniforms + if (custom) + { + UNIFORM_1(shader->uniforms[gluniform_leveltime], (float)gl_leveltime, pglUniform1f); + } + #undef UNIFORM_1 + #undef UNIFORM_2 + #undef UNIFORM_3 + #undef UNIFORM_4 + } + } + else + pglUseProgram(0); + } + else +#endif + pglUseProgram(0); +} // -----------------+ // DrawPolygon : Render a polygon, set the texture, set render mode // -----------------+ -EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, - //FTextureInfo *pTexInfo, - FOutVector *pOutVerts, - FUINT iNumPts, - FBITFIELD PolyFlags) +EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags) { - FUINT i; - FUINT j; + static GLRGBAFloat poly = {0,0,0,0}; + static GLRGBAFloat tint = {0,0,0,0}; + static GLRGBAFloat fade = {0,0,0,0}; if ((PolyFlags & PF_Corona) && (oglflags & GLF_NOZBUFREAD)) PolyFlags &= ~(PF_NoDepthTest|PF_Corona); SetBlend(PolyFlags); //TODO: inline (#pragma..) - // If Modulated, mix the surface colour to the texture - if ((CurrentPolyFlags & PF_Modulated) && pSurf) - pglColor4ubv((GLubyte*)&pSurf->FlatColor.s); + // PolyColor + if (pSurf) + { + // If Modulated, mix the surface colour to the texture + if (CurrentPolyFlags & PF_Modulated) + { + // Poly color + poly.red = byte2float[pSurf->PolyColor.s.red]; + poly.green = byte2float[pSurf->PolyColor.s.green]; + poly.blue = byte2float[pSurf->PolyColor.s.blue]; + poly.alpha = byte2float[pSurf->PolyColor.s.alpha]; + + pglColor4ubv((GLubyte*)&pSurf->PolyColor.s); + } + + // Tint color + tint.red = byte2float[pSurf->TintColor.s.red]; + tint.green = byte2float[pSurf->TintColor.s.green]; + tint.blue = byte2float[pSurf->TintColor.s.blue]; + tint.alpha = byte2float[pSurf->TintColor.s.alpha]; + + // Fade color + fade.red = byte2float[pSurf->FadeColor.s.red]; + fade.green = byte2float[pSurf->FadeColor.s.green]; + fade.blue = byte2float[pSurf->FadeColor.s.blue]; + fade.alpha = byte2float[pSurf->FadeColor.s.alpha]; + } // this test is added for new coronas' code (without depth buffer) // I think I should do a separate function for drawing coronas, so it will be a little faster if (PolyFlags & PF_Corona) // check to see if we need to draw the corona { + FUINT i; + FUINT j; + //rem: all 8 (or 8.0f) values are hard coded: it can be changed to a higher value GLfloat buf[8][8]; GLfloat cx, cy, cz; @@ -1347,7 +1897,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, // I dont know if this is slow or not GLProject(cx, cy, cz, &px, &py, &pz); - //DBG_Printf("Projection: (%f, %f, %f)\n", px, py, pz); + //GL_DBG_Printf("Projection: (%f, %f, %f)\n", px, py, pz); if ((pz < 0.0l) || (px < -8.0l) || @@ -1358,7 +1908,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, // the damned slow glReadPixels functions :( pglReadPixels((INT32)px-4, (INT32)py, 8, 8, GL_DEPTH_COMPONENT, GL_FLOAT, buf); - //DBG_Printf("DepthBuffer: %f %f\n", buf[0][0], buf[3][3]); + //GL_DBG_Printf("DepthBuffer: %f %f\n", buf[0][0], buf[3][3]); for (i = 0; i < 8; i++) for (j = 0; j < 8; j++) @@ -1371,24 +1921,26 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, if (py > viewport[1]+viewport[3]-4) scalef -= (GLfloat)(8*(4-(viewport[1]+viewport[3]-py))); scalef /= 64; - //DBG_Printf("Scale factor: %f\n", scalef); + //GL_DBG_Printf("Scale factor: %f\n", scalef); if (scalef < 0.05f) return; // GLubyte c[4]; - c[0] = pSurf->FlatColor.s.red; - c[1] = pSurf->FlatColor.s.green; - c[2] = pSurf->FlatColor.s.blue; + c[0] = pSurf->PolyColor.s.red; + c[1] = pSurf->PolyColor.s.green; + c[2] = pSurf->PolyColor.s.blue; - alpha = byte2float[pSurf->FlatColor.s.alpha]; + alpha = byte2float[pSurf->PolyColor.s.alpha]; alpha *= scalef; // change the alpha value (it seems better than changing the size of the corona) c[3] = (unsigned char)(alpha * 255); pglColor4ubv(c); } + load_shaders(pSurf, &poly, &tint, &fade); + pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); - pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].sow); + pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s); pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); if (PolyFlags & PF_RemoveYWrap) @@ -1399,6 +1951,10 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, if (PolyFlags & PF_ForceWrapY) Clamp2D(GL_TEXTURE_WRAP_T); + +#ifdef GL_SHADERS + pglUseProgram(0); +#endif } typedef struct vbo_vertex_s @@ -1705,6 +2261,18 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) pglDisable(GL_FOG); break; + case HWD_SET_SHADERS: + switch (Value) + { + case 1: + gl_allowshaders = true; + break; + default: + gl_allowshaders = false; + break; + } + break; + case HWD_SET_TEXTUREFILTERMODE: switch (Value) { @@ -1957,12 +2525,13 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) } } -#define BUFFER_OFFSET(i) ((char*)NULL + (i)) +#define BUFFER_OFFSET(i) ((char*)(i)) -static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) +static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface) { - GLfloat ambient[4]; - GLfloat diffuse[4]; + static GLRGBAFloat poly = {0,0,0,0}; + static GLRGBAFloat tint = {0,0,0,0}; + static GLRGBAFloat fade = {0,0,0,0}; float pol = 0.0f; float scalex, scaley, scalez; @@ -1993,24 +2562,26 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pol = 0.0f; } - if (color) - { - ambient[0] = (color[0]/255.0f); - ambient[1] = (color[1]/255.0f); - ambient[2] = (color[2]/255.0f); - ambient[3] = (color[3]/255.0f); - diffuse[0] = (color[0]/255.0f); - diffuse[1] = (color[1]/255.0f); - diffuse[2] = (color[2]/255.0f); - diffuse[3] = (color[3]/255.0f); + poly.red = byte2float[Surface->PolyColor.s.red]; + poly.green = byte2float[Surface->PolyColor.s.green]; + poly.blue = byte2float[Surface->PolyColor.s.blue]; + poly.alpha = byte2float[Surface->PolyColor.s.alpha]; - if (ambient[0] > 0.75f) - ambient[0] = 0.75f; - if (ambient[1] > 0.75f) - ambient[1] = 0.75f; - if (ambient[2] > 0.75f) - ambient[2] = 0.75f; - } + SetBlend((poly.alpha < 1 ? PF_Translucent : (PF_Masked|PF_Occlude))|PF_Modulated); + + pglColor4ubv((GLubyte*)&Surface->PolyColor.s); + + tint.red = byte2float[Surface->TintColor.s.red]; + tint.green = byte2float[Surface->TintColor.s.green]; + tint.blue = byte2float[Surface->TintColor.s.blue]; + tint.alpha = byte2float[Surface->TintColor.s.alpha]; + + fade.red = byte2float[Surface->FadeColor.s.red]; + fade.green = byte2float[Surface->FadeColor.s.green]; + fade.blue = byte2float[Surface->FadeColor.s.blue]; + fade.alpha = byte2float[Surface->FadeColor.s.alpha]; + + load_shaders(Surface, &poly, &tint, &fade); pglEnable(GL_CULL_FACE); pglEnable(GL_NORMALIZE); @@ -2045,25 +2616,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglShadeModel(GL_SMOOTH); } - if (color) - { -#ifdef GL_LIGHT_MODEL_AMBIENT - if (model_lighting) - { - pglEnable(GL_LIGHTING); - pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); - pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); - } - else -#endif - pglColor4ubv((GLubyte*)color); - - if (color[3] < 255) - SetBlend(PF_Translucent|PF_Modulated|PF_Clip); - else - SetBlend(PF_Masked|PF_Modulated|PF_Occlude|PF_Clip); - } - pglPushMatrix(); // should be the same as glLoadIdentity //Hurdler: now it seems to work pglTranslatef(pos->x, pos->z, pos->y); @@ -2126,13 +2678,12 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 { short *vertPtr; char *normPtr; - int j; + int j = 0; // Dangit, I soooo want to do this in a GLSL shader... AllocLerpTinyBuffer(mesh->numVertices * sizeof(short) * 3); vertPtr = vertTinyBuffer; normPtr = normTinyBuffer; - j = 0; for (j = 0; j < mesh->numVertices * 3; j++) { @@ -2203,19 +2754,20 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglDisableClientState(GL_NORMAL_ARRAY); pglPopMatrix(); // should be the same as glLoadIdentity - if (color) - pglDisable(GL_LIGHTING); - pglShadeModel(GL_FLAT); pglDisable(GL_CULL_FACE); pglDisable(GL_NORMALIZE); + +#ifdef GL_SHADERS + pglUseProgram(0); +#endif } // -----------------+ -// HWRAPI DrawMD2 : Draw an MD2 model with glcommands +// HWRAPI DrawModel : Draw a model // -----------------+ -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface) { - DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, color); + DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, Surface); } // -----------------+ @@ -2224,11 +2776,16 @@ EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, EXPORT void HWRAPI(SetTransform) (FTransform *stransform) { static boolean special_splitscreen; + boolean shearing = false; + pglLoadIdentity(); + if (stransform) { boolean fovx90; + shearing = stransform->shearing; + #ifdef USE_FTRANSFORM_MIRROR // mirroring from Kart if (stransform->mirror) @@ -2240,12 +2797,23 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) else pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez); - pglRotatef(stransform->anglex , 1.0f, 0.0f, 0.0f); + pglMatrixMode(GL_MODELVIEW); + pglRotatef(stransform->anglex, 1.0f, 0.0f, 0.0f); pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f); pglTranslatef(-stransform->x, -stransform->z, -stransform->y); pglMatrixMode(GL_PROJECTION); pglLoadIdentity(); + + // jimita 14042019 + // Simulate Software's y-shearing + // https://zdoom.org/wiki/Y-shearing + if (shearing) + { + float dy = FIXED_TO_FLOAT(AIMINGTODY(stransform->viewaiming)) * 2; //screen_width/BASEVIDWIDTH; + pglTranslatef(0.0f, -dy/BASEVIDHEIGHT, 0.0f); + } + fovx90 = stransform->fovxangle > 0.0f && fabsf(stransform->fovxangle - 90.0f) < 0.5f; special_splitscreen = (stransform->splitscreen && fovx90); if (special_splitscreen) @@ -2286,11 +2854,6 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void) return res; } -EXPORT INT32 HWRAPI(GetRenderVersion) (void) -{ - return VERSION; -} - EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) { INT32 x, y; @@ -2328,6 +2891,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) pglVertexPointer(3, GL_FLOAT, 0, blackBack); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); for(x=0;x>FRACBITS)< 0) return x-f; else diff --git a/src/p_enemy.c b/src/p_enemy.c index 6b60a697f..6b6ce62c7 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1035,7 +1035,7 @@ void A_Chase(mobj_t *actor) actor->threshold--; } - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -1092,7 +1092,7 @@ nomissile: && P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase towards player + // chase tards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } @@ -1125,7 +1125,7 @@ void A_FaceStabChase(mobj_t *actor) actor->threshold--; } - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -1182,7 +1182,7 @@ nomissile: && P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase towards player + // chase tards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } @@ -1493,7 +1493,7 @@ void A_JetJawChomp(mobj_t *actor) return; #endif - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -1513,7 +1513,7 @@ void A_JetJawChomp(mobj_t *actor) return; } - // chase towards player + // chase tards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } @@ -1915,7 +1915,7 @@ void A_SharpChase(mobj_t *actor) actor->reactiontime--; - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -1937,7 +1937,7 @@ void A_SharpChase(mobj_t *actor) return; } - // chase towards player + // chase tards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } @@ -2469,7 +2469,7 @@ void A_VultureBlast(mobj_t *actor) // Function: A_VultureFly // -// Description: Vulture charging towards target. +// Description: Vulture charging tards target. // // var1 = unused // var2 = unused @@ -2592,7 +2592,7 @@ void A_SkimChase(mobj_t *actor) actor->threshold--; } - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -2649,14 +2649,14 @@ nomissile: && P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase towards player + // chase tards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } // Function: A_FaceTarget // -// Description: Immediately turn to face towards your target. +// Description: Immediately turn to face tards your target. // // var1 = unused // var2 = unused @@ -2675,7 +2675,7 @@ void A_FaceTarget(mobj_t *actor) // Function: A_FaceTracer // -// Description: Immediately turn to face towards your tracer. +// Description: Immediately turn to face tards your tracer. // // var1 = unused // var2 = unused @@ -5371,7 +5371,7 @@ void A_JetChase(mobj_t *actor) actor->threshold--; } - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); if ((multiplayer || netgame) && !actor->threshold && (actor->target->health <= 0 || !P_CheckSight(actor, actor->target))) @@ -5385,7 +5385,7 @@ void A_JetChase(mobj_t *actor) return; // got a new target } - // chase towards player + // chase tards player if (ultimatemode) P_Thrust(actor, actor->angle, FixedMul(actor->info->speed/2, actor->scale)); else @@ -5938,7 +5938,7 @@ void A_DetonChase(mobj_t *actor) } } - // chase towards player + // chase tards player if ((dist = P_AproxDistance(xydist, actor->tracer->z-actor->z)) > FixedMul((actor->info->painchance << FRACBITS), actor->scale)) { @@ -7077,7 +7077,7 @@ void A_Boss1Chase(mobj_t *actor) if (actor->reactiontime) actor->reactiontime--; - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -7150,7 +7150,7 @@ nomissile: actor->momz = FixedMul(actor->momz,7*FRACUNIT/8); } - // chase towards player + // chase tards player if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) > actor->radius+actor->target->radius) { if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) @@ -7405,7 +7405,7 @@ void A_Boss7Chase(mobj_t *actor) return; } - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -7499,7 +7499,7 @@ void A_Boss7Chase(mobj_t *actor) if (leveltime & 1) { - // chase towards player + // chase tards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } @@ -7640,7 +7640,7 @@ void A_Boss2PogoTarget(mobj_t *actor) actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); P_InstaThrust(actor, actor->angle, FixedDiv(P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y), airtime)); } - // Wander semi-randomly towards the player to get closer. + // Wander semi-randomly tards the player to get closer. else { UINT8 prandom = P_RandomByte(); @@ -7860,7 +7860,7 @@ void A_BuzzFly(mobj_t *actor) return; } - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); if (actor->target->health <= 0 || (!actor->threshold && !P_CheckSight(actor, actor->target))) @@ -7883,7 +7883,7 @@ void A_BuzzFly(mobj_t *actor) return; } - // chase towards player + // chase tards player { INT32 dist, realspeed; const fixed_t mf = 5*(FRACUNIT/4); @@ -7975,7 +7975,7 @@ void A_GuardChase(mobj_t *actor) } else // Break ranks! { - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -8002,7 +8002,7 @@ void A_GuardChase(mobj_t *actor) && P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase towards player + // chase tards player if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) { P_NewChaseDir(actor); @@ -10940,7 +10940,7 @@ void A_RemoteDamage(mobj_t *actor) // Function: A_HomingChase // -// Description: Actor chases directly towards its destination object +// Description: Actor chases directly tards its destination object // // var1 = speed multiple // var2 = destination: 0 = target, 1 = tracer @@ -11400,7 +11400,7 @@ void A_BrakChase(mobj_t *actor) actor->threshold--; } - // turn towards movement direction if not there yet + // turn tards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -11458,7 +11458,7 @@ void A_BrakChase(mobj_t *actor) && P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase towards player + // chase tards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); @@ -11519,7 +11519,7 @@ void A_BrakFireShot(mobj_t *actor) // Function: A_BrakLobShot // -// Description: Lobs an object at the floor about a third of the way toward your target. +// Description: Lobs an object at the floor about a third of the way tard your target. // Implication is it'll bounce the rest of the way. // (You can also just aim straight at the target, but whatever) // Formula grabbed from http://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Angle_required_to_hit_coordinate_.28x.2Cy.29 diff --git a/src/p_floor.c b/src/p_floor.c index c23d469bc..b1e9d1fda 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1349,13 +1349,13 @@ wegotit: { // Lower controlsec like a regular T_RaiseSector // Set the heights of all the other control sectors to - // be a gradient of this height toward the edges + // be a gradient of this height tard the edges } else { // Raise controlsec like a regular T_RaiseSector // Set the heights of all the other control sectors to - // be a gradient of this height toward the edges. + // be a gradient of this height tard the edges. } if (playeronme && controlsec) diff --git a/src/p_inter.c b/src/p_inter.c index 70fb01fd0..2645c5e62 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2428,7 +2428,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget // Also, add to the link. // I don't know if NiGHTS did this, but // Sonic Time Attacked did and it seems like a good enough incentive - // to make people want to actually dash towards/paraloop enemies + // to make people want to actually dash tards/paraloop enemies if (++source->player->linkcount > source->player->maxlink) source->player->maxlink = source->player->linkcount; source->player->linktimer = nightslinktics; diff --git a/src/p_local.h b/src/p_local.h index 286d7201f..a5fd0eaa8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -201,7 +201,7 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type); void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range); void P_PlayLivesJingle(player_t *player); -#define P_PlayRinglossSound(s) S_StartSound(s, (mariomode) ? sfx_mario8 : sfx_altow1 + P_RandomKey(4)); +#define P_PlayRinglossSound(s) S_StartSound(s, (mariomode) ? sfx_mario8 : sfx_alt1 + P_RandomKey(4)); #define P_PlayDeathSound(s) S_StartSound(s, sfx_altdi1 + P_RandomKey(4)); #define P_PlayVictorySound(s) S_StartSound(s, sfx_victr1 + P_RandomKey(4)); diff --git a/src/p_mobj.c b/src/p_mobj.c index 87ec1fe9f..283219bea 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2601,7 +2601,7 @@ static boolean P_ZMovement(mobj_t *mo) if (mo->flags & MF_FLOAT && mo->target && mo->health && !(mo->type == MT_EGGMOBILE) && mo->target->health > 0) { - // float down towards target if too close + // float down tards target if too close if (!(mo->flags2 & MF2_SKULLFLY) && !(mo->flags2 & MF2_INFLOAT)) { dist = P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y); @@ -2938,7 +2938,7 @@ static void P_PlayerZMovement(mobj_t *mo) if (mo->player->powers[pw_carry] == CR_NIGHTSMODE) { - // bounce off floor if you were flying towards it + // bounce off floor if you were flying tards it if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 0 && mo->player->flyangle < 180) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->player->flyangle > 180 && mo->player->flyangle <= 359)) { @@ -3088,7 +3088,7 @@ nightsdone: if (mo->player->powers[pw_carry] == CR_NIGHTSMODE) { - // bounce off ceiling if you were flying towards it + // bounce off ceiling if you were flying tards it if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 180 && mo->player->flyangle <= 359) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->player->flyangle > 0 && mo->player->flyangle < 180)) { @@ -6289,7 +6289,7 @@ static void P_MoveHoop(mobj_t *mobj) y = mobj->target->y; z = mobj->target->z+mobj->target->height/2; - // Make the sprite travel towards the center of the hoop + // Make the sprite travel tards the center of the hoop v[0] = FixedMul(FINECOSINE(fa),fuse); v[1] = 0; v[2] = FixedMul(FINESINE(fa),fuse); @@ -6758,7 +6758,7 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) if (!pos_lengthways[3] || P_MobjWasRemoved(mobj) || (mobj->flags & MF_NOCLIPHEIGHT)) goto cont; - if ((fa = ((center->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it + if ((fa = ((center->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move tards center when the motion is tards/away from the ground, rather than alongside it goto cont; if (mobj->subsector->sector->ffloors) diff --git a/src/p_setup.c b/src/p_setup.c index bc736588e..01629651f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1559,7 +1559,7 @@ static void P_CreateBlockMap(void) // // If current block is the same as the ending vertex's block, exit loop. // - // Move to an adjacent block by moving towards the ending block in + // Move to an adjacent block by moving tards the ending block in // either the x or y direction, to the block which contains the linedef. { @@ -2581,10 +2581,10 @@ boolean P_SetupLevel(boolean skipprecip) if (RESETMUSIC || strnicmp(S_MusicName(), (mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap-1]->musname : mapmusname, 7)) - S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE) + S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_thite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE) F_WipeStartScreen(); - wipestyleflags |= (WSF_FADEOUT|WSF_TOWHITE); + wipestyleflags |= (WSF_FADEOUT|WSF_tHITE); #ifdef HWRENDER // uh.......... @@ -2593,7 +2593,7 @@ boolean P_SetupLevel(boolean skipprecip) #endif F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_speclevel_towhite], false); + F_RunWipe(wipedefs[wipe_speclevel_thite], false); I_OsPolling(); I_FinishUpdate(); // page flip or blit buffer @@ -2619,7 +2619,7 @@ boolean P_SetupLevel(boolean skipprecip) if (G_GetModeAttackRetryFlag()) { if (modeattacking) - wipestyleflags |= (WSF_FADEOUT|WSF_TOWHITE); + wipestyleflags |= (WSF_FADEOUT|WSF_tHITE); G_ClearModeAttackRetryFlag(); } diff --git a/src/p_spec.c b/src/p_spec.c index bf7f6210a..bccd9510f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6043,7 +6043,7 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) /** Adds a raise thinker. * A raise thinker checks to see if the * player is standing on its 3D Floor, - * and if so, raises the platform towards + * and if so, raises the platform tards * it's destination. Otherwise, it lowers * to the lowest nearby height if not * there already. diff --git a/src/p_user.c b/src/p_user.c index 2b82ae697..f700588ac 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5189,7 +5189,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (!(player->pflags & (PF_THOKKED|PF_USEDOWN)) || (player->charflags & SF_MULTIABILITY)) { P_Telekinesis(player, - -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player) + -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling tards player) FixedMul(384*FRACUNIT, player->mo->scale)); } break; @@ -6177,7 +6177,7 @@ static void P_3dMovement(player_t *player) // The rest is unaffected. angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection; - if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward + if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face tard if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) { P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); } @@ -8644,7 +8644,7 @@ static void P_MovePlayer(player_t *player) } #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none && cv_grfovchange.value) + if (rendermode == render_opengl && cv_grfovchange.value) { fixed_t speed; const fixed_t runnyspeed = 20*FRACUNIT; diff --git a/src/r_main.c b/src/r_main.c index 0ef0a3d88..fedc217a4 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -591,11 +591,6 @@ void R_ExecuteSetViewSize(void) R_InitTextureMapping(); -#ifdef HWRENDER - if (rendermode != render_soft) - HWR_InitTextureMapping(); -#endif - // thing clipping for (i = 0; i < viewwidth; i++) screenheightarray[i] = (INT16)viewheight; @@ -725,29 +720,34 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) static mobj_t *viewmobj; -// WARNING: a should be unsigned but to add with 2048, it isn't! -#define AIMINGTODY(a) ((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS) - // recalc necessary stuff for mouseaiming // slopes are already calculated for the full possible view (which is 4*viewheight). // 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out) static void R_SetupFreelook(void) { INT32 dy = 0; + + // clip it in the case we are looking a hardware 90 degrees full aiming + // (lmps, network and use F12...) + if (rendermode == render_soft +#ifdef HWRENDER + || cv_grshearing.value +#endif + ) + { + G_SoftwareClipAimingPitch((INT32 *)&aimingangle); + } + if (rendermode == render_soft) { - // clip it in the case we are looking a hardware 90 degrees full aiming - // (lmps, network and use F12...) - G_SoftwareClipAimingPitch((INT32 *)&aimingangle); - dy = AIMINGTODY(aimingangle) * viewwidth/BASEVIDWIDTH; + dy = (AIMINGTODY(aimingangle)>>FRACBITS) * viewwidth/BASEVIDWIDTH; yslope = &yslopetab[viewheight*8 - (viewheight/2 + dy)]; } + centery = (viewheight/2) + dy; centeryfrac = centery<>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); VID_Command_ModeList_f(); #ifdef HWRENDER - if (M_CheckParm("-opengl") || rendermode == render_opengl) + if (rendermode == render_opengl) { - rendermode = render_opengl; HWD.pfnInit = hwSym("Init",NULL); HWD.pfnFinishUpdate = NULL; HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); @@ -1658,7 +1660,6 @@ void I_StartupGraphics(void) HWD.pfnDrawModel = hwSym("DrawModel",NULL); HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL); HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); @@ -1668,10 +1669,16 @@ void I_StartupGraphics(void) HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); - if (!HWD.pfnInit(I_Error)) // let load the OpenGL library + + HWD.pfnLoadShaders = hwSym("LoadShaders",NULL); + HWD.pfnKillShaders = hwSym("KillShaders",NULL); + HWD.pfnSetShader = hwSym("SetShader",NULL); + HWD.pfnUnSetShader = hwSym("UnSetShader",NULL); + + HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); + HWD.pfnInitCustomShaders = hwSym("InitCustomShaders",NULL); + + if (!HWD.pfnInit()) // load the OpenGL library { rendermode = render_soft; } diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index 6c0dd35a5..e20e4d091 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -37,6 +37,7 @@ #ifdef HWRENDER #include "../hardware/r_opengl/r_opengl.h" +#include "../hardware/hw_main.h" #include "ogl_sdl.h" #include "../i_system.h" #include "hwsym_sdl.h" @@ -90,15 +91,15 @@ boolean LoadGL(void) const char *OGLLibname = NULL; const char *GLULibname = NULL; - if (M_CheckParm ("-OGLlib") && M_IsNextParm()) + if (M_CheckParm("-OGLlib") && M_IsNextParm()) OGLLibname = M_GetNextParm(); if (SDL_GL_LoadLibrary(OGLLibname) != 0) { - I_OutputMsg("Could not load OpenGL Library: %s\n" + CONS_Alert(CONS_ERROR, "Could not load OpenGL Library: %s\n" "Falling back to Software mode.\n", SDL_GetError()); - if (!M_CheckParm ("-OGLlib")) - I_OutputMsg("If you know what is the OpenGL library's name, use -OGLlib\n"); + if (!M_CheckParm("-OGLlib")) + CONS_Printf("If you know what is the OpenGL library's name, use -OGLlib\n"); return 0; } @@ -118,7 +119,7 @@ boolean LoadGL(void) GLULibname = NULL; #endif - if (M_CheckParm ("-GLUlib") && M_IsNextParm()) + if (M_CheckParm("-GLUlib") && M_IsNextParm()) GLULibname = M_GetNextParm(); if (GLULibname) @@ -152,31 +153,29 @@ boolean LoadGL(void) */ boolean OglSdlSurface(INT32 w, INT32 h) { - INT32 cbpp; - const GLvoid *glvendor = NULL, *glrenderer = NULL, *glversion = NULL; + INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; + static boolean first_init = false; - cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; - - glvendor = pglGetString(GL_VENDOR); - // Get info and extensions. - //BP: why don't we make it earlier ? - //Hurdler: we cannot do that before intialising gl context - glrenderer = pglGetString(GL_RENDERER); - glversion = pglGetString(GL_VERSION); - gl_extensions = pglGetString(GL_EXTENSIONS); - - DBG_Printf("Vendor : %s\n", glvendor); - DBG_Printf("Renderer : %s\n", glrenderer); - DBG_Printf("Version : %s\n", glversion); - DBG_Printf("Extensions : %s\n", gl_extensions); oglflags = 0; + if (!first_init) + { + gl_version = pglGetString(GL_VERSION); + gl_renderer = pglGetString(GL_RENDERER); + gl_extensions = pglGetString(GL_EXTENSIONS); + + GL_DBG_Printf("OpenGL %s\n", gl_version); + GL_DBG_Printf("GPU: %s\n", gl_renderer); + GL_DBG_Printf("Extensions: %s\n", gl_extensions); + } + first_init = true; + if (isExtAvailable("GL_EXT_texture_filter_anisotropic", gl_extensions)) pglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy); else maximumAnisotropy = 1; - SetupGLFunc13(); + SetupGLFunc4(); granisotropicmode_cons_t[1].value = maximumAnisotropy; @@ -222,7 +221,7 @@ void OglSdlFinishUpdate(boolean waitvbl) HWR_DrawScreenFinalTexture(realwidth, realheight); } -EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette) +EXPORT void HWRAPI(OglSdlSetPalette) (RGBA_t *palette) { size_t palsize = (sizeof(RGBA_t) * 256); // on a palette change, you have to reload all of the textures diff --git a/src/sounds.c b/src/sounds.c index 175bd8960..6b0a11ed7 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -57,10 +57,10 @@ sfxinfo_t S_sfx[NUMSFX] = {"altdi2", false, 192, 16, -1, NULL, 0, SKSPLDET2, -1, LUMPERROR, "Dying"}, {"altdi3", false, 192, 16, -1, NULL, 0, SKSPLDET3, -1, LUMPERROR, "Dying"}, {"altdi4", false, 192, 16, -1, NULL, 0, SKSPLDET4, -1, LUMPERROR, "Dying"}, - {"altow1", false, 192, 16, -1, NULL, 0, SKSPLPAN1, -1, LUMPERROR, "Ring loss"}, - {"altow2", false, 192, 16, -1, NULL, 0, SKSPLPAN2, -1, LUMPERROR, "Ring loss"}, - {"altow3", false, 192, 16, -1, NULL, 0, SKSPLPAN3, -1, LUMPERROR, "Ring loss"}, - {"altow4", false, 192, 16, -1, NULL, 0, SKSPLPAN4, -1, LUMPERROR, "Ring loss"}, + {"alt1", false, 192, 16, -1, NULL, 0, SKSPLPAN1, -1, LUMPERROR, "Ring loss"}, + {"alt2", false, 192, 16, -1, NULL, 0, SKSPLPAN2, -1, LUMPERROR, "Ring loss"}, + {"alt3", false, 192, 16, -1, NULL, 0, SKSPLPAN3, -1, LUMPERROR, "Ring loss"}, + {"alt4", false, 192, 16, -1, NULL, 0, SKSPLPAN4, -1, LUMPERROR, "Ring loss"}, {"victr1", false, 64, 16, -1, NULL, 0, SKSPLVCT1, -1, LUMPERROR, "/"}, {"victr2", false, 64, 16, -1, NULL, 0, SKSPLVCT2, -1, LUMPERROR, "/"}, {"victr3", false, 64, 16, -1, NULL, 0, SKSPLVCT3, -1, LUMPERROR, "/"}, diff --git a/src/sounds.h b/src/sounds.h index e520c6243..dfd3fb731 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -106,10 +106,10 @@ typedef enum sfx_altdi2, sfx_altdi3, sfx_altdi4, - sfx_altow1, - sfx_altow2, - sfx_altow3, - sfx_altow4, + sfx_alt1, + sfx_alt2, + sfx_alt3, + sfx_alt4, sfx_victr1, sfx_victr2, sfx_victr3, diff --git a/src/v_video.c b/src/v_video.c index c6ec22767..1cc3c22d4 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -417,7 +417,7 @@ void V_SetPalette(INT32 palettenum) LoadMapPalette(); #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) HWR_SetPalette(&pLocalPalette[palettenum*256]); #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) else @@ -431,7 +431,7 @@ void V_SetPaletteLump(const char *pal) { LoadPalette(pal); #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) HWR_SetPalette(pLocalPalette); #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) else @@ -528,7 +528,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca #ifdef HWRENDER //if (rendermode != render_soft && !con_startup) // Why? - if (rendermode != render_soft) + if (rendermode == render_opengl) { HWR_DrawStretchyFixedPatch((GLPatch_t *)patch, x, y, pscale, vscale, scrn, colormap); return; @@ -828,7 +828,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ #ifdef HWRENDER //if (rendermode != render_soft && !con_startup) // Not this again - if (rendermode != render_soft) + if (rendermode == render_opengl) { HWR_DrawCroppedPatch((GLPatch_t*)patch,x,y,pscale,scrn,sx,sy,w,h); return; @@ -1152,7 +1152,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) #ifdef HWRENDER //if (rendermode != render_soft && !con_startup) // Not this again - if (rendermode != render_soft) + if (rendermode == render_opengl) { HWR_DrawFill(x, y, w, h, c); return; @@ -1349,7 +1349,7 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) return; #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { UINT32 hwcolor = V_GetHWConsBackColor(); HWR_DrawConsoleFill(x, y, w, h, c, hwcolor); // we still use the regular color stuff but only for flags. actual draw color is "hwcolor" for this. @@ -1546,7 +1546,7 @@ void V_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c, UINT16 color, U return; #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { // ughhhhh please can someone else do this? thanks ~toast 25/7/19 in 38 degrees centigrade w/o AC HWR_DrawFadeFill(x, y, w, h, c, color, strength); // toast two days later - left above comment in 'cause it's funny @@ -1708,7 +1708,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum) size_t size, lflatsize, flatshift; #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { HWR_DrawFlatFill(x, y, w, h, flatnum); return; @@ -1818,7 +1818,7 @@ void V_DrawPatchFill(patch_t *pat) void V_DrawFadeScreen(UINT16 color, UINT8 strength) { #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { HWR_FadeScreenMenuBack(color, strength); return; @@ -1847,7 +1847,7 @@ void V_DrawFadeConsBack(INT32 plines) UINT8 *deststop, *buf; #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { UINT32 hwcolor = V_GetHWConsBackColor(); HWR_DrawConsoleBack(hwcolor, plines); @@ -1880,7 +1880,7 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color) color = cons_backcolor.value; #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { UINT32 hwcolor; switch (color) @@ -3089,8 +3089,7 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param) INT32 height, yoffset; #ifdef HWRENDER - // draw a hardware converted patch - if (rendermode != render_soft && rendermode != render_none) + if (rendermode != render_soft) return; #endif diff --git a/src/w_wad.c b/src/w_wad.c index a86e99237..bcccb5b96 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -803,6 +803,11 @@ UINT16 W_InitFile(const char *filename, boolean mainfile) wadfiles[numwadfiles] = wadfile; numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded +#ifdef HWRENDER + if (rendermode == render_opengl) + HWR_LoadShaders(numwadfiles - 1, (wadfile->type == RET_PK3)); +#endif + // TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now. switch (wadfile->type) { @@ -1590,7 +1595,7 @@ void W_UnlockCachedPatch(void *patch) // The hardware code does its own memory management, as its patches // have different lifetimes from software's. #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) HWR_UnlockCachedPatch((GLPatch_t*)patch); else #endif @@ -1884,6 +1889,11 @@ int W_VerifyNMUSlumps(const char *filename) {"M_", 2}, // As does menu stuff {"MUSICDEF", 8}, // Song definitions (thanks kart) +#ifdef HWRENDER + {"SHADERS", 7}, + {"SH_", 3}, +#endif + {NULL, 0}, }; return W_VerifyFile(filename, NMUSlist, false); diff --git a/src/z_zone.c b/src/z_zone.c index daad5489d..b1a44b392 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -776,7 +776,7 @@ static void Command_Memfree_f(void) sizeu1(Z_TagsUsage(PU_PURGELEVEL, INT32_MAX)>>10)); #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + 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)); From 439474882ad95db26b1b230a73e0b22f8a5767ad Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 25 Dec 2019 18:46:30 -0500 Subject: [PATCH 002/168] Update blend textures to smooth out colors that have duplicate indices --- src/dehacked.c | 8 ++-- src/f_finale.h | 4 +- src/f_wipe.c | 2 +- src/hardware/hw_md2.c | 101 ++++++++++++++++++++++++++++++++---------- src/p_mobj.c | 2 +- src/p_setup.c | 8 ++-- 6 files changed, 89 insertions(+), 36 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 530667c11..0d1881c25 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4127,8 +4127,8 @@ static void readwipes(MYFILE *f) else if (fastncmp(word, "SPECLEVEL_", 10)) { pword = word + 10; - if (fastcmp(pword, "tHITE")) - wipeoffset = wipe_speclevel_thite; + if (fastcmp(pword, "TOWHITE")) + wipeoffset = wipe_speclevel_towhite; } if (wipeoffset < 0) @@ -4138,10 +4138,10 @@ static void readwipes(MYFILE *f) } if (value == UINT8_MAX - && (wipeoffset <= wipe_level_toblack || wipeoffset >= wipe_speclevel_thite)) + && (wipeoffset <= wipe_level_toblack || wipeoffset >= wipe_speclevel_towhite)) { // Cannot disable non-toblack wipes - // (or the level toblack wipe, or the special thite wipe) + // (or the level toblack wipe, or the special towhite wipe) deh_warning("Wipes: can't disable wipe of type '%s'", word); continue; } diff --git a/src/f_finale.h b/src/f_finale.h index 0de570c7e..efc2de2e6 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -154,7 +154,7 @@ typedef enum { WSF_FADEOUT = 1, WSF_FADEIN = 1<<1, - WSF_tHITE = 1<<2, + WSF_TOWHITE = 1<<2, WSF_CROSSFADE = 1<<3, } wipestyleflags_t; extern wipestyleflags_t wipestyleflags; @@ -204,7 +204,7 @@ enum // custom intermissions wipe_specinter_toblack, wipe_multinter_toblack, - wipe_speclevel_thite, + wipe_speclevel_towhite, wipe_level_final, wipe_intermission_final, diff --git a/src/f_wipe.c b/src/f_wipe.c index 355fba4df..a83d104f2 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -68,7 +68,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = { 0, // wipe_specinter_toblack 0, // wipe_multinter_toblack - 0, // wipe_speclevel_thite + 0, // wipe_speclevel_towhite 0, // wipe_level_final 0, // wipe_intermission_final diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index f15063b30..0591f9b8f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -654,10 +654,14 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; RGBA_t *image, *blendimage, *cur, blendcolor; + UINT8 i; + + UINT8 translation[16]; // First the color index + UINT8 cutoff[16]; // Brightness cutoff before using the next color + UINT8 translen = 0; - // vanilla port - UINT8 translation[16]; memset(translation, 0, sizeof(translation)); + memset(cutoff, 0, sizeof(cutoff)); if (grmip->width == 0) { @@ -684,7 +688,33 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, blendcolor = V_GetColor(0); // initialize if (color != SKINCOLOR_NONE) - memcpy(&translation, &Color_Index[color - 1], 16); + { + UINT8 numdupes = 1; + + translation[translen] = Color_Index[color-1][0]; + cutoff[translen] = 255; + + for (i = 1; i < 16; i++) + { + if (translation[translen] == Color_Index[color-1][i]) + { + numdupes++; + continue; + } + + if (translen > 0) + { + cutoff[translen] = cutoff[translen-1] - (256 / (16 / numdupes)); + } + + numdupes = 1; + translen++; + + translation[translen] = (UINT8)Color_Index[color-1][i]; + } + + translen++; + } while (size--) { @@ -710,7 +740,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, // Turn everything below a certain blue threshold white if (image->s.red == 0 && image->s.green == 0 && image->s.blue <= 82) { - cur->s.red = cur->s.green = cur->s.blue = 255; + cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue); } else { @@ -762,6 +792,8 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, { UINT16 brightness; + I_Assert(translen > 0); + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 if (skinnum == TC_RAINBOW) { @@ -798,8 +830,8 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...) { RGBA_t nextcolor; - UINT8 firsti, secondi, mul; - UINT32 r, g, b; + UINT8 firsti, secondi, mul, mulmax; + INT32 r, g, b; // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors. // Ensue horrible mess. @@ -808,7 +840,6 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, UINT16 brightdif = 256; UINT8 colorbrightnesses[16]; INT32 compare, m, d; - UINT8 i; // Ignore pure white & pitch black if (brightness > 253 || brightness < 2) @@ -820,18 +851,21 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, firsti = 0; mul = 0; + mulmax = 1; - for (i = 0; i < 16; i++) + for (i = 0; i < translen; i++) { RGBA_t tempc = V_GetColor(translation[i]); SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison } - for (i = 0; i < 16; i++) + for (i = 0; i < translen; i++) { if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is) continue; + compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness)); + if (compare < brightdif) { brightdif = (UINT16)compare; @@ -840,7 +874,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, } secondi = firsti+1; // next color in line - if (secondi == 16) + if (secondi >= translen) { m = (INT16)brightness; // - 0; d = (INT16)colorbrightnesses[firsti]; // - 0; @@ -856,38 +890,57 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, // calculate the "gradient" multiplier based on how close this color is to the one next in line if (m <= 0 || d <= 0) + { mul = 0; + } else - mul = 15 - ((m * 16) / d); + { + mulmax = cutoff[firsti]; + if (secondi < translen) + mulmax -= cutoff[secondi]; + + mul = (mulmax-1) - ((m * mulmax) / d); + } } else { - // Thankfully, it's normally way more simple. - // Just convert brightness to a skincolor value, use remainder to find the gradient multipler - firsti = ((UINT8)(255-brightness) / 16); + // Just convert brightness to a skincolor value, use distance to next position to find the gradient multipler + firsti = 0; + + for (i = 1; i < translen; i++) + { + if (brightness >= cutoff[i]) + break; + firsti = i; + } + secondi = firsti+1; - mul = ((UINT8)(255-brightness) % 16); + + mulmax = cutoff[firsti]; + if (secondi < translen) + mulmax -= cutoff[secondi]; + + mul = cutoff[firsti] - brightness; } blendcolor = V_GetColor(translation[firsti]); - if (mul > 0 // If it's 0, then we only need the first color. - && translation[firsti] != translation[secondi]) // Some colors have duplicate colors in a row, so let's just save the process + if (mul > 0) // If it's 0, then we only need the first color. { - if (secondi == 16) // blend to black + if (secondi >= translen) // blend to black nextcolor = V_GetColor(31); else nextcolor = V_GetColor(translation[secondi]); // Find difference between points - r = (UINT32)(nextcolor.s.red - blendcolor.s.red); - g = (UINT32)(nextcolor.s.green - blendcolor.s.green); - b = (UINT32)(nextcolor.s.blue - blendcolor.s.blue); + r = (INT32)(nextcolor.s.red - blendcolor.s.red); + g = (INT32)(nextcolor.s.green - blendcolor.s.green); + b = (INT32)(nextcolor.s.blue - blendcolor.s.blue); // Find the gradient of the two points - r = ((mul * r) / 16); - g = ((mul * g) / 16); - b = ((mul * b) / 16); + r = ((mul * r) / mulmax); + g = ((mul * g) / mulmax); + b = ((mul * b) / mulmax); // Add gradient value to color blendcolor.s.red += r; diff --git a/src/p_mobj.c b/src/p_mobj.c index 0a2e1b66b..9b88758c6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13005,7 +13005,7 @@ static void P_SetObjectSpecial(mobj_t *mobj) } } -mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, mobjtype_t i) +static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, mobjtype_t i) { mobj_t *mobj = NULL; boolean doangle = true; diff --git a/src/p_setup.c b/src/p_setup.c index 2fb6ba48c..288a483f4 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2580,10 +2580,10 @@ boolean P_SetupLevel(boolean skipprecip) if (RESETMUSIC || strnicmp(S_MusicName(), (mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap-1]->musname : mapmusname, 7)) - S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_thite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE) + S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE) F_WipeStartScreen(); - wipestyleflags |= (WSF_FADEOUT|WSF_tHITE); + wipestyleflags |= (WSF_FADEOUT|WSF_TOWHITE); #ifdef HWRENDER // uh.......... @@ -2592,7 +2592,7 @@ boolean P_SetupLevel(boolean skipprecip) #endif F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_speclevel_thite], false); + F_RunWipe(wipedefs[wipe_speclevel_towhite], false); I_OsPolling(); I_FinishUpdate(); // page flip or blit buffer @@ -2618,7 +2618,7 @@ boolean P_SetupLevel(boolean skipprecip) if (G_GetModeAttackRetryFlag()) { if (modeattacking) - wipestyleflags |= (WSF_FADEOUT|WSF_tHITE); + wipestyleflags |= (WSF_FADEOUT|WSF_TOWHITE); G_ClearModeAttackRetryFlag(); } From 3eb6570123f4fb1e8d956a31f91ea90670b39263 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 25 Dec 2019 20:09:31 -0500 Subject: [PATCH 003/168] Fake contrast --- src/hardware/hw_main.c | 67 ++++++++++++++++++++++++++++++++++-------- src/hardware/hw_main.h | 1 + 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b33b930aa..5105ed77f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -674,6 +674,46 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) } #endif +static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y) +{ + INT16 finallight = lightnum; + + if (cv_grfakecontrast.value != 0) + { + const UINT8 contrast = 8; + fixed_t extralight = 0; + + if (cv_grfakecontrast.value == 2) // Smooth setting + { + extralight = -(contrast<>1)) >> FRACBITS; + } + else + { + if (v1y == v2y) + extralight = -contrast; + else if (v1x == v2x) + extralight = contrast; + } + + if (extralight != 0) + { + finallight += extralight; + + if (finallight < 0) + finallight = 0; + if (finallight > 255) + finallight = 255; + } + } + + return (FUINT)finallight; +} + // // HWR_SplitWall // @@ -692,19 +732,20 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, float endpegt, endpegb, endpegmul; float endheight = 0.0f, endbheight = 0.0f; - fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x); - fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo - fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x); - fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly // use this as a temp var to store P_GetZAt's return value each time fixed_t temp; #endif - INT32 solid, i; + fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x); + fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo + fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x); + fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo + + INT32 solid, i; lightlist_t * list = sector->lightlist; const UINT8 alpha = Surf->PolyColor.s.alpha; - FUINT lightnum = sector->lightlevel; + FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y); extracolormap_t *colormap = NULL; realtop = top = wallVerts[3].y; @@ -733,12 +774,12 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, { if (pfloor && (pfloor->flags & FF_FOG)) { - lightnum = pfloor->master->frontsector->lightlevel; + lightnum = HWR_CalcWallLight(pfloor->master->frontsector->lightlevel, v1x, v1y, v2x, v2y); colormap = pfloor->master->frontsector->extra_colormap; } else { - lightnum = *list[i].lightlevel; + lightnum = HWR_CalcWallLight(*list[i].lightlevel, v1x, v1y, v2x, v2y); colormap = *list[i].extra_colormap; } } @@ -1021,7 +1062,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT)); } - lightnum = gr_frontsector->lightlevel; + lightnum = HWR_CalcWallLight(gr_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); colormap = gr_frontsector->extra_colormap; if (gr_frontsector) @@ -1784,7 +1825,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom blendmode = PF_Fog|PF_NoTexture; - lightnum = rover->master->frontsector->lightlevel; + lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); colormap = rover->master->frontsector->extra_colormap; Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); @@ -1896,7 +1937,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom blendmode = PF_Fog|PF_NoTexture; - lightnum = rover->master->frontsector->lightlevel; + lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); colormap = rover->master->frontsector->extra_colormap; Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); @@ -6125,6 +6166,7 @@ static void HWR_FoggingOn(void) static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; +static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}}; static void CV_grmodellighting_OnChange(void); static void CV_grfiltermode_OnChange(void); @@ -6161,6 +6203,7 @@ consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_O consvar_t cv_grshearing = {"gr_shearing", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -6229,7 +6272,7 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grskydome); CV_RegisterVar(&cv_grspritebillboarding); - + CV_RegisterVar(&cv_grfakecontrast); CV_RegisterVar(&cv_grshearing); CV_RegisterVar(&cv_grshaders); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 2b008a3ca..ae2e3230e 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -102,6 +102,7 @@ extern consvar_t cv_grsolvetjoin; extern consvar_t cv_grshearing; extern consvar_t cv_grspritebillboarding; extern consvar_t cv_grskydome; +extern consvar_t cv_grfakecontrast; extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy; From 4c6664292e1f9b0d5c2ff34e28f05a8b63a4dd45 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 25 Dec 2019 22:50:41 -0500 Subject: [PATCH 004/168] Increase precision of smooth contrast --- src/hardware/hw_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5105ed77f..7fd214a29 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -685,12 +685,11 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t if (cv_grfakecontrast.value == 2) // Smooth setting { - extralight = -(contrast<>1)) >> FRACBITS; + * (contrast * 2)) >> FRACBITS; } else { From 74d7f256a7849d0c829177614b37089e2446f86b Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 29 Dec 2019 16:36:53 -0500 Subject: [PATCH 005/168] More blend image updates - Allow the translations that don't make use a blend image to work without requiring a blend image to be present - Fix TC_RAINBOW not working properly - TC_METALSONIC now remaps the _blend image to SKINCOLOR_COBALT, then inverts all of the blue, replicating how it works in Software --- src/hardware/hw_md2.c | 502 ++++++++++++++++++++++-------------------- 1 file changed, 260 insertions(+), 242 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 02e8df9a3..903331a23 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -654,12 +654,12 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; RGBA_t *image, *blendimage, *cur, blendcolor; - UINT8 i; - UINT8 translation[16]; // First the color index UINT8 cutoff[16]; // Brightness cutoff before using the next color UINT8 translen = 0; + UINT8 i; + blendcolor = V_GetColor(0); // initialize memset(translation, 0, sizeof(translation)); memset(cutoff, 0, sizeof(cutoff)); @@ -685,7 +685,10 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, image = gpatch->mipmap->grInfo.data; blendimage = blendgpatch->mipmap->grInfo.data; - blendcolor = V_GetColor(0); // initialize + + // TC_METALSONIC includes an actual skincolor translation, on top of its flashing. + if (skinnum == TC_METALSONIC) + color = SKINCOLOR_COBALT; if (color != SKINCOLOR_NONE) { @@ -721,7 +724,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, if (skinnum == TC_BOSS) { // Turn everything below a certain threshold white - if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue <= 82) + if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue < 127) { // Lactozilla: Invert the colors cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue); @@ -735,53 +738,6 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, cur->s.alpha = image->s.alpha; } - else if (skinnum == TC_METALSONIC) - { - // Turn everything below a certain blue threshold white - if (image->s.red == 0 && image->s.green == 0 && image->s.blue <= 82) - { - cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue); - } - else - { - cur->s.red = image->s.red; - cur->s.green = image->s.green; - cur->s.blue = image->s.blue; - } - - cur->s.alpha = image->s.alpha; - } - else if (skinnum == TC_DASHMODE) - { - if (image->s.alpha == 0 && blendimage->s.alpha == 0) - { - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 - cur->rgba = image->rgba; - } - else - { - UINT8 ialpha = 255 - blendimage->s.alpha, balpha = blendimage->s.alpha; - RGBA_t icolor = *image, bcolor; - - memset(&bcolor, 0x00, sizeof(RGBA_t)); - - if (blendimage->s.alpha) - { - bcolor.s.blue = 0; - bcolor.s.red = 255; - bcolor.s.green = (blendimage->s.red + blendimage->s.green + blendimage->s.blue) / 3; - } - if (image->s.alpha && image->s.red > image->s.green << 1) // this is pretty arbitrary, but it works well for Metal Sonic - { - icolor.s.red = image->s.blue; - icolor.s.blue = image->s.red; - } - cur->s.red = (ialpha * icolor.s.red + balpha * bcolor.s.red)/255; - cur->s.green = (ialpha * icolor.s.green + balpha * bcolor.s.green)/255; - cur->s.blue = (ialpha * icolor.s.blue + balpha * bcolor.s.blue)/255; - cur->s.alpha = image->s.alpha; - } - } else if (skinnum == TC_ALLWHITE) { // Turn everything white @@ -790,208 +746,268 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, } else { - UINT16 brightness; + // Everything below requires a blend image + if (blendimage == NULL) + { + cur->rgba = image->rgba; + goto skippixel; + } - I_Assert(translen > 0); - - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 - if (skinnum == TC_RAINBOW) + // Metal Sonic dash mode + if (skinnum == TC_DASHMODE) { if (image->s.alpha == 0 && blendimage->s.alpha == 0) { + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 cur->rgba = image->rgba; - cur++; image++; blendimage++; - continue; } else { - UINT16 imagebright, blendbright; - SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); - SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue); - // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway - brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; + UINT8 ialpha = 255 - blendimage->s.alpha, balpha = blendimage->s.alpha; + RGBA_t icolor = *image, bcolor; + + memset(&bcolor, 0x00, sizeof(RGBA_t)); + + if (blendimage->s.alpha) + { + bcolor.s.blue = 0; + bcolor.s.red = 255; + bcolor.s.green = (blendimage->s.red + blendimage->s.green + blendimage->s.blue) / 3; + } + + if (image->s.alpha && image->s.red > image->s.green << 1) // this is pretty arbitrary, but it works well for Metal Sonic + { + icolor.s.red = image->s.blue; + icolor.s.blue = image->s.red; + } + + cur->s.red = (ialpha * icolor.s.red + balpha * bcolor.s.red)/255; + cur->s.green = (ialpha * icolor.s.green + balpha * bcolor.s.green)/255; + cur->s.blue = (ialpha * icolor.s.blue + balpha * bcolor.s.blue)/255; + cur->s.alpha = image->s.alpha; } } else { - if (blendimage->s.alpha == 0) + // All settings that use skincolors! + UINT16 brightness; + + if (translen <= 0) { cur->rgba = image->rgba; - cur++; image++; blendimage++; - continue; + goto skippixel; + } + + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 + if (skinnum == TC_RAINBOW) + { + if (image->s.alpha == 0 && blendimage->s.alpha == 0) + { + cur->rgba = image->rgba; + goto skippixel; + } + else + { + UINT16 imagebright, blendbright; + SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); + SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue); + // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway + brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; + } } else { - SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue); - } - } - - // Calculate a sort of "gradient" for the skincolor - // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...) - { - RGBA_t nextcolor; - UINT8 firsti, secondi, mul, mulmax; - INT32 r, g, b; - - // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors. - // Ensue horrible mess. - if (skinnum == TC_RAINBOW) - { - UINT16 brightdif = 256; - UINT8 colorbrightnesses[16]; - INT32 compare, m, d; - - // Ignore pure white & pitch black - if (brightness > 253 || brightness < 2) + if (blendimage->s.alpha == 0) { cur->rgba = image->rgba; - cur++; image++; blendimage++; - continue; + goto skippixel; // for metal sonic blend } - - firsti = 0; - mul = 0; - mulmax = 1; - - for (i = 0; i < translen; i++) + else { - RGBA_t tempc = V_GetColor(translation[i]); - SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison + SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue); } + } - for (i = 0; i < translen; i++) + // Calculate a sort of "gradient" for the skincolor + // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...) + { + RGBA_t nextcolor; + UINT8 firsti, secondi, mul, mulmax; + INT32 r, g, b; + + // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors. + // Ensue horrible mess. + if (skinnum == TC_RAINBOW) { - if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is) - continue; + UINT16 brightdif = 256; + UINT8 colorbrightnesses[16]; + INT32 compare, m, d; - compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness)); - - if (compare < brightdif) + // Ignore pure white & pitch black + if (brightness > 253 || brightness < 2) { - brightdif = (UINT16)compare; - firsti = i; // best matching color that's equal brightness or darker + cur->rgba = image->rgba; + cur++; image++; blendimage++; + continue; } - } - secondi = firsti+1; // next color in line - if (secondi >= translen) - { - m = (INT16)brightness; // - 0; - d = (INT16)colorbrightnesses[firsti]; // - 0; - } - else - { - m = (INT16)brightness - (INT16)colorbrightnesses[secondi]; - d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi]; - } - - if (m >= d) - m = d-1; - - // calculate the "gradient" multiplier based on how close this color is to the one next in line - if (m <= 0 || d <= 0) - { + firsti = 0; mul = 0; + mulmax = 1; + + for (i = 0; i < translen; i++) + { + RGBA_t tempc = V_GetColor(translation[i]); + SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison + } + + for (i = 0; i < translen; i++) + { + if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is) + continue; + + compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness)); + + if (compare < brightdif) + { + brightdif = (UINT16)compare; + firsti = i; // best matching color that's equal brightness or darker + } + } + + secondi = firsti+1; // next color in line + if (secondi >= translen) + { + m = (INT16)brightness; // - 0; + d = (INT16)colorbrightnesses[firsti]; // - 0; + } + else + { + m = (INT16)brightness - (INT16)colorbrightnesses[secondi]; + d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi]; + } + + if (m >= d) + m = d-1; + + mulmax = 16; + + // calculate the "gradient" multiplier based on how close this color is to the one next in line + if (m <= 0 || d <= 0) + mul = 0; + else + mul = (mulmax-1) - ((m * mulmax) / d); } else { + // Just convert brightness to a skincolor value, use distance to next position to find the gradient multipler + firsti = 0; + + for (i = 1; i < translen; i++) + { + if (brightness >= cutoff[i]) + break; + firsti = i; + } + + secondi = firsti+1; + mulmax = cutoff[firsti]; if (secondi < translen) mulmax -= cutoff[secondi]; - mul = (mulmax-1) - ((m * mulmax) / d); + mul = cutoff[firsti] - brightness; } + + blendcolor = V_GetColor(translation[firsti]); + + if (mul > 0) // If it's 0, then we only need the first color. + { + if (secondi >= translen) // blend to black + nextcolor = V_GetColor(31); + else + nextcolor = V_GetColor(translation[secondi]); + + // Find difference between points + r = (INT32)(nextcolor.s.red - blendcolor.s.red); + g = (INT32)(nextcolor.s.green - blendcolor.s.green); + b = (INT32)(nextcolor.s.blue - blendcolor.s.blue); + + // Find the gradient of the two points + r = ((mul * r) / mulmax); + g = ((mul * g) / mulmax); + b = ((mul * b) / mulmax); + + // Add gradient value to color + blendcolor.s.red += r; + blendcolor.s.green += g; + blendcolor.s.blue += b; + } + } + + if (skinnum == TC_RAINBOW) + { + UINT32 tempcolor; + UINT16 colorbright; + + SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue); + if (colorbright == 0) + colorbright = 1; // no dividing by 0 please + + tempcolor = (brightness * blendcolor.s.red) / colorbright; + tempcolor = min(255, tempcolor); + cur->s.red = (UINT8)tempcolor; + + tempcolor = (brightness * blendcolor.s.green) / colorbright; + tempcolor = min(255, tempcolor); + cur->s.green = (UINT8)tempcolor; + + tempcolor = (brightness * blendcolor.s.blue) / colorbright; + tempcolor = min(255, tempcolor); + cur->s.blue = (UINT8)tempcolor; + cur->s.alpha = image->s.alpha; } else { - // Just convert brightness to a skincolor value, use distance to next position to find the gradient multipler - firsti = 0; + // Color strength depends on image alpha + INT32 tempcolor; - for (i = 1; i < translen; i++) + tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); + cur->s.red = (UINT8)tempcolor; + + tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); + cur->s.green = (UINT8)tempcolor; + + tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); + cur->s.blue = (UINT8)tempcolor; + cur->s.alpha = image->s.alpha; + } + +skippixel: + + // *Now* we can do Metal Sonic's flashing + if (skinnum == TC_METALSONIC) + { + // Blend dark blue into white + if (cur->s.alpha > 0 && cur->s.red == 0 && cur->s.green == 0 && cur->s.blue < 255 && cur->s.blue > 31) { - if (brightness >= cutoff[i]) - break; - firsti = i; + // Sal: Invert non-blue + cur->s.red = cur->s.green = (255 - cur->s.blue); + cur->s.blue = 255; } - secondi = firsti+1; - - mulmax = cutoff[firsti]; - if (secondi < translen) - mulmax -= cutoff[secondi]; - - mul = cutoff[firsti] - brightness; + cur->s.alpha = image->s.alpha; } - - blendcolor = V_GetColor(translation[firsti]); - - if (mul > 0) // If it's 0, then we only need the first color. - { - if (secondi >= translen) // blend to black - nextcolor = V_GetColor(31); - else - nextcolor = V_GetColor(translation[secondi]); - - // Find difference between points - r = (INT32)(nextcolor.s.red - blendcolor.s.red); - g = (INT32)(nextcolor.s.green - blendcolor.s.green); - b = (INT32)(nextcolor.s.blue - blendcolor.s.blue); - - // Find the gradient of the two points - r = ((mul * r) / mulmax); - g = ((mul * g) / mulmax); - b = ((mul * b) / mulmax); - - // Add gradient value to color - blendcolor.s.red += r; - blendcolor.s.green += g; - blendcolor.s.blue += b; - } - } - - if (skinnum == TC_RAINBOW) - { - UINT32 tempcolor; - UINT16 colorbright; - - SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue); - if (colorbright == 0) - colorbright = 1; // no dividing by 0 please - - tempcolor = (brightness * blendcolor.s.red) / colorbright; - tempcolor = min(255, tempcolor); - cur->s.red = (UINT8)tempcolor; - - tempcolor = (brightness * blendcolor.s.green) / colorbright; - tempcolor = min(255, tempcolor); - cur->s.green = (UINT8)tempcolor; - - tempcolor = (brightness * blendcolor.s.blue) / colorbright; - tempcolor = min(255, tempcolor); - cur->s.blue = (UINT8)tempcolor; - cur->s.alpha = image->s.alpha; - } - else - { - // Color strength depends on image alpha - INT32 tempcolor; - - tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255); - tempcolor = min(255, tempcolor); - cur->s.red = (UINT8)tempcolor; - - tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255); - tempcolor = min(255, tempcolor); - cur->s.green = (UINT8)tempcolor; - - tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255); - tempcolor = min(255, tempcolor); - cur->s.blue = (UINT8)tempcolor; - cur->s.alpha = image->s.alpha; } } - cur++; image++; blendimage++; + cur++; image++; + + if (blendimage != NULL) + blendimage++; } return; @@ -1030,6 +1046,14 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT // If here, the blended texture has not been created // So we create it + if ((blendgpatch && blendgpatch->mipmap->grInfo.format) + && (gpatch->width != blendgpatch->width || gpatch->height != blendgpatch->height)) + { + // Blend image exists, but it's bad. + HWD.pfnSetTexture(gpatch->mipmap); + return; + } + //BP: WARNING: don't free it manually without clearing the cache of harware renderer // (it have a liste of mipmap) // this malloc is cleared in HWR_FreeTextureCache @@ -1269,50 +1293,44 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { - if (md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format - && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) - { - INT32 skinnum = INT32_MAX; - if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" - { - if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized) - skinnum = TC_ALLWHITE; - else if (spr->mobj->type == MT_METALSONIC_BATTLE) - skinnum = TC_METALSONIC; - else - skinnum = TC_BOSS; - } - else if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE) - { - if (spr->mobj->colorized) - skinnum = TC_RAINBOW; - else if (spr->mobj->player && spr->mobj->player->dashmode >= DASHMODE_THRESHOLD - && (spr->mobj->player->charflags & SF_DASHMODE) - && ((leveltime/2) & 1)) - { - if (spr->mobj->player->charflags & SF_MACHINE) - skinnum = TC_DASHMODE; - else - skinnum = TC_RAINBOW; - } - else if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - skinnum = (INT32)((skin_t*)spr->mobj->skin-skins); - else - skinnum = TC_DEFAULT; - } + INT32 skinnum = INT32_MAX; - // Translation or skin number found - if (skinnum != INT32_MAX) - HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); + if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" + { + if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized) + skinnum = TC_ALLWHITE; + else if (spr->mobj->type == MT_METALSONIC_BATTLE) + skinnum = TC_METALSONIC; else + skinnum = TC_BOSS; + } + else if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE) + { + if (spr->mobj->colorized) + skinnum = TC_RAINBOW; + else if (spr->mobj->player && spr->mobj->player->dashmode >= DASHMODE_THRESHOLD + && (spr->mobj->player->charflags & SF_DASHMODE) + && ((leveltime/2) & 1)) { - // Sorry nothing - HWD.pfnSetTexture(gpatch->mipmap); + if (spr->mobj->player->charflags & SF_MACHINE) + skinnum = TC_DASHMODE; + else + skinnum = TC_RAINBOW; } + else if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + skinnum = (INT32)((skin_t*)spr->mobj->skin-skins); + else + skinnum = TC_DEFAULT; + } + + // Translation or skin number found + if (skinnum != INT32_MAX) + { + HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); } else { - // This is safe, since we know the texture has been downloaded + // Sorry nothing HWD.pfnSetTexture(gpatch->mipmap); } } From a35a2c81e27414b49995bd04aea386bc8f5f0fef Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Tue, 7 Jan 2020 19:30:09 -0500 Subject: [PATCH 006/168] Fix errors --- src/sdl/i_video.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5fa631c97..ceabb926d 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1722,8 +1722,6 @@ void I_StartupHardwareGraphics(void) #ifdef HWRENDER static boolean glstartup = false; if (!glstartup) - { - if (rendermode == render_opengl) { HWD.pfnInit = hwSym("Init",NULL); HWD.pfnFinishUpdate = NULL; @@ -1760,10 +1758,7 @@ void I_StartupHardwareGraphics(void) HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); HWD.pfnInitCustomShaders = hwSym("InitCustomShaders",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); - if (!HWD.pfnInit(I_Error)) // let load the OpenGL library + if (!HWD.pfnInit()) // let load the OpenGL library rendermode = render_soft; else glstartup = true; From 7d8ff430190c33c257848e6d3c04327655202224 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Tue, 7 Jan 2020 20:55:36 -0500 Subject: [PATCH 007/168] Basic fog shader HWR_FogBlockAlpha is still very inaccurate, which gives different results than Software even with the shader, but it's a start --- src/hardware/hw_main.c | 29 +++++++++++++--------- src/hardware/r_opengl/r_opengl.c | 42 ++++++++++++++++---------------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2ce8c1364..5568ff6e5 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -216,20 +216,27 @@ UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if RGBA_t realcolor, surfcolor; INT32 alpha; - light = light - (255 - light); - - // Don't go out of bounds - if (light < 0) - light = 0; - else if (light > 255) - light = 255; - realcolor.rgba = (colormap != NULL) ? colormap->rgba : GL_DEFAULTMIX; - alpha = (realcolor.s.alpha*255)/25; + if (cv_grshaders.value) + { + surfcolor.s.alpha = (255 - light); + } + else + { + light = light - (255 - light); - // at 255 brightness, alpha is between 0 and 127, at 0 brightness alpha will always be 255 - surfcolor.s.alpha = (alpha*light)/(2*256)+255-light; + // Don't go out of bounds + if (light < 0) + light = 0; + else if (light > 255) + light = 255; + + alpha = (realcolor.s.alpha*255)/25; + + // at 255 brightness, alpha is between 0 and 127, at 0 brightness alpha will always be 255 + surfcolor.s.alpha = (alpha*light) / (2*256) + 255-light; + } return surfcolor.s.alpha; } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 5689d7945..9b9b8c9dd 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -31,6 +31,7 @@ #include #include "r_opengl.h" #include "r_vbo.h" +#include "../../p_tick.h" // for leveltime (NOTE: THIS IS BAD, FIGURE OUT HOW TO PROPERLY IMPLEMENT gl_leveltime) #if defined (HWRENDER) && !defined (NOROPENGL) @@ -595,19 +596,6 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; // GLSL Software fragment shader // - -#if 0 -// Old ZDoom style -#define GLSL_DOOM_COLORMAP \ - "float R_DoomColormap(float light, float z)\n" \ - "{\n" \ - "float vis = min(29.0 / z, 24.0 / 32.0);\n" \ - "float shade = 2.0 - (light + 12.0) / 128.0;\n" \ - "float lightscale = shade - vis;\n" \ - "return lightscale * 31.0;\n" \ - "}\n" -#else -// TODO: This is R_PlaneColormap, need a way to get polygon normal to add R_WallColormap #define GLSL_DOOM_COLORMAP \ "float R_DoomColormap(float light, float z)\n" \ "{\n" \ @@ -617,7 +605,6 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; "float scale = 160.0 / (lightz + 1.0);\n" \ "return startmap - scale * 0.5;\n" \ "}\n" -#endif #define GLSL_DOOM_LIGHT_EQUATION \ "float R_DoomLightingEquation(float light)\n" \ @@ -666,6 +653,21 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; "gl_FragColor = final_color;\n" \ "}\0" +#define GLSL_FOG_FRAGMENT_SHADER \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "vec4 base_color = gl_Color;\n" \ + "vec4 final_color = base_color;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "gl_FragColor = final_color;\n" \ + "}\0" // // GLSL generic fragment shader @@ -698,9 +700,7 @@ static const char *fragment_shaders[] = { GLSL_SOFTWARE_FRAGMENT_SHADER, // Fog fragment shader - "void main(void) {\n" - "gl_FragColor = gl_Color;\n" - "}\0", + GLSL_FOG_FRAGMENT_SHADER, // Sky fragment shader "uniform sampler2D tex;\n" @@ -1812,12 +1812,12 @@ static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat * UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f); UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f); UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)leveltime) / TICRATE, pglUniform1f); // Custom shader uniforms - if (custom) - { - UNIFORM_1(shader->uniforms[gluniform_leveltime], (float)gl_leveltime, pglUniform1f); - } + //if (custom) { } + (void)custom; + #undef UNIFORM_1 #undef UNIFORM_2 #undef UNIFORM_3 From 465b3b155968f1298bf7b8b31790453fcb1b2146 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 8 Jan 2020 03:37:46 -0500 Subject: [PATCH 008/168] Water surface shader Does not warp anything beneath the surface YET, just the texture itself, but it's far better than nothing --- src/hardware/r_opengl/r_opengl.c | 46 ++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 9b9b8c9dd..9253cab51 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -653,6 +653,48 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; "gl_FragColor = final_color;\n" \ "}\0" +// +// Water surface shader +// +// Mostly guesstimated, rather than the rest being built off Software science. +// Still needs to distort things underneath/around the water... +// + +#define GLSL_WATER_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform vec4 poly_color;\n" \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + "uniform float leveltime;\n" \ + "const float freq = 0.025;\n" \ + "const float amp = 0.025;\n" \ + "const float speed = 2.0;\n" \ + "const float pi = 3.14159;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "float z = gl_FragCoord.z / gl_FragCoord.w;\n" \ + "float input = -pi * (z * freq) + (leveltime * speed);\n" \ + "float sdistort = sin(input) * amp;\n" \ + "float cdistort = cos(input) * amp;\n" \ + "vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n" \ + "vec4 base_color = texel * poly_color;\n" \ + "vec4 final_color = base_color;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "final_color.a = texel.a * poly_color.a;\n" \ + "gl_FragColor = final_color;\n" \ + "}\0" + +// +// Fog block shader +// +// Alpha of the planes themselves are still slightly off -- see HWR_FogBlockAlpha +// + #define GLSL_FOG_FRAGMENT_SHADER \ "uniform vec4 tint_color;\n" \ "uniform vec4 fade_color;\n" \ @@ -697,7 +739,7 @@ static const char *fragment_shaders[] = { GLSL_SOFTWARE_FRAGMENT_SHADER, // Water fragment shader - GLSL_SOFTWARE_FRAGMENT_SHADER, + GLSL_WATER_FRAGMENT_SHADER, // Fog fragment shader GLSL_FOG_FRAGMENT_SHADER, @@ -705,7 +747,7 @@ static const char *fragment_shaders[] = { // Sky fragment shader "uniform sampler2D tex;\n" "void main(void) {\n" - "gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n" \ + "gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n" "}\0", NULL, From fe809b2734d430655966151e56f96963e2d7b2cf Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 8 Jan 2020 04:10:23 -0500 Subject: [PATCH 009/168] Fullbright transparent planes (I disagree with this feature so hard but w/e) --- src/hardware/hw_main.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5568ff6e5..150ecbfaa 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4744,7 +4744,12 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo planeinfo[numplanes].isceiling = isceiling; planeinfo[numplanes].fixedheight = fixedheight; - planeinfo[numplanes].lightlevel = lightlevel; + + if (planecolormap && (planecolormap->fog & 1)) + planeinfo[numplanes].lightlevel = lightlevel; + else + planeinfo[numplanes].lightlevel = 255; + planeinfo[numplanes].levelflat = levelflat; planeinfo[numplanes].xsub = xsub; planeinfo[numplanes].alpha = alpha; @@ -4775,7 +4780,12 @@ void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polyse polyplaneinfo[numpolyplanes].isceiling = isceiling; polyplaneinfo[numpolyplanes].fixedheight = fixedheight; - polyplaneinfo[numpolyplanes].lightlevel = lightlevel; + + if (planecolormap && (planecolormap->fog & 1)) + polyplaneinfo[numpolyplanes].lightlevel = lightlevel; + else + polyplaneinfo[numpolyplanes].lightlevel = 255; + polyplaneinfo[numpolyplanes].levelflat = levelflat; polyplaneinfo[numpolyplanes].polysector = polysector; polyplaneinfo[numpolyplanes].alpha = alpha; From d865b72b13f68f26ba2551615600001f2ba631cb Mon Sep 17 00:00:00 2001 From: Nami <50415197+namishere@users.noreply.github.com> Date: Wed, 8 Jan 2020 03:48:30 -0800 Subject: [PATCH 010/168] Splits part of PTR_SlideTraverse into a lua-exposed function, exposes P_RailThinker --- src/lua_baselib.c | 26 ++++ src/p_local.h | 1 + src/p_map.c | 299 ++++++++++++++++++++++++---------------------- 3 files changed, 181 insertions(+), 145 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 695e9367e..b6edb5fc2 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -681,6 +681,17 @@ static int lib_pSpawnPlayerMissile(lua_State *L) return 1; } +static int lib_pRailThinker(lua_State *L) +{ + mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + NOHUD + INLEVEL + if (!mobj) + return LUA_ErrInvalid(L, "mobj_t"); + lua_pushboolean(L, P_RailThinker(mobj)); + return 1; +} + static int lib_pMobjFlip(lua_State *L) { mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -1406,6 +1417,19 @@ static int lib_pTeleportMove(lua_State *L) return 2; } +static int lib_pCheckMoveBlocked(lua_State *L) +{ + line_t *li = luaL_checkudata(L, 1, META_LINE); + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + INLEVEL + if (!li) + return LUA_ErrInvalid(L, "line_t"); + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + lua_pushboolean(L, P_CheckMoveBlocked(li, mo)); + return 1; +} + static int lib_pSlideMove(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -2979,6 +3003,7 @@ static luaL_Reg lib[] = { {"P_ColorTeamMissile",lib_pColorTeamMissile}, {"P_SPMAngle",lib_pSPMAngle}, {"P_SpawnPlayerMissile",lib_pSpawnPlayerMissile}, + {"P_RailThinker",lib_pRailThinker}, {"P_MobjFlip",lib_pMobjFlip}, {"P_GetMobjGravity",lib_pGetMobjGravity}, {"P_WeaponOrPanel",lib_pWeaponOrPanel}, @@ -3041,6 +3066,7 @@ static luaL_Reg lib[] = { {"P_TryMove",lib_pTryMove}, {"P_Move",lib_pMove}, {"P_TeleportMove",lib_pTeleportMove}, + {"P_CheckMoveBlocked",lib_pCheckMoveBlocked}, {"P_SlideMove",lib_pSlideMove}, {"P_BounceMove",lib_pBounceMove}, {"P_CheckSight", lib_pCheckSight}, diff --git a/src/p_local.h b/src/p_local.h index 88deb0942..22d732298 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -403,6 +403,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam); boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); boolean P_Move(mobj_t *actor, fixed_t speed); boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); +boolean P_CheckMoveBlocked(line_t *li, mobj_t *mo); void P_SlideMove(mobj_t *mo); void P_BounceMove(mobj_t *mo); boolean P_CheckSight(mobj_t *t1, mobj_t *t2); diff --git a/src/p_map.c b/src/p_map.c index 1b6f23cde..1ca4946ea 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3367,6 +3367,45 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) return false; } +// +//P_CheckMoveBlocked +// +boolean P_CheckMoveBlocked(line_t *li, mobj_t *mo) +{ + // one-sided linedefs are always solid to sliding movement. + // one-sided linedef + if (!li->backsector) + { + if (P_PointOnLineSide(mo->x, mo->y, li)) + return true; // don't hit the back side + return false; + } + + if (!(mo->flags & MF_MISSILE)) + { + if (li->flags & ML_IMPASSIBLE) + return false; + + if ((mo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS) + return false; + } + + // set openrange, opentop, openbottom + P_LineOpening(li, mo); + + if (openrange < mo->height) + return false; // doesn't fit + + if (opentop - mo->z < mo->height) + return false; // mobj is too high + + if (openbottom - mo->z > FixedMul(MAXSTEPMOVE, mo->scale)) + return false; // too big a step up + + // this line doesn't block movement + return true; +} + // // PTR_SlideTraverse // @@ -3378,163 +3417,133 @@ static boolean PTR_SlideTraverse(intercept_t *in) li = in->d.line; - // one-sided linedefs are always solid to sliding movement. - // one-sided linedef - if (!li->backsector) + if (!P_CheckMoveBlocked(li, slidemo)) { - if (P_PointOnLineSide(slidemo->x, slidemo->y, li)) - return true; // don't hit the back side - goto isblocking; - } - - if (!(slidemo->flags & MF_MISSILE)) - { - if (li->flags & ML_IMPASSIBLE) - goto isblocking; - - if ((slidemo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS) - goto isblocking; - } - - // set openrange, opentop, openbottom - P_LineOpening(li, slidemo); - - if (openrange < slidemo->height) - goto isblocking; // doesn't fit - - if (opentop - slidemo->z < slidemo->height) - goto isblocking; // mobj is too high - - if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale)) - goto isblocking; // too big a step up - - // this line doesn't block movement - return true; - - // the line does block movement, - // see if it is closer than best so far -isblocking: - if (li->polyobj && slidemo->player) - { - if ((li->polyobj->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS)) - P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); - } - - if (slidemo->player && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing) - && slidemo->player->charability == CA_GLIDEANDCLIMB) - { - line_t *checkline = li; - sector_t *checksector; - ffloor_t *rover; - fixed_t topheight, bottomheight; - boolean fofline = false; - INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - if (!side && li->backsector) - checksector = li->backsector; - else - checksector = li->frontsector; - - if (checksector->ffloors) + // the line does block movement, + // see if it is closer than best so far + if (li->polyobj && slidemo->player) { - for (rover = checksector->ffloors; rover; rover = rover->next) + if ((li->polyobj->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS)) + P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); + } + + if (slidemo->player && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing) + && slidemo->player->charability == CA_GLIDEANDCLIMB) + { + line_t *checkline = li; + sector_t *checksector; + ffloor_t *rover; + fixed_t topheight, bottomheight; + boolean fofline = false; + INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); + + if (!side && li->backsector) + checksector = li->backsector; + else + checksector = li->frontsector; + + if (checksector->ffloors) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - -#ifdef ESLOPE - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); -#endif - - if (topheight < slidemo->z) - continue; - - if (bottomheight > slidemo->z + slidemo->height) - continue; - - // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? - if (rover->master->flags & ML_TFERLINE) + for (rover = checksector->ffloors; rover; rover = rover->next) { - size_t linenum = li-checksector->lines[0]; - checkline = rover->master->frontsector->lines[0] + linenum; - fofline = true; - } + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) + continue; - break; + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + + #ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); + #endif + + if (topheight < slidemo->z) + continue; + + if (bottomheight > slidemo->z + slidemo->height) + continue; + + // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? + if (rover->master->flags & ML_TFERLINE) + { + size_t linenum = li-checksector->lines[0]; + checkline = rover->master->frontsector->lines[0] + linenum; + fofline = true; + } + + break; + } + } + + // see about climbing on the wall + if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) + { + boolean canclimb; + angle_t climbangle, climbline; + INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); + + climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y); + + if (whichside) // on second side? + climbline += ANGLE_180; + + climbangle += (ANGLE_90 * (whichside ? -1 : 1)); + + canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true); + + if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) + || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135)) + && canclimb) + { + slidemo->angle = climbangle; + /*if (!demoplayback || P_AnalogMove(slidemo->player)) + { + if (slidemo->player == &players[consoleplayer]) + localangle = slidemo->angle; + else if (slidemo->player == &players[secondarydisplayplayer]) + localangle2 = slidemo->angle; + }*/ + + if (!slidemo->player->climbing) + { + S_StartSound(slidemo->player->mo, sfx_s3k4a); + slidemo->player->climbing = 5; + } + + slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); + slidemo->player->glidetime = 0; + slidemo->player->secondjump = 0; + + if (slidemo->player->climbing > 1) + slidemo->momz = slidemo->momx = slidemo->momy = 0; + + if (fofline) + whichside = 0; + + if (!whichside) + { + slidemo->player->lastsidehit = checkline->sidenum[whichside]; + slidemo->player->lastlinehit = (INT16)(checkline - lines); + } + + P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); + } } } - // see about climbing on the wall - if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) + if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) { - boolean canclimb; - angle_t climbangle, climbline; - INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y); - - if (whichside) // on second side? - climbline += ANGLE_180; - - climbangle += (ANGLE_90 * (whichside ? -1 : 1)); - - canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true); - - if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) - || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135)) - && canclimb) - { - slidemo->angle = climbangle; - /*if (!demoplayback || P_AnalogMove(slidemo->player)) - { - if (slidemo->player == &players[consoleplayer]) - localangle = slidemo->angle; - else if (slidemo->player == &players[secondarydisplayplayer]) - localangle2 = slidemo->angle; - }*/ - - if (!slidemo->player->climbing) - { - S_StartSound(slidemo->player->mo, sfx_s3k4a); - slidemo->player->climbing = 5; - } - - slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); - slidemo->player->glidetime = 0; - slidemo->player->secondjump = 0; - - if (slidemo->player->climbing > 1) - slidemo->momz = slidemo->momx = slidemo->momy = 0; - - if (fofline) - whichside = 0; - - if (!whichside) - { - slidemo->player->lastsidehit = checkline->sidenum[whichside]; - slidemo->player->lastlinehit = (INT16)(checkline - lines); - } - - P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); - } + secondslidefrac = bestslidefrac; + secondslideline = bestslideline; + bestslidefrac = in->frac; + bestslideline = li; } - } - if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) - { - secondslidefrac = bestslidefrac; - secondslideline = bestslideline; - bestslidefrac = in->frac; - bestslideline = li; + return false; // stop } - - return false; // stop + return true; // keep going! } // From d87f2565f1e45904109f677c64a9ed253b26791a Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sat, 11 Jan 2020 09:36:47 -0500 Subject: [PATCH 011/168] How'd this happen...? --- src/command.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/command.c b/src/command.c index 77f1d71b9..2893106dd 100644 --- a/src/command.c +++ b/src/command.c @@ -2110,20 +2110,15 @@ void CV_SaveVariables(FILE *f) for (cvar = consvar_vars; cvar; cvar = cvar->next) if (cvar->flags & CV_SAVE) { - char stringtrite[MAXTEXTCMD+1]; + char stringtowrite[MAXTEXTCMD+1]; // Silly hack for Min/Max vars if (!strcmp(cvar->string, "MAX") || !strcmp(cvar->string, "MIN")) - { - if (cvar->flags & CV_FLOAT) - sprintf(stringtowrite, "%f", FIXED_TO_FLOAT(cvar->value)); - else - sprintf(stringtowrite, "%d", cvar->value); - } + sprintf(stringtowrite, "%d", cvar->value); else - strcpy(stringtrite, cvar->string); + strcpy(stringtowrite, cvar->string); - fprintf(f, "%s \"%s\"\n", cvar->name, stringtrite); + fprintf(f, "%s \"%s\"\n", cvar->name, stringtowrite); } } From c98497e6c5e97345e5e1839439f4d88295e41d80 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sat, 11 Jan 2020 10:14:20 -0500 Subject: [PATCH 012/168] More breakage --- src/p_map.c | 25 ------------------------- src/p_maputl.h | 2 +- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index d1d175f8a..266c5e579 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3424,31 +3424,6 @@ boolean P_CheckMoveBlocked(line_t *li, mobj_t *mo) return true; } - if (!(mo->flags & MF_MISSILE)) - { - if (li->flags & ML_IMPASSIBLE) - return false; - - if ((mo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS) - return false; - } - - // set openrange, opentop, openbottom - P_LineOpening(li, mo); - - if (openrange < mo->height) - return false; // doesn't fit - - if (opentop - mo->z < mo->height) - return false; // mobj is too high - - if (openbottom - mo->z > FixedMul(MAXSTEPMOVE, mo->scale)) - return false; // too big a step up - - // this line doesn't block movement - return true; -} - // // PTR_SlideTraverse // diff --git a/src/p_maputl.h b/src/p_maputl.h index 16cfc834e..d73dae5e6 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -60,7 +60,7 @@ extern pslope_t *opentopslope, *openbottomslope; #endif extern ffloor_t *openfloorrover, *openceilingrover; -void P_LineOpening(line_t *plinedef, mobj_t *mobj); +void P_LineOpening(line_t *linedef, mobj_t *mobj); boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean(*func)(line_t *)); boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *)); From ef81bf810b6f828714e9fbfee631cd93f9037ee7 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 16 Jan 2020 14:56:11 -0500 Subject: [PATCH 013/168] ?? did not commit?? --- src/doomdef.h | 3 --- src/r_main.h | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 51495eba3..928fd53db 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -501,9 +501,6 @@ extern INT32 cv_debug; extern UINT8 shiftdown, ctrldown, altdown; extern boolean capslock; -// WARNING: a should be unsigned but to add with 2048, it isn't! -#define AIMINGTODY(a) (FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160) - // if we ever make our alloc stuff... #define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL) #define ZZ_Calloc(x) Z_Calloc(x, PU_STATIC, NULL) diff --git a/src/r_main.h b/src/r_main.h index 4654f4d72..a624d8773 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -26,6 +26,10 @@ extern INT32 centerx, centery; extern fixed_t centerxfrac, centeryfrac; extern fixed_t projection, projectiony; +extern fixed_t fovtan; + +// WARNING: a should be unsigned but to add with 2048, it isn't! +#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan) extern size_t validcount, linecount, loopcount, framecount; From 56f96674b03be8c9db0e09d33b363423eb5699a6 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 16 Jan 2020 16:45:49 -0500 Subject: [PATCH 014/168] Slope contrast Off by default --- src/hardware/hw_main.c | 128 ++++++++++++++++++++++++++++------------- src/hardware/hw_main.h | 1 + 2 files changed, 90 insertions(+), 39 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2df11f08c..b4403a8f6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -242,6 +242,89 @@ UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if return surfcolor.s.alpha; } +static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y) +{ + INT16 finallight = lightnum; + + if (cv_grfakecontrast.value != 0) + { + const UINT8 contrast = 8; + fixed_t extralight = 0; + + if (cv_grfakecontrast.value == 2) // Smooth setting + { + extralight = (-(contrast<> FRACBITS; + } + else + { + if (v1y == v2y) + extralight = -contrast; + else if (v1x == v2x) + extralight = contrast; + } + + if (extralight != 0) + { + finallight += extralight; + + if (finallight < 0) + finallight = 0; + if (finallight > 255) + finallight = 255; + } + } + + return (FUINT)finallight; +} + +static FUINT HWR_CalcSlopeLight(FUINT lightnum, angle_t dir, fixed_t delta) +{ + INT16 finallight = lightnum; + + if (cv_grfakecontrast.value != 0 && cv_grslopecontrast.value != 0) + { + const UINT8 contrast = 8; + fixed_t extralight = 0; + + if (cv_grfakecontrast.value == 2) // Smooth setting + { + fixed_t dirmul = abs(FixedDiv(AngleFixed(dir) - (180<> FRACBITS; + } + else + { + dir = ((dir + ANGLE_45) / ANGLE_90) * ANGLE_90; + + if (dir == ANGLE_180) + extralight = -contrast; + else if (dir == 0) + extralight = contrast; + + if (delta >= FRACUNIT/2) + extralight *= 2; + } + + if (extralight != 0) + { + finallight += extralight; + + if (finallight < 0) + finallight = 0; + if (finallight > 255) + finallight = 255; + } + } + + return (FUINT)finallight; +} + // ========================================================================== // FLOOR/CEILING GENERATION FROM SUBSECTORS // ========================================================================== @@ -459,6 +542,11 @@ static void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t f #endif } +#ifdef ESLOPE + if (slope) + lightlevel = HWR_CalcSlopeLight(lightlevel, R_PointToAngle2(0, 0, slope->normal.x, slope->normal.y), abs(slope->zdelta)); +#endif + HWR_Lighting(&Surf, lightlevel, planecolormap); if (PolyFlags & (PF_Translucent|PF_Fog)) @@ -682,45 +770,6 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) } #endif -static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y) -{ - INT16 finallight = lightnum; - - if (cv_grfakecontrast.value != 0) - { - const UINT8 contrast = 8; - fixed_t extralight = 0; - - if (cv_grfakecontrast.value == 2) // Smooth setting - { - extralight = (-(contrast<> FRACBITS; - } - else - { - if (v1y == v2y) - extralight = -contrast; - else if (v1x == v2x) - extralight = contrast; - } - - if (extralight != 0) - { - finallight += extralight; - - if (finallight < 0) - finallight = 0; - if (finallight > 255) - finallight = 255; - } - } - - return (FUINT)finallight; -} - // // HWR_SplitWall // @@ -6105,6 +6154,7 @@ consvar_t cv_grshearing = {"gr_shearing", "Off", CV_SAVE, CV_OnOff, NULL, 0, NUL consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grslopecontrast = {"gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned, diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 8f022555b..a27bc5a74 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -104,6 +104,7 @@ extern consvar_t cv_grshearing; extern consvar_t cv_grspritebillboarding; extern consvar_t cv_grskydome; extern consvar_t cv_grfakecontrast; +extern consvar_t cv_grslopecontrast; extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy; From 7e333c63311cff34386c3d791c223cf013584f24 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sat, 18 Jan 2020 09:25:09 -0500 Subject: [PATCH 015/168] input is reserved apparently --- src/hardware/r_opengl/r_opengl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 051c31b47..b40c2b9e9 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -678,10 +678,10 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; GLSL_DOOM_COLORMAP \ GLSL_DOOM_LIGHT_EQUATION \ "void main(void) {\n" \ - "float z = gl_FragCoord.z / gl_FragCoord.w;\n" \ - "float input = -pi * (z * freq) + (leveltime * speed);\n" \ - "float sdistort = sin(input) * amp;\n" \ - "float cdistort = cos(input) * amp;\n" \ + "float z = (gl_FragCoord.z / gl_FragCoord.w) / 2;\n" \ + "float a = -pi * (z * freq) + (leveltime * speed);\n" \ + "float sdistort = sin(a) * amp;\n" \ + "float cdistort = cos(a) * amp;\n" \ "vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n" \ "vec4 base_color = texel * poly_color;\n" \ "vec4 final_color = base_color;\n" \ From 7266e0876a35c13f622214a224f312d133c20f5e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 19:17:05 -0300 Subject: [PATCH 016/168] towards --- src/doomdata.h | 2 +- src/f_finale.c | 12 ++++----- src/hardware/hw_main.c | 4 +-- src/m_fixed.c | 2 +- src/m_fixed.h | 2 +- src/p_enemy.c | 58 +++++++++++++++++++++--------------------- src/p_floor.c | 4 +-- src/p_inter.c | 2 +- src/p_local.h | 2 +- src/p_mobj.c | 10 ++++---- src/p_setup.c | 2 +- src/p_spec.c | 2 +- src/p_user.c | 4 +-- src/s_sound.c | 8 +++--- src/sounds.c | 8 +++--- src/sounds.h | 8 +++--- 16 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/doomdata.h b/src/doomdata.h index fdd7c291a..f6e7cb584 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -76,7 +76,7 @@ typedef struct { INT16 textureoffset, rowoffset; char toptexture[8], bottomtexture[8], midtexture[8]; - // Front sector, tards viewer. + // Front sector, towards viewer. INT16 sector; } ATTRPACK mapsidedef_t; diff --git a/src/f_finale.c b/src/f_finale.c index 68170767b..87e41df78 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -233,7 +233,7 @@ static tic_t cutscene_lasttextwrite = 0; // static UINT8 F_WriteText(void) { - INT32 numtrite = 1; + INT32 numtowrite = 1; const char *c; tic_t ltw = I_GetTime(); @@ -244,7 +244,7 @@ static UINT8 F_WriteText(void) if (cutscene_boostspeed) { // for custom cutscene speedup mode - numtrite = 8; + numtowrite = 8; } else { @@ -253,10 +253,10 @@ static UINT8 F_WriteText(void) return 1; if (cutscene_textspeed < 7) - numtrite = 8 - cutscene_textspeed; + numtowrite = 8 - cutscene_textspeed; } - for (;numtrite > 0;++cutscene_baseptr) + for (;numtowrite > 0;++cutscene_baseptr) { c = &cutscene_basetext[cutscene_baseptr]; if (!c || !*c || *c=='#') @@ -272,7 +272,7 @@ static UINT8 F_WriteText(void) else if ((UINT8)*c >= 0xB0 && (UINT8)*c <= (0xB0+TICRATE-1)) { cutscene_textcount = (INT32)((UINT8)*c - 0xAF); - numtrite = 0; + numtowrite = 0; continue; } @@ -280,7 +280,7 @@ static UINT8 F_WriteText(void) // Ignore other control codes (color) if ((UINT8)*c < 0x80) - --numtrite; + --numtowrite; } // Reset textcount for next tic based on speed // if it wasn't already set by a delay. diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index dcd13c93a..d28b14019 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3521,7 +3521,7 @@ static void HWR_RenderBSPNode(INT32 bspnum) // Decide which side the view point is on INT32 side = R_PointOnSide(dup_viewx, dup_viewy, bsp); - // Recursively divide front space (tard the viewer) + // Recursively divide front space (toward the viewer) HWR_RenderBSPNode(bsp->children[side]); // Possibly divide back space (away from viewer) @@ -3979,7 +3979,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) baseWallVerts[0].t = baseWallVerts[1].t = gpatch->max_t; } - // if it has a dispoffset, push it a little tards the camera + // if it has a dispoffset, push it a little towards the camera if (spr->dispoffset) { float co = -gr_viewcos*(0.05f*spr->dispoffset); float si = -gr_viewsin*(0.05f*spr->dispoffset); diff --git a/src/m_fixed.c b/src/m_fixed.c index 3bd675dbe..6be54c486 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -670,7 +670,7 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin // 3) If we take the dot product between our line vector and the normal of the polygon, // this will give us the cosine of the angle between the 2 (since they are both normalized - length 1). - // We will then divide our Numerator by this value to find the offset tards the plane from our arbitrary point. + // We will then divide our Numerator by this value to find the offset towards the plane from our arbitrary point. Denominator = FV3_Dot(vNormal, &vLineDir); // Get the dot product of the line's vector and the normal of the plane // Since we are using division, we need to make sure we don't get a divide by zero error diff --git a/src/m_fixed.h b/src/m_fixed.h index 34d13fa23..02d4c73ff 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -264,7 +264,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedTrunc(fixed_t x) const fixed_t i = (a>>FRACBITS)< 0) return x-f; else diff --git a/src/p_enemy.c b/src/p_enemy.c index a95c631dc..763146d81 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1033,7 +1033,7 @@ void A_Chase(mobj_t *actor) actor->threshold--; } - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -1090,7 +1090,7 @@ nomissile: && P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase tards player + // chase towards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } @@ -1123,7 +1123,7 @@ void A_FaceStabChase(mobj_t *actor) actor->threshold--; } - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -1180,7 +1180,7 @@ nomissile: && P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase tards player + // chase towards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } @@ -1491,7 +1491,7 @@ void A_JetJawChomp(mobj_t *actor) return; #endif - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -1511,7 +1511,7 @@ void A_JetJawChomp(mobj_t *actor) return; } - // chase tards player + // chase towards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } @@ -1913,7 +1913,7 @@ void A_SharpChase(mobj_t *actor) actor->reactiontime--; - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -1935,7 +1935,7 @@ void A_SharpChase(mobj_t *actor) return; } - // chase tards player + // chase towards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } @@ -2467,7 +2467,7 @@ void A_VultureBlast(mobj_t *actor) // Function: A_VultureFly // -// Description: Vulture charging tards target. +// Description: Vulture charging towards target. // // var1 = unused // var2 = unused @@ -2590,7 +2590,7 @@ void A_SkimChase(mobj_t *actor) actor->threshold--; } - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -2647,14 +2647,14 @@ nomissile: && P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase tards player + // chase towards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } // Function: A_FaceTarget // -// Description: Immediately turn to face tards your target. +// Description: Immediately turn to face towards your target. // // var1 = unused // var2 = unused @@ -2673,7 +2673,7 @@ void A_FaceTarget(mobj_t *actor) // Function: A_FaceTracer // -// Description: Immediately turn to face tards your tracer. +// Description: Immediately turn to face towards your tracer. // // var1 = unused // var2 = unused @@ -5375,7 +5375,7 @@ void A_JetChase(mobj_t *actor) actor->threshold--; } - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); if ((multiplayer || netgame) && !actor->threshold && (actor->target->health <= 0 || !P_CheckSight(actor, actor->target))) @@ -5389,7 +5389,7 @@ void A_JetChase(mobj_t *actor) return; // got a new target } - // chase tards player + // chase towards player if (ultimatemode) P_Thrust(actor, actor->angle, FixedMul(actor->info->speed/2, actor->scale)); else @@ -5942,7 +5942,7 @@ void A_DetonChase(mobj_t *actor) } } - // chase tards player + // chase towards player if ((dist = P_AproxDistance(xydist, actor->tracer->z-actor->z)) > FixedMul((actor->info->painchance << FRACBITS), actor->scale)) { @@ -7081,7 +7081,7 @@ void A_Boss1Chase(mobj_t *actor) if (actor->reactiontime) actor->reactiontime--; - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -7154,7 +7154,7 @@ nomissile: actor->momz = FixedMul(actor->momz,7*FRACUNIT/8); } - // chase tards player + // chase towards player if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) > actor->radius+actor->target->radius) { if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) @@ -7409,7 +7409,7 @@ void A_Boss7Chase(mobj_t *actor) return; } - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -7503,7 +7503,7 @@ void A_Boss7Chase(mobj_t *actor) if (leveltime & 1) { - // chase tards player + // chase towards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); } @@ -7644,7 +7644,7 @@ void A_Boss2PogoTarget(mobj_t *actor) actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); P_InstaThrust(actor, actor->angle, FixedDiv(P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y), airtime)); } - // Wander semi-randomly tards the player to get closer. + // Wander semi-randomly towards the player to get closer. else { UINT8 prandom = P_RandomByte(); @@ -7864,7 +7864,7 @@ void A_BuzzFly(mobj_t *actor) return; } - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); if (actor->target->health <= 0 || (!actor->threshold && !P_CheckSight(actor, actor->target))) @@ -7887,7 +7887,7 @@ void A_BuzzFly(mobj_t *actor) return; } - // chase tards player + // chase towards player { INT32 dist, realspeed; const fixed_t mf = 5*(FRACUNIT/4); @@ -7979,7 +7979,7 @@ void A_GuardChase(mobj_t *actor) } else // Break ranks! { - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -8006,7 +8006,7 @@ void A_GuardChase(mobj_t *actor) && P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase tards player + // chase towards player if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) { P_NewChaseDir(actor); @@ -10923,7 +10923,7 @@ void A_RemoteDamage(mobj_t *actor) // Function: A_HomingChase // -// Description: Actor chases directly tards its destination object +// Description: Actor chases directly towards its destination object // // var1 = speed multiple // var2 = destination: 0 = target, 1 = tracer @@ -11383,7 +11383,7 @@ void A_BrakChase(mobj_t *actor) actor->threshold--; } - // turn tards movement direction if not there yet + // turn towards movement direction if not there yet if (actor->movedir < NUMDIRS) { actor->angle &= (7<<29); @@ -11441,7 +11441,7 @@ void A_BrakChase(mobj_t *actor) && P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase tards player + // chase towards player if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); @@ -11502,7 +11502,7 @@ void A_BrakFireShot(mobj_t *actor) // Function: A_BrakLobShot // -// Description: Lobs an object at the floor about a third of the way tard your target. +// Description: Lobs an object at the floor about a third of the way toward your target. // Implication is it'll bounce the rest of the way. // (You can also just aim straight at the target, but whatever) // Formula grabbed from http://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Angle_required_to_hit_coordinate_.28x.2Cy.29 diff --git a/src/p_floor.c b/src/p_floor.c index b1e9d1fda..c23d469bc 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1349,13 +1349,13 @@ wegotit: { // Lower controlsec like a regular T_RaiseSector // Set the heights of all the other control sectors to - // be a gradient of this height tard the edges + // be a gradient of this height toward the edges } else { // Raise controlsec like a regular T_RaiseSector // Set the heights of all the other control sectors to - // be a gradient of this height tard the edges. + // be a gradient of this height toward the edges. } if (playeronme && controlsec) diff --git a/src/p_inter.c b/src/p_inter.c index ac9a6b1a7..71dcd70a1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2429,7 +2429,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget // Also, add to the link. // I don't know if NiGHTS did this, but // Sonic Time Attacked did and it seems like a good enough incentive - // to make people want to actually dash tards/paraloop enemies + // to make people want to actually dash towards/paraloop enemies if (++source->player->linkcount > source->player->maxlink) source->player->maxlink = source->player->linkcount; source->player->linktimer = nightslinktics; diff --git a/src/p_local.h b/src/p_local.h index 2a96b0558..a825c3400 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -203,7 +203,7 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type); void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range); void P_PlayLivesJingle(player_t *player); -#define P_PlayRinglossSound(s) S_StartSound(s, (mariomode) ? sfx_mario8 : sfx_alt1 + P_RandomKey(4)); +#define P_PlayRinglossSound(s) S_StartSound(s, (mariomode) ? sfx_mario8 : sfx_altow1 + P_RandomKey(4)); #define P_PlayDeathSound(s) S_StartSound(s, sfx_altdi1 + P_RandomKey(4)); #define P_PlayVictorySound(s) S_StartSound(s, sfx_victr1 + P_RandomKey(4)); diff --git a/src/p_mobj.c b/src/p_mobj.c index 6aacdffc9..a8599ceb5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2601,7 +2601,7 @@ static boolean P_ZMovement(mobj_t *mo) if (mo->flags & MF_FLOAT && mo->target && mo->health && !(mo->type == MT_EGGMOBILE) && mo->target->health > 0) { - // float down tards target if too close + // float down towards target if too close if (!(mo->flags2 & MF2_SKULLFLY) && !(mo->flags2 & MF2_INFLOAT)) { dist = P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y); @@ -2938,7 +2938,7 @@ static void P_PlayerZMovement(mobj_t *mo) if (mo->player->powers[pw_carry] == CR_NIGHTSMODE) { - // bounce off floor if you were flying tards it + // bounce off floor if you were flying towards it if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 0 && mo->player->flyangle < 180) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->player->flyangle > 180 && mo->player->flyangle <= 359)) { @@ -3088,7 +3088,7 @@ nightsdone: if (mo->player->powers[pw_carry] == CR_NIGHTSMODE) { - // bounce off ceiling if you were flying tards it + // bounce off ceiling if you were flying towards it if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 180 && mo->player->flyangle <= 359) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->player->flyangle > 0 && mo->player->flyangle < 180)) { @@ -6293,7 +6293,7 @@ static void P_MoveHoop(mobj_t *mobj) y = mobj->target->y; z = mobj->target->z+mobj->target->height/2; - // Make the sprite travel tards the center of the hoop + // Make the sprite travel towards the center of the hoop v[0] = FixedMul(FINECOSINE(fa),fuse); v[1] = 0; v[2] = FixedMul(FINESINE(fa),fuse); @@ -6762,7 +6762,7 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) if (!pos_lengthways[3] || P_MobjWasRemoved(mobj) || (mobj->flags & MF_NOCLIPHEIGHT)) goto cont; - if ((fa = ((center->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move tards center when the motion is tards/away from the ground, rather than alongside it + if ((fa = ((center->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it goto cont; if (mobj->subsector->sector->ffloors) diff --git a/src/p_setup.c b/src/p_setup.c index 3bc2a7c8c..c7f4cd81b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2367,7 +2367,7 @@ static void P_CreateBlockMap(void) // // If current block is the same as the ending vertex's block, exit loop. // - // Move to an adjacent block by moving tards the ending block in + // Move to an adjacent block by moving towards the ending block in // either the x or y direction, to the block which contains the linedef. { diff --git a/src/p_spec.c b/src/p_spec.c index 27f0002a6..e5b026a3d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6033,7 +6033,7 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) /** Adds a raise thinker. * A raise thinker checks to see if the * player is standing on its 3D Floor, - * and if so, raises the platform tards + * and if so, raises the platform towards * it's destination. Otherwise, it lowers * to the lowest nearby height if not * there already. diff --git a/src/p_user.c b/src/p_user.c index 268fc0b86..44bc31b90 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5205,7 +5205,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (!(player->pflags & (PF_THOKKED|PF_USEDOWN)) || (player->charflags & SF_MULTIABILITY)) { P_Telekinesis(player, - -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling tards player) + -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player) FixedMul(384*FRACUNIT, player->mo->scale)); } break; @@ -6196,7 +6196,7 @@ static void P_3dMovement(player_t *player) // The rest is unaffected. angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection; - if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face tard + if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) { P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); } diff --git a/src/s_sound.c b/src/s_sound.c index f95328e4b..c4c92ebf5 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -768,10 +768,10 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id) { switch (sfx_id) { -// case sfx_alt1: -// case sfx_alt2: -// case sfx_alt3: -// case sfx_alt4: +// case sfx_altow1: +// case sfx_altow2: +// case sfx_altow3: +// case sfx_altow4: // sfx_id = sfx_mario8; // break; case sfx_thok: diff --git a/src/sounds.c b/src/sounds.c index e2351a430..720ba851e 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -57,10 +57,10 @@ sfxinfo_t S_sfx[NUMSFX] = {"altdi2", false, 192, 16, -1, NULL, 0, SKSPLDET2, -1, LUMPERROR, "Dying"}, {"altdi3", false, 192, 16, -1, NULL, 0, SKSPLDET3, -1, LUMPERROR, "Dying"}, {"altdi4", false, 192, 16, -1, NULL, 0, SKSPLDET4, -1, LUMPERROR, "Dying"}, - {"alt1", false, 192, 16, -1, NULL, 0, SKSPLPAN1, -1, LUMPERROR, "Ring loss"}, - {"alt2", false, 192, 16, -1, NULL, 0, SKSPLPAN2, -1, LUMPERROR, "Ring loss"}, - {"alt3", false, 192, 16, -1, NULL, 0, SKSPLPAN3, -1, LUMPERROR, "Ring loss"}, - {"alt4", false, 192, 16, -1, NULL, 0, SKSPLPAN4, -1, LUMPERROR, "Ring loss"}, + {"altow1", false, 192, 16, -1, NULL, 0, SKSPLPAN1, -1, LUMPERROR, "Ring loss"}, + {"altow2", false, 192, 16, -1, NULL, 0, SKSPLPAN2, -1, LUMPERROR, "Ring loss"}, + {"altow3", false, 192, 16, -1, NULL, 0, SKSPLPAN3, -1, LUMPERROR, "Ring loss"}, + {"altow4", false, 192, 16, -1, NULL, 0, SKSPLPAN4, -1, LUMPERROR, "Ring loss"}, {"victr1", false, 64, 16, -1, NULL, 0, SKSPLVCT1, -1, LUMPERROR, "/"}, {"victr2", false, 64, 16, -1, NULL, 0, SKSPLVCT2, -1, LUMPERROR, "/"}, {"victr3", false, 64, 16, -1, NULL, 0, SKSPLVCT3, -1, LUMPERROR, "/"}, diff --git a/src/sounds.h b/src/sounds.h index 6880e44bb..039349d4f 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -106,10 +106,10 @@ typedef enum sfx_altdi2, sfx_altdi3, sfx_altdi4, - sfx_alt1, - sfx_alt2, - sfx_alt3, - sfx_alt4, + sfx_altow1, + sfx_altow2, + sfx_altow3, + sfx_altow4, sfx_victr1, sfx_victr2, sfx_victr3, From 014638ead711200f58ead5b2a9e636bef185d59e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 19:44:46 -0300 Subject: [PATCH 017/168] Fix view aiming / shearing --- src/hardware/hw_defs.h | 2 +- src/hardware/hw_main.c | 71 ++++++++++++++++---------------- src/hardware/r_opengl/r_opengl.c | 3 +- src/r_main.h | 2 +- 4 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index dfecbea85..2560d651f 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -121,7 +121,7 @@ typedef struct boolean mirror; // SRB2Kart: Encore Mode #endif boolean shearing; // 14042019 - angle_t viewaiming; // 17052019 + float viewaiming; // 17052019 } FTransform; // Transformed vector, as passed to HWR API diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d28b14019..6f0b645e5 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -149,10 +149,12 @@ static float gr_viewx, gr_viewy, gr_viewz; static float gr_viewsin, gr_viewcos; // Maybe not necessary with the new T&L code (needs to be checked!) -static angle_t gr_aimingangle; static float gr_viewludsin, gr_viewludcos; // look up down kik test static float gr_fovlud; +static angle_t gr_aimingangle; +static void HWR_SetTransformAiming(FTransform *trans); + // ========================================================================== // Lighting // ========================================================================== @@ -5478,7 +5480,7 @@ static void HWR_DrawSkyBackground(player_t *player) //04/01/2000: Hurdler: added for T&L // It should replace all other gr_viewxxx when finished - dometransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + HWR_SetTransformAiming(&dometransform); dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); if (*type == postimg_flip) @@ -5641,6 +5643,25 @@ void HWR_SetViewSize(void) HWD.pfnFlushScreenTextures(); } +// Set view aiming, for the sky dome, the skybox, +// and the normal view, all with a single function. +static void HWR_SetTransformAiming(FTransform *trans) +{ + if (cv_grshearing.value) + { + fixed_t fixedaiming = AIMINGTODY(aimingangle); + trans->viewaiming = FIXED_TO_FLOAT(fixedaiming); + trans->shearing = true; + gr_aimingangle = 0; + } + else + { + trans->shearing = false; + gr_aimingangle = aimingangle; + } + trans->anglex = (float)(gr_aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); +} + // ========================================================================== // Same as rendering the player view, but from the skybox object // ========================================================================== @@ -5693,16 +5714,16 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) gr_viewsin = FIXED_TO_FLOAT(viewsin); gr_viewcos = FIXED_TO_FLOAT(viewcos); - gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(aimingangle>>ANGLETOFINESHIFT)); - gr_viewludcos = FIXED_TO_FLOAT(-FINESINE(aimingangle>>ANGLETOFINESHIFT)); - //04/01/2000: Hurdler: added for T&L // It should replace all other gr_viewxxx when finished memset(&atransform, 0x00, sizeof(FTransform)); - atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + HWR_SetTransformAiming(&atransform); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(gr_aimingangle>>ANGLETOFINESHIFT)); + gr_viewludcos = FIXED_TO_FLOAT(-FINESINE(gr_aimingangle>>ANGLETOFINESHIFT)); + if (*type == postimg_flip) atransform.flip = true; else @@ -5715,17 +5736,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) atransform.scaley = (float)vid.width/vid.height; atransform.scalez = 1; - // 14042019 - gr_aimingangle = aimingangle; - atransform.shearing = false; - atransform.viewaiming = aimingangle; - - if (cv_grshearing.value) - { - gr_aimingangle = 0; - atransform.shearing = true; - } - atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails atransform.splitscreen = splitscreen; @@ -5787,14 +5797,14 @@ if (0) viewangle = localaiming2; // Handle stuff when you are looking farther up or down. - if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) + if ((gr_aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) { dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); HWR_RenderBSPNode((INT32)numnodes-1); //left dup_viewangle += ANGLE_90; - if (((INT32)aimingangle > ANGLE_45 || (INT32)aimingangle<-ANGLE_45)) + if (((INT32)gr_aimingangle > ANGLE_45 || (INT32)gr_aimingangle<-ANGLE_45)) { HWR_ClearClipSegs(); HWR_RenderBSPNode((INT32)numnodes-1); //back @@ -5914,16 +5924,16 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) gr_viewsin = FIXED_TO_FLOAT(viewsin); gr_viewcos = FIXED_TO_FLOAT(viewcos); - gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(aimingangle>>ANGLETOFINESHIFT)); - gr_viewludcos = FIXED_TO_FLOAT(-FINESINE(aimingangle>>ANGLETOFINESHIFT)); - //04/01/2000: Hurdler: added for T&L // It should replace all other gr_viewxxx when finished memset(&atransform, 0x00, sizeof(FTransform)); - atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + HWR_SetTransformAiming(&atransform); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(gr_aimingangle>>ANGLETOFINESHIFT)); + gr_viewludcos = FIXED_TO_FLOAT(-FINESINE(gr_aimingangle>>ANGLETOFINESHIFT)); + if (*type == postimg_flip) atransform.flip = true; else @@ -5936,17 +5946,6 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) atransform.scaley = (float)vid.width/vid.height; atransform.scalez = 1; - // 14042019 - gr_aimingangle = aimingangle; - atransform.shearing = false; - atransform.viewaiming = aimingangle; - - if (cv_grshearing.value) - { - gr_aimingangle = 0; - atransform.shearing = true; - } - atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails atransform.splitscreen = splitscreen; @@ -6008,14 +6007,14 @@ if (0) viewangle = localaiming2; // Handle stuff when you are looking farther up or down. - if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) + if ((gr_aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) { dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); HWR_RenderBSPNode((INT32)numnodes-1); //left dup_viewangle += ANGLE_90; - if (((INT32)aimingangle > ANGLE_45 || (INT32)aimingangle<-ANGLE_45)) + if (((INT32)gr_aimingangle > ANGLE_45 || (INT32)gr_aimingangle<-ANGLE_45)) { HWR_ClearClipSegs(); HWR_RenderBSPNode((INT32)numnodes-1); //back diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index b40c2b9e9..9a89567ea 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2858,8 +2858,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) // https://zdoom.org/wiki/Y-shearing if (shearing) { - fixed_t dy = AIMINGTODY(stransform->viewaiming); - float fdy = FIXED_TO_FLOAT(dy) * 2; //screen_width/BASEVIDWIDTH; + float fdy = stransform->viewaiming * 2; pglTranslatef(0.0f, -fdy/BASEVIDHEIGHT, 0.0f); } diff --git a/src/r_main.h b/src/r_main.h index 16ea4b3e2..8436998cb 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -29,7 +29,7 @@ extern fixed_t projection, projectiony; extern fixed_t fovtan; // WARNING: a should be unsigned but to add with 2048, it isn't! -#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan) +#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160), fovtan) extern size_t validcount, linecount, loopcount, framecount; From 1601f0c66f5b92bb2b72d6f8196f141083695515 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 20:12:15 -0300 Subject: [PATCH 018/168] Update copyright text --- src/hardware/hw3dsdrv.h | 18 +++++------------- src/hardware/hw3sound.c | 17 +++++------------ src/hardware/hw3sound.h | 18 +++++------------- src/hardware/hw_bsp.c | 17 +++++------------ src/hardware/hw_cache.c | 19 ++++++------------- src/hardware/hw_data.h | 21 +++++++-------------- src/hardware/hw_defs.h | 18 ++++++------------ src/hardware/hw_dll.h | 19 ++++++------------- src/hardware/hw_draw.c | 5 ++--- src/hardware/hw_drv.h | 19 ++++++------------- src/hardware/hw_glide.h | 17 +++++------------ src/hardware/hw_glob.h | 19 ++++++------------- src/hardware/hw_light.c | 18 ++++++------------ src/hardware/hw_light.h | 18 ++++++------------ src/hardware/hw_main.c | 18 ++++++------------ src/hardware/hw_main.h | 19 ++++++------------- src/hardware/hw_md2.c | 21 +++++++-------------- src/hardware/hw_md2.h | 21 +++++++-------------- src/hardware/hws_data.h | 19 ++++++------------- src/hardware/r_opengl/r_opengl.c | 20 ++++++-------------- 20 files changed, 114 insertions(+), 247 deletions(-) diff --git a/src/hardware/hw3dsdrv.h b/src/hardware/hw3dsdrv.h index 8811d4546..9b8670705 100644 --- a/src/hardware/hw3dsdrv.h +++ b/src/hardware/hw3dsdrv.h @@ -1,20 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 2001 by DooM Legacy Team. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw3dsdrv.h /// \brief 3D sound import/export prototypes for low-level hardware interface #ifndef __HW_3DS_DRV_H__ diff --git a/src/hardware/hw3sound.c b/src/hardware/hw3sound.c index f7c6e1da0..344d8b4c1 100644 --- a/src/hardware/hw3sound.c +++ b/src/hardware/hw3sound.c @@ -1,19 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 2001 by DooM Legacy Team. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw3sound.c /// \brief Hardware 3D sound general code #include "../doomdef.h" diff --git a/src/hardware/hw3sound.h b/src/hardware/hw3sound.h index a8a475b69..1796dd696 100644 --- a/src/hardware/hw3sound.h +++ b/src/hardware/hw3sound.h @@ -1,20 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 2001 by DooM Legacy Team. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw3sound.h /// \brief High-level functions of hardware 3D sound #ifndef __HW3_SOUND_H__ diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index 6f3dd9fbd..9cb062f8c 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -1,19 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_bsp.c /// \brief convert SRB2 map #include "../doomdef.h" diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index ccffc8a49..7c509c273 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -1,20 +1,13 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_cache.c /// \brief load and convert graphics to the hardware format #include "../doomdef.h" diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index f525e041f..4279b87f5 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -1,21 +1,14 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file -/// \brief defines structures and exports for the standard 3D driver DLL used by Doom Legacy +/// \file hw_data.h +/// \brief defines structures and exports for the hardware interface used by Sonic Robo Blast 2 #ifndef _HWR_DATA_ #define _HWR_DATA_ diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 2560d651f..85b8b52a2 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -1,19 +1,13 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_defs.h /// \brief 3D hardware renderer definitions #ifndef _HWR_DEFS_ diff --git a/src/hardware/hw_dll.h b/src/hardware/hw_dll.h index 43dfbcf0b..d7658c4da 100644 --- a/src/hardware/hw_dll.h +++ b/src/hardware/hw_dll.h @@ -1,19 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- +// Copyright (C) 2005 by Sonic Team Junior. // -// Copyright (C) 2005 by SRB2 Jr. Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_dll.h /// \brief Win32 DLL and Shared Objects API definitions #ifndef __HWR_DLL_H__ diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 746f1c9ec..beab3b290 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1,14 +1,13 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2019 by Sonic Team Junior. +// Copyright (C) 1999-2020 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_draw.c /// \brief miscellaneous drawing (mainly 2d) #ifdef __GNUC__ diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 400034bb2..40a9ace91 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -1,20 +1,13 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_drv.h /// \brief imports/exports for the 3D hardware low-level interface API #ifndef __HWR_DRV_H__ diff --git a/src/hardware/hw_glide.h b/src/hardware/hw_glide.h index bf91229ef..f539412af 100644 --- a/src/hardware/hw_glide.h +++ b/src/hardware/hw_glide.h @@ -1,19 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_glide.h /// \brief Declaration needed by Glide renderer /// !!! To be replaced by our own def in the future !!! diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index dbb31fb32..4003d8ef7 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -1,20 +1,13 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_glob.h /// \brief globals (shared data & code) for hw_ modules #ifndef _HWR_GLOB_H_ diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 99a45ee86..b8cca0576 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -1,19 +1,13 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_light.c /// \brief Corona/Dynamic/Static lighting add on by Hurdler /// !!! Under construction !!! diff --git a/src/hardware/hw_light.h b/src/hardware/hw_light.h index 2733cc698..3b12f9c87 100644 --- a/src/hardware/hw_light.h +++ b/src/hardware/hw_light.h @@ -1,19 +1,13 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_light.h /// \brief Dynamic lighting & coronas add on by Hurdler #ifndef _HW_LIGHTS_ diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6f0b645e5..1d009e624 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1,19 +1,13 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_main.c /// \brief hardware renderer, using the standard HardWareRender driver DLL for SRB2 #include diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index a27bc5a74..b06ff10b3 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -1,20 +1,13 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hw_main.h /// \brief 3D render mode functions #ifndef __HWR_MAIN_H__ diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9ff5df4dc..3914a1bcb 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1,23 +1,16 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file -/// \brief MD2 Handling +/// \file hw_md2.c +/// \brief 3D Model Handling /// Inspired from md2.c by Mete Ciragan (mete@swissquake.ch) - #ifdef __GNUC__ #include #endif diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 6f5985a44..479c68e5b 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -1,21 +1,14 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file -/// \brief MD2 Handling +/// \file hw_md2.h +/// \brief 3D Model Handling /// Inspired from md2.h by Mete Ciragan (mete@swissquake.ch) #ifndef _HW_MD2_H_ diff --git a/src/hardware/hws_data.h b/src/hardware/hws_data.h index b890d976b..a8607ac67 100644 --- a/src/hardware/hws_data.h +++ b/src/hardware/hws_data.h @@ -1,19 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- +// Copyright (C) 2005 by Sonic Team Junior. // -// Copyright (C) 2005 by SRB2 Jr. Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file hws_data.h /// \brief 3D sound definitions #ifndef __HWS_DATA_H__ diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 9a89567ea..132a9dbf3 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1,20 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- +// Copyright (C) 1998-2020 by Sonic Team Junior. // -// Copyright (C) 1998-2019 by Sonic Team Junior. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file +/// \file r_opengl.c /// \brief OpenGL API for Sonic Robo Blast 2 #if defined (_WIN32) From 544d6acc516a4aa13b9029b429a32ed0c084507e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 20:21:13 -0300 Subject: [PATCH 019/168] Delete USE_PALETTED_TEXTURE again --- src/Makefile | 2 -- src/hardware/r_opengl/r_opengl.c | 26 -------------------------- src/hardware/r_opengl/r_opengl.h | 4 ---- 3 files changed, 32 deletions(-) diff --git a/src/Makefile b/src/Makefile index c30c236de..eb92364bd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -222,8 +222,6 @@ endif ifdef NOHW OPTS+=-DNOHW else - #Hurdler: not really supported and not tested recently - #OPTS+=-DUSE_PALETTED_TEXTURE OPTS+=-DHWRENDER OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \ $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o \ diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 132a9dbf3..6174bb3ce 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -87,11 +87,6 @@ static GLfloat modelMatrix[16]; static GLfloat projMatrix[16]; static GLint viewport[4]; -#ifdef USE_PALETTED_TEXTURE - PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL; - GLubyte palette_tex[256*3]; -#endif - // Yay for arbitrary numbers! NextTexAvail is buggy for some reason. // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing // flush all of the stored textures, leaving them unavailable at times such as between levels @@ -1615,16 +1610,6 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) w = pTexInfo->width; h = pTexInfo->height; -#ifdef USE_PALETTED_TEXTURE - if (glColorTableEXT && - (pTexInfo->grInfo.format == GR_TEXFMT_P_8) && - !(pTexInfo->flags & TF_CHROMAKEYED)) - { - // do nothing here. - // Not a problem with MiniGL since we don't use paletted texture - } - else -#endif if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) || (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)) { @@ -1724,17 +1709,6 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); } -#ifdef USE_PALETTED_TEXTURE - //Hurdler: not really supported and not tested recently - if (glColorTableEXT && - (pTexInfo->grInfo.format == GR_TEXFMT_P_8) && - !(pTexInfo->flags & TF_CHROMAKEYED)) - { - glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex); - pglTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, w, h, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, pTexInfo->grInfo.data); - } - else -#endif if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) { //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index 6d11bf4e3..89920d4d4 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -73,10 +73,6 @@ void Flush(void); INT32 isExtAvailable(const char *extension, const GLubyte *start); void SetModelView(GLint w, GLint h); void SetStates(void); -#ifdef USE_PALETTED_TEXTURE -extern PFNGLCOLORTABLEEXTPROC glColorTableEXT; -extern GLubyte palette_tex[256*3]; -#endif #ifndef GL_EXT_texture_filter_anisotropic #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE From 1755c240bf4fe244955394222c629136ba161bcc Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 21:25:54 -0300 Subject: [PATCH 020/168] Fix the gl_leveltime problem, I guess. This is probably superfluous. --- src/hardware/hw_defs.h | 9 +++++++ src/hardware/hw_drv.h | 14 +++++----- src/hardware/hw_glob.h | 3 --- src/hardware/hw_main.c | 6 ++++- src/hardware/r_opengl/r_opengl.c | 45 +++++++++++++++++++++++++++----- src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 11 ++++---- 7 files changed, 68 insertions(+), 21 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 85b8b52a2..33f80a4d3 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -221,6 +221,15 @@ enum hwdsetspecialstate typedef enum hwdsetspecialstate hwdspecialstate_t; +// Lactozilla: Shader info +// Generally set at the start of the frame. +enum hwdshaderinfo +{ + HWD_SHADERINFO_LEVELTIME = 1, +}; + +typedef enum hwdshaderinfo hwdshaderinfo_t; + enum hwdfiltermode { HWD_SET_TEXTUREFILTER_POINTSAMPLED, diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 40a9ace91..99687ccf5 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -71,6 +71,7 @@ EXPORT void HWRAPI(KillShaders) (void); EXPORT void HWRAPI(SetShader) (int shader); EXPORT void HWRAPI(UnSetShader) (void); +EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value); EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment); EXPORT void HWRAPI(InitCustomShaders) (void); @@ -115,13 +116,14 @@ struct hwdriver_s MakeScreenFinalTexture pfnMakeScreenFinalTexture; DrawScreenFinalTexture pfnDrawScreenFinalTexture; - LoadShaders pfnLoadShaders; - KillShaders pfnKillShaders; - SetShader pfnSetShader; - UnSetShader pfnUnSetShader; + LoadShaders pfnLoadShaders; + KillShaders pfnKillShaders; + SetShader pfnSetShader; + UnSetShader pfnUnSetShader; - LoadCustomShader pfnLoadCustomShader; - InitCustomShaders pfnInitCustomShaders; + SetShaderInfo pfnSetShaderInfo; + LoadCustomShader pfnLoadCustomShader; + InitCustomShaders pfnInitCustomShaders; }; extern struct hwdriver_s hwdriver; diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 4003d8ef7..570074a09 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -108,9 +108,6 @@ GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump); GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum); void HWR_GetFadeMask(lumpnum_t fademasklumpnum); -// hardware driver -extern INT32 gl_leveltime; - // -------- // hw_draw.c // -------- diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 1d009e624..9dc1d0702 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5872,6 +5872,9 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) ClearColor.blue = 0.0f; ClearColor.alpha = 1.0f; + if (cv_grshaders.value) + HWD.pfnSetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime. + 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. @@ -6450,7 +6453,8 @@ void HWR_DoPostProcessor(player_t *player) } } HWD.pfnPostImgRedraw(v); - disStart += 1; + if (!(paused || P_AutoPause())) + disStart += 1; // Capture the screen again for screen waving on the intermission if(gamestate != GS_INTERMISSION) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6174bb3ce..d6e79b91c 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -24,7 +24,7 @@ #include "r_opengl.h" #include "r_vbo.h" -#include "../../p_tick.h" // for leveltime (NOTE: THIS IS BAD, FIGURE OUT HOW TO PROPERLY IMPLEMENT gl_leveltime) +//#include "../../p_tick.h" // for leveltime (NOTE: THIS IS BAD, FIGURE OUT HOW TO PROPERLY IMPLEMENT gl_leveltime) #include "../../r_main.h" // AIMINGTODY (ALSO BAD) #if defined (HWRENDER) && !defined (NOROPENGL) @@ -496,8 +496,6 @@ boolean SetupGLfunc(void) return true; } -INT32 gl_leveltime = 0; - #ifdef GL_SHADERS typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum); typedef void (APIENTRY *PFNglShaderSource) (GLuint, GLsizei, const GLchar**, GLint*); @@ -577,6 +575,9 @@ typedef struct gl_shaderprogram_s } gl_shaderprogram_t; static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; +// Shader info +static INT32 shader_leveltime = 0; + // ======================== // Fragment shader macros // ======================== @@ -942,6 +943,31 @@ EXPORT void HWRAPI(LoadShaders) (void) #endif } +// +// Shader info +// Those are given to the uniforms. +// + +EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value) +{ +#ifdef GL_SHADERS + switch (info) + { + case HWD_SHADERINFO_LEVELTIME: + shader_leveltime = value; + break; + default: + break; + } +#else + (void)info; + (void)value; +#endif +} + +// +// Custom shader loading +// EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment) { #ifdef GL_SHADERS @@ -960,6 +986,11 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boo strncpy(gl_customvertexshaders[number], shader, size); gl_customvertexshaders[number][size] = 0; } +#else + (void)number; + (void)shader; + (void)size; + (void)fragment; #endif } @@ -978,10 +1009,12 @@ EXPORT void HWRAPI(SetShader) (int shader) { gl_shadersenabled = true; gl_currentshaderprogram = shader; + return; } - else +#else + (void)shader; #endif - gl_shadersenabled = false; + gl_shadersenabled = false; } EXPORT void HWRAPI(UnSetShader) (void) @@ -1822,7 +1855,7 @@ static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat * UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f); UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f); UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f); - UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)leveltime) / TICRATE, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)shader_leveltime) / TICRATE, pglUniform1f); // Custom shader uniforms //if (custom) { } diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 0d617e836..9c4e5a22b 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -107,6 +107,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(SetShader); GETFUNC(UnSetShader); + GETFUNC(SetShaderInfo); GETFUNC(LoadCustomShader); GETFUNC(InitCustomShaders); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index ceabb926d..0911ca606 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1750,13 +1750,14 @@ void I_StartupHardwareGraphics(void) HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - HWD.pfnLoadShaders = hwSym("LoadShaders",NULL); - HWD.pfnKillShaders = hwSym("KillShaders",NULL); - HWD.pfnSetShader = hwSym("SetShader",NULL); - HWD.pfnUnSetShader = hwSym("UnSetShader",NULL); + HWD.pfnLoadShaders = hwSym("LoadShaders",NULL); + HWD.pfnKillShaders = hwSym("KillShaders",NULL); + HWD.pfnSetShader = hwSym("SetShader",NULL); + HWD.pfnUnSetShader = hwSym("UnSetShader",NULL); + HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL); HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); - HWD.pfnInitCustomShaders = hwSym("InitCustomShaders",NULL); + HWD.pfnInitCustomShaders= hwSym("InitCustomShaders",NULL); if (!HWD.pfnInit()) // let load the OpenGL library rendermode = render_soft; From 770135451fbe34581f901555fdb4b98b17dcbd03 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 22:02:18 -0300 Subject: [PATCH 021/168] Restore some model lighting code that went gone in the shaders code --- src/hardware/hw_main.c | 13 +++----- src/hardware/r_opengl/r_opengl.c | 55 ++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 9dc1d0702..149d090cf 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4908,6 +4908,7 @@ static void HWR_DrawSprites(void) if (gr_visspritecount > 0) { gr_vissprite_t *spr; + HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value); // draw all vissprites back to front for (spr = gr_vsprsortedhead.next; @@ -4947,6 +4948,8 @@ static void HWR_DrawSprites(void) } } } + + HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, 0); } } @@ -6116,7 +6119,6 @@ static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, " static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}}; -static void CV_grmodellighting_OnChange(void); static void CV_grfiltermode_OnChange(void); static void CV_granisotropic_OnChange(void); static void CV_grfogdensity_OnChange(void); @@ -6144,7 +6146,7 @@ consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE|CV_FLOAT, 0, NULL, 0, consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_grmodellighting_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grshearing = {"gr_shearing", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6164,12 +6166,6 @@ consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotro consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static void CV_grmodellighting_OnChange(void) -{ - if (rendermode == render_opengl) - HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value); -} - static void CV_grfogdensity_OnChange(void) { if (rendermode == render_opengl) @@ -6272,7 +6268,6 @@ void HWR_Startup(void) void HWR_Switch(void) { // Set special states from CVARs - HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value); HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value); HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_grfiltermode.value); HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d6e79b91c..57d28ab7c 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -76,7 +76,7 @@ static GLboolean MipMap = GL_FALSE; static GLint min_filter = GL_LINEAR; static GLint mag_filter = GL_LINEAR; static GLint anisotropic_filter = 0; -static boolean model_lighting = true; +static boolean model_lighting = false; const GLubyte *gl_version = NULL; const GLubyte *gl_renderer = NULL; @@ -2583,8 +2583,12 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 int i; - // Because Otherwise, scaling the screen negatively vertically breaks the lighting + // Because otherwise, scaling the screen negatively vertically breaks the lighting GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f}; +#ifdef GL_LIGHT_MODEL_AMBIENT + GLfloat ambient[4]; + GLfloat diffuse[4]; +#endif // Affect input model scaling scale *= 0.5f; @@ -2610,9 +2614,38 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 poly.blue = byte2float[Surface->PolyColor.s.blue]; poly.alpha = byte2float[Surface->PolyColor.s.alpha]; - SetBlend((poly.alpha < 1 ? PF_Translucent : (PF_Masked|PF_Occlude))|PF_Modulated); +#ifdef GL_LIGHT_MODEL_AMBIENT + if (model_lighting && (!gl_shadersenabled)) // doesn't work with shaders anyway + { + ambient[0] = poly.red; + ambient[1] = poly.green; + ambient[2] = poly.blue; + ambient[3] = poly.alpha; - pglColor4ubv((GLubyte*)&Surface->PolyColor.s); + diffuse[0] = poly.red; + diffuse[1] = poly.green; + diffuse[2] = poly.blue; + diffuse[3] = poly.alpha; + + if (ambient[0] > 0.75f) + ambient[0] = 0.75f; + if (ambient[1] > 0.75f) + ambient[1] = 0.75f; + if (ambient[2] > 0.75f) + ambient[2] = 0.75f; + + pglLightfv(GL_LIGHT0, GL_POSITION, LightPos); + pglShadeModel(GL_SMOOTH); + + pglEnable(GL_LIGHTING); + pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); + pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); + } +#endif + else + pglColor4ubv((GLubyte*)&Surface->PolyColor.s); + + SetBlend((poly.alpha < 1 ? PF_Translucent : (PF_Masked|PF_Occlude))|PF_Modulated); tint.red = byte2float[Surface->TintColor.s.red]; tint.green = byte2float[Surface->TintColor.s.green]; @@ -2653,12 +2686,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 } #endif - if (model_lighting) - { - pglLightfv(GL_LIGHT0, GL_POSITION, LightPos); - pglShadeModel(GL_SMOOTH); - } - pglPushMatrix(); // should be the same as glLoadIdentity //Hurdler: now it seems to work pglTranslatef(pos->x, pos->z, pos->y); @@ -2798,6 +2825,14 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglDisable(GL_CULL_FACE); pglDisable(GL_NORMALIZE); +#ifdef GL_LIGHT_MODEL_AMBIENT + if (model_lighting && (!gl_shadersenabled)) + { + pglDisable(GL_LIGHTING); + pglShadeModel(GL_FLAT); + } +#endif + #ifdef GL_SHADERS pglUseProgram(0); #endif From 968fea0383f3aa55be7f4b1ecd1216675f4a8e8b Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 23 Jan 2020 17:22:02 -0800 Subject: [PATCH 022/168] Fix implicit operand because GLSL is a goof or such --- src/hardware/r_opengl/r_opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 57d28ab7c..1f8a64c9a 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -666,7 +666,7 @@ static INT32 shader_leveltime = 0; GLSL_DOOM_COLORMAP \ GLSL_DOOM_LIGHT_EQUATION \ "void main(void) {\n" \ - "float z = (gl_FragCoord.z / gl_FragCoord.w) / 2;\n" \ + "float z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \ "float a = -pi * (z * freq) + (leveltime * speed);\n" \ "float sdistort = sin(a) * amp;\n" \ "float cdistort = cos(a) * amp;\n" \ From d24060bb9407de850a50b572b83ac08eac30f66e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 22:24:35 -0300 Subject: [PATCH 023/168] Wait. --- src/hardware/r_opengl/r_opengl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 1f8a64c9a..f8a92ed87 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -496,6 +496,9 @@ boolean SetupGLfunc(void) return true; } +static boolean gl_allowshaders = false; +static boolean gl_shadersenabled = false; + #ifdef GL_SHADERS typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum); typedef void (APIENTRY *PFNglShaderSource) (GLuint, GLsizei, const GLchar**, GLint*); @@ -545,9 +548,6 @@ static PFNglGetUniformLocation pglGetUniformLocation; // 18032019 static char *gl_customvertexshaders[MAXSHADERS]; static char *gl_customfragmentshaders[MAXSHADERS]; - -static boolean gl_allowshaders = false; -static boolean gl_shadersenabled = false; static GLuint gl_currentshaderprogram = 0; // 13062019 From 11c3721db4e4e1b34970bb33b40d44c76a697f80 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 22:30:36 -0300 Subject: [PATCH 024/168] Fix warnings around load_shaders --- src/doomdef.h | 2 +- src/hardware/r_opengl/r_opengl.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index c1d6d78ef..533546303 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -620,7 +620,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP -/// Hardware renderer: OpenGL +/// OpenGL shaders #define GL_SHADERS /// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink. diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index f8a92ed87..2a373b68a 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1871,8 +1871,13 @@ static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat * pglUseProgram(0); } else -#endif pglUseProgram(0); +#else + (void)Surface; + (void)poly; + (void)tint; + (void)fade; +#endif } // -----------------+ From d019080327cf4b36891a37e7442982463ef974b9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 22:38:54 -0300 Subject: [PATCH 025/168] I LOVE MENU CODE! --- src/m_menu.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ec4e51c9c..281cee474 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1394,21 +1394,23 @@ static menuitem_t OP_OpenGLOptionsMenu[] = {IT_HEADER, NULL, "3D Models", NULL, 0}, {IT_STRING|IT_CVAR, NULL, "Models", &cv_grmodels, 12}, {IT_STRING|IT_CVAR, NULL, "Model interpolation", &cv_grmodelinterpolation, 22}, - {IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32}, + {IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32}, {IT_HEADER, NULL, "General", NULL, 51}, - {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 63}, - {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 73}, - {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 83}, - {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,93}, + {IT_STRING|IT_CVAR, NULL, "Shaders", &cv_grshaders, 63}, + {IT_STRING|IT_CVAR, NULL, "Lack of perspective", &cv_grshearing, 73}, + {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 83}, + {IT_STRING|IT_CVAR, NULL, "Bit depth", &cv_scr_depth, 93}, + {IT_STRING|IT_CVAR, NULL, "Texture filter", &cv_grfiltermode, 103}, + {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 113}, - {IT_HEADER, NULL, "Miscellaneous", NULL, 112}, - {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 124}, + {IT_HEADER, NULL, "Miscellaneous", NULL, 132}, + {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 144}, #ifdef ALAM_LIGHTING - {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 134}, + {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 154}, #endif #if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL))) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 144}, + {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 164}, #endif }; From a521e40c0e1ee4ee1b453990cae8f07d30264215 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 23:09:53 -0300 Subject: [PATCH 026/168] bye --- src/hardware/hw_defs.h | 3 - src/hardware/hw_main.c | 91 ----------------------- src/hardware/hw_main.h | 4 - src/hardware/r_opengl/r_opengl.c | 47 +----------- src/m_menu.c | 123 ++----------------------------- 5 files changed, 9 insertions(+), 259 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 33f80a4d3..ea7117315 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -210,9 +210,6 @@ typedef struct FSurfaceInfo FSurfaceInfo; enum hwdsetspecialstate { HWD_SET_MODEL_LIGHTING = 1, - HWD_SET_FOG_MODE, - HWD_SET_FOG_COLOR, - HWD_SET_FOG_DENSITY, HWD_SET_SHADERS, HWD_SET_TEXTUREFILTERMODE, HWD_SET_TEXTUREANISOTROPICMODE, diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 149d090cf..6537e32c0 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -69,9 +69,6 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); -static void HWR_FoggingOn(void); -static UINT32 atohex(const char *s); - boolean drawsky = true; // ========================================================================== @@ -153,8 +150,6 @@ static void HWR_SetTransformAiming(FTransform *trans); // Lighting // ========================================================================== -#define CALCLIGHT(x,y) ((float)(x)*((y)/255.0f)) - void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap) { RGBA_t poly_color, tint_color, fade_color; @@ -5742,14 +5737,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) //------------------------------------------------------------------------ HWR_ClearView(); -if (0) -{ // I don't think this is ever used. - if (cv_grfog.value) - HWR_FoggingOn(); // First of all, turn it on, set the default user settings too - else - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 0); // Turn it off -} - if (drawsky) HWR_DrawSkyBackground(player); @@ -5841,10 +5828,6 @@ if (0) HWD.pfnSetTransform(NULL); HWD.pfnUnSetShader(); - // put it off for menus etc - if (cv_grfog.value) - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 0); - // Check for new console commands. NetUpdate(); @@ -5955,14 +5938,6 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) //------------------------------------------------------------------------ HWR_ClearView(); // Clears the depth buffer and resets the view I believe -if (0) -{ // I don't think this is ever used. - if (cv_grfog.value) - HWR_FoggingOn(); // First of all, turn it on, set the default user settings too - else - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 0); // Turn it off -} - if (!skybox && drawsky) // Don't draw the regular sky if there's a skybox HWR_DrawSkyBackground(player); @@ -6054,10 +6029,6 @@ if (0) HWD.pfnSetTransform(NULL); HWD.pfnUnSetShader(); - // put it off for menus etc - if (cv_grfog.value) - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 0); - HWR_DoPostProcessor(player); // Check for new console commands. @@ -6068,60 +6039,15 @@ if (0) HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE); } -// ========================================================================== -// FOG -// ========================================================================== - -/// \author faB - -static UINT32 atohex(const char *s) -{ - INT32 iCol; - const char *sCol; - char cCol; - INT32 i; - - if (strlen(s)<6) - return 0; - - iCol = 0; - sCol = s; - for (i = 0; i < 6; i++, sCol++) - { - iCol <<= 4; - cCol = *sCol; - if (cCol >= '0' && cCol <= '9') - iCol |= cCol - '0'; - else - { - if (cCol >= 'F') - cCol -= 'a' - 'A'; - if (cCol >= 'A' && cCol <= 'F') - iCol = iCol | (cCol - 'A' + 10); - } - } - //CONS_Debug(DBG_RENDER, "col %x\n", iCol); - return iCol; -} - -static void HWR_FoggingOn(void) -{ - HWD.pfnSetSpecialState(HWD_SET_FOG_COLOR, atohex(cv_grfogcolor.string)); - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value); - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 1); -} - // ========================================================================== // 3D ENGINE COMMANDS // ========================================================================== -static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}}; static void CV_grfiltermode_OnChange(void); static void CV_granisotropic_OnChange(void); -static void CV_grfogdensity_OnChange(void); static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"}, {HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"}, @@ -6133,9 +6059,6 @@ CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NU consvar_t cv_grshaders = {"gr_shaders", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef ALAM_LIGHTING consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6155,8 +6078,6 @@ consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontr consvar_t cv_grslopecontrast = {"gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned, - CV_grfogdensity_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_SAVE|CV_CALL, grfiltermode_cons_t, CV_grfiltermode_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -6166,12 +6087,6 @@ consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotro consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static void CV_grfogdensity_OnChange(void) -{ - if (rendermode == render_opengl) - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value); -} - static void CV_grfiltermode_OnChange(void) { if (rendermode == render_opengl) @@ -6189,11 +6104,6 @@ void HWR_AddCommands(void) { CV_RegisterVar(&cv_fovchange); - CV_RegisterVar(&cv_grfogdensity); - CV_RegisterVar(&cv_grfogcolor); - CV_RegisterVar(&cv_grfog); - CV_RegisterVar(&cv_grsoftwarefog); - #ifdef ALAM_LIGHTING CV_RegisterVar(&cv_grstaticlighting); CV_RegisterVar(&cv_grdynamiclighting); @@ -6268,7 +6178,6 @@ void HWR_Startup(void) void HWR_Switch(void) { // Set special states from CVARs - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value); HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_grfiltermode.value); HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value); } diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index b06ff10b3..6e3e7d2b0 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -84,10 +84,6 @@ extern consvar_t cv_grshaders; extern consvar_t cv_grmodels; extern consvar_t cv_grmodelinterpolation; extern consvar_t cv_grmodellighting; -extern consvar_t cv_grfog; -extern consvar_t cv_grfogcolor; -extern consvar_t cv_grfogdensity; -extern consvar_t cv_grsoftwarefog; extern consvar_t cv_grfiltermode; extern consvar_t cv_granisotropicmode; extern consvar_t cv_grcorrecttricks; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 2a373b68a..48c3faece 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1206,10 +1206,7 @@ void SetStates(void) //pglEnable(GL_CULL_FACE); //pglCullFace(GL_FRONT); - //glFogi(GL_FOG_MODE, GL_EXP); - //pglHint(GL_FOG_HINT, GL_FASTEST); - //pglFogfv(GL_FOG_COLOR, fogcolor); - //pglFogf(GL_FOG_DENSITY, 0.0005f); + pglDisable(GL_FOG); // Lighting for models #ifdef GL_LIGHT_MODEL_AMBIENT @@ -2267,48 +2264,6 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) model_lighting = Value; break; - case HWD_SET_FOG_COLOR: - { - GLfloat fogcolor[4]; - - fogcolor[0] = byte2float[((Value>>16)&0xff)]; - fogcolor[1] = byte2float[((Value>>8)&0xff)]; - fogcolor[2] = byte2float[((Value)&0xff)]; - fogcolor[3] = 0x0; - pglFogfv(GL_FOG_COLOR, fogcolor); - break; - } - - case HWD_SET_FOG_DENSITY: - pglFogf(GL_FOG_DENSITY, Value*1200/(500*1000000.0f)); - break; - - case HWD_SET_FOG_MODE: - if (Value) - { - pglEnable(GL_FOG); - // experimental code - /* - switch (Value) - { - case 1: - glFogi(GL_FOG_MODE, GL_LINEAR); - pglFogf(GL_FOG_START, -1000.0f); - pglFogf(GL_FOG_END, 2000.0f); - break; - case 2: - glFogi(GL_FOG_MODE, GL_EXP); - break; - case 3: - glFogi(GL_FOG_MODE, GL_EXP2); - break; - } - */ - } - else - pglDisable(GL_FOG); - break; - case HWD_SET_SHADERS: switch (Value) { diff --git a/src/m_menu.c b/src/m_menu.c index 281cee474..926b3dd7f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -313,7 +313,7 @@ static void M_ChangeControl(INT32 choice); menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef; #ifdef HWRENDER static void M_OpenGLOptionsMenu(void); -menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef; +menu_t OP_OpenGLOptionsDef; #endif menu_t OP_SoundOptionsDef; menu_t OP_SoundAdvancedDef; @@ -360,9 +360,6 @@ static void M_DrawVideoMode(void); static void M_DrawColorMenu(void); static void M_DrawScreenshotMenu(void); static void M_DrawMonitorToggles(void); -#ifdef HWRENDER -static void M_OGL_DrawFogMenu(void); -#endif #ifndef NONET static void M_DrawScreenshotMenu(void); static void M_DrawConnectMenu(void); @@ -387,9 +384,6 @@ static boolean M_CancelConnect(void); static void M_HandleConnectIP(INT32 choice); #endif static void M_HandleSetupMultiPlayer(INT32 choice); -#ifdef HWRENDER -static void M_HandleFogColor(INT32 choice); -#endif static void M_HandleVideoMode(INT32 choice); static void M_ResetCvars(void); @@ -1404,13 +1398,12 @@ static menuitem_t OP_OpenGLOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Texture filter", &cv_grfiltermode, 103}, {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 113}, - {IT_HEADER, NULL, "Miscellaneous", NULL, 132}, - {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 144}, #ifdef ALAM_LIGHTING - {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 154}, + {IT_HEADER, NULL, "Miscellaneous", NULL, 132}, + {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 144}, #endif #if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL))) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 164}, + {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 154}, #endif }; @@ -1422,15 +1415,8 @@ static menuitem_t OP_OpenGLLightingMenu[] = {IT_STRING|IT_CVAR, NULL, "Dynamic lighting", &cv_grdynamiclighting, 20}, {IT_STRING|IT_CVAR, NULL, "Static lighting", &cv_grstaticlighting, 30}, }; -#endif +#endif // ALAM_LIGHTING -static menuitem_t OP_OpenGLFogMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Fog", &cv_grfog, 10}, - {IT_STRING|IT_KEYHANDLER, NULL, "Fog color", M_HandleFogColor, 20}, - {IT_STRING|IT_CVAR, NULL, "Fog density", &cv_grfogdensity, 30}, - {IT_STRING|IT_CVAR, NULL, "Software Fog",&cv_grsoftwarefog,40}, -}; #endif static menuitem_t OP_SoundOptionsMenu[] = @@ -2154,20 +2140,9 @@ menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE( menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE( MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_LIGHTING << 18), "M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40); -#endif -menu_t OP_OpenGLFogDef = -{ - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_FOG << 18), - "M_VIDEO", - sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t), - &OP_OpenGLOptionsDef, - OP_OpenGLFogMenu, - M_OGL_DrawFogMenu, - 60, 40, - 0, - NULL -}; -#endif +#endif // ALAM_LIGHTING +#endif // HWRENDER + menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE( MN_OP_MAIN + (MN_OP_DATA << 6), "M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); @@ -12386,85 +12361,3 @@ static void M_QuitSRB2(INT32 choice) (void)choice; M_StartMessage(quitmsg[M_RandomKey(NUM_QUITMESSAGES)], M_QuitResponse, MM_YESNO); } - -#ifdef HWRENDER -// ===================================================================== -// OpenGL specific options -// ===================================================================== - -#define FOG_COLOR_ITEM 1 -// =================== -// M_OGL_DrawFogMenu() -// =================== -static void M_OGL_DrawFogMenu(void) -{ - INT32 mx, my; - - mx = currentMenu->x; - my = currentMenu->y; - M_DrawGenericMenu(); // use generic drawer for cursor, items and title - V_DrawString(BASEVIDWIDTH - mx - V_StringWidth(cv_grfogcolor.string, 0), - my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, V_YELLOWMAP, cv_grfogcolor.string); - // blink cursor on FOG_COLOR_ITEM if selected - if (itemOn == FOG_COLOR_ITEM && skullAnimCounter < 4) - V_DrawCharacter(BASEVIDWIDTH - mx, - my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, '_' | 0x80,false); -} - -//=================== -// M_HandleFogColor() -//=================== -static void M_HandleFogColor(INT32 choice) -{ - size_t i, l; - char temp[8]; - boolean exitmenu = false; // exit to previous menu and send name change - - switch (choice) - { - case KEY_DOWNARROW: - S_StartSound(NULL, sfx_menu1); - itemOn++; - break; - - case KEY_UPARROW: - S_StartSound(NULL, sfx_menu1); - itemOn--; - break; - - case KEY_ESCAPE: - exitmenu = true; - break; - - case KEY_BACKSPACE: - S_StartSound(NULL, sfx_menu1); - strcpy(temp, cv_grfogcolor.string); - strcpy(cv_grfogcolor.zstring, "000000"); - l = strlen(temp)-1; - for (i = 0; i < l; i++) - cv_grfogcolor.zstring[i + 6 - l] = temp[i]; - break; - - default: - if ((choice >= '0' && choice <= '9') || (choice >= 'a' && choice <= 'f') - || (choice >= 'A' && choice <= 'F')) - { - S_StartSound(NULL, sfx_menu1); - strcpy(temp, cv_grfogcolor.string); - strcpy(cv_grfogcolor.zstring, "000000"); - l = strlen(temp); - for (i = 0; i < l; i++) - cv_grfogcolor.zstring[5 - i] = temp[l - i]; - cv_grfogcolor.zstring[5] = (char)choice; - } - break; - } - if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); - } -} -#endif From 922ac735940c6e8301904d3c88bc885e5eab70fb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 23:15:27 -0300 Subject: [PATCH 027/168] Menu organisation --- src/m_menu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 926b3dd7f..33ea6b42c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1387,23 +1387,23 @@ static menuitem_t OP_OpenGLOptionsMenu[] = { {IT_HEADER, NULL, "3D Models", NULL, 0}, {IT_STRING|IT_CVAR, NULL, "Models", &cv_grmodels, 12}, - {IT_STRING|IT_CVAR, NULL, "Model interpolation", &cv_grmodelinterpolation, 22}, - {IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32}, + {IT_STRING|IT_CVAR, NULL, "Frame interpolation", &cv_grmodelinterpolation, 22}, + {IT_STRING|IT_CVAR, NULL, "Ambient lighting", &cv_grmodellighting, 32}, {IT_HEADER, NULL, "General", NULL, 51}, {IT_STRING|IT_CVAR, NULL, "Shaders", &cv_grshaders, 63}, {IT_STRING|IT_CVAR, NULL, "Lack of perspective", &cv_grshearing, 73}, {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 83}, - {IT_STRING|IT_CVAR, NULL, "Bit depth", &cv_scr_depth, 93}, - {IT_STRING|IT_CVAR, NULL, "Texture filter", &cv_grfiltermode, 103}, - {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 113}, + {IT_HEADER, NULL, "Miscellaneous", NULL, 102}, + {IT_STRING|IT_CVAR, NULL, "Bit depth", &cv_scr_depth, 114}, + {IT_STRING|IT_CVAR, NULL, "Texture filter", &cv_grfiltermode, 124}, + {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 134}, #ifdef ALAM_LIGHTING - {IT_HEADER, NULL, "Miscellaneous", NULL, 132}, - {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 144}, + {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 144}, #endif #if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL))) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 154}, + {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 154}, #endif }; From afa9b58ceecebe95fd8d7b94fb371ddfc69d76f4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 23:41:09 -0300 Subject: [PATCH 028/168] fix corona compiling lol --- src/hardware/hw_defs.h | 6 ++++++ src/m_menu.c | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index ea7117315..715c45ef3 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -74,6 +74,12 @@ typedef struct FLOAT x,y; } F2DCoord, v2d_t; +// Simple 3D vector +typedef struct FVector +{ + FLOAT x,y,z; +} FVector; + // ====================== // wallVert3D // ---------------------- diff --git a/src/m_menu.c b/src/m_menu.c index 33ea6b42c..8ba4b20db 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -314,7 +314,10 @@ menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef; #ifdef HWRENDER static void M_OpenGLOptionsMenu(void); menu_t OP_OpenGLOptionsDef; -#endif +#ifdef ALAM_LIGHTING +menu_t OP_OpenGLLightingDef; +#endif // ALAM_LIGHTING +#endif // HWRENDER menu_t OP_SoundOptionsDef; menu_t OP_SoundAdvancedDef; From 686d8e418ef60205441d08fef335910a7b612cdf Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 23 Jan 2020 23:52:11 -0300 Subject: [PATCH 029/168] st_translucency went missing in here for... reasons... --- src/hardware/hw_draw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index beab3b290..d2dcec181 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -369,9 +369,9 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t { FSurfaceInfo Surf; Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff; - if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value]; - else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[cv_translucenthud.value]; - else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value]; + if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency]; + else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency]; + else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency]; else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; HWD.pfnDrawPolygon(&Surf, v, 4, flags); @@ -527,9 +527,9 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal { FSurfaceInfo Surf; Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff; - if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value]; - else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[cv_translucenthud.value]; - else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value]; + if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency]; + else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency]; + else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency]; else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; HWD.pfnDrawPolygon(&Surf, v, 4, flags); From 0246026ade42b07a1d22e0bbce851c03ae37491d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 24 Jan 2020 00:35:51 -0300 Subject: [PATCH 030/168] I don't know why this happened --- src/command.c | 7 +- src/lua_baselib.c | 26 ---- src/p_local.h | 1 - src/p_map.c | 319 ++++++++++++++++++++++------------------------ src/p_maputl.h | 2 +- 5 files changed, 162 insertions(+), 193 deletions(-) diff --git a/src/command.c b/src/command.c index 31a83d643..8c72eeaa3 100644 --- a/src/command.c +++ b/src/command.c @@ -2107,7 +2107,12 @@ void CV_SaveVariables(FILE *f) // Silly hack for Min/Max vars if (!strcmp(cvar->string, "MAX") || !strcmp(cvar->string, "MIN")) - sprintf(stringtowrite, "%d", cvar->value); + { + if (cvar->flags & CV_FLOAT) + sprintf(stringtowrite, "%f", FIXED_TO_FLOAT(cvar->value)); + else + sprintf(stringtowrite, "%d", cvar->value); + } else strcpy(stringtowrite, cvar->string); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d850aabe8..7a16f3c69 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -681,17 +681,6 @@ static int lib_pSpawnPlayerMissile(lua_State *L) return 1; } -static int lib_pRailThinker(lua_State *L) -{ - mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - NOHUD - INLEVEL - if (!mobj) - return LUA_ErrInvalid(L, "mobj_t"); - lua_pushboolean(L, P_RailThinker(mobj)); - return 1; -} - static int lib_pMobjFlip(lua_State *L) { mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -1417,19 +1406,6 @@ static int lib_pTeleportMove(lua_State *L) return 2; } -static int lib_pCheckMoveBlocked(lua_State *L) -{ - line_t *li = luaL_checkudata(L, 1, META_LINE); - mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); - INLEVEL - if (!li) - return LUA_ErrInvalid(L, "line_t"); - if (!mo) - return LUA_ErrInvalid(L, "mobj_t"); - lua_pushboolean(L, P_CheckMoveBlocked(li, mo)); - return 1; -} - static int lib_pSlideMove(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -3041,7 +3017,6 @@ static luaL_Reg lib[] = { {"P_ColorTeamMissile",lib_pColorTeamMissile}, {"P_SPMAngle",lib_pSPMAngle}, {"P_SpawnPlayerMissile",lib_pSpawnPlayerMissile}, - {"P_RailThinker",lib_pRailThinker}, {"P_MobjFlip",lib_pMobjFlip}, {"P_GetMobjGravity",lib_pGetMobjGravity}, {"P_WeaponOrPanel",lib_pWeaponOrPanel}, @@ -3104,7 +3079,6 @@ static luaL_Reg lib[] = { {"P_TryMove",lib_pTryMove}, {"P_Move",lib_pMove}, {"P_TeleportMove",lib_pTeleportMove}, - {"P_CheckMoveBlocked",lib_pCheckMoveBlocked}, {"P_SlideMove",lib_pSlideMove}, {"P_BounceMove",lib_pBounceMove}, {"P_CheckSight", lib_pCheckSight}, diff --git a/src/p_local.h b/src/p_local.h index a825c3400..a5f3d313c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -405,7 +405,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam); boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); boolean P_Move(mobj_t *actor, fixed_t speed); boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); -boolean P_CheckMoveBlocked(line_t *li, mobj_t *mo); void P_SlideMove(mobj_t *mo); void P_BounceMove(mobj_t *mo); boolean P_CheckSight(mobj_t *t1, mobj_t *t2); diff --git a/src/p_map.c b/src/p_map.c index 266c5e579..40fee7b46 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3385,45 +3385,6 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) return false; } -// -//P_CheckMoveBlocked -// -boolean P_CheckMoveBlocked(line_t *li, mobj_t *mo) -{ - // one-sided linedefs are always solid to sliding movement. - // one-sided linedef - if (!li->backsector) - { - if (P_PointOnLineSide(mo->x, mo->y, li)) - return true; // don't hit the back side - return false; - } - - if (!(mo->flags & MF_MISSILE)) - { - if (li->flags & ML_IMPASSIBLE) - return false; - - if ((mo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS) - return false; - } - - // set openrange, opentop, openbottom - P_LineOpening(li, mo); - - if (openrange < mo->height) - return false; // doesn't fit - - if (opentop - mo->z < mo->height) - return false; // mobj is too high - - if (openbottom - mo->z > FixedMul(MAXSTEPMOVE, mo->scale)) - return false; // too big a step up - - // this line doesn't block movement - return true; -} - // // PTR_SlideTraverse // @@ -3435,133 +3396,163 @@ static boolean PTR_SlideTraverse(intercept_t *in) li = in->d.line; - if (!P_CheckMoveBlocked(li, slidemo)) + // one-sided linedefs are always solid to sliding movement. + // one-sided linedef + if (!li->backsector) { - // the line does block movement, - // see if it is closer than best so far - if (li->polyobj && slidemo->player) - { - if ((li->polyobj->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS)) - P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); - } - - if (slidemo->player && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing) - && slidemo->player->charability == CA_GLIDEANDCLIMB) - { - line_t *checkline = li; - sector_t *checksector; - ffloor_t *rover; - fixed_t topheight, bottomheight; - boolean fofline = false; - INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - if (!side && li->backsector) - checksector = li->backsector; - else - checksector = li->frontsector; - - if (checksector->ffloors) - { - for (rover = checksector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - #ifdef ESLOPE - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); - #endif - - if (topheight < slidemo->z) - continue; - - if (bottomheight > slidemo->z + slidemo->height) - continue; - - // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? - if (rover->master->flags & ML_TFERLINE) - { - size_t linenum = li-checksector->lines[0]; - checkline = rover->master->frontsector->lines[0] + linenum; - fofline = true; - } - - break; - } - } - - // see about climbing on the wall - if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) - { - boolean canclimb; - angle_t climbangle, climbline; - INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y); - - if (whichside) // on second side? - climbline += ANGLE_180; - - climbangle += (ANGLE_90 * (whichside ? -1 : 1)); - - canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true); - - if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) - || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135)) - && canclimb) - { - slidemo->angle = climbangle; - /*if (!demoplayback || P_AnalogMove(slidemo->player)) - { - if (slidemo->player == &players[consoleplayer]) - localangle = slidemo->angle; - else if (slidemo->player == &players[secondarydisplayplayer]) - localangle2 = slidemo->angle; - }*/ - - if (!slidemo->player->climbing) - { - S_StartSound(slidemo->player->mo, sfx_s3k4a); - slidemo->player->climbing = 5; - } - - slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); - slidemo->player->glidetime = 0; - slidemo->player->secondjump = 0; - - if (slidemo->player->climbing > 1) - slidemo->momz = slidemo->momx = slidemo->momy = 0; - - if (fofline) - whichside = 0; - - if (!whichside) - { - slidemo->player->lastsidehit = checkline->sidenum[whichside]; - slidemo->player->lastlinehit = (INT16)(checkline - lines); - } - - P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); - } - } - } - - if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) - { - secondslidefrac = bestslidefrac; - secondslideline = bestslideline; - bestslidefrac = in->frac; - bestslideline = li; - } - - return false; // stop + if (P_PointOnLineSide(slidemo->x, slidemo->y, li)) + return true; // don't hit the back side + goto isblocking; } - return true; // keep going! + + if (!(slidemo->flags & MF_MISSILE)) + { + if (li->flags & ML_IMPASSIBLE) + goto isblocking; + + if ((slidemo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS) + goto isblocking; + } + + // set openrange, opentop, openbottom + P_LineOpening(li, slidemo); + + if (openrange < slidemo->height) + goto isblocking; // doesn't fit + + if (opentop - slidemo->z < slidemo->height) + goto isblocking; // mobj is too high + + if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale)) + goto isblocking; // too big a step up + + // this line doesn't block movement + return true; + + // the line does block movement, + // see if it is closer than best so far +isblocking: + if (li->polyobj && slidemo->player) + { + if ((li->polyobj->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS)) + P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); + } + + if (slidemo->player && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing) + && slidemo->player->charability == CA_GLIDEANDCLIMB) + { + line_t *checkline = li; + sector_t *checksector; + ffloor_t *rover; + fixed_t topheight, bottomheight; + boolean fofline = false; + INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); + + if (!side && li->backsector) + checksector = li->backsector; + else + checksector = li->frontsector; + + if (checksector->ffloors) + { + for (rover = checksector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) + continue; + + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); +#endif + + if (topheight < slidemo->z) + continue; + + if (bottomheight > slidemo->z + slidemo->height) + continue; + + // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? + if (rover->master->flags & ML_TFERLINE) + { + size_t linenum = li-checksector->lines[0]; + checkline = rover->master->frontsector->lines[0] + linenum; + fofline = true; + } + + break; + } + } + + // see about climbing on the wall + if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) + { + boolean canclimb; + angle_t climbangle, climbline; + INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); + + climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y); + + if (whichside) // on second side? + climbline += ANGLE_180; + + climbangle += (ANGLE_90 * (whichside ? -1 : 1)); + + canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true); + + if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) + || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135)) + && canclimb) + { + slidemo->angle = climbangle; + /*if (!demoplayback || P_ControlStyle(slidemo->player) == CS_LMAOGALOG) + { + if (slidemo->player == &players[consoleplayer]) + localangle = slidemo->angle; + else if (slidemo->player == &players[secondarydisplayplayer]) + localangle2 = slidemo->angle; + }*/ + + if (!slidemo->player->climbing) + { + S_StartSound(slidemo->player->mo, sfx_s3k4a); + slidemo->player->climbing = 5; + } + + slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); + slidemo->player->glidetime = 0; + slidemo->player->secondjump = 0; + + if (slidemo->player->climbing > 1) + slidemo->momz = slidemo->momx = slidemo->momy = 0; + + if (fofline) + whichside = 0; + + if (!whichside) + { + slidemo->player->lastsidehit = checkline->sidenum[whichside]; + slidemo->player->lastlinehit = (INT16)(checkline - lines); + } + + P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); + } + } + } + + if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) + { + secondslidefrac = bestslidefrac; + secondslideline = bestslideline; + bestslidefrac = in->frac; + bestslideline = li; + } + + return false; // stop } // diff --git a/src/p_maputl.h b/src/p_maputl.h index d73dae5e6..16cfc834e 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -60,7 +60,7 @@ extern pslope_t *opentopslope, *openbottomslope; #endif extern ffloor_t *openfloorrover, *openceilingrover; -void P_LineOpening(line_t *linedef, mobj_t *mobj); +void P_LineOpening(line_t *plinedef, mobj_t *mobj); boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean(*func)(line_t *)); boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *)); From b18c0cfcabf983f40034ace44d4b0f688d8f45f6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 24 Jan 2020 16:42:55 -0300 Subject: [PATCH 031/168] Un-HWRENDER shader lump names --- src/w_wad.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 15338ac41..ce74e2141 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1890,11 +1890,8 @@ int W_VerifyNMUSlumps(const char *filename) {"YB_", 3}, // Intermission graphics, goes with the above {"M_", 2}, // As does menu stuff {"MUSICDEF", 8}, // Song definitions (thanks kart) - -#ifdef HWRENDER - {"SHADERS", 7}, - {"SH_", 3}, -#endif + {"SHADERS", 7}, // Shader definitions + {"SH_", 3}, // GLSL shader {NULL, 0}, }; From 7c4c04ca6a26dcaf889458c6178fdb0a7be84de9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 24 Jan 2020 16:57:21 -0300 Subject: [PATCH 032/168] Fix custom shader loading --- src/hardware/hw_main.c | 9 ++++----- src/w_wad.c | 5 ----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6537e32c0..1d1b9cbfe 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6147,6 +6147,7 @@ void HWR_AddSessionCommands(void) // -------------------------------------------------------------------------- void HWR_Startup(void) { + INT32 i; static boolean startupdone = false; // do this once @@ -6167,9 +6168,9 @@ void HWR_Startup(void) startupdone = true; - // jimita - HWD.pfnKillShaders(); - HWD.pfnLoadShaders(); + for (i = 0; i < numwadfiles; i++) + HWR_LoadShaders(i, (wadfiles[i]->type == RET_PK3)); + HWD.pfnInitCustomShaders(); } // -------------------------------------------------------------------------- @@ -6596,8 +6597,6 @@ skip_field: } } - HWD.pfnInitCustomShaders(); - Z_Free(line); return; } diff --git a/src/w_wad.c b/src/w_wad.c index ce74e2141..1684af2a4 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -788,11 +788,6 @@ UINT16 W_InitFile(const char *filename, boolean mainfile) wadfiles[numwadfiles] = wadfile; numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded -#ifdef HWRENDER - if (rendermode == render_opengl) - HWR_LoadShaders(numwadfiles - 1, (wadfile->type == RET_PK3)); -#endif - // TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now. switch (wadfile->type) { From 1c7b584dee974a86f1e4653e2a3516b6829fc073 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 24 Jan 2020 17:03:00 -0300 Subject: [PATCH 033/168] I_Error is too extreme I think, just CONS_Alert instead --- src/hardware/r_opengl/r_opengl.c | 33 ++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 48c3faece..54181de96 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -858,12 +858,19 @@ EXPORT void HWRAPI(LoadShaders) (void) if (i >= MAXSHADERPROGRAMS) break; + shader = &gl_shaderprograms[i]; + shader->program = 0; + shader->custom = custom; + // // Load and compile vertex shader // gl_vertShader = pglCreateShader(GL_VERTEX_SHADER); if (!gl_vertShader) - I_Error("Hardware driver: Error creating vertex shader %d", i); + { + CONS_Alert(CONS_ERROR, "LoadShaders: Error creating vertex shader %d", i); + continue; + } pglShaderSource(gl_vertShader, 1, &vert_shader, NULL); pglCompileShader(gl_vertShader); @@ -880,7 +887,8 @@ EXPORT void HWRAPI(LoadShaders) (void) infoLog = malloc(logLength); pglGetShaderInfoLog(gl_vertShader, logLength, NULL, infoLog); - I_Error("Hardware driver: Error compiling vertex shader %d\n%s", i, infoLog); + CONS_Alert(CONS_ERROR, "LoadShaders: Error compiling vertex shader %d\n%s", i, infoLog); + continue; } // @@ -888,7 +896,10 @@ EXPORT void HWRAPI(LoadShaders) (void) // gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER); if (!gl_fragShader) - I_Error("Hardware driver: Error creating fragment shader %d", i); + { + CONS_Alert(CONS_ERROR, "LoadShaders: Error creating fragment shader %d", i); + continue; + } pglShaderSource(gl_fragShader, 1, &frag_shader, NULL); pglCompileShader(gl_fragShader); @@ -905,25 +916,31 @@ EXPORT void HWRAPI(LoadShaders) (void) infoLog = malloc(logLength); pglGetShaderInfoLog(gl_fragShader, logLength, NULL, infoLog); - I_Error("Hardware driver: Error compiling fragment shader %d\n%s", i, infoLog); + CONS_Alert(CONS_ERROR, "LoadShaders: Error compiling fragment shader %d\n%s", i, infoLog); + continue; } - shader = &gl_shaderprograms[i]; shader->program = pglCreateProgram(); - shader->custom = custom; pglAttachShader(shader->program, gl_vertShader); pglAttachShader(shader->program, gl_fragShader); pglLinkProgram(shader->program); // check link status pglGetProgramiv(shader->program, GL_LINK_STATUS, &result); - if (result != GL_TRUE) - I_Error("Hardware driver: Error linking shader program %d", i); // delete the shader objects pglDeleteShader(gl_vertShader); pglDeleteShader(gl_fragShader); + // couldn't link? + if (result != GL_TRUE) + { + shader->program = 0; + shader->custom = false; + CONS_Alert(CONS_ERROR, "LoadShaders: Error linking shader program %d", i); + continue; + } + // 13062019 #define GETUNI(uniform) pglGetUniformLocation(shader->program, uniform); From 075ae996fa0c95446747d175b57e2f8c111edfbd Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 24 Jan 2020 17:04:38 -0300 Subject: [PATCH 034/168] GL_DBG_Printf instead of CONS_Alert --- src/hardware/r_opengl/r_opengl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 54181de96..d2b868380 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -868,7 +868,7 @@ EXPORT void HWRAPI(LoadShaders) (void) gl_vertShader = pglCreateShader(GL_VERTEX_SHADER); if (!gl_vertShader) { - CONS_Alert(CONS_ERROR, "LoadShaders: Error creating vertex shader %d", i); + GL_DBG_Printf("LoadShaders: Error creating vertex shader %d", i); continue; } @@ -887,7 +887,7 @@ EXPORT void HWRAPI(LoadShaders) (void) infoLog = malloc(logLength); pglGetShaderInfoLog(gl_vertShader, logLength, NULL, infoLog); - CONS_Alert(CONS_ERROR, "LoadShaders: Error compiling vertex shader %d\n%s", i, infoLog); + GL_DBG_Printf("LoadShaders: Error compiling vertex shader %d\n%s", i, infoLog); continue; } @@ -897,7 +897,7 @@ EXPORT void HWRAPI(LoadShaders) (void) gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER); if (!gl_fragShader) { - CONS_Alert(CONS_ERROR, "LoadShaders: Error creating fragment shader %d", i); + GL_DBG_Printf("LoadShaders: Error creating fragment shader %d", i); continue; } @@ -916,7 +916,7 @@ EXPORT void HWRAPI(LoadShaders) (void) infoLog = malloc(logLength); pglGetShaderInfoLog(gl_fragShader, logLength, NULL, infoLog); - CONS_Alert(CONS_ERROR, "LoadShaders: Error compiling fragment shader %d\n%s", i, infoLog); + GL_DBG_Printf("LoadShaders: Error compiling fragment shader %d\n%s", i, infoLog); continue; } @@ -937,7 +937,7 @@ EXPORT void HWRAPI(LoadShaders) (void) { shader->program = 0; shader->custom = false; - CONS_Alert(CONS_ERROR, "LoadShaders: Error linking shader program %d", i); + GL_DBG_Printf("LoadShaders: Error linking shader program %d", i); continue; } From bdc1594b07a2c0c07463c05ad99ee40d7c02fcfb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 24 Jan 2020 17:05:40 -0300 Subject: [PATCH 035/168] Redundant define? --- src/hardware/hw_dll.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/hw_dll.h b/src/hardware/hw_dll.h index d7658c4da..d22c8c312 100644 --- a/src/hardware/hw_dll.h +++ b/src/hardware/hw_dll.h @@ -55,7 +55,6 @@ #define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360 void GL_DBG_Printf(const char *format, ...) /*FUNCPRINTF*/; -#define GL_DBG_Printf GL_DBG_Printf #ifdef _WINDOWS BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); From 2731c9e92d795e905ffd5fe39ec13ce7d27f73fb Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 24 Jan 2020 15:44:57 -0500 Subject: [PATCH 036/168] Add newlines to GL debug print. --- src/hardware/r_opengl/r_opengl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d2b868380..4e1a6290b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -868,7 +868,7 @@ EXPORT void HWRAPI(LoadShaders) (void) gl_vertShader = pglCreateShader(GL_VERTEX_SHADER); if (!gl_vertShader) { - GL_DBG_Printf("LoadShaders: Error creating vertex shader %d", i); + GL_DBG_Printf("LoadShaders: Error creating vertex shader %d\n", i); continue; } @@ -897,7 +897,7 @@ EXPORT void HWRAPI(LoadShaders) (void) gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER); if (!gl_fragShader) { - GL_DBG_Printf("LoadShaders: Error creating fragment shader %d", i); + GL_DBG_Printf("LoadShaders: Error creating fragment shader %d\n", i); continue; } @@ -937,7 +937,7 @@ EXPORT void HWRAPI(LoadShaders) (void) { shader->program = 0; shader->custom = false; - GL_DBG_Printf("LoadShaders: Error linking shader program %d", i); + GL_DBG_Printf("LoadShaders: Error linking shader program %d\n", i); continue; } From 8401e097878d659318e72ae08b9287d046ec69e1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 25 Jan 2020 21:21:44 -0300 Subject: [PATCH 037/168] remove includes --- src/hardware/r_opengl/r_opengl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d2b868380..74bd19a5e 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -24,9 +24,6 @@ #include "r_opengl.h" #include "r_vbo.h" -//#include "../../p_tick.h" // for leveltime (NOTE: THIS IS BAD, FIGURE OUT HOW TO PROPERLY IMPLEMENT gl_leveltime) -#include "../../r_main.h" // AIMINGTODY (ALSO BAD) - #if defined (HWRENDER) && !defined (NOROPENGL) struct GLRGBAFloat From b9b19588866747332efca71154cff9dda16ac2b8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 25 Jan 2020 21:22:24 -0300 Subject: [PATCH 038/168] make NOTEXTURE_NUM 1 --- src/hardware/r_opengl/r_opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 74bd19a5e..b3bfb675d 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -41,7 +41,7 @@ static const GLubyte white[4] = { 255, 255, 255, 255 }; // ========================================================================== // With OpenGL 1.1+, the first texture should be 1 -#define NOTEXTURE_NUM 0 // small white texture +#define NOTEXTURE_NUM 1 // small white texture #define FIRST_TEX_AVAIL (NOTEXTURE_NUM + 1) #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) From c219a170da40f0b3b7820c4c65b4563d6f28c1fa Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 25 Jan 2020 21:37:33 -0300 Subject: [PATCH 039/168] Stop using NextTexAvail you dunce --- src/hardware/r_opengl/r_opengl.c | 41 +++++++++----------------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index b3bfb675d..09dcef22c 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -55,13 +55,12 @@ static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; // ************************************************************************** -static GLuint NextTexAvail = FIRST_TEX_AVAIL; static GLuint tex_downloaded = 0; static GLfloat fov = 90.0f; static FBITFIELD CurrentPolyFlags; -static FTextureInfo* gr_cachetail = NULL; -static FTextureInfo* gr_cachehead = NULL; +static FTextureInfo *gr_cachetail = NULL; +static FTextureInfo *gr_cachehead = NULL; RGBA_t myPaletteData[256]; GLint screen_width = 0; // used by Draw2DLine() @@ -1245,33 +1244,12 @@ void Flush(void) while (gr_cachehead) { - // this is not necessary at all, because you have loaded them normally, - // and so they already are in your list! -#if 0 - //Hurdler: 25/04/2000: now support colormap in hardware mode - FTextureInfo *tmp = gr_cachehead->nextskin; - - // The memory should be freed in the main code - while (tmp) - { - pglDeleteTextures(1, &tmp->downloaded); - tmp->downloaded = 0; - tmp = tmp->nextcolormap; - } -#endif - pglDeleteTextures(1, (GLuint *)&gr_cachehead->downloaded); + if (gr_cachehead->downloaded) + pglDeleteTextures(1, (GLuint *)&gr_cachehead->downloaded); gr_cachehead->downloaded = 0; gr_cachehead = gr_cachehead->nextmipmap; } gr_cachetail = gr_cachehead = NULL; //Hurdler: well, gr_cachehead is already NULL - NextTexAvail = FIRST_TEX_AVAIL; -#if 0 - if (screentexture != FIRST_TEX_AVAIL) - { - pglDeleteTextures(1, &screentexture); - screentexture = FIRST_TEX_AVAIL; - } -#endif tex_downloaded = 0; } @@ -1648,8 +1626,10 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) static RGBA_t tex[2048*2048]; const GLvoid *ptex = tex; INT32 w, h; + GLuint texnum = 0; - //GL_DBG_Printf ("DownloadMipmap %d %x\n",NextTexAvail,pTexInfo->grInfo.data); + pglGenTextures(1, &texnum); + //GL_DBG_Printf ("DownloadMipmap %d %x\n",(INT32)texnum,pTexInfo->grInfo.data); w = pTexInfo->width; h = pTexInfo->height; @@ -1737,9 +1717,10 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) else GL_DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); - pTexInfo->downloaded = NextTexAvail++; - tex_downloaded = pTexInfo->downloaded; - pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); + // the texture number was already generated by pglGenTextures + pglBindTexture(GL_TEXTURE_2D, texnum); + pTexInfo->downloaded = texnum; + tex_downloaded = texnum; // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues if (pTexInfo->flags & TF_TRANSPARENT) From 647107a220d0201307b4474c2d11f025bea48750 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 25 Jan 2020 21:46:52 -0300 Subject: [PATCH 040/168] Same deal for screen textures --- src/hardware/r_opengl/r_opengl.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 09dcef22c..3083302a5 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -83,16 +83,10 @@ static GLfloat modelMatrix[16]; static GLfloat projMatrix[16]; static GLint viewport[4]; -// Yay for arbitrary numbers! NextTexAvail is buggy for some reason. // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing // flush all of the stored textures, leaving them unavailable at times such as between levels // These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs // can know when the textures aren't there, as textures are always considered resident in their virtual memory -// TODO: Store them in a more normal way -#define SCRTEX_SCREENTEXTURE 4294967295U -#define SCRTEX_STARTSCREENWIPE 4294967294U -#define SCRTEX_ENDSCREENWIPE 4294967293U -#define SCRTEX_FINALSCREENTEXTURE 4294967292U static GLuint screentexture = 0; static GLuint startScreenWipe = 0; static GLuint endScreenWipe = 0; @@ -3012,7 +3006,7 @@ EXPORT void HWRAPI(StartScreenWipe) (void) // Create screen texture if (firstTime) - startScreenWipe = SCRTEX_STARTSCREENWIPE; + pglGenTextures(1, &startScreenWipe); pglBindTexture(GL_TEXTURE_2D, startScreenWipe); if (firstTime) @@ -3043,7 +3037,7 @@ EXPORT void HWRAPI(EndScreenWipe)(void) // Create screen texture if (firstTime) - endScreenWipe = SCRTEX_ENDSCREENWIPE; + pglGenTextures(1, &endScreenWipe); pglBindTexture(GL_TEXTURE_2D, endScreenWipe); if (firstTime) @@ -3214,7 +3208,7 @@ EXPORT void HWRAPI(MakeScreenTexture) (void) // Create screen texture if (firstTime) - screentexture = SCRTEX_SCREENTEXTURE; + pglGenTextures(1, &screentexture); pglBindTexture(GL_TEXTURE_2D, screentexture); if (firstTime) @@ -3244,7 +3238,7 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void) // Create screen texture if (firstTime) - finalScreenTexture = SCRTEX_FINALSCREENTEXTURE; + pglGenTextures(1, &finalScreenTexture); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); if (firstTime) From 8bcdd105ced0c1584572b1dd49d51e29c869ffa3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 25 Jan 2020 21:57:05 -0300 Subject: [PATCH 041/168] I'll put this back in here, I guess. --- src/hardware/r_opengl/r_opengl.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index 89920d4d4..f44e0818b 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -57,6 +57,15 @@ #undef DEBUG_TO_FILE // maybe defined in previous *.h #define DEBUG_TO_FILE // output debugging msgs to ogllog.txt +// todo: find some way of getting SDL to log to ogllog.txt, without +// interfering with r_opengl.dll +#ifdef HAVE_SDL +#undef DEBUG_TO_FILE +#endif +//#if defined(HAVE_SDL) && !defined(_DEBUG) +//#undef DEBUG_TO_FILE +//#endif + #ifdef DEBUG_TO_FILE extern FILE *gllogstream; #endif From e576c1ada12763b032bc05a6ebac0a25119a8214 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 25 Jan 2020 22:17:39 -0300 Subject: [PATCH 042/168] make up for the lack of ogllog.txt --- src/hardware/r_opengl/r_opengl.c | 64 ++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 3083302a5..bf5b9ec7b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -157,6 +157,56 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...) #endif } +// -----------------+ +// GL_MSG_Warning : Raises a warning. +// : +// Returns : +// -----------------+ + +static void GL_MSG_Warning(const char *format, ...) +{ + char str[4096] = ""; + va_list arglist; + + va_start(arglist, format); + vsnprintf(str, 4096, format, arglist); + va_end(arglist); + +#ifdef HAVE_SDL + CONS_Alert(CONS_WARNING, "%s", str); +#endif +#ifdef DEBUG_TO_FILE + if (!gllogstream) + gllogstream = fopen("ogllog.txt", "w"); + fwrite(str, strlen(str), 1, gllogstream); +#endif +} + +// -----------------+ +// GL_MSG_Error : Raises an error. +// : +// Returns : +// -----------------+ + +static void GL_MSG_Error(const char *format, ...) +{ + char str[4096] = ""; + va_list arglist; + + va_start(arglist, format); + vsnprintf(str, 4096, format, arglist); + va_end(arglist); + +#ifdef HAVE_SDL + CONS_Alert(CONS_ERROR, "%s", str); +#endif +#ifdef DEBUG_TO_FILE + if (!gllogstream) + gllogstream = fopen("ogllog.txt", "w"); + fwrite(str, strlen(str), 1, gllogstream); +#endif +} + #ifdef STATIC_OPENGL /* 1.0 functions */ /* Miscellaneous */ @@ -413,7 +463,7 @@ boolean SetupGLfunc(void) func = GetGLFunc(#proc); \ if (!func) \ { \ - GL_DBG_Printf("failed to get OpenGL function: %s", #proc); \ + GL_MSG_Warning("failed to get OpenGL function: %s", #proc); \ } \ GETOPENGLFUNC(pglClearColor, glClearColor) @@ -858,7 +908,7 @@ EXPORT void HWRAPI(LoadShaders) (void) gl_vertShader = pglCreateShader(GL_VERTEX_SHADER); if (!gl_vertShader) { - GL_DBG_Printf("LoadShaders: Error creating vertex shader %d", i); + GL_MSG_Error("LoadShaders: Error creating vertex shader %d\n", i); continue; } @@ -877,7 +927,7 @@ EXPORT void HWRAPI(LoadShaders) (void) infoLog = malloc(logLength); pglGetShaderInfoLog(gl_vertShader, logLength, NULL, infoLog); - GL_DBG_Printf("LoadShaders: Error compiling vertex shader %d\n%s", i, infoLog); + GL_MSG_Error("LoadShaders: Error compiling vertex shader %d\n%s", i, infoLog); continue; } @@ -887,7 +937,7 @@ EXPORT void HWRAPI(LoadShaders) (void) gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER); if (!gl_fragShader) { - GL_DBG_Printf("LoadShaders: Error creating fragment shader %d", i); + GL_MSG_Error("LoadShaders: Error creating fragment shader %d\n", i); continue; } @@ -906,7 +956,7 @@ EXPORT void HWRAPI(LoadShaders) (void) infoLog = malloc(logLength); pglGetShaderInfoLog(gl_fragShader, logLength, NULL, infoLog); - GL_DBG_Printf("LoadShaders: Error compiling fragment shader %d\n%s", i, infoLog); + GL_MSG_Error("LoadShaders: Error compiling fragment shader %d\n%s", i, infoLog); continue; } @@ -927,7 +977,7 @@ EXPORT void HWRAPI(LoadShaders) (void) { shader->program = 0; shader->custom = false; - GL_DBG_Printf("LoadShaders: Error linking shader program %d", i); + GL_MSG_Error("LoadShaders: Error linking shader program %d\n", i); continue; } @@ -1709,7 +1759,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } } else - GL_DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); + GL_MSG_Warning ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); // the texture number was already generated by pglGenTextures pglBindTexture(GL_TEXTURE_2D, texnum); From 9e79b337b1ff0594ee8c4d43bab7dd3276e40ba2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 25 Jan 2020 22:20:27 -0300 Subject: [PATCH 043/168] Fix NOTEXTURE_NUM --- src/hardware/r_opengl/r_opengl.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index bf5b9ec7b..1547ead99 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -41,8 +41,7 @@ static const GLubyte white[4] = { 255, 255, 255, 255 }; // ========================================================================== // With OpenGL 1.1+, the first texture should be 1 -#define NOTEXTURE_NUM 1 // small white texture -#define FIRST_TEX_AVAIL (NOTEXTURE_NUM + 1) +static GLuint NOTEXTURE_NUM = 0; #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) @@ -1095,6 +1094,8 @@ static void SetNoTexture(void) // Disable texture. if (tex_downloaded != NOTEXTURE_NUM) { + if (NOTEXTURE_NUM == 0) + pglGenTextures(1, &NOTEXTURE_NUM); pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM); tex_downloaded = NOTEXTURE_NUM; } @@ -1209,11 +1210,6 @@ void SetModelView(GLint w, GLint h) // -----------------+ void SetStates(void) { - // Bind little white RGBA texture to ID NOTEXTURE_NUM. - /* - FUINT Data[8*8]; - INT32 i; - */ #ifdef GL_LIGHT_MODEL_AMBIENT GLfloat LightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; #endif @@ -1247,16 +1243,8 @@ void SetStates(void) CurrentPolyFlags = 0xffffffff; SetBlend(0); - /* - for (i = 0; i < 64; i++) - Data[i] = 0xffFFffFF; // white pixel - */ - - tex_downloaded = (GLuint)-1; + tex_downloaded = 0; SetNoTexture(); - //pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM); - //tex_downloaded = NOTEXTURE_NUM; - //pglTexImage2D(GL_TEXTURE_2D, 0, 4, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, Data); pglPolygonOffset(-1.0f, -1.0f); From bdd43efb255154cd9e58eb108069344d470813c2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 27 Jan 2020 01:57:55 -0300 Subject: [PATCH 044/168] Fix -OGLlib --- src/i_video.h | 13 ++++++++++-- src/screen.c | 2 +- src/sdl/i_video.c | 54 +++++++++++++++++++++++++++++++++++++++++------ src/sdl/ogl_sdl.c | 8 +++---- 4 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/i_video.h b/src/i_video.h index 76b984d25..8f87a360e 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -32,10 +32,13 @@ typedef enum render_none = 3 // for dedicated server } rendermode_t; -/** \brief currect render mode +/** \brief current render mode */ extern rendermode_t rendermode; +/** \brief hardware renderer loaded +*/ +extern boolean hwrenderloaded; /** \brief use highcolor modes if true */ @@ -44,6 +47,9 @@ extern boolean highcolor; /** \brief setup video mode */ void I_StartupGraphics(void); + +/** \brief setup hardware mode +*/ void I_StartupHardwareGraphics(void); /** \brief restore old video mode @@ -82,9 +88,12 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h); \param modenum video mode to set to - \return currect video mode + \return current video mode */ INT32 VID_SetMode(INT32 modenum); + +/** \brief Checks the render state +*/ void VID_CheckRenderer(void); /** \brief The VID_GetModeName function diff --git a/src/screen.c b/src/screen.c index 5bb304c08..5406ee46f 100644 --- a/src/screen.c +++ b/src/screen.c @@ -461,7 +461,7 @@ void SCR_ChangeRenderer(void) { target_renderer = cv_renderer.value; #ifdef HWRENDER - if (M_CheckParm("-opengl")) + if (M_CheckParm("-opengl") && hwrenderloaded) target_renderer = rendermode = render_opengl; else #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 0911ca606..e4f4790fd 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -93,7 +93,8 @@ static INT32 numVidModes = -1; */ static char vidModeName[33][32]; // allow 33 different modes -rendermode_t rendermode=render_soft; +rendermode_t rendermode = render_soft; +static rendermode_t chosenrendermode = render_soft; // set by command line arguments boolean highcolor = false; @@ -103,6 +104,7 @@ static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff static consvar_t cv_alwaysgrabmouse = {"alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; UINT8 graphics_started = 0; // Is used in console.c and screen.c +boolean hwrenderloaded = false; // To disable fullscreen at startup; is set in VID_PrepareModeList boolean allow_fullscreen = false; @@ -1454,14 +1456,44 @@ static SDL_bool Impl_CreateContext(void) return SDL_TRUE; } +#ifdef HWRENDER +static void VID_CheckGLLoaded(rendermode_t oldrender) +{ + if (!hwrenderloaded) // Well, it didn't work the first time anyway. + { + CONS_Alert(CONS_ERROR, "OpenGL never loaded\n"); + rendermode = oldrender; + if (chosenrendermode == render_opengl) // fallback to software + rendermode = render_soft; + if (setrenderneeded) + { + CV_StealthSetValue(&cv_renderer, oldrender); + CV_StealthSetValue(&cv_newrenderer, oldrender); + setrenderneeded = 0; + } + } +} +#endif + void VID_CheckRenderer(void) { + rendermode_t oldrenderer = rendermode; + if (dedicated) return; +#ifdef HWRENDER + if (!graphics_started) + VID_CheckGLLoaded(oldrenderer); +#endif + if (setrenderneeded) { rendermode = setrenderneeded; +#ifdef HWRENDER + if (setrenderneeded == render_opengl) + VID_CheckGLLoaded(oldrenderer); +#endif Impl_CreateContext(); } @@ -1484,9 +1516,15 @@ void VID_CheckRenderer(void) else if (rendermode == render_opengl) { I_StartupHardwareGraphics(); - R_InitHardwareMode(); - HWR_Switch(); + // Needs to check if switching failed somehow, too. + if (rendermode == render_opengl) + { + R_InitHardwareMode(); + HWR_Switch(); + } } +#else + (void)oldrenderer; #endif } @@ -1651,10 +1689,10 @@ void I_StartupGraphics(void) #ifdef HWRENDER if (M_CheckParm("-opengl")) - rendermode = render_opengl; + chosenrendermode = rendermode = render_opengl; else if (M_CheckParm("-software")) #endif - rendermode = render_soft; + chosenrendermode = rendermode = render_soft; usesdl2soft = M_CheckParm("-softblit"); borderlesswindow = M_CheckParm("-borderless"); @@ -1760,9 +1798,13 @@ void I_StartupHardwareGraphics(void) HWD.pfnInitCustomShaders= hwSym("InitCustomShaders",NULL); if (!HWD.pfnInit()) // let load the OpenGL library + { rendermode = render_soft; + setrenderneeded = 0; + } else - glstartup = true; + hwrenderloaded = true; + glstartup = true; } #endif } diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index e20e4d091..bbaaeea80 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -129,15 +129,15 @@ boolean LoadGL(void) return SetupGLfunc(); else { - I_OutputMsg("Could not load GLU Library: %s\n", GLULibname); + CONS_Alert(CONS_ERROR, "Could not load GLU Library: %s\n", GLULibname); if (!M_CheckParm ("-GLUlib")) - I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); + CONS_Alert(CONS_ERROR, "If you know what is the GLU library's name, use -GLUlib\n"); } } else { - I_OutputMsg("Could not load GLU Library\n"); - I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); + CONS_Alert(CONS_ERROR, "Could not load GLU Library\n"); + CONS_Alert(CONS_ERROR, "If you know what is the GLU library's name, use -GLUlib\n"); } #endif return SetupGLfunc(); From c87119f18f9f2ac24b52d3ebe316724cd37691ee Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 27 Jan 2020 02:15:34 -0300 Subject: [PATCH 045/168] Fix shader reading yet again --- src/hardware/hw_main.c | 30 +++++++++++++++++------------- src/hardware/hw_main.h | 3 ++- src/w_wad.c | 9 +++++++++ 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 1d1b9cbfe..4aa6ebfdb 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6147,13 +6147,14 @@ void HWR_AddSessionCommands(void) // -------------------------------------------------------------------------- void HWR_Startup(void) { - INT32 i; static boolean startupdone = false; // do this once if (!startupdone) { + INT32 i; CONS_Printf("HWR_Startup()...\n"); + HWR_InitPolyPool(); HWR_AddSessionCommands(); HWR_InitTextureCache(); @@ -6161,16 +6162,17 @@ void HWR_Startup(void) #ifdef ALAM_LIGHTING HWR_InitLight(); #endif + + // read every custom shader + for (i = 0; i < numwadfiles; i++) + HWR_ReadShaders(i, (wadfiles[i]->type == RET_PK3)); + HWR_LoadShaders(); } if (rendermode == render_opengl) textureformat = patchformat = GR_RGBA; startupdone = true; - - for (i = 0; i < numwadfiles; i++) - HWR_LoadShaders(i, (wadfiles[i]->type == RET_PK3)); - HWD.pfnInitCustomShaders(); } // -------------------------------------------------------------------------- @@ -6466,7 +6468,12 @@ static inline UINT16 HWR_CheckShader(UINT16 wadnum) return INT16_MAX; } -void HWR_LoadShaders(UINT16 wadnum, boolean PK3) +void HWR_LoadShaders(void) +{ + HWD.pfnInitCustomShaders(); +} + +void HWR_ReadShaders(UINT16 wadnum, boolean PK3) { UINT16 lump; char *shaderdef, *line; @@ -6497,9 +6504,6 @@ void HWR_LoadShaders(UINT16 wadnum, boolean PK3) size = W_LumpLengthPwad(wadnum, lump); line = Z_Malloc(size+1, PU_STATIC, NULL); - if (!line) - I_Error("HWR_LoadShaders: No more free memory\n"); - M_Memcpy(line, shaderdef, size); line[size] = '\0'; @@ -6518,7 +6522,7 @@ void HWR_LoadShaders(UINT16 wadnum, boolean PK3) value = strtok(NULL, "\r\n "); if (!value) { - CONS_Alert(CONS_WARNING, "HWR_LoadShaders: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + CONS_Alert(CONS_WARNING, "HWR_ReadShaders: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); stoken = strtok(NULL, "\r\n"); // skip end of line goto skip_lump; } @@ -6537,14 +6541,14 @@ skip_lump: value = strtok(NULL, "\r\n= "); if (!value) { - CONS_Alert(CONS_WARNING, "HWR_LoadShaders: Missing shader target (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + CONS_Alert(CONS_WARNING, "HWR_ReadShaders: Missing shader target (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); stoken = strtok(NULL, "\r\n"); // skip end of line goto skip_field; } if (!shadertype) { - CONS_Alert(CONS_ERROR, "HWR_LoadShaders: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + CONS_Alert(CONS_ERROR, "HWR_ReadShaders: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); Z_Free(line); return; } @@ -6575,7 +6579,7 @@ skip_lump: if (shader_lumpnum == INT16_MAX) { - CONS_Alert(CONS_ERROR, "HWR_LoadShaders: Missing shader source %s (file %s, line %d)\n", shader_lumpname, wadfiles[wadnum]->filename, linenum); + CONS_Alert(CONS_ERROR, "HWR_ReadShaders: Missing shader source %s (file %s, line %d)\n", shader_lumpname, wadfiles[wadnum]->filename, linenum); Z_Free(shader_lumpname); continue; } diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 6e3e7d2b0..aedfa9cd6 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -69,7 +69,8 @@ void HWR_DrawScreenFinalTexture(int width, int height); void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap); UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work -void HWR_LoadShaders(UINT16 wadnum, boolean PK3); +void HWR_ReadShaders(UINT16 wadnum, boolean PK3); +void HWR_LoadShaders(void); extern CV_PossibleValue_t granisotropicmode_cons_t[]; diff --git a/src/w_wad.c b/src/w_wad.c index 1684af2a4..9ff082aa5 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -788,6 +788,15 @@ UINT16 W_InitFile(const char *filename, boolean mainfile) wadfiles[numwadfiles] = wadfile; numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded +#ifdef HWRENDER + // Read shaders from file + if (rendermode == render_opengl && hwrenderloaded) + { + HWR_ReadShaders(numwadfiles - 1, (type == RET_PK3)); + HWR_LoadShaders(); + } +#endif // HWRENDER + // TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now. switch (wadfile->type) { From af7b4795b73f1ccd3310def7adc202c14c9dc55f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 28 Jan 2020 00:16:38 -0300 Subject: [PATCH 046/168] port pfnUpdateTexture --- src/hardware/hw_drv.h | 2 + src/hardware/r_opengl/r_opengl.c | 379 +++++++++++++++++-------------- src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + src/win32/win_dll.c | 2 + 5 files changed, 212 insertions(+), 173 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 99687ccf5..a09f3f224 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -40,6 +40,7 @@ EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); +EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *TexInfo); EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data); EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); EXPORT void HWRAPI(ClearMipMapCache) (void); @@ -92,6 +93,7 @@ struct hwdriver_s SetBlend pfnSetBlend; ClearBuffer pfnClearBuffer; SetTexture pfnSetTexture; + UpdateTexture pfnUpdateTexture; ReadRect pfnReadRect; GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 1547ead99..d0a07d262 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -267,6 +267,7 @@ static void GL_MSG_Error(const char *format, ...) #define pglTexEnvi glTexEnvi #define pglTexParameteri glTexParameteri #define pglTexImage2D glTexImage2D +#define pglTexSubImage2D glTexSubImage2D /* Fog */ #define pglFogf glFogf @@ -381,6 +382,8 @@ typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint static PFNglTexParameteri pglTexParameteri; typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static PFNglTexImage2D pglTexImage2D; +typedef void (APIENTRY * PFNglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +static PFNglTexSubImage2D pglTexSubImage2D; /* Fog */ typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param); @@ -518,6 +521,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglTexEnvi, glTexEnvi) GETOPENGLFUNC(pglTexParameteri, glTexParameteri) GETOPENGLFUNC(pglTexImage2D, glTexImage2D) + GETOPENGLFUNC(pglTexSubImage2D , glTexSubImage2D) GETOPENGLFUNC(pglFogf, glFogf) GETOPENGLFUNC(pglFogfv, glFogfv) @@ -1633,6 +1637,207 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) CurrentPolyFlags = PolyFlags; } +// -----------------+ +// UpdateTexture : Updates the texture data. +// -----------------+ +EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) +{ + // Download a mipmap + boolean updatemipmap = true; + static RGBA_t tex[2048*2048]; + const GLvoid *ptex = tex; + INT32 w, h; + GLuint texnum = 0; + + if (!pTexInfo->downloaded) + { + pglGenTextures(1, &texnum); + pTexInfo->downloaded = texnum; + updatemipmap = false; + } + else + texnum = pTexInfo->downloaded; + + //GL_DBG_Printf ("DownloadMipmap %d %x\n",(INT32)texnum,pTexInfo->grInfo.data); + + w = pTexInfo->width; + h = pTexInfo->height; + + if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) || + (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)) + { + const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; + INT32 i, j; + + for (j = 0; j < h; j++) + { + for (i = 0; i < w; i++) + { + if ((*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX) && + (pTexInfo->flags & TF_CHROMAKEYED)) + { + tex[w*j+i].s.red = 0; + tex[w*j+i].s.green = 0; + tex[w*j+i].s.blue = 0; + tex[w*j+i].s.alpha = 0; + pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it + } + else + { + tex[w*j+i].s.red = myPaletteData[*pImgData].s.red; + tex[w*j+i].s.green = myPaletteData[*pImgData].s.green; + tex[w*j+i].s.blue = myPaletteData[*pImgData].s.blue; + tex[w*j+i].s.alpha = myPaletteData[*pImgData].s.alpha; + } + + pImgData++; + + if (pTexInfo->grInfo.format == GR_TEXFMT_AP_88) + { + if (!(pTexInfo->flags & TF_CHROMAKEYED)) + tex[w*j+i].s.alpha = *pImgData; + pImgData++; + } + + } + } + } + else if (pTexInfo->grInfo.format == GR_RGBA) + { + // corona test : passed as ARGB 8888, which is not in glide formats + // Hurdler: not used for coronas anymore, just for dynamic lighting + ptex = pTexInfo->grInfo.data; + } + else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) + { + const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; + INT32 i, j; + + for (j = 0; j < h; j++) + { + for (i = 0; i < w; i++) + { + tex[w*j+i].s.red = *pImgData; + tex[w*j+i].s.green = *pImgData; + tex[w*j+i].s.blue = *pImgData; + pImgData++; + tex[w*j+i].s.alpha = *pImgData; + pImgData++; + } + } + } + else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) // Used for fade masks + { + const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; + INT32 i, j; + + for (j = 0; j < h; j++) + { + for (i = 0; i < w; i++) + { + tex[w*j+i].s.red = 255; // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't + tex[w*j+i].s.green = 255; + tex[w*j+i].s.blue = 255; + tex[w*j+i].s.alpha = *pImgData; + pImgData++; + } + } + } + else + GL_MSG_Warning ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); + + // the texture number was already generated by pglGenTextures + pglBindTexture(GL_TEXTURE_2D, texnum); + tex_downloaded = texnum; + + // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues + if (pTexInfo->flags & TF_TRANSPARENT) + { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + else + { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + } + + if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) + { + //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + if (MipMap) + { + pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); + if (pTexInfo->flags & TF_TRANSPARENT) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff + else + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); + //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); + } + else + { + if (updatemipmap) + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + else + pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + } + } + else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) + { + //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + if (MipMap) + { + pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); + if (pTexInfo->flags & TF_TRANSPARENT) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff + else + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); + //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); + } + else + { + if (updatemipmap) + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + else + pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + } + } + else + { + if (MipMap) + { + pgluBuild2DMipmaps(GL_TEXTURE_2D, textureformatGL, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + // Control the mipmap level of detail + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail + if (pTexInfo->flags & TF_TRANSPARENT) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff + else + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5); + } + else + { + if (updatemipmap) + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + else + pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + } + } + + if (pTexInfo->flags & TF_WRAPX) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + else + Clamp2D(GL_TEXTURE_WRAP_S); + + if (pTexInfo->flags & TF_WRAPY) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + else + Clamp2D(GL_TEXTURE_WRAP_T); + + if (maximumAnisotropy) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_filter); +} // -----------------+ // SetTexture : The mipmap becomes the current texture source @@ -1654,179 +1859,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } else { - // Download a mipmap - static RGBA_t tex[2048*2048]; - const GLvoid *ptex = tex; - INT32 w, h; - GLuint texnum = 0; - - pglGenTextures(1, &texnum); - //GL_DBG_Printf ("DownloadMipmap %d %x\n",(INT32)texnum,pTexInfo->grInfo.data); - - w = pTexInfo->width; - h = pTexInfo->height; - - if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) || - (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)) - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - if ((*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX) && - (pTexInfo->flags & TF_CHROMAKEYED)) - { - tex[w*j+i].s.red = 0; - tex[w*j+i].s.green = 0; - tex[w*j+i].s.blue = 0; - tex[w*j+i].s.alpha = 0; - pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it - } - else - { - tex[w*j+i].s.red = myPaletteData[*pImgData].s.red; - tex[w*j+i].s.green = myPaletteData[*pImgData].s.green; - tex[w*j+i].s.blue = myPaletteData[*pImgData].s.blue; - tex[w*j+i].s.alpha = myPaletteData[*pImgData].s.alpha; - } - - pImgData++; - - if (pTexInfo->grInfo.format == GR_TEXFMT_AP_88) - { - if (!(pTexInfo->flags & TF_CHROMAKEYED)) - tex[w*j+i].s.alpha = *pImgData; - pImgData++; - } - - } - } - } - else if (pTexInfo->grInfo.format == GR_RGBA) - { - // corona test : passed as ARGB 8888, which is not in glide formats - // Hurdler: not used for coronas anymore, just for dynamic lighting - ptex = pTexInfo->grInfo.data; - } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - tex[w*j+i].s.red = *pImgData; - tex[w*j+i].s.green = *pImgData; - tex[w*j+i].s.blue = *pImgData; - pImgData++; - tex[w*j+i].s.alpha = *pImgData; - pImgData++; - } - } - } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) // Used for fade masks - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - tex[w*j+i].s.red = 255; // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't - tex[w*j+i].s.green = 255; - tex[w*j+i].s.blue = 255; - tex[w*j+i].s.alpha = *pImgData; - pImgData++; - } - } - } - else - GL_MSG_Warning ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); - - // the texture number was already generated by pglGenTextures - pglBindTexture(GL_TEXTURE_2D, texnum); - pTexInfo->downloaded = texnum; - tex_downloaded = texnum; - - // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues - if (pTexInfo->flags & TF_TRANSPARENT) - { - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - else - { - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); - } - - if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) - { - //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - if (MipMap) - { - pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); - if (pTexInfo->flags & TF_TRANSPARENT) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff - else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); - //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); - } - else - pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) - { - //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - if (MipMap) - { - pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); - if (pTexInfo->flags & TF_TRANSPARENT) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff - else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); - //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); - } - else - pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - } - else - { - if (MipMap) - { - pgluBuild2DMipmaps(GL_TEXTURE_2D, textureformatGL, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - // Control the mipmap level of detail - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail - if (pTexInfo->flags & TF_TRANSPARENT) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff - else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5); - } - else - pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - } - - if (pTexInfo->flags & TF_WRAPX) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - else - Clamp2D(GL_TEXTURE_WRAP_S); - - if (pTexInfo->flags & TF_WRAPY) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - else - Clamp2D(GL_TEXTURE_WRAP_T); - - if (maximumAnisotropy) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_filter); - + UpdateTexture(pTexInfo); pTexInfo->nextmipmap = NULL; if (gr_cachetail) { // insertion at the tail diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 9c4e5a22b..974ac5edd 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -84,6 +84,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(SetBlend); GETFUNC(ClearBuffer); GETFUNC(SetTexture); + GETFUNC(UpdateTexture); GETFUNC(ReadRect); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index e4f4790fd..747f37f1a 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1769,6 +1769,7 @@ void I_StartupHardwareGraphics(void) HWD.pfnSetBlend = hwSym("SetBlend",NULL); HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); + HWD.pfnUpdateTexture = hwSym("UpdateTexture",NULL); HWD.pfnReadRect = hwSym("ReadRect",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index 986eb32dc..1fd7e4a98 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -106,6 +106,7 @@ static loadfunc_t hwdFuncTable[] = { {"SetBlend@4", &hwdriver.pfnSetBlend}, {"ClearBuffer@12", &hwdriver.pfnClearBuffer}, {"SetTexture@4", &hwdriver.pfnSetTexture}, + {"UpdateTexture@4", &hwdriver.pfnUpdateTexture}, {"ReadRect@24", &hwdriver.pfnReadRect}, {"GClipRect@20", &hwdriver.pfnGClipRect}, {"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache}, @@ -137,6 +138,7 @@ static loadfunc_t hwdFuncTable[] = { {"SetBlend", &hwdriver.pfnSetBlend}, {"ClearBuffer", &hwdriver.pfnClearBuffer}, {"SetTexture", &hwdriver.pfnSetTexture}, + {"UpdateTexture", &hwdriver.pfnUpdateTexture}, {"ReadRect", &hwdriver.pfnReadRect}, {"GClipRect", &hwdriver.pfnGClipRect}, {"ClearMipMapCache", &hwdriver.pfnClearMipMapCache}, From 82492f353b4dc5a28f63a778d0a28615a0823b56 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 28 Jan 2020 00:17:07 -0300 Subject: [PATCH 047/168] DoScreenWipe is void --- src/win32/win_dll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index 1fd7e4a98..3f6c5e290 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -121,7 +121,7 @@ static loadfunc_t hwdFuncTable[] = { {"FlushScreenTextures@0",&hwdriver.pfnFlushScreenTextures}, {"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe}, {"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe}, - {"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe}, + {"DoScreenWipe@0", &hwdriver.pfnDoScreenWipe}, {"DrawIntermissionBG@0",&hwdriver.pfnDrawIntermissionBG}, {"MakeScreenTexture@0", &hwdriver.pfnMakeScreenTexture}, {"MakeScreenFinalTexture@0", &hwdriver.pfnMakeScreenFinalTexture}, From 35983c7ae5a52e55f5fe08469f108701c0385f53 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 28 Jan 2020 00:20:10 -0300 Subject: [PATCH 048/168] load_shaders -> Shader_Load + Shader_SetUniforms --- src/hardware/r_opengl/r_opengl.c | 108 +++++++++++++++++-------------- 1 file changed, 61 insertions(+), 47 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d0a07d262..526ec8d3c 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -91,6 +91,10 @@ static GLuint startScreenWipe = 0; static GLuint endScreenWipe = 0; static GLuint finalScreenTexture = 0; +// Lactozilla: Set shader programs and uniforms +static void *Shader_Load(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade); +static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade); + // shortcut for ((float)1/i) static const GLfloat byte2float[256] = { 0.000000f, 0.003922f, 0.007843f, 0.011765f, 0.015686f, 0.019608f, 0.023529f, 0.027451f, @@ -1871,7 +1875,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } } -static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade) +static void *Shader_Load(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade) { #ifdef GL_SHADERS if (gl_shadersenabled) @@ -1879,50 +1883,9 @@ static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat * gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram]; if (shader->program) { - boolean custom = (gl_shaderprograms[gl_currentshaderprogram].custom); - // 13062019 - // Check for fog - //if (changed) - { - pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program); - } - - // set uniforms - { - #define UNIFORM_1(uniform, a, function) \ - if (uniform != -1) \ - function (uniform, a); - - #define UNIFORM_2(uniform, a, b, function) \ - if (uniform != -1) \ - function (uniform, a, b); - - #define UNIFORM_3(uniform, a, b, c, function) \ - if (uniform != -1) \ - function (uniform, a, b, c); - - #define UNIFORM_4(uniform, a, b, c, d, function) \ - if (uniform != -1) \ - function (uniform, a, b, c, d); - - // polygon - UNIFORM_4(shader->uniforms[gluniform_poly_color], poly->red, poly->green, poly->blue, poly->alpha, pglUniform4f); - UNIFORM_4(shader->uniforms[gluniform_tint_color], tint->red, tint->green, tint->blue, tint->alpha, pglUniform4f); - UNIFORM_4(shader->uniforms[gluniform_fade_color], fade->red, fade->green, fade->blue, fade->alpha, pglUniform4f); - UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f); - UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f); - UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f); - UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)shader_leveltime) / TICRATE, pglUniform1f); - - // Custom shader uniforms - //if (custom) { } - (void)custom; - - #undef UNIFORM_1 - #undef UNIFORM_2 - #undef UNIFORM_3 - #undef UNIFORM_4 - } + pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program); + Shader_SetUniforms(Surface, poly, tint, fade); + return shader; } else pglUseProgram(0); @@ -1934,6 +1897,57 @@ static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat * (void)poly; (void)tint; (void)fade; +#endif + return NULL; +} + +static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade) +{ +#ifdef GL_SHADERS + if (gl_shadersenabled) + { + gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram]; + if (!shader->program) + return; + + #define UNIFORM_1(uniform, a, function) \ + if (uniform != -1) \ + function (uniform, a); + + #define UNIFORM_2(uniform, a, b, function) \ + if (uniform != -1) \ + function (uniform, a, b); + + #define UNIFORM_3(uniform, a, b, c, function) \ + if (uniform != -1) \ + function (uniform, a, b, c); + + #define UNIFORM_4(uniform, a, b, c, d, function) \ + if (uniform != -1) \ + function (uniform, a, b, c, d); + + // polygon + UNIFORM_4(shader->uniforms[gluniform_poly_color], poly->red, poly->green, poly->blue, poly->alpha, pglUniform4f); + UNIFORM_4(shader->uniforms[gluniform_tint_color], tint->red, tint->green, tint->blue, tint->alpha, pglUniform4f); + UNIFORM_4(shader->uniforms[gluniform_fade_color], fade->red, fade->green, fade->blue, fade->alpha, pglUniform4f); + if (Surface != NULL) + { + UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f); + } + UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)shader_leveltime) / TICRATE, pglUniform1f); + + #undef UNIFORM_1 + #undef UNIFORM_2 + #undef UNIFORM_3 + #undef UNIFORM_4 + } +#else + (void)Surface; + (void)poly; + (void)tint; + (void)fade; #endif } @@ -2042,7 +2056,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI pglColor4ubv(c); } - load_shaders(pSurf, &poly, &tint, &fade); + Shader_Load(pSurf, &poly, &tint, &fade); pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s); @@ -2677,7 +2691,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 fade.blue = byte2float[Surface->FadeColor.s.blue]; fade.alpha = byte2float[Surface->FadeColor.s.alpha]; - load_shaders(Surface, &poly, &tint, &fade); + Shader_Load(Surface, &poly, &tint, &fade); pglEnable(GL_CULL_FACE); pglEnable(GL_NORMALIZE); From 93fe6a50acbb8df648bbf440f068f96604796b20 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 28 Jan 2020 00:26:09 -0300 Subject: [PATCH 049/168] glFog is unused --- src/hardware/r_opengl/r_opengl.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 526ec8d3c..f15da0ef6 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -273,10 +273,6 @@ static void GL_MSG_Error(const char *format, ...) #define pglTexImage2D glTexImage2D #define pglTexSubImage2D glTexSubImage2D -/* Fog */ -#define pglFogf glFogf -#define pglFogfv glFogfv - /* 1.1 functions */ /* texture objects */ //GL_EXT_texture_object #define pglGenTextures glGenTextures @@ -389,12 +385,6 @@ static PFNglTexImage2D pglTexImage2D; typedef void (APIENTRY * PFNglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); static PFNglTexSubImage2D pglTexSubImage2D; -/* Fog */ -typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param); -static PFNglFogf pglFogf; -typedef void (APIENTRY * PFNglFogfv) (GLenum pname, const GLfloat *params); -static PFNglFogfv pglFogfv; - /* 1.1 functions */ /* texture objects */ //GL_EXT_texture_object typedef void (APIENTRY * PFNglGenTextures) (GLsizei n, const GLuint *textures); @@ -527,9 +517,6 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglTexImage2D, glTexImage2D) GETOPENGLFUNC(pglTexSubImage2D , glTexSubImage2D) - GETOPENGLFUNC(pglFogf, glFogf) - GETOPENGLFUNC(pglFogfv, glFogfv) - GETOPENGLFUNC(pglGenTextures, glGenTextures) GETOPENGLFUNC(pglDeleteTextures, glDeleteTextures) GETOPENGLFUNC(pglBindTexture, glBindTexture) From b6b875f934950b95c37c0d70424755ec03416ba2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 28 Jan 2020 00:33:45 -0300 Subject: [PATCH 050/168] so is the accumulation buffer (deprecated) --- src/hardware/r_opengl/r_opengl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index f15da0ef6..9892439aa 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -515,7 +515,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglTexEnvi, glTexEnvi) GETOPENGLFUNC(pglTexParameteri, glTexParameteri) GETOPENGLFUNC(pglTexImage2D, glTexImage2D) - GETOPENGLFUNC(pglTexSubImage2D , glTexSubImage2D) + GETOPENGLFUNC(pglTexSubImage2D, glTexSubImage2D) GETOPENGLFUNC(pglGenTextures, glGenTextures) GETOPENGLFUNC(pglDeleteTextures, glDeleteTextures) @@ -1181,9 +1181,6 @@ void SetModelView(GLint w, GLint h) screen_height = h; pglViewport(0, 0, w, h); -#ifdef GL_ACCUM_BUFFER_BIT - pglClear(GL_ACCUM_BUFFER_BIT); -#endif pglMatrixMode(GL_PROJECTION); pglLoadIdentity(); From b0ba9d22a8d9b9a6212390be7f3a159e3331ef62 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 28 Jan 2020 00:41:41 -0300 Subject: [PATCH 051/168] i want to die --- src/hardware/hw_cache.c | 158 ++-------------------------------------- src/hardware/hw_glide.h | 25 ------- src/hardware/hw_glob.h | 2 - src/hardware/hw_light.c | 5 -- src/hardware/hw_main.c | 3 - src/hardware/hw_md2.c | 14 ---- 6 files changed, 8 insertions(+), 199 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 7c509c273..6af54d4cd 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -435,123 +435,10 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, GrTexInfo *grInfo) { -#ifdef GLIDE_API_COMPATIBILITY - // Build the full textures from patches. - static const GrLOD_t gr_lods[9] = - { - GR_LOD_LOG2_256, - GR_LOD_LOG2_128, - GR_LOD_LOG2_64, - GR_LOD_LOG2_32, - GR_LOD_LOG2_16, - GR_LOD_LOG2_8, - GR_LOD_LOG2_4, - GR_LOD_LOG2_2, - GR_LOD_LOG2_1 - }; - - typedef struct - { - GrAspectRatio_t aspect; - float max_s; - float max_t; - } booring_aspect_t; - - static const booring_aspect_t gr_aspects[8] = - { - {GR_ASPECT_LOG2_1x1, 255, 255}, - {GR_ASPECT_LOG2_2x1, 255, 127}, - {GR_ASPECT_LOG2_4x1, 255, 63}, - {GR_ASPECT_LOG2_8x1, 255, 31}, - - {GR_ASPECT_LOG2_1x1, 255, 255}, - {GR_ASPECT_LOG2_1x2, 127, 255}, - {GR_ASPECT_LOG2_1x4, 63, 255}, - {GR_ASPECT_LOG2_1x8, 31, 255} - }; - - INT32 j,k; - INT32 max,min; -#else (void)grInfo; -#endif - - // find a power of 2 width/height - if (cv_grrounddown.value) - { - blockwidth = 256; - while (originalwidth < blockwidth) - blockwidth >>= 1; - if (blockwidth < 1) - I_Error("3D GenerateTexture : too small"); - - blockheight = 256; - while (originalheight < blockheight) - blockheight >>= 1; - if (blockheight < 1) - I_Error("3D GenerateTexture : too small"); - } - else - { -#ifdef GLIDE_API_COMPATIBILITY - //size up to nearest power of 2 - blockwidth = 1; - while (blockwidth < originalwidth) - blockwidth <<= 1; - // scale down the original graphics to fit in 256 - if (blockwidth > 2048) - blockwidth = 2048; - //I_Error("3D GenerateTexture : too big"); - - //size up to nearest power of 2 - blockheight = 1; - while (blockheight < originalheight) - blockheight <<= 1; - // scale down the original graphics to fit in 256 - if (blockheight > 2048) - blockheight = 2048; - //I_Error("3D GenerateTexture : too big"); -#else - blockwidth = originalwidth; - blockheight = originalheight; -#endif - } - - // do the boring LOD stuff.. blech! -#ifdef GLIDE_API_COMPATIBILITY - if (blockwidth >= blockheight) - { - max = blockwidth; - min = blockheight; - } - else - { - max = blockheight; - min = blockwidth; - } - - for (k = 2048, j = 0; k > max; j++) - k>>=1; - grInfo->smallLodLog2 = gr_lods[j]; - grInfo->largeLodLog2 = gr_lods[j]; - - for (k = max, j = 0; k > min && j < 4; j++) - k>>=1; - // aspect ratio too small for 3Dfx (eg: 8x128 is 1x16 : use 1x8) - if (j == 4) - { - j = 3; - //CONS_Debug(DBG_RENDER, "HWR_ResizeBlock : bad aspect ratio %dx%d\n", blockwidth,blockheight); - if (blockwidth < blockheight) - blockwidth = max>>3; - else - blockheight = max>>3; - } - if (blockwidth < blockheight) - j += 4; - grInfo->aspectRatioLog2 = gr_aspects[j].aspect; -#endif + blockwidth = originalwidth; + blockheight = originalheight; blocksize = blockwidth * blockheight; //CONS_Debug(DBG_RENDER, "Width is %d, Height is %d\n", blockwidth, blockheight); @@ -725,18 +612,9 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm Z_Free(grMipmap->grInfo.data); grMipmap->grInfo.data = NULL; - // if rounddown, rounddown patches as well as textures - if (cv_grrounddown.value) - { - newwidth = blockwidth; - newheight = blockheight; - } - else - { - // no rounddown, do not size up patches, so they don't look 'scaled' - newwidth = min(grPatch->width, blockwidth); - newheight = min(grPatch->height, blockheight); - } + // no rounddown, do not size up patches, so they don't look 'scaled' + newwidth = min(grPatch->width, blockwidth); + newheight = min(grPatch->height, blockheight); if (makebitmap) { @@ -903,11 +781,6 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) size_t size, pflatsize; // setup the texture info -#ifdef GLIDE_API_COMPATIBILITY - grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64; - grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64; - grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; -#endif grMipmap->grInfo.format = GR_TEXFMT_P_8; grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; @@ -954,11 +827,6 @@ static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum) W_FlushCachedPatches(); // setup the texture info -#ifdef GLIDE_API_COMPATIBILITY - grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64; - grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64; - grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; -#endif grMipmap->grInfo.format = GR_TEXFMT_P_8; grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; @@ -1255,19 +1123,9 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) // allocate block block = MakeBlock(grpatch->mipmap); - // if rounddown, rounddown patches as well as textures - if (cv_grrounddown.value) - { - newwidth = blockwidth; - newheight = blockheight; - } - else - { - // no rounddown, do not size up patches, so they don't look 'scaled' - newwidth = min(SHORT(pic->width),blockwidth); - newheight = min(SHORT(pic->height),blockheight); - } - + // no rounddown, do not size up patches, so they don't look 'scaled' + newwidth = min(SHORT(pic->width),blockwidth); + newheight = min(SHORT(pic->height),blockheight); if (grpatch->width == blockwidth && grpatch->height == blockheight && diff --git a/src/hardware/hw_glide.h b/src/hardware/hw_glide.h index f539412af..d0eeebaeb 100644 --- a/src/hardware/hw_glide.h +++ b/src/hardware/hw_glide.h @@ -18,26 +18,6 @@ typedef unsigned long FxU32; typedef long FxI32; -typedef FxI32 GrAspectRatio_t; -#define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */ -#define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */ -#define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */ -#define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */ -#define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */ -#define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */ -#define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */ - -typedef FxI32 GrLOD_t; -#define GR_LOD_LOG2_256 0x8 -#define GR_LOD_LOG2_128 0x7 -#define GR_LOD_LOG2_64 0x6 -#define GR_LOD_LOG2_32 0x5 -#define GR_LOD_LOG2_16 0x4 -#define GR_LOD_LOG2_8 0x3 -#define GR_LOD_LOG2_4 0x2 -#define GR_LOD_LOG2_2 0x1 -#define GR_LOD_LOG2_1 0x0 - typedef FxI32 GrTextureFormat_t; #define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */ #define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */ @@ -52,11 +32,6 @@ typedef FxI32 GrTextureFormat_t; typedef struct { -#ifdef GLIDE_API_COMPATIBILITY - GrLOD_t smallLodLog2; - GrLOD_t largeLodLog2; - GrAspectRatio_t aspectRatioLog2; -#endif GrTextureFormat_t format; void *data; } GrTexInfo; diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 570074a09..861c2f382 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -111,8 +111,6 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum); // -------- // hw_draw.c // -------- -extern consvar_t cv_grrounddown; // on/off - extern INT32 patchformat; extern INT32 textureformat; diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index b8cca0576..a47f12749 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -1245,11 +1245,6 @@ static void HWR_SetLight(void) lightmappatch.height = 128; lightmappatch.mipmap->width = 128; lightmappatch.mipmap->height = 128; -#ifdef GLIDE_API_COMPATIBILITY - lightmappatch.mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_128; - lightmappatch.mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_128; - lightmappatch.mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; -#endif lightmappatch.mipmap->flags = 0; //TF_WRAPXY; // DEBUG: view the overdraw ! } HWD.pfnSetTexture(lightmappatch.mipmap); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 4aa6ebfdb..759e26b67 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6077,8 +6077,6 @@ consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grslopecontrast = {"gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_SAVE|CV_CALL, grfiltermode_cons_t, CV_grfiltermode_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t, @@ -6122,7 +6120,6 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grshaders); CV_RegisterVar(&cv_grfiltermode); - CV_RegisterVar(&cv_grrounddown); CV_RegisterVar(&cv_grcorrecttricks); CV_RegisterVar(&cv_grsolvetjoin); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 3914a1bcb..461a3403d 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -393,13 +393,6 @@ static void md2_loadTexture(md2_t *model) V_CubeApply(&image->s.red, &image->s.green, &image->s.blue); image++; } - -#ifdef GLIDE_API_COMPATIBILITY - // not correct! - grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; -#endif } HWD.pfnSetTexture(grpatch->mipmap); } @@ -448,13 +441,6 @@ static void md2_loadBlendTexture(md2_t *model) grpatch->height = (INT16)h; grpatch->mipmap->width = (UINT16)w; grpatch->mipmap->height = (UINT16)h; - -#ifdef GLIDE_API_COMPATIBILITY - // not correct! - grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; -#endif } HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary From a321ec9135d9641fd745e856523df16d386ce19b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 28 Jan 2020 00:56:22 -0300 Subject: [PATCH 052/168] no more 3dfx --- src/hardware/hw_cache.c | 92 +++++++++++------------------------------ 1 file changed, 25 insertions(+), 67 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 6af54d4cd..12f3d4cee 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -26,9 +26,6 @@ #include "../r_patch.h" #include "../p_setup.h" -// Values set after a call to HWR_ResizeBlock() -static INT32 blocksize, blockwidth, blockheight; - INT32 patchformat = GR_TEXFMT_AP_88; // use alpha for holes INT32 textureformat = GR_TEXFMT_P_8; // use chromakey for hole @@ -315,7 +312,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); // NOTE: should this actually be pblockwidth*bpp? - blockmodulo = blockwidth*bpp; + blockmodulo = pblockwidth*bpp; // Draw each column to the block cache for (; ncols--; block += bpp, xfrac += xfracstep) @@ -408,7 +405,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); // NOTE: should this actually be pblockwidth*bpp? - blockmodulo = blockwidth*bpp; + blockmodulo = pblockwidth*bpp; // Draw each column to the block cache for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep) @@ -426,29 +423,12 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, } } - -// resize the patch to be 3dfx compliant -// set : blocksize = blockwidth * blockheight (no bpp used) -// blockwidth -// blockheight -//note : 8bit (1 byte per pixel) palettized format -static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, - GrTexInfo *grInfo) -{ - (void)grInfo; - - blockwidth = originalwidth; - blockheight = originalheight; - blocksize = blockwidth * blockheight; - - //CONS_Debug(DBG_RENDER, "Width is %d, Height is %d\n", blockwidth, blockheight); -} - static UINT8 *MakeBlock(GLMipmap_t *grMipmap) { UINT8 *block; INT32 bpp, i; UINT16 bu16 = ((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX); + INT32 blocksize = (grMipmap->width * grMipmap->height); bpp = format2bpp[grMipmap->grInfo.format]; block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->grInfo.data)); @@ -479,6 +459,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) texpatch_t *patch; patch_t *realpatch; UINT8 *pdata; + INT32 blockwidth, blockheight, blocksize; INT32 i; boolean skyspecial = false; //poor hack for Legacy large skies.. @@ -499,11 +480,13 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) else grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY; - HWR_ResizeBlock (texture->width, texture->height, &grtex->mipmap.grInfo); - grtex->mipmap.width = (UINT16)blockwidth; - grtex->mipmap.height = (UINT16)blockheight; + grtex->mipmap.width = (UINT16)texture->width; + grtex->mipmap.height = (UINT16)texture->height; grtex->mipmap.grInfo.format = textureformat; + blockwidth = texture->width; + blockheight = texture->height; + blocksize = (blockwidth * blockheight); block = MakeBlock(&grtex->mipmap); if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading) @@ -572,8 +555,6 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) // patch may be NULL if grMipmap has been initialised already and makebitmap is false void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap) { - INT32 newwidth, newheight; - #ifndef NO_PNG_LUMPS // lump is a png so convert it size_t len = W_LumpLengthPwad(grPatch->wadnum, grPatch->lumpnum); @@ -592,42 +573,29 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm grPatch->leftoffset = SHORT(patch->leftoffset); grPatch->topoffset = SHORT(patch->topoffset); - // find the good 3dfx size (boring spec) - HWR_ResizeBlock (SHORT(patch->width), SHORT(patch->height), &grMipmap->grInfo); - grMipmap->width = (UINT16)blockwidth; - grMipmap->height = (UINT16)blockheight; + grMipmap->width = (UINT16)SHORT(patch->width); + grMipmap->height = (UINT16)SHORT(patch->height); // no wrap around, no chroma key grMipmap->flags = 0; // setup the texture info grMipmap->grInfo.format = patchformat; } - else - { - blockwidth = grMipmap->width; - blockheight = grMipmap->height; - blocksize = blockwidth * blockheight; - } Z_Free(grMipmap->grInfo.data); grMipmap->grInfo.data = NULL; - // no rounddown, do not size up patches, so they don't look 'scaled' - newwidth = min(grPatch->width, blockwidth); - newheight = min(grPatch->height, blockheight); - if (makebitmap) { MakeBlock(grMipmap); HWR_DrawPatchInCache(grMipmap, - newwidth, newheight, + grPatch->width, grPatch->height, grPatch->width, grPatch->height, patch); } - grPatch->max_s = (float)newwidth / (float)blockwidth; - grPatch->max_t = (float)newheight / (float)blockheight; + grPatch->max_s = grPatch->max_t = 1.0f; } @@ -1098,7 +1066,6 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) pic_t *pic; UINT8 *block; size_t len; - INT32 newwidth, newheight; pic = W_CacheLumpNum(lumpnum, PU_CACHE); grpatch->width = SHORT(pic->width); @@ -1108,10 +1075,8 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) grpatch->leftoffset = 0; grpatch->topoffset = 0; - // find the good 3dfx size (boring spec) - HWR_ResizeBlock (grpatch->width, grpatch->height, &grpatch->mipmap->grInfo); - grpatch->mipmap->width = (UINT16)blockwidth; - grpatch->mipmap->height = (UINT16)blockheight; + grpatch->mipmap->width = (UINT16)grpatch->width; + grpatch->mipmap->height = (UINT16)grpatch->height; if (pic->mode == PALETTE) grpatch->mipmap->grInfo.format = textureformat; // can be set by driver @@ -1123,20 +1088,16 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) // allocate block block = MakeBlock(grpatch->mipmap); - // no rounddown, do not size up patches, so they don't look 'scaled' - newwidth = min(SHORT(pic->width),blockwidth); - newheight = min(SHORT(pic->height),blockheight); - - if (grpatch->width == blockwidth && - grpatch->height == blockheight && + if (grpatch->width == SHORT(pic->width) && + grpatch->height == SHORT(pic->height) && format2bpp[grpatch->mipmap->grInfo.format] == format2bpp[picmode2GR[pic->mode]]) { // no conversion needed M_Memcpy(grpatch->mipmap->grInfo.data, pic->data,len); } else - HWR_DrawPicInCache(block, newwidth, newheight, - blockwidth*format2bpp[grpatch->mipmap->grInfo.format], + HWR_DrawPicInCache(block, SHORT(pic->width), SHORT(pic->height), + SHORT(pic->width)*format2bpp[grpatch->mipmap->grInfo.format], pic, format2bpp[grpatch->mipmap->grInfo.format]); @@ -1144,8 +1105,7 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) Z_ChangeTag(block, PU_HWRCACHE_UNLOCKED); grpatch->mipmap->flags = 0; - grpatch->max_s = (float)newwidth / (float)blockwidth; - grpatch->max_t = (float)newheight / (float)blockheight; + grpatch->max_s = grpatch->max_t = 1.0f; } HWD.pfnSetTexture(grpatch->mipmap); //CONS_Debug(DBG_RENDER, "picloaded at %x as texture %d\n",grpatch->mipmap.grInfo.data, grpatch->mipmap.downloaded); @@ -1181,7 +1141,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 { INT32 i,j; fixed_t posx, posy, stepx, stepy; - UINT8 *block = mipmap->grInfo.data; // places the data directly into here, it already has the space allocated from HWR_ResizeBlock + UINT8 *block = mipmap->grInfo.data; // places the data directly into here UINT8 *flat; UINT8 *dest, *src, texel; RGBA_t col; @@ -1196,7 +1156,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 for (j = 0; j < pblockheight; j++) { posx = 0; - dest = &block[j*blockwidth]; // 1bpp + dest = &block[j*(mipmap->width)]; // 1bpp src = &flat[(posy>>FRACBITS)*SHORT(fmwidth)]; for (i = 0; i < pblockwidth;i++) { @@ -1250,14 +1210,12 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum) } // Thankfully, this will still work for this scenario - HWR_ResizeBlock(fmwidth, fmheight, &grMipmap->grInfo); - - grMipmap->width = blockwidth; - grMipmap->height = blockheight; + grMipmap->width = fmwidth; + grMipmap->height = fmheight; MakeBlock(grMipmap); - HWR_DrawFadeMaskInCache(grMipmap, blockwidth, blockheight, fademasklumpnum, fmwidth, fmheight); + HWR_DrawFadeMaskInCache(grMipmap, fmwidth, fmheight, fademasklumpnum, fmwidth, fmheight); // I DO need to convert this because it isn't power of 2 and we need the alpha } From d2bfc673a998c5027af13717d000b275bdb3f3a2 Mon Sep 17 00:00:00 2001 From: lachwright Date: Sat, 1 Feb 2020 17:01:27 +0800 Subject: [PATCH 053/168] Distance orbital camera appropriately when gr_shearing is enabled --- src/p_user.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 44bc31b90..399b1fbbf 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10162,9 +10162,11 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (camorbit) //Sev here, I'm guessing this is where orbital cam lives { - if (rendermode == render_opengl) +#ifdef HWRENDER + if (rendermode == render_opengl && !cv_grshearing.value) distxy = FixedMul(dist, FINECOSINE((focusaiming>>ANGLETOFINESHIFT) & FINEMASK)); else +#endif distxy = dist; distz = -FixedMul(dist, FINESINE((focusaiming>>ANGLETOFINESHIFT) & FINEMASK)) + slopez; } From 65da251a2fd4ab680e79380fe30067bf31eec9a0 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 1 Feb 2020 22:25:48 -0300 Subject: [PATCH 054/168] Fix ACZ fence texture --- src/r_data.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index 871816672..a2a87d5ec 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -230,25 +230,31 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, tex UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha) { RGBA_t output; + INT16 fullalpha = (alpha - (0xFF - foreground.s.alpha)); if (style == AST_TRANSLUCENT) { - if (alpha == 0) + if (fullalpha <= 0) output.rgba = background.rgba; - else if (alpha == 0xFF) - output.rgba = foreground.rgba; - else if (alpha < 0xFF) - { - UINT8 beta = (0xFF - alpha); - output.s.red = ((background.s.red * beta) + (foreground.s.red * alpha)) / 0xFF; - output.s.green = ((background.s.green * beta) + (foreground.s.green * alpha)) / 0xFF; - output.s.blue = ((background.s.blue * beta) + (foreground.s.blue * alpha)) / 0xFF; - } - // write foreground pixel alpha - // if there's no pixel in here - if (!background.rgba) - output.s.alpha = foreground.s.alpha; else - output.s.alpha = 0xFF; + { + // don't go too high + if (fullalpha >= 0xFF) + fullalpha = 0xFF; + alpha = (UINT8)fullalpha; + + // if the background pixel is empty, + // match software and don't blend anything + if (!background.s.alpha) + output.s.alpha = 0; + else + { + UINT8 beta = (0xFF - alpha); + output.s.red = ((background.s.red * beta) + (foreground.s.red * alpha)) / 0xFF; + output.s.green = ((background.s.green * beta) + (foreground.s.green * alpha)) / 0xFF; + output.s.blue = ((background.s.blue * beta) + (foreground.s.blue * alpha)) / 0xFF; + output.s.alpha = 0xFF; + } + } return output.rgba; } #define clamp(c) max(min(c, 0xFF), 0x00); From 828961264e1bd29e93be7edbb12688f9c1f4a809 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 1 Feb 2020 22:50:52 -0300 Subject: [PATCH 055/168] Update w_wad.c --- src/w_wad.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 9ff082aa5..0db81096b 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1894,8 +1894,6 @@ int W_VerifyNMUSlumps(const char *filename) {"YB_", 3}, // Intermission graphics, goes with the above {"M_", 2}, // As does menu stuff {"MUSICDEF", 8}, // Song definitions (thanks kart) - {"SHADERS", 7}, // Shader definitions - {"SH_", 3}, // GLSL shader {NULL, 0}, }; From 07b2a5aca80bc3e91c80bb31e917a6de40e65bc3 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sat, 1 Feb 2020 22:11:21 -0500 Subject: [PATCH 056/168] FIX COLOR BUG --- src/hardware/hw_data.h | 1 - src/hardware/hw_md2.c | 57 ++++++++++++++++++------------------------ src/p_setup.c | 5 ++++ src/w_wad.c | 2 +- src/z_zone.c | 2 ++ src/z_zone.h | 1 + 6 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index 4279b87f5..686d522a0 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -41,7 +41,6 @@ struct GLMipmap_s struct GLMipmap_s *nextcolormap; const UINT8 *colormap; - INT32 tcindex; // opengl struct GLMipmap_s *nextmipmap; // opengl : liste of all texture in opengl driver diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 461a3403d..82d062da1 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -999,32 +999,13 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT // mostly copied from HWR_GetMappedPatch, hence the similarities and comment GLMipmap_t *grmip, *newmip; - if ((colormap == colormaps || colormap == NULL) && (skinnum > TC_DEFAULT)) + if (colormap == colormaps || colormap == NULL) { // Don't do any blending HWD.pfnSetTexture(gpatch->mipmap); return; } - // search for the mipmap - // skip the first (no colormap translated) - for (grmip = gpatch->mipmap; grmip->nextcolormap; ) - { - grmip = grmip->nextcolormap; - if (grmip->colormap == colormap || (skinnum < TC_DEFAULT && grmip->tcindex == skinnum)) - { - if (grmip->downloaded && grmip->grInfo.data) - { - HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture - Z_ChangeTag(grmip->grInfo.data, PU_HWRMODELTEXTURE); - return; - } - } - } - - // If here, the blended texture has not been created - // So we create it - if ((blendgpatch && blendgpatch->mipmap->grInfo.format) && (gpatch->width != blendgpatch->width || gpatch->height != blendgpatch->height)) { @@ -1033,21 +1014,39 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT return; } + // search for the mipmap + // skip the first (no colormap translated) + for (grmip = gpatch->mipmap; grmip->nextcolormap; ) + { + grmip = grmip->nextcolormap; + if (grmip->colormap == colormap) + { + if (grmip->downloaded && grmip->grInfo.data) + { + HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture + Z_ChangeTag(grmip->grInfo.data, PU_HWRMODELTEXTURE_UNLOCKED); + return; + } + } + } + + // If here, the blended texture has not been created + // So we create it + //BP: WARNING: don't free it manually without clearing the cache of harware renderer // (it have a liste of mipmap) // this malloc is cleared in HWR_FreeTextureCache // (...) unfortunately z_malloc fragment alot the memory :(so malloc is better newmip = calloc(1, sizeof (*newmip)); if (newmip == NULL) - I_Error("%s: Out of memory", "HWR_GetMappedPatch"); + I_Error("%s: Out of memory", "HWR_GetBlendedTexture"); grmip->nextcolormap = newmip; newmip->colormap = colormap; - newmip->tcindex = skinnum; HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color); HWD.pfnSetTexture(newmip); - Z_ChangeTag(newmip->grInfo.data, PU_HWRMODELTEXTURE); + Z_ChangeTag(newmip->grInfo.data, PU_HWRMODELTEXTURE_UNLOCKED); } #define NORMALFOG 0x00000000 @@ -1273,7 +1272,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { - INT32 skinnum = INT32_MAX; + INT32 skinnum = TC_DEFAULT; if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" { @@ -1304,15 +1303,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) } // Translation or skin number found - if (skinnum != INT32_MAX) - { - HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); - } - else - { - // Sorry nothing - HWD.pfnSetTexture(gpatch->mipmap); - } + HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); } else { diff --git a/src/p_setup.c b/src/p_setup.c index c7f4cd81b..868793534 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3701,10 +3701,15 @@ void HWR_SetupLevel(void) // Meaning, they had memory allocated and marked with the PU_LEVEL tag. // Level textures are only reloaded after R_LoadTextures, which is // when the texture list is loaded. + + // Sal: Unfortunately, NOT freeing them causes the dreaded Color Bug. + HWR_FreeMipmapCache(); + #ifdef ALAM_LIGHTING // BP: reset light between levels (we draw preview frame lights on current frame) HWR_ResetLights(); #endif + // Correct missing sidedefs & deep water trick HWR_CorrectSWTricks(); HWR_CreatePlanePolygons((INT32)numnodes - 1); diff --git a/src/w_wad.c b/src/w_wad.c index 9ff082aa5..67fab50d8 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1484,7 +1484,7 @@ void W_FlushCachedPatches(void) Z_FreeTag(PU_HWRPATCHINFO); Z_FreeTag(PU_HWRMODELTEXTURE); Z_FreeTag(PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); + Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRMODELTEXTURE_UNLOCKED); } needpatchflush = false; } diff --git a/src/z_zone.c b/src/z_zone.c index 0abd77257..bd41cbe67 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -516,6 +516,7 @@ void Z_FlushCachedPatches(void) Z_FreeTag(PU_HWRCACHE); Z_FreeTag(PU_HWRCACHE_UNLOCKED); Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); + Z_FreeTag(PU_HWRMODELTEXTURE_UNLOCKED); } // happens before a renderer switch @@ -813,6 +814,7 @@ static void Command_Memfree_f(void) 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 Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10); + CONS_Printf(M_GetText("HW model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10)); } #endif diff --git a/src/z_zone.h b/src/z_zone.h index 9e5f74343..250885e10 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -64,6 +64,7 @@ enum // 'second-level' cache for graphics // stored in hardware format and downloaded as needed PU_HWRPATCHINFO_UNLOCKED = 103, // 'unlocked' PU_HWRPATCHINFO memory + PU_HWRMODELTEXTURE_UNLOCKED = 104, // 'unlocked' PU_HWRMODELTEXTURE memory }; // From 8305d657680f8a9dd2597b508db1c8c48178af10 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sat, 1 Feb 2020 22:58:11 -0500 Subject: [PATCH 057/168] Drop shadows closer to software --- src/hardware/hw_main.c | 53 +++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 34 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 759e26b67..5380d2e38 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3742,13 +3742,12 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v return false; } -static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale) +static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) { GLPatch_t *gpatch; FOutVector shadowVerts[4]; FSurfaceInfo sSurf; float fscale; float fx; float fy; float offset; - UINT8 lightlevel = 255; extracolormap_t *colormap = NULL; UINT8 i; @@ -3791,10 +3790,18 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale else offset = (float)(gpatch->height/2); - shadowVerts[0].x = shadowVerts[3].x = fx - offset; - shadowVerts[2].x = shadowVerts[1].x = fx + offset; - shadowVerts[0].z = shadowVerts[1].z = fy - offset; - shadowVerts[3].z = shadowVerts[2].z = fy + offset; + shadowVerts[2].x = shadowVerts[3].x = fx + offset; + shadowVerts[1].x = shadowVerts[0].x = fx - offset; + shadowVerts[1].z = shadowVerts[2].z = fy - offset; + shadowVerts[0].z = shadowVerts[3].z = fy + offset; + + for (i = 0; i < 4; i++) + { + float oldx = shadowVerts[i].x; + float oldy = shadowVerts[i].z; + shadowVerts[i].x = fx + ((oldx - fx) * gr_viewcos) - ((oldy - fy) * gr_viewsin); + shadowVerts[i].z = fy + ((oldx - fx) * gr_viewsin) + ((oldy - fy) * gr_viewcos); + } if (floorslope) { @@ -3810,47 +3817,25 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale shadowVerts[i].y = FIXED_TO_FLOAT(floorz) + 0.05f; } - if (spr->flip) - { - shadowVerts[0].s = shadowVerts[3].s = gpatch->max_s; - shadowVerts[2].s = shadowVerts[1].s = 0; - } - else - { - shadowVerts[0].s = shadowVerts[3].s = 0; - shadowVerts[2].s = shadowVerts[1].s = gpatch->max_s; - } + shadowVerts[0].s = shadowVerts[3].s = 0; + shadowVerts[2].s = shadowVerts[1].s = gpatch->max_s; - // flip the texture coords (look familiar?) - if (spr->vflip) - { - shadowVerts[3].t = shadowVerts[2].t = gpatch->max_t; - shadowVerts[0].t = shadowVerts[1].t = 0; - } - else - { - shadowVerts[3].t = shadowVerts[2].t = 0; - shadowVerts[0].t = shadowVerts[1].t = gpatch->max_t; - } + shadowVerts[3].t = shadowVerts[2].t = 0; + shadowVerts[0].t = shadowVerts[1].t = gpatch->max_t; if (thing->subsector->sector->numlights) { light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before - - lightlevel = *thing->subsector->sector->lightlist[light].lightlevel; - if (*thing->subsector->sector->lightlist[light].extra_colormap) colormap = *thing->subsector->sector->lightlist[light].extra_colormap; } else { - lightlevel = thing->subsector->sector->lightlevel; - if (thing->subsector->sector->extra_colormap) colormap = thing->subsector->sector->extra_colormap; } - HWR_Lighting(&sSurf, lightlevel, colormap); + HWR_Lighting(&sSurf, 0, colormap); sSurf.PolyColor.s.alpha = alpha; HWD.pfnSetShader(3); // sprite shader @@ -4918,7 +4903,7 @@ static void HWR_DrawSprites(void) { if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value) { - HWR_DrawDropShadow(spr->mobj, spr, spr->mobj->shadowscale); + HWR_DrawDropShadow(spr->mobj, spr->mobj->shadowscale); } if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) From 33a75fcd30ff0bfdb528185de7f6ca6b2a92a26f Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 2 Feb 2020 01:08:23 -0500 Subject: [PATCH 058/168] Remove blend to black --- src/hardware/hw_md2.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 82d062da1..8abf370ca 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -900,11 +900,19 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, blendcolor = V_GetColor(translation[firsti]); + if (secondi >= translen) + mul = 0; + if (mul > 0) // If it's 0, then we only need the first color. { - if (secondi >= translen) // blend to black +#if 0 + if (secondi >= translen) + { + // blend to black nextcolor = V_GetColor(31); + } else +#endif nextcolor = V_GetColor(translation[secondi]); // Find difference between points From 11e6cf0adec5f4fd4432d8b1584e95b3dfb4fb88 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 8 Feb 2020 17:42:26 -0300 Subject: [PATCH 059/168] add "third person only" option to gr_shearing. --- src/hardware/hw_main.c | 18 +++++++++++------- src/r_main.c | 24 ++++++++++++++++++++++++ src/r_main.h | 7 ++++--- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3282f81df..0fe4a79e1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -144,7 +144,7 @@ static float gr_viewludsin, gr_viewludcos; // look up down kik test static float gr_fovlud; static angle_t gr_aimingangle; -static void HWR_SetTransformAiming(FTransform *trans); +static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); // ========================================================================== // Lighting @@ -5425,7 +5425,7 @@ static void HWR_DrawSkyBackground(player_t *player) //04/01/2000: Hurdler: added for T&L // It should replace all other gr_viewxxx when finished - HWR_SetTransformAiming(&dometransform); + HWR_SetTransformAiming(&dometransform, player, false); dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); if (*type == postimg_flip) @@ -5590,9 +5590,11 @@ void HWR_SetViewSize(void) // Set view aiming, for the sky dome, the skybox, // and the normal view, all with a single function. -static void HWR_SetTransformAiming(FTransform *trans) +static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox) { - if (cv_grshearing.value) + // 1 = always on + // 2 = chasecam only + if (cv_grshearing.value == 1 || (cv_grshearing.value == 2 && R_IsViewpointFirstPerson(player, skybox))) { fixed_t fixedaiming = AIMINGTODY(aimingangle); trans->viewaiming = FIXED_TO_FLOAT(fixedaiming); @@ -5604,6 +5606,7 @@ static void HWR_SetTransformAiming(FTransform *trans) trans->shearing = false; gr_aimingangle = aimingangle; } + trans->anglex = (float)(gr_aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); } @@ -5663,7 +5666,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) // It should replace all other gr_viewxxx when finished memset(&atransform, 0x00, sizeof(FTransform)); - HWR_SetTransformAiming(&atransform); + HWR_SetTransformAiming(&atransform, player, true); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(gr_aimingangle>>ANGLETOFINESHIFT)); @@ -5864,7 +5867,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // It should replace all other gr_viewxxx when finished memset(&atransform, 0x00, sizeof(FTransform)); - HWR_SetTransformAiming(&atransform); + HWR_SetTransformAiming(&atransform, player, false); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(gr_aimingangle>>ANGLETOFINESHIFT)); @@ -5998,6 +6001,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}}; +static CV_PossibleValue_t grshearing_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Third-person"}, {0, NULL}}; static void CV_grfiltermode_OnChange(void); static void CV_granisotropic_OnChange(void); @@ -6024,7 +6028,7 @@ consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, N consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grshearing = {"gr_shearing", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grshearing = {"gr_shearing", "Third-person", CV_SAVE, grshearing_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/r_main.c b/src/r_main.c index a8e7137ce..76a510c30 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1011,6 +1011,30 @@ void R_SkyboxFrame(player_t *player) R_SetupFreelook(); } +boolean R_IsViewpointFirstPerson(player_t *player, boolean skybox) +{ + boolean chasecam = false; + if (splitscreen && player == &players[secondarydisplayplayer] && player != &players[consoleplayer]) + chasecam = (cv_chasecam2.value != 0); + else + chasecam = (cv_chasecam.value != 0); + + if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode) + chasecam = true; // force chasecam on + else if (player->spectator) // no spectator chasecam + chasecam = false; // force chasecam off + + // cut-away view stuff + if (player->awayviewtics || skybox) + return chasecam; + // use outside cam view + else if (!player->spectator && chasecam) + return true; + + // use the player's eyes view + return false; +} + static void R_PortalFrame(portal_t *portal) { viewx = portal->viewx; diff --git a/src/r_main.h b/src/r_main.h index 0c5f196e1..5ce3e922c 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -102,10 +102,11 @@ void R_SetViewSize(void); // do it (sometimes explicitly called) void R_ExecuteSetViewSize(void); -void R_SkyboxFrame(player_t *player); - void R_SetupFrame(player_t *player); -// Called by G_Drawer. +void R_SkyboxFrame(player_t *player); +boolean R_IsViewpointFirstPerson(player_t *player, boolean skybox); + +// Called by D_Display. void R_RenderPlayerView(player_t *player); // add commands related to engine, at game startup From e1573913878edf282910016e6c9257543b70ff13 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 8 Feb 2020 17:49:27 -0300 Subject: [PATCH 060/168] split r_isviewpointfirstperson --- src/r_main.c | 10 +++++++++- src/r_main.h | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/r_main.c b/src/r_main.c index 76a510c30..c7e8df4a3 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1011,9 +1011,10 @@ void R_SkyboxFrame(player_t *player) R_SetupFreelook(); } -boolean R_IsViewpointFirstPerson(player_t *player, boolean skybox) +boolean R_ViewpointHasChasecam(player_t *player) { boolean chasecam = false; + if (splitscreen && player == &players[secondarydisplayplayer] && player != &players[consoleplayer]) chasecam = (cv_chasecam2.value != 0); else @@ -1024,6 +1025,13 @@ boolean R_IsViewpointFirstPerson(player_t *player, boolean skybox) else if (player->spectator) // no spectator chasecam chasecam = false; // force chasecam off + return chasecam; +} + +boolean R_IsViewpointFirstPerson(player_t *player, boolean skybox) +{ + boolean chasecam = R_ViewpointHasChasecam(player); + // cut-away view stuff if (player->awayviewtics || skybox) return chasecam; diff --git a/src/r_main.h b/src/r_main.h index 5ce3e922c..0dbc3e9cf 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -104,6 +104,8 @@ void R_ExecuteSetViewSize(void); void R_SetupFrame(player_t *player); void R_SkyboxFrame(player_t *player); + +boolean R_ViewpointHasChasecam(player_t *player); boolean R_IsViewpointFirstPerson(player_t *player, boolean skybox); // Called by D_Display. From d633435cd6b5b0e1f51d2bf42e395c227f9b4b83 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 8 Feb 2020 18:08:56 -0300 Subject: [PATCH 061/168] i'm not paying too much attention, am i. --- src/hardware/hw_main.c | 2 +- src/r_main.c | 2 +- src/r_main.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 0fe4a79e1..1327e548a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5594,7 +5594,7 @@ static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean { // 1 = always on // 2 = chasecam only - if (cv_grshearing.value == 1 || (cv_grshearing.value == 2 && R_IsViewpointFirstPerson(player, skybox))) + if (cv_grshearing.value == 1 || (cv_grshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))) { fixed_t fixedaiming = AIMINGTODY(aimingangle); trans->viewaiming = FIXED_TO_FLOAT(fixedaiming); diff --git a/src/r_main.c b/src/r_main.c index c7e8df4a3..40025c5b0 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1028,7 +1028,7 @@ boolean R_ViewpointHasChasecam(player_t *player) return chasecam; } -boolean R_IsViewpointFirstPerson(player_t *player, boolean skybox) +boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox) { boolean chasecam = R_ViewpointHasChasecam(player); diff --git a/src/r_main.h b/src/r_main.h index 0dbc3e9cf..52bff4140 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -106,7 +106,7 @@ void R_SetupFrame(player_t *player); void R_SkyboxFrame(player_t *player); boolean R_ViewpointHasChasecam(player_t *player); -boolean R_IsViewpointFirstPerson(player_t *player, boolean skybox); +boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox); // Called by D_Display. void R_RenderPlayerView(player_t *player); From b38f336dc5a9a136880337845bbf0411a77d9b7e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 8 Feb 2020 18:19:27 -0300 Subject: [PATCH 062/168] why does this still exist? --- src/console.c | 3 --- src/d_main.c | 7 ++++--- src/hardware/hw_cache.c | 28 ++-------------------------- src/w_wad.c | 18 ------------------ src/w_wad.h | 1 - src/z_zone.c | 4 +--- 6 files changed, 7 insertions(+), 54 deletions(-) diff --git a/src/console.c b/src/console.c index ba5ba71df..890d424fa 100644 --- a/src/console.c +++ b/src/console.c @@ -1615,10 +1615,7 @@ void CON_Drawer(void) return; if (needpatchrecache) - { - W_FlushCachedPatches(); HU_LoadGraphics(); - } if (con_recalc) { diff --git a/src/d_main.c b/src/d_main.c index dc9bfbfea..46bcd2db9 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -594,15 +594,16 @@ static void D_Display(void) needpatchrecache = false; } -// Lactozilla: Check the renderer's state +// Check the renderer's state // after a possible renderer switch. void D_CheckRendererState(void) { // flush all patches from memory - // (also frees memory tagged with PU_CACHE) - // (which are not necessarily patches but I don't care) if (needpatchflush) + { Z_FlushCachedPatches(); + needpatchflush = false; + } // some patches have been freed, // so cache them again diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 12f3d4cee..66f4e3c28 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -791,9 +791,6 @@ static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum) { UINT8 *flat; - if (needpatchflush) - W_FlushCachedPatches(); - // setup the texture info grMipmap->grInfo.format = GR_TEXFMT_P_8; grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; @@ -814,9 +811,6 @@ void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum) if (flatlumpnum == LUMPERROR) return; - if (needpatchflush) - W_FlushCachedPatches(); - grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) HWR_CacheFlat(grmip, flatlumpnum); @@ -895,9 +889,6 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) // -----------------+ void HWR_GetPatch(GLPatch_t *gpatch) { - if (needpatchflush) - W_FlushCachedPatches(); - // is it in hardware cache if (!gpatch->mipmap->downloaded && !gpatch->mipmap->grInfo.data) { @@ -928,9 +919,6 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) { GLMipmap_t *grmip, *newmip; - if (needpatchflush) - W_FlushCachedPatches(); - if (colormap == colormaps || colormap == NULL) { // Load the default (green) color in doom cache (temporary?) AND hardware cache @@ -1054,13 +1042,7 @@ static void HWR_DrawPicInCache(UINT8 *block, INT32 pblockwidth, INT32 pblockheig // -----------------+ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) { - GLPatch_t *grpatch; - - if (needpatchflush) - W_FlushCachedPatches(); - - grpatch = HWR_GetCachedGLPatch(lumpnum); - + GLPatch_t *grpatch = HWR_GetCachedGLPatch(lumpnum); if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data) { pic_t *pic; @@ -1223,13 +1205,7 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum) void HWR_GetFadeMask(lumpnum_t fademasklumpnum) { - GLMipmap_t *grmip; - - if (needpatchflush) - W_FlushCachedPatches(); - - grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; - + GLMipmap_t *grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) HWR_CacheFadeMask(grmip, fademasklumpnum); diff --git a/src/w_wad.c b/src/w_wad.c index 5f91996ca..01053ff65 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1474,21 +1474,6 @@ boolean W_IsPatchCached(lumpnum_t lumpnum, void *ptr) return W_IsPatchCachedPWAD(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr); } -void W_FlushCachedPatches(void) -{ - if (needpatchflush) - { - Z_FreeTag(PU_CACHE); - Z_FreeTag(PU_PATCH); - Z_FreeTag(PU_HUDGFX); - Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRMODELTEXTURE); - Z_FreeTag(PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRMODELTEXTURE_UNLOCKED); - } - needpatchflush = false; -} - // ========================================================================== // W_CacheLumpName // ========================================================================== @@ -1518,9 +1503,6 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) GLPatch_t *grPatch; #endif - if (needpatchflush) - W_FlushCachedPatches(); - if (!TestValidLump(wad, lump)) return NULL; diff --git a/src/w_wad.h b/src/w_wad.h index aca67c00f..8008a577c 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -196,7 +196,6 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); // return a patch void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t void W_UnlockCachedPatch(void *patch); -void W_FlushCachedPatches(void); void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); diff --git a/src/z_zone.c b/src/z_zone.c index bd41cbe67..c916ff2e2 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -498,13 +498,11 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) // Utility functions // ----------------- -// for renderer switching, free a bunch of stuff +// for renderer switching boolean needpatchflush = false; boolean needpatchrecache = false; // flush all patches from memory -// (also frees memory tagged with PU_CACHE) -// (which are not necessarily patches but I don't care) void Z_FlushCachedPatches(void) { CONS_Debug(DBG_RENDER, "Z_FlushCachedPatches()...\n"); From 9bc0592e56300c65be21249907448e301eb92d48 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 8 Feb 2020 18:23:37 -0300 Subject: [PATCH 063/168] don't free pu_cache. --- src/d_main.c | 2 +- src/z_zone.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 46bcd2db9..fadf357ca 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -659,7 +659,7 @@ void D_SRB2Loop(void) */ /* Smells like a hack... Don't fade Sonic's ass into the title screen. */ if (gamestate != GS_TITLESCREEN) - V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_CACHE)); + V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_PATCH)); for (;;) { diff --git a/src/z_zone.c b/src/z_zone.c index c916ff2e2..2156f34f3 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -506,7 +506,6 @@ boolean needpatchrecache = false; void Z_FlushCachedPatches(void) { CONS_Debug(DBG_RENDER, "Z_FlushCachedPatches()...\n"); - Z_FreeTag(PU_CACHE); Z_FreeTag(PU_PATCH); Z_FreeTag(PU_HUDGFX); Z_FreeTag(PU_HWRPATCHINFO); From 384f5af1f89f65abb418b9395ba51587d9e70f5c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 8 Feb 2020 18:27:44 -0300 Subject: [PATCH 064/168] move hw texture used to be always below. --- src/z_zone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/z_zone.c b/src/z_zone.c index 2156f34f3..25e4ea4c7 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -810,8 +810,8 @@ static void Command_Memfree_f(void) 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 Texture used : %7d KB\n"), HWR_GetTextureUsed()>>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); } #endif From 7cfc8d022e2d5387555139e54904a940e9c4906e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 8 Feb 2020 20:29:28 -0300 Subject: [PATCH 065/168] allow models for skin/sprites with same name --- src/hardware/hw_md2.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8abf370ca..7e9f36966 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -500,15 +500,10 @@ void HWR_InitModels(void) { if (stricmp(name, sprnames[i]) == 0) { - //if (stricmp(name, "PLAY") == 0) - //continue; - - //CONS_Debug(DBG_RENDER, " Found: %s %s %f %f\n", name, filename, scale, offset); md2_models[i].scale = scale; md2_models[i].offset = offset; md2_models[i].notfound = false; strcpy(md2_models[i].filename, filename); - goto md2found; } } @@ -516,18 +511,14 @@ void HWR_InitModels(void) { if (stricmp(name, skins[s].name) == 0) { - //CONS_Printf(" Found: %s %s %f %f\n", name, filename, scale, offset); md2_playermodels[s].skin = s; md2_playermodels[s].scale = scale; md2_playermodels[s].offset = offset; md2_playermodels[s].notfound = false; strcpy(md2_playermodels[s].filename, filename); - goto md2found; } } - // no sprite/player skin name found?!? - //CONS_Printf("Unknown sprite/player skin %s detected in models.dat\n", name); -md2found: + // move on to next line... continue; } @@ -570,7 +561,6 @@ void HWR_AddPlayerModel(int skin) // For skins that were added after startup } } - //CONS_Printf("Model for player skin %s not found\n", skins[skin].name); md2_playermodels[skin].notfound = true; playermd2found: fclose(f); @@ -614,7 +604,6 @@ void HWR_AddSpriteModel(size_t spritenum) // For sprites that were added after s } } - //CONS_Printf("MD2 for sprite %s not found\n", sprnames[spritenum]); md2_models[spritenum].notfound = true; spritemd2found: fclose(f); From 81a2a9e91212ca30156d935b77e3ee8030e106b9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 8 Feb 2020 20:38:37 -0300 Subject: [PATCH 066/168] fix crash --- src/d_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_main.c b/src/d_main.c index fadf357ca..cbf9c8091 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1295,6 +1295,7 @@ void D_SRB2Main(void) needpatchrecache = true; VID_CheckRenderer(); SCR_ChangeRendererCVars(setrenderneeded); + setrenderneeded = 0; } D_CheckRendererState(); From d0ee4ad440a318ac51e7534e90ca588c1c4d3bbb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 17 Feb 2020 12:30:02 -0300 Subject: [PATCH 067/168] Change the default setting of cv_grshearing to Off --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 1327e548a..37a27a2aa 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6028,7 +6028,7 @@ consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, N consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grshearing = {"gr_shearing", "Third-person", CV_SAVE, grshearing_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grshearing = {"gr_shearing", "Off", CV_SAVE, grshearing_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; From adee6c3910b509f02197cd23b5f696f335bd4143 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 19 Feb 2020 00:56:14 -0300 Subject: [PATCH 068/168] I forgot to save :] --- src/d_main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index bec5a3e2d..418da4ecc 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1292,10 +1292,7 @@ void D_SRB2Main(void) needpatchrecache = true; VID_CheckRenderer(); SCR_ChangeRendererCVars(setrenderneeded); -<<<<<<< HEAD -======= D_CheckRendererState(); ->>>>>>> origin/master setrenderneeded = 0; } From 572bffcd8337bafc2f146c43b5b76d5e3bd2851e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:38:32 -0300 Subject: [PATCH 069/168] Award pink shields in friendly gametypes --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index a24f9bf03..cc8d5db6b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3158,7 +3158,7 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou // In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (G_PlatformGametype())) { - if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only + if ((gametyperules & GTR_FRIENDLY) && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only { if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers. { From f313a0386f6e939d4043c03cea58fd4595250c13 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:40:16 -0300 Subject: [PATCH 070/168] Don't reset player between maps in campaign gametypes --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 08192bfb8..c1e5a519c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3856,7 +3856,7 @@ static void G_DoWorldDone(void) { if (server) { - if (gametype == GT_COOP) + if (gametyperules & GTR_CAMPAIGN) // don't reset player between maps D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false); else From b622f539ff02802c0f02cb6953f5c01b16322d5a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:40:52 -0300 Subject: [PATCH 071/168] Always allow skin switching in friendly gametypes --- src/d_netcmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c25929929..6e8e67fc4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1158,7 +1158,7 @@ UINT8 CanChangeSkin(INT32 playernum) // Server has skin change restrictions. if (cv_restrictskinchange.value) { - if (gametype == GT_COOP) + if (gametyperules & GTR_FRIENDLY) return true; // Can change skin during initial countdown. @@ -3753,11 +3753,11 @@ static void ExitMove_OnChange(void) { if (players[i].mo->target && players[i].mo->target->type == MT_SIGN) P_SetTarget(&players[i].mo->target, NULL); - + if (players[i].pflags & PF_FINISHED) P_GiveFinishFlags(&players[i]); } - + CONS_Printf(M_GetText("Players can now move after completing the level.\n")); } else From a334542f348622539afb6d4a820a2ed57bb78785 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:41:39 -0300 Subject: [PATCH 072/168] Scan for emeralds in gametypes with Emerald Hunt --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index c1e5a519c..d66af417c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2611,7 +2611,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); } - if (gametype == GT_COOP) + if (gametyperules & GTR_EMERALDHUNT) P_FindEmerald(); // scan for emeralds to hunt for // If NiGHTS, find lowest mare to start with. From 1b8e172af327f03cca04eb5792f91dcf636b7a87 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:45:01 -0300 Subject: [PATCH 073/168] Consider Co-Op here as any campaign gametype --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6e8e67fc4..c44a14f8b 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1737,7 +1737,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese } CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n", mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene); - if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP))) + if ((netgame || multiplayer) && !((gametype == newgametype) && (gametypedefaultrules[newgametype] & GTR_CAMPAIGN))) FLS = false; if (delay != 2) From 290cd9d08e1a87c5f92d66b42eb10f107a3b4fff Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:46:45 -0300 Subject: [PATCH 074/168] Same here --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c44a14f8b..3c17987e1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1979,7 +1979,7 @@ static void Command_Map_f(void) fromlevelselect = ( netgame || multiplayer ) && newgametype == gametype && - newgametype == GT_COOP; + gametypedefaultrules[newgametype] & GTR_CAMPAIGN; } } From 7439ab5296a4664cb65a9974aff5bb3f054f22ae Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:50:36 -0300 Subject: [PATCH 075/168] Allow countdown time-up in any campaign gametype --- src/g_game.c | 2 +- src/p_tick.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index d66af417c..265fb115f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2899,7 +2899,7 @@ void G_DoReborn(INT32 playernum) return; } - if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP)) + if (countdowntimeup || (!(netgame || multiplayer) && (gametyperules & GTR_CAMPAIGN))) resetlevel = true; else if ((G_GametypeUsesCoopLives() || G_GametypeUsesCoopStarposts()) && (netgame || multiplayer) && !G_IsSpecialStage(gamemap)) { diff --git a/src/p_tick.c b/src/p_tick.c index 1d421ad37..39a2fc6f6 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -698,7 +698,7 @@ void P_Ticker(boolean run) if (run) { - if (countdowntimer && G_PlatformGametype() && (gametype == GT_COOP || leveltime >= 4*TICRATE) && !stoppedclock && --countdowntimer <= 0) + if (countdowntimer && G_PlatformGametype() && ((gametyperules & GTR_CAMPAIGN) || leveltime >= 4*TICRATE) && !stoppedclock && --countdowntimer <= 0) { countdowntimer = 0; countdowntimeup = true; From 678935f26aa6a38320db9cd8c881764866dbbd69 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 17:02:50 -0300 Subject: [PATCH 076/168] Turn players IT if they join the game after the hide time in tag gametypes Except in gametypes with hide time stasis, because they can't change team. --- src/d_netcmd.c | 2 +- src/g_game.c | 2 +- src/p_inter.c | 2 +- src/p_user.c | 6 +++--- src/st_stuff.c | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 3c17987e1..a77ea0dd5 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2775,7 +2775,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) players[playernum].spectator = false; //If joining after hidetime in normal tag, default to being IT. - if (gametype == GT_TAG && (leveltime > (hidetime * TICRATE))) + if (((gametyperules & (GTR_TAG|GTR_HIDEFROZEN)) == GTR_TAG) && (leveltime > (hidetime * TICRATE))) { NetPacket.packet.newteam = 1; //minor hack, causes the "is it" message to be printed later. players[playernum].pflags |= PF_TAGIT; //make the player IT. diff --git a/src/g_game.c b/src/g_game.c index 265fb115f..47226931a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3221,7 +3221,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = // Tag GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // Hide and Seek - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_HIDEFROZEN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // CTF GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, diff --git a/src/p_inter.c b/src/p_inter.c index cc8d5db6b..800f07d83 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2285,7 +2285,7 @@ void P_CheckSurvivors(void) if (!taggers) //If there are no taggers, pick a survivor at random to be it. { // Exception for hide and seek. If a round has started and the IT player leaves, end the round. - if (gametype == GT_HIDEANDSEEK && (leveltime >= (hidetime * TICRATE))) + if ((gametyperules & GTR_HIDEFROZEN) && (leveltime >= (hidetime * TICRATE))) { CONS_Printf(M_GetText("The IT player has left the game.\n")); if (server) diff --git a/src/p_user.c b/src/p_user.c index 880d932af..a481969cf 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -392,7 +392,7 @@ void P_GiveFinishFlags(player_t *player) mobj_t* flag = P_SpawnMobjFromMobj(player->mo, xoffs, yoffs, 0, MT_FINISHFLAG); flag->angle = angle; angle += FixedAngle(120*FRACUNIT); - + P_SetTarget(&flag->target, player->mo); } } @@ -3679,7 +3679,7 @@ static boolean PIT_CheckSolidsTeeter(mobj_t *thing) if (thing == teeterer) return true; - if (thing->player && cv_tailspickup.value && gametype != GT_HIDEANDSEEK) + if (thing->player && cv_tailspickup.value && !(gametyperules & GTR_HIDEFROZEN)) return true; blockdist = teeterer->radius + thing->radius; @@ -8034,7 +8034,7 @@ static void P_MovePlayer(player_t *player) if (player->pflags & PF_TAGIT) forcestasis = true; } - else if (gametype == GT_HIDEANDSEEK) + else if (gametyperules & GTR_HIDEFROZEN) { if (!(player->pflags & PF_TAGIT)) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 4864f2af6..1e792db79 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1444,7 +1444,7 @@ static void ST_drawPowerupHUD(void) if (stplyr->spectator || stplyr->playerstate != PST_LIVE) return; - + // --------- // Finish icon // --------- @@ -2363,12 +2363,12 @@ static void ST_drawTextHUD(void) textHUDdraw(M_GetText("\x82""You are blindfolded!")) textHUDdraw(M_GetText("Waiting for players to hide...")) } - else if (gametype == GT_HIDEANDSEEK) + else if (gametyperules & GTR_HIDEFROZEN) textHUDdraw(M_GetText("Hide before time runs out!")) else textHUDdraw(M_GetText("Flee before you are hunted!")) } - else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) + else if ((gametyperules & GTR_HIDEFROZEN) && !(stplyr->pflags & PF_TAGIT)) { if (!splitscreen && !donef12) { From b103a792c055ab1e41f62fd9250dd9e0fb112bde Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 19:23:00 -0300 Subject: [PATCH 077/168] Let spectators decide where they spawn Also fixes some issues with tag gametypes --- src/g_game.c | 49 +++++++++++++++++++++++++++++++++++++------------ src/p_inter.c | 4 ++-- src/p_user.c | 5 +++-- src/st_stuff.c | 2 +- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 47226931a..c8b4757e3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2781,6 +2781,26 @@ mapthing_t *G_FindCoopStart(INT32 playernum) return NULL; } +// Find a Co-op start, or fallback into other types of starts. +static inline mapthing_t *G_FindCoopStartOrFallback(INT32 playernum) +{ + mapthing_t *spawnpoint = NULL; + if (!(spawnpoint = G_FindCoopStart(playernum)) // find a Co-op start + && !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start + spawnpoint = G_FindCTFStart(playernum); // fallback + return spawnpoint; +} + +// Find a Match start, or fallback into other types of starts. +static inline mapthing_t *G_FindMatchStartOrFallback(INT32 playernum) +{ + mapthing_t *spawnpoint = NULL; + if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start + && !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start + spawnpoint = G_FindCoopStart(playernum); // fallback + return spawnpoint; +} + mapthing_t *G_FindMapStart(INT32 playernum) { mapthing_t *spawnpoint; @@ -2788,9 +2808,22 @@ mapthing_t *G_FindMapStart(INT32 playernum) if (!playeringame[playernum]) return NULL; + // -- Spectators -- + // Order in platform gametypes: Coop->DM->CTF + // And, with deathmatch starts: DM->CTF->Coop + if (players[playernum].spectator) + { + // In platform gametypes, spawn in Co-op starts first + // Overriden by GTR_DEATHMATCHSTARTS. + if (G_PlatformGametype() && !(gametyperules & GTR_DEATHMATCHSTARTS)) + spawnpoint = G_FindCoopStartOrFallback(playernum); + else + spawnpoint = G_FindMatchStartOrFallback(playernum); + } + // -- CTF -- // Order: CTF->DM->Coop - if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam) + else if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam) { if (!(spawnpoint = G_FindCTFStart(playernum)) // find a CTF start && !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start @@ -2799,21 +2832,13 @@ mapthing_t *G_FindMapStart(INT32 playernum) // -- DM/Tag/CTF-spectator/etc -- // Order: DM->CTF->Coop - else if ((gametyperules & GTR_DEATHMATCHSTARTS) && !(players[playernum].pflags & PF_TAGIT)) - { - if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start - && !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start - spawnpoint = G_FindCoopStart(playernum); // fallback - } + else if (G_TagGametype() ? (!(players[playernum].pflags & PF_TAGIT)) : (gametyperules & GTR_DEATHMATCHSTARTS)) + spawnpoint = G_FindMatchStartOrFallback(playernum); // -- Other game modes -- // Order: Coop->DM->CTF else - { - if (!(spawnpoint = G_FindCoopStart(playernum)) // find a Co-op start - && !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start - spawnpoint = G_FindCTFStart(playernum); // fallback - } + spawnpoint = G_FindCoopStartOrFallback(playernum); //No spawns found. ANYWHERE. if (!spawnpoint) diff --git a/src/p_inter.c b/src/p_inter.c index 800f07d83..b30921d01 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2603,7 +2603,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget // allow them to try again, rather than sitting the whole thing out. if (leveltime >= hidetime * TICRATE) { - if (gametype == GT_TAG)//suiciding in survivor makes you IT. + if (!(gametyperules & GTR_HIDEFROZEN))//suiciding in survivor makes you IT. { target->player->pflags |= PF_TAGIT; CONS_Printf(M_GetText("%s is now IT!\n"), player_names[target->player-players]); // Tell everyone who is it! @@ -3097,7 +3097,7 @@ static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, IN P_AddPlayerScore(source->player, 100); //award points to tagger. P_HitDeathMessages(player, inflictor, source, 0); - if (gametype == GT_TAG) //survivor + if (!(gametyperules & GTR_HIDEFROZEN)) //survivor { player->pflags |= PF_TAGIT; //in survivor, the player becomes IT and helps hunt down the survivors. CONS_Printf(M_GetText("%s is now IT!\n"), player_names[player-players]); // Tell everyone who is it! diff --git a/src/p_user.c b/src/p_user.c index a481969cf..83f69a4d9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1048,7 +1048,8 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) // Point penalty for hitting a hazard during tag. // Discourages players from intentionally hurting themselves to avoid being tagged. - if (gametype == GT_TAG && (!(player->pflags & PF_GAMETYPEOVER) && !(player->pflags & PF_TAGIT))) + if (((gametyperules & (GTR_TAG|GTR_HIDEFROZEN)) == GTR_TAG) + && (!(player->pflags & PF_GAMETYPEOVER) && !(player->pflags & PF_TAGIT))) { if (player->score >= 50) player->score -= 50; @@ -10681,7 +10682,7 @@ boolean P_SpectatorJoinGame(player_t *player) player->spectator = player->outofcoop = false; player->playerstate = PST_REBORN; - if (gametype == GT_TAG) + if ((gametyperules & (GTR_TAG|GTR_HIDEFROZEN)) == GTR_TAG) { //Make joining players "it" after hidetime. if (leveltime > (hidetime * TICRATE)) diff --git a/src/st_stuff.c b/src/st_stuff.c index 1e792db79..cb5c0fbc1 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2368,7 +2368,7 @@ static void ST_drawTextHUD(void) else textHUDdraw(M_GetText("Flee before you are hunted!")) } - else if ((gametyperules & GTR_HIDEFROZEN) && !(stplyr->pflags & PF_TAGIT)) + else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) { if (!splitscreen && !donef12) { From 952bce362ec9f3db1b22a8b28fa48d7b72b495de Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 22:31:17 -0300 Subject: [PATCH 078/168] Remove unused SOC menu types --- src/dehacked.c | 2 -- src/m_menu.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 4d1147276..e9ee6f58f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9199,8 +9199,6 @@ static const char *const MENUTYPES_LIST[] = { "OP_COLOR", "OP_OPENGL", "OP_OPENGL_LIGHTING", - "OP_OPENGL_FOG", - "OP_OPENGL_COLOR", "OP_SOUND", diff --git a/src/m_menu.h b/src/m_menu.h index 862303426..1985bbac2 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -88,8 +88,6 @@ typedef enum MN_OP_COLOR, MN_OP_OPENGL, MN_OP_OPENGL_LIGHTING, - MN_OP_OPENGL_FOG, - MN_OP_OPENGL_COLOR, MN_OP_SOUND, From 51c593e6334db385850044ea02023e4ff8a656af Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Feb 2020 23:21:27 -0300 Subject: [PATCH 079/168] Fix homing ring using the wrong team gametype rule --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 5d067ebc3..26edff35f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4986,7 +4986,7 @@ void A_ThrownRing(mobj_t *actor) continue; // Don't home in on teammates. - if ((gametyperules & GTR_TEAMFLAGS) + if ((gametyperules & GTR_TEAMS) && actor->target->player->ctfteam == player->ctfteam) continue; } From 3ce4ddf85425f3cca2aaa6934fa172d1c29b1c6f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Feb 2020 23:25:25 -0300 Subject: [PATCH 080/168] Fix incorrect team gametype rule being used in A_OldRingExplode --- src/p_enemy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 26edff35f..ec21eb299 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -6601,7 +6601,7 @@ void A_OldRingExplode(mobj_t *actor) { if (changecolor) { - if (!(gametyperules & GTR_TEAMFLAGS)) + if (!(gametyperules & GTR_TEAMS)) mo->color = actor->target->color; //copy color else if (actor->target->player->ctfteam == 2) mo->color = skincolor_bluering; @@ -6617,7 +6617,7 @@ void A_OldRingExplode(mobj_t *actor) { if (changecolor) { - if (!(gametyperules & GTR_TEAMFLAGS)) + if (!(gametyperules & GTR_TEAMS)) mo->color = actor->target->color; //copy color else if (actor->target->player->ctfteam == 2) mo->color = skincolor_bluering; @@ -6632,7 +6632,7 @@ void A_OldRingExplode(mobj_t *actor) { if (changecolor) { - if (!(gametyperules & GTR_TEAMFLAGS)) + if (!(gametyperules & GTR_TEAMS)) mo->color = actor->target->color; //copy color else if (actor->target->player->ctfteam == 2) mo->color = skincolor_bluering; From fd062308fe2252606ea97ca7df2feb0e4d1ec399 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Feb 2020 23:41:10 -0300 Subject: [PATCH 081/168] Score adding and stealing should check the gametype's rules. --- src/p_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 83f69a4d9..f9dbd5823 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1437,7 +1437,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) } // In team match, all awarded points are incremented to the team's running score. - if (gametype == GT_TEAMMATCH) + if ((gametyperules & (GTR_TEAMS|GTR_TEAMFLAGS)) == GTR_TEAMS) { if (player->ctfteam == 1) redscore += amount; @@ -1471,7 +1471,7 @@ void P_StealPlayerScore(player_t *player, UINT32 amount) if (stolen > 0) { // In team match, all stolen points are removed from the enemy team's running score. - if (gametype == GT_TEAMMATCH) + if ((gametyperules & (GTR_TEAMS|GTR_TEAMFLAGS)) == GTR_TEAMS) { if (player->ctfteam == 1) bluescore -= amount; From d3ed5ad44f2c2d2cd3ffc1de254c2ddac9690bf0 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Feb 2020 23:47:38 -0300 Subject: [PATCH 082/168] Race is Competition without the lives --- src/d_netcmd.c | 4 ++-- src/p_setup.c | 2 +- src/p_spec.c | 4 ++-- src/st_stuff.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a77ea0dd5..60f03f137 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3629,7 +3629,7 @@ static void PointLimit_OnChange(void) static void NumLaps_OnChange(void) { // Just don't be verbose - if (gametype == GT_RACE) + if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) CONS_Printf(M_GetText("Number of laps set to %d\n"), cv_numlaps.value); } @@ -4608,7 +4608,7 @@ static void Command_ShowTime_f(void) static void BaseNumLaps_OnChange(void) { - if (gametype == GT_RACE) + if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) { if (cv_basenumlaps.value) CONS_Printf(M_GetText("Number of laps will be changed to map defaults next round.\n")); diff --git a/src/p_setup.c b/src/p_setup.c index 7b4c6773b..1bb67c9b8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3374,7 +3374,7 @@ static void P_InitGametype(void) if (G_TagGametype()) P_InitTagGametype(); - else if (gametype == GT_RACE && server) + else if (((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) && server) CV_StealthSetValue(&cv_numlaps, (cv_basenumlaps.value) ? cv_basenumlaps.value diff --git a/src/p_spec.c b/src/p_spec.c index d9bbab246..15c88927e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4991,7 +4991,7 @@ DoneSection2: break; case 10: // Finish Line - if (gametype == GT_RACE && !player->exiting) + if (((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) && !player->exiting) { if (player->starpostnum == numstarposts) // Must have touched all the starposts { @@ -6483,7 +6483,7 @@ void P_SpawnSpecials(boolean fromnetsave) switch(GETSECSPECIAL(sector->special, 4)) { case 10: // Circuit finish line - if (gametype == GT_RACE) + if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) circuitmap = true; break; } diff --git a/src/st_stuff.c b/src/st_stuff.c index cb5c0fbc1..6bc5b452c 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2688,7 +2688,7 @@ static void ST_overlayDrawer(void) && (netgame || multiplayer) && (cv_cooplives.value == 0)) ; - else if ((G_GametypeUsesLives() || gametype == GT_RACE) && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) + else if ((G_GametypeUsesLives() || ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE)) && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) { INT32 i = MAXPLAYERS; INT32 deadtimer = stplyr->spectator ? TICRATE : (stplyr->deadtimer-(TICRATE<<1)); From 6fb5a6efb6306492713f9a3a46edbbe94bf961b4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Feb 2020 23:52:33 -0300 Subject: [PATCH 083/168] Consider hide-and-seek as GTR_HIDEFROZEN --- src/g_game.c | 2 +- src/p_map.c | 2 +- src/st_stuff.c | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index c8b4757e3..33edae9bc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2085,7 +2085,7 @@ boolean G_Responder(event_t *ev) && players[displayplayer].ctfteam != players[consoleplayer].ctfteam) continue; } - else if (gametype == GT_HIDEANDSEEK) + else if (gametyperules & GTR_HIDEFROZEN) { if (players[consoleplayer].pflags & PF_TAGIT) continue; diff --git a/src/p_map.c b/src/p_map.c index 966684818..15bd1111e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1613,7 +1613,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } // Force solid players in hide and seek to avoid corner stacking. - if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK) + if (cv_tailspickup.value && !(gametyperules & GTR_HIDEFROZEN)) { if (tmthing->player && thing->player) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 6bc5b452c..49f586976 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2368,15 +2368,14 @@ static void ST_drawTextHUD(void) else textHUDdraw(M_GetText("Flee before you are hunted!")) } - else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) + else if ((gametyperules & GTR_HIDEFROZEN) && !(stplyr->pflags & PF_TAGIT)) { if (!splitscreen && !donef12) { textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view")) donef12 = true; } - if (gametyperules & GTR_HIDEFROZEN) - textHUDdraw(M_GetText("You cannot move while hiding.")) + textHUDdraw(M_GetText("You cannot move while hiding.")) } } From 4e7b47440ff90b6d2fc8a1285400ffa94fbe0d97 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 29 Feb 2020 00:57:22 -0300 Subject: [PATCH 084/168] G_CoopGametype, for all the GT_COOP cases --- src/d_netcmd.c | 2 +- src/g_game.c | 12 +++++++++++- src/g_game.h | 1 + src/hu_stuff.c | 2 +- src/lua_baselib.c | 9 +++++++++ src/p_inter.c | 6 +++--- src/p_mobj.c | 10 +++++----- src/p_spec.c | 8 ++++---- src/p_user.c | 36 ++++++++++++++++++------------------ src/st_stuff.c | 10 +++++----- 10 files changed, 58 insertions(+), 38 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 60f03f137..ed612aaef 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3743,7 +3743,7 @@ static void ExitMove_OnChange(void) { UINT8 i; - if (!(netgame || multiplayer) || gametype != GT_COOP) + if (!(netgame || multiplayer) || !G_CoopGametype()) return; if (cv_exitmove.value) diff --git a/src/g_game.c b/src/g_game.c index 33edae9bc..f0ca101fa 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3131,7 +3131,7 @@ void G_AddPlayer(INT32 playernum) p->height = mobjinfo[MT_PLAYER].height; - if (G_GametypeUsesLives() || ((netgame || multiplayer) && gametype == GT_COOP)) + if (G_GametypeUsesLives() || ((netgame || multiplayer) && (gametyperules & GTR_FRIENDLY))) p->lives = cv_startinglives.value; if ((countplayers && !notexiting) || G_IsSpecialStage(gamemap)) @@ -3591,6 +3591,16 @@ boolean G_PlatformGametype(void) return (!(gametyperules & GTR_RINGSLINGER)); } +// +// G_CoopGametype +// +// Returns true if a gametype is a Co-op gametype. +// +boolean G_CoopGametype(void) +{ + return ((gametyperules & (GTR_FRIENDLY|GTR_CAMPAIGN)) == (GTR_FRIENDLY|GTR_CAMPAIGN)); +} + // // G_TagGametype // diff --git a/src/g_game.h b/src/g_game.h index c4c40d84b..bb68ddb20 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -253,6 +253,7 @@ boolean G_GametypeHasTeams(void); boolean G_GametypeHasSpectators(void); boolean G_RingSlingerGametype(void); boolean G_PlatformGametype(void); +boolean G_CoopGametype(void); boolean G_TagGametype(void); boolean G_CompetitionGametype(void); boolean G_EnoughPlayersFinished(void); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 74b68ce69..b31f023d6 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2175,7 +2175,7 @@ void HU_Drawer(void) if (LUA_HudEnabled(hud_rankings)) #endif HU_DrawRankings(); - if (gametype == GT_COOP) + if (gametyperules & GTR_CAMPAIGN) HU_DrawNetplayCoopOverlay(); } else diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 03f142446..b42586834 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2937,6 +2937,14 @@ static int lib_gPlatformGametype(lua_State *L) return 1; } +static int lib_gCoopGametype(lua_State *L) +{ + //HUDSAFE + INLEVEL + lua_pushboolean(L, G_CoopGametype()); + return 1; +} + static int lib_gTagGametype(lua_State *L) { //HUDSAFE @@ -3209,6 +3217,7 @@ static luaL_Reg lib[] = { {"G_GametypeHasSpectators",lib_gGametypeHasSpectators}, {"G_RingSlingerGametype",lib_gRingSlingerGametype}, {"G_PlatformGametype",lib_gPlatformGametype}, + {"G_CoopGametype",lib_gCoopGametype}, {"G_TagGametype",lib_gTagGametype}, {"G_CompetitionGametype",lib_gCompetitionGametype}, {"G_TicsToHours",lib_gTicsToHours}, diff --git a/src/p_inter.c b/src/p_inter.c index b30921d01..851229f9a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2525,7 +2525,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } P_RestoreMusic(target->player); - if (gametype != GT_COOP) + if (!G_CoopGametype()) { HU_SetCEchoFlags(0); HU_SetCEchoDuration(5); @@ -3257,7 +3257,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) } // If the player was super, tell them he/she ain't so super nomore. - if (gametype != GT_COOP && player->powers[pw_super]) + if (!G_CoopGametype() && player->powers[pw_super]) { S_StartSound(NULL, sfx_s3k66); //let all players hear it. HU_SetCEchoFlags(0); @@ -3627,7 +3627,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source == target) return false; // Don't hit yourself with your own paraloop, baka if (source && source->player && !(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) - && (gametype == GT_COOP + && ((gametyperules & GTR_FRIENDLY) || (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam))) return false; // Don't run eachother over in special stages and team games and such } diff --git a/src/p_mobj.c b/src/p_mobj.c index 2bb2cc028..ab9793229 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11440,7 +11440,7 @@ void P_SpawnPlayer(INT32 playernum) if (!G_GametypeHasSpectators()) { p->spectator = p->outofcoop = - (((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop + (((multiplayer || netgame) && G_CoopGametype()) // only question status in coop && ((leveltime > 0 && ((G_IsSpecialStage(gamemap)) // late join special stage || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop @@ -11594,7 +11594,7 @@ void P_AfterPlayerSpawn(INT32 playernum) if (CheckForReverseGravity) P_CheckGravity(mobj, false); - + if (p->pflags & PF_FINISHED) P_GiveFinishFlags(p); } @@ -11918,7 +11918,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) case MT_EMERALD5: case MT_EMERALD6: case MT_EMERALD7: - if (gametype != GT_COOP) // Don't place emeralds in non-coop modes + if (!G_CoopGametype()) // Don't place emeralds in non-coop modes return false; if (metalrecording) @@ -11938,7 +11938,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) runemeraldmanager = true; break; case MT_ROSY: - if (!(gametype == GT_COOP || (mthing->options & MTF_EXTRA))) + if (!(G_CoopGametype() || (mthing->options & MTF_EXTRA))) return false; // she doesn't hang out here if (!mariomode && !(netgame || multiplayer) && players[consoleplayer].skin == 3) @@ -12053,7 +12053,7 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) } } // Set powerup boxes to user settings for other netplay modes - else if (gametype != GT_COOP) + else if (!G_CoopGametype()) { switch (cv_matchboxes.value) { diff --git a/src/p_spec.c b/src/p_spec.c index 15c88927e..f4057fba5 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4100,7 +4100,7 @@ void P_SetupSignExit(player_t *player) if (!numfound && !(player->mo->target && player->mo->target->type == MT_SIGN) - && !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value)) + && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value)) P_SetTarget(&player->mo->target, thing); if (thing->state != &states[thing->info->spawnstate]) @@ -4131,7 +4131,7 @@ void P_SetupSignExit(player_t *player) if (!numfound && !(player->mo->target && player->mo->target->type == MT_SIGN) - && !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value)) + && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value)) P_SetTarget(&player->mo->target, thing); if (thing->state != &states[thing->info->spawnstate]) @@ -4486,7 +4486,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers continue; if (players[i].bot) continue; - if (gametype == GT_COOP && players[i].lives <= 0) + if (G_CoopGametype() && players[i].lives <= 0) continue; if (roversector) { @@ -4717,7 +4717,7 @@ DoneSection2: // FOF custom exits not to work. lineindex = P_FindSpecialLineFromTag(2, sector->tag, -1); - if (gametype == GT_COOP && lineindex != -1) // Custom exit! + if (G_CoopGametype() && lineindex != -1) // Custom exit! { // Special goodies with the block monsters flag depending on emeralds collected if ((lines[lineindex].flags & ML_BLOCKMONSTERS) && ALL7EMERALDS(emeralds)) diff --git a/src/p_user.c b/src/p_user.c index f9dbd5823..33329a929 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1351,7 +1351,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) player->powers[pw_sneakers] = 0; } - if (gametype != GT_COOP) + if (!G_CoopGametype()) { HU_SetCEchoFlags(0); HU_SetCEchoDuration(5); @@ -1418,7 +1418,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) } } - if (gametype == GT_COOP) + if (G_CoopGametype()) return; } @@ -4305,7 +4305,7 @@ static void P_DoSuperStuff(player_t *player) G_GhostAddColor(GHC_NORMAL); } - if (gametype != GT_COOP) + if (!G_CoopGametype()) { HU_SetCEchoFlags(0); HU_SetCEchoDuration(5); @@ -4355,14 +4355,14 @@ static void P_DoSuperStuff(player_t *player) G_GhostAddColor(GHC_NORMAL); } - if (gametype != GT_COOP) + if (!G_CoopGametype()) player->powers[pw_flashing] = flashingtics-1; if (player->mo->sprite2 & FF_SPR2SUPER) P_SetPlayerMobjState(player->mo, player->mo->state-states); // Inform the netgame that the champion has fallen in the heat of battle. - if (gametype != GT_COOP) + if (!G_CoopGametype()) { S_StartSound(NULL, sfx_s3k66); //let all players hear it. HU_SetCEchoFlags(0); @@ -9639,7 +9639,7 @@ static void P_DeathThink(player_t *player) } if ((cv_cooplives.value != 1) - && (gametype == GT_COOP) + && (G_GametypeUsesCoopLives()) && (netgame || multiplayer) && (player->lives <= 0)) { @@ -9721,17 +9721,17 @@ static void P_DeathThink(player_t *player) countdown2 = 1*TICRATE; } } - //else if (gametype == GT_COOP) -- moved to G_DoReborn + //else if (G_CoopGametype()) -- moved to G_DoReborn } - if (gametype == GT_COOP && (multiplayer || netgame) && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) + if (G_CoopGametype() && (multiplayer || netgame) && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) { //player->spectator = true; player->outofcoop = true; player->playerstate = PST_REBORN; } - if ((gametyperules & GTR_RACE) || (gametype == GT_COOP && (multiplayer || netgame))) + if ((gametyperules & GTR_RACE) || (G_CoopGametype() && (multiplayer || netgame))) { // Keep time rolling in race mode if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_GAMETYPEOVER) && !stoppedclock) @@ -9748,7 +9748,7 @@ static void P_DeathThink(player_t *player) } // Return to level music - if (gametype != GT_COOP && player->lives <= 0 && player->deadtimer == gameovertics) + if (!G_CoopGametype() && player->lives <= 0 && player->deadtimer == gameovertics) P_RestoreMultiMusic(player); } @@ -9925,7 +9925,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player->exiting) { if (mo->target && mo->target->type == MT_SIGN && mo->target->spawnpoint - && !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value) + && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value) && !(twodlevel || (mo->flags2 & MF2_TWOD))) sign = mo->target; else if ((player->powers[pw_carry] == CR_NIGHTSMODE) @@ -10594,7 +10594,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall boolean P_SpectatorJoinGame(player_t *player) { - if (gametype != GT_COOP && !cv_allowteamchange.value) + if (!G_CoopGametype() && !cv_allowteamchange.value) { if (P_IsLocalPlayer(player)) CONS_Printf(M_GetText("Server does not allow team change.\n")); @@ -10705,7 +10705,7 @@ boolean P_SpectatorJoinGame(player_t *player) displayplayer = consoleplayer; } - if (gametype != GT_COOP) + if (!G_CoopGametype()) CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); return true; // no more player->mo, cannot continue. } @@ -11753,7 +11753,7 @@ void P_PlayerThink(player_t *player) // so we can fade music if (!exitfadestarted && player->exiting > 0 && player->exiting <= 1*TICRATE && - (!multiplayer || gametype == GT_COOP ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) && + (!multiplayer || G_CoopGametype() ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) && // don't fade if we're fading during intermission. follows Y_StartIntermission intertype = int_coop ((gametyperules & GTR_RACE) ? countdown2 == 0 : true) && // don't fade on timeout player->lives > 0 && // don't fade on game over (competition) @@ -11826,7 +11826,7 @@ void P_PlayerThink(player_t *player) if (player->pflags & PF_FINISHED) { - if ((gametype == GT_COOP && cv_exitmove.value) && !G_EnoughPlayersFinished()) + if ((G_CoopGametype() && cv_exitmove.value) && !G_EnoughPlayersFinished()) player->exiting = 0; else P_DoPlayerExit(player); @@ -11864,10 +11864,10 @@ void P_PlayerThink(player_t *player) // Make sure spectators always have a score and ring count of 0. if (player->spectator) { - if (gametype != GT_COOP) + if (!(gametyperules & GTR_CAMPAIGN)) player->score = 0; } - else if ((netgame || multiplayer) && player->lives <= 0 && gametype != GT_COOP) + else if ((netgame || multiplayer) && player->lives <= 0 && !G_CoopGametype()) { // Outside of Co-Op, replenish a user's lives if they are depleted. // of course, this is just a cheap hack, meh... @@ -12732,7 +12732,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->momz = tails->momz; } - if (gametype == GT_COOP && (!tails->player || tails->player->bot != 1)) + if (G_CoopGametype() && (!tails->player || tails->player->bot != 1)) { player->mo->angle = tails->angle; diff --git a/src/st_stuff.c b/src/st_stuff.c index 49f586976..89ce1d6d7 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2239,7 +2239,7 @@ static void ST_drawTextHUD(void) if (F_GetPromptHideHud(y)) return; - if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE)) + if (stplyr->spectator && (!G_CoopGametype() || stplyr->playerstate == PST_LIVE)) textHUDdraw(M_GetText("\x86""Spectator mode:")) if (circuitmap) @@ -2250,7 +2250,7 @@ static void ST_drawTextHUD(void) textHUDdraw(va("Lap:""\x82 %u/%d", stplyr->laps+1, cv_numlaps.value)) } - if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) + if (!G_CoopGametype() && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) { if (!splitscreen && !donef12) { @@ -2267,7 +2267,7 @@ static void ST_drawTextHUD(void) else textHUDdraw(M_GetText("\x82""JUMP:""\x80 Respawn")) } - else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE)) + else if (stplyr->spectator && (!G_CoopGametype() || stplyr->playerstate == PST_LIVE)) { if (!splitscreen && !donef12) { @@ -2314,7 +2314,7 @@ static void ST_drawTextHUD(void) textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game")) } - if (gametype == GT_COOP && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && (stplyr->exiting || (stplyr->pflags & PF_FINISHED))) + if (G_CoopGametype() && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && (stplyr->exiting || (stplyr->pflags & PF_FINISHED))) { UINT8 numneeded = (G_IsSpecialStage(gamemap) ? 4 : cv_playersforexit.value); if (numneeded) @@ -2683,7 +2683,7 @@ static void ST_overlayDrawer(void) } // GAME OVER hud - if ((gametype == GT_COOP) + if (G_GametypeUsesCoopLives() && (netgame || multiplayer) && (cv_cooplives.value == 0)) ; From 7d77600e71f31ec41564c94a5b47c6b5246e9072 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 29 Feb 2020 01:51:45 -0300 Subject: [PATCH 085/168] Make exitmove friendly, don't start empty intermission screens --- src/d_netcmd.c | 2 +- src/g_game.c | 7 ++++-- src/p_spec.c | 4 ++-- src/p_user.c | 4 ++-- src/y_inter.c | 63 +++++++++++++++++++++++++------------------------- src/y_inter.h | 4 ++++ 6 files changed, 45 insertions(+), 39 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ed612aaef..196d67a60 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3743,7 +3743,7 @@ static void ExitMove_OnChange(void) { UINT8 i; - if (!(netgame || multiplayer) || !G_CoopGametype()) + if (!(netgame || multiplayer) || !(gametyperules & GTR_FRIENDLY)) return; if (cv_exitmove.value) diff --git a/src/g_game.c b/src/g_game.c index f0ca101fa..5c7b5fbcb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3180,7 +3180,7 @@ void G_ExitLevel(void) CV_SetValue(&cv_teamscramble, cv_scrambleonchange.value); } - if (!(gametyperules & GTR_CAMPAIGN)) + if (!(gametyperules & (GTR_FRIENDLY|GTR_CAMPAIGN))) CONS_Printf(M_GetText("The round has ended.\n")); // Remove CEcho text on round end. @@ -3840,7 +3840,10 @@ static void G_DoCompleted(void) if (nextmap < NUMMAPS && !mapheaderinfo[nextmap]) P_AllocMapHeader(nextmap); - if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed)) + // If the current gametype has no intermission screen set, then don't start it. + Y_DetermineIntermissionType(); + + if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed) || (intertype == int_none)) { G_UpdateVisited(); G_AfterIntermission(); diff --git a/src/p_spec.c b/src/p_spec.c index f4057fba5..30379fcb7 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4100,7 +4100,7 @@ void P_SetupSignExit(player_t *player) if (!numfound && !(player->mo->target && player->mo->target->type == MT_SIGN) - && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value)) + && !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value)) P_SetTarget(&player->mo->target, thing); if (thing->state != &states[thing->info->spawnstate]) @@ -4131,7 +4131,7 @@ void P_SetupSignExit(player_t *player) if (!numfound && !(player->mo->target && player->mo->target->type == MT_SIGN) - && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value)) + && !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value)) P_SetTarget(&player->mo->target, thing); if (thing->state != &states[thing->info->spawnstate]) diff --git a/src/p_user.c b/src/p_user.c index 33329a929..d90300e01 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9925,7 +9925,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player->exiting) { if (mo->target && mo->target->type == MT_SIGN && mo->target->spawnpoint - && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value) + && !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value) && !(twodlevel || (mo->flags2 & MF2_TWOD))) sign = mo->target; else if ((player->powers[pw_carry] == CR_NIGHTSMODE) @@ -11826,7 +11826,7 @@ void P_PlayerThink(player_t *player) if (player->pflags & PF_FINISHED) { - if ((G_CoopGametype() && cv_exitmove.value) && !G_EnoughPlayersFinished()) + if (((gametyperules & GTR_FRIENDLY) && cv_exitmove.value) && !G_EnoughPlayersFinished()) player->exiting = 0; else P_DoPlayerExit(player); diff --git a/src/y_inter.c b/src/y_inter.c index 36cb64d06..701739ad1 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -229,8 +229,7 @@ static void Y_IntermissionTokenDrawer(void) // // Y_ConsiderScreenBuffer // -// Can we copy the current screen -// to a buffer? +// Can we copy the current screen to a buffer? // void Y_ConsiderScreenBuffer(void) { @@ -256,9 +255,7 @@ void Y_ConsiderScreenBuffer(void) // // Y_RescaleScreenBuffer // -// Write the rescaled source picture, -// to the destination picture that -// has the current screen's resolutions. +// Write the rescaled source picture, to the destination picture that has the current screen's resolutions. // static void Y_RescaleScreenBuffer(void) { @@ -328,14 +325,6 @@ void Y_IntermissionDrawer(void) if (rendermode == render_none) return; - if (intertype == int_none) - { -#ifdef HAVE_BLUA - LUAh_IntermissionHUD(); -#endif - return; - } - if (!usebuffer) // Lactozilla: Renderer switching if (needpatchrecache) @@ -1196,6 +1185,34 @@ void Y_Ticker(void) } } +// +// Y_DetermineIntermissionType +// +// Determines the intermission type from the current gametype. +// +void Y_DetermineIntermissionType(void) +{ + // set to int_none initially + intertype = int_none; + + if (intermissiontypes[gametype] != int_none) + intertype = intermissiontypes[gametype]; + else if (gametype == GT_COOP) + intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop; + else if (gametype == GT_TEAMMATCH) + intertype = int_teammatch; + else if (gametype == GT_MATCH + || gametype == GT_TAG + || gametype == GT_HIDEANDSEEK) + intertype = int_match; + else if (gametype == GT_RACE) + intertype = int_race; + else if (gametype == GT_COMPETITION) + intertype = int_comp; + else if (gametype == GT_CTF) + intertype = int_ctf; +} + // // Y_StartIntermission // @@ -1217,12 +1234,11 @@ void Y_StartIntermission(void) if (!multiplayer) { timer = 0; - intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop; } else { - if (cv_inttime.value == 0 && gametype == GT_COOP) + if (cv_inttime.value == 0 && ((intertype == int_coop) || (intertype == int_spec))) timer = 0; else { @@ -1231,23 +1247,6 @@ void Y_StartIntermission(void) if (!timer) timer = 1; } - - if (intermissiontypes[gametype] != int_none) - intertype = intermissiontypes[gametype]; - else if (gametype == GT_COOP) - intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop; - else if (gametype == GT_TEAMMATCH) - intertype = int_teammatch; - else if (gametype == GT_MATCH - || gametype == GT_TAG - || gametype == GT_HIDEANDSEEK) - intertype = int_match; - else if (gametype == GT_RACE) - intertype = int_race; - else if (gametype == GT_COMPETITION) - intertype = int_comp; - else if (gametype == GT_CTF) - intertype = int_ctf; } // We couldn't display the intermission even if we wanted to. diff --git a/src/y_inter.h b/src/y_inter.h index 855844fcc..859144b1d 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -13,11 +13,15 @@ extern boolean usebuffer; void Y_IntermissionDrawer(void); void Y_Ticker(void); + void Y_StartIntermission(void); void Y_EndIntermission(void); + void Y_ConsiderScreenBuffer(void); void Y_CleanupScreenBuffer(void); +void Y_DetermineIntermissionType(void); + typedef enum { int_none, From bb08b55b43ed1bcca313e5d294c355d9d8628c3f Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 12 Mar 2020 12:22:04 -0500 Subject: [PATCH 086/168] Created GameQuit hook, but I need to decide where to execute it --- src/lua_hook.h | 2 ++ src/lua_hooklib.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/lua_hook.h b/src/lua_hook.h index 265700e4f..380e45991 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -58,6 +58,7 @@ enum hook { hook_ViewpointSwitch, hook_SeenPlayer, hook_PlayerThink, + hook_GameQuit, hook_MAX // last hook }; @@ -110,5 +111,6 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean 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 +void LUAh_GameQuit(void); // Hook for game quitting #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index c29edbd61..dc66b39e8 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -69,6 +69,7 @@ const char *const hookNames[hook_MAX+1] = { "ViewpointSwitch", "SeenPlayer", "PlayerThink", + "GameQuit", NULL }; @@ -1660,4 +1661,27 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) } #endif // SEENAMES +// Hook for game quitting +void LUAh_GameQuit(void) +{ + hook_p hookp; + if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8)))) + return; + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_GameQuit) + continue; + + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + } + } +} + #endif From 4d7f64a53d7837b4e15fa0d983e3802684bf45cf Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 12 Mar 2020 12:45:41 -0500 Subject: [PATCH 087/168] Let's call LUAh_GameQuit in D_QuitNetGame since that function is still called outside of netgames However, the D_QuitNetGame function returns early if you are not in a netgame. --- src/d_clisrv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index ae9b91ec5..0cdf3fb73 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3188,6 +3188,10 @@ static inline void SV_GenContext(void) // void D_QuitNetGame(void) { +#ifdef HAVE_BLUA + LUAh_GameQuit(); +#endif + if (!netgame || !netbuffer) return; From 4d144f2e400987173fd36e1e7f9babdf573d78f9 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 12 Mar 2020 19:59:50 -0500 Subject: [PATCH 088/168] No longer call LUAh_GameQuit in D_QuitNetGame --- src/d_clisrv.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 0cdf3fb73..ae9b91ec5 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3188,10 +3188,6 @@ static inline void SV_GenContext(void) // void D_QuitNetGame(void) { -#ifdef HAVE_BLUA - LUAh_GameQuit(); -#endif - if (!netgame || !netbuffer) return; From 2b16971137ed0d29055708181e83415c0e94f91f Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 12 Mar 2020 20:15:21 -0500 Subject: [PATCH 089/168] Call LUAh_GameQuit in Command_ExitGame_f --- src/d_netcmd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c6ea974ae..eca80907a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4235,6 +4235,10 @@ void Command_ExitGame_f(void) { INT32 i; +#ifdef HAVE_BLUA + LUAh_GameQuit(); +#endif + D_QuitNetGame(); CL_Reset(); CV_ClearChangedFlags(); From bef49f56605e61fb7f3fc0092577b6804d179131 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 12 Mar 2020 20:51:16 -0500 Subject: [PATCH 090/168] Don't execute LUAh_GameQuit in Command_ExitGame_f if you are in a multiplayer game --- src/d_netcmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index eca80907a..8d21d62a2 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4236,7 +4236,8 @@ void Command_ExitGame_f(void) INT32 i; #ifdef HAVE_BLUA - LUAh_GameQuit(); + if (!multiplayer) + LUAh_GameQuit(); #endif D_QuitNetGame(); From 7ec241c59e71e0a219766b2252fe54a30990e83f Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 12 Mar 2020 22:31:39 -0500 Subject: [PATCH 091/168] Revert "Don't execute LUAh_GameQuit in Command_ExitGame_f if you are in a multiplayer game" This reverts commit bef49f56605e61fb7f3fc0092577b6804d179131. --- src/d_netcmd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 8d21d62a2..eca80907a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4236,8 +4236,7 @@ void Command_ExitGame_f(void) INT32 i; #ifdef HAVE_BLUA - if (!multiplayer) - LUAh_GameQuit(); + LUAh_GameQuit(); #endif D_QuitNetGame(); From f97187f59b60b7768fae167fc1bb09fd5394a94e Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 12 Mar 2020 22:31:48 -0500 Subject: [PATCH 092/168] Revert "Call LUAh_GameQuit in Command_ExitGame_f" This reverts commit 2b16971137ed0d29055708181e83415c0e94f91f. --- src/d_netcmd.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index eca80907a..c6ea974ae 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4235,10 +4235,6 @@ void Command_ExitGame_f(void) { INT32 i; -#ifdef HAVE_BLUA - LUAh_GameQuit(); -#endif - D_QuitNetGame(); CL_Reset(); CV_ClearChangedFlags(); From e3b17cd82bf2db4e18d6fa4af1dc8e83ee65417c Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 14 Mar 2020 15:52:25 -0500 Subject: [PATCH 093/168] Use po2 patches to fix mipmaps --- src/hardware/hw_cache.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 66f4e3c28..5dc02e00b 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -298,13 +298,13 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, if (pwidth <= 0 || pheight <= 0) return; - ncols = (pwidth * pblockwidth) / pwidth; + ncols = pwidth; // source advance xfrac = 0; - xfracstep = (pwidth << FRACBITS) / pblockwidth; - yfracstep = (pheight << FRACBITS) / pblockheight; - scale_y = (pblockheight << FRACBITS) / pheight; + xfracstep = FRACUNIT; + yfracstep = FRACUNIT; + scale_y = FRACUNIT; bpp = format2bpp[mipmap->grInfo.format]; @@ -573,13 +573,18 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm grPatch->leftoffset = SHORT(patch->leftoffset); grPatch->topoffset = SHORT(patch->topoffset); - grMipmap->width = (UINT16)SHORT(patch->width); - grMipmap->height = (UINT16)SHORT(patch->height); + grMipmap->width = grMipmap->height = 1; + while (grMipmap->width < grPatch->width) grMipmap->width <<= 1; + while (grMipmap->height < grPatch->height) grMipmap->height <<= 1; // no wrap around, no chroma key grMipmap->flags = 0; // setup the texture info grMipmap->grInfo.format = patchformat; + + //grPatch->max_s = grPatch->max_t = 1.0f; + grPatch->max_s = (float)grPatch->width / (float)grMipmap->width; + grPatch->max_t = (float)grPatch->height / (float)grMipmap->height; } Z_Free(grMipmap->grInfo.data); @@ -590,12 +595,10 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm MakeBlock(grMipmap); HWR_DrawPatchInCache(grMipmap, - grPatch->width, grPatch->height, + grMipmap->width, grMipmap->height, grPatch->width, grPatch->height, patch); } - - grPatch->max_s = grPatch->max_t = 1.0f; } From a329ca43bad7341a28ceaa25c038406cdb87ac35 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sun, 15 Mar 2020 00:53:05 -0400 Subject: [PATCH 094/168] Call ``LUAh_GameQuit`` in 2 places. --- src/sdl/i_system.c | 4 ++++ src/sdl/i_video.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a86af316e..ca135a96b 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -171,6 +171,7 @@ static char returnWadPath[256]; #include "../d_net.h" #include "../g_game.h" #include "../filesrch.h" +#include "../lua_hook.h" #include "endtxt.h" #include "sdlmain.h" @@ -303,6 +304,9 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) FUNCNORETURN static ATTRNORETURN void quit_handler(int num) { +#ifdef HAVE_BLUA + LUAh_GameQuit(); +#endif signal(num, SIG_DFL); //default signal action raise(num); I_Quit(); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c2f492000..78c5e8170 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -73,6 +73,7 @@ #include "../console.h" #include "../command.h" #include "../r_main.h" +#include "../lua_hook.h" #include "sdlmain.h" #ifdef HWRENDER #include "../hardware/hw_main.h" @@ -1059,6 +1060,9 @@ void I_GetEvent(void) M_SetupJoystickMenu(0); break; case SDL_QUIT: +#ifdef HAVE_BLUA + LUAh_GameQuit(); +#endif I_Quit(); M_QuitResponse('y'); break; From b067d1e134d3f165c2ff9fb4c425ade1b2a2b50d Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sun, 15 Mar 2020 00:08:57 -0500 Subject: [PATCH 095/168] Revert "Call ``LUAh_GameQuit`` in 2 places." This reverts commit a329ca43bad7341a28ceaa25c038406cdb87ac35. --- src/sdl/i_system.c | 4 ---- src/sdl/i_video.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index ca135a96b..a86af316e 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -171,7 +171,6 @@ static char returnWadPath[256]; #include "../d_net.h" #include "../g_game.h" #include "../filesrch.h" -#include "../lua_hook.h" #include "endtxt.h" #include "sdlmain.h" @@ -304,9 +303,6 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) FUNCNORETURN static ATTRNORETURN void quit_handler(int num) { -#ifdef HAVE_BLUA - LUAh_GameQuit(); -#endif signal(num, SIG_DFL); //default signal action raise(num); I_Quit(); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 78c5e8170..c2f492000 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -73,7 +73,6 @@ #include "../console.h" #include "../command.h" #include "../r_main.h" -#include "../lua_hook.h" #include "sdlmain.h" #ifdef HWRENDER #include "../hardware/hw_main.h" @@ -1060,9 +1059,6 @@ void I_GetEvent(void) M_SetupJoystickMenu(0); break; case SDL_QUIT: -#ifdef HAVE_BLUA - LUAh_GameQuit(); -#endif I_Quit(); M_QuitResponse('y'); break; From 0e56202d638fe0d2b71f78a1056ea7efd21f0e1d Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sun, 15 Mar 2020 00:28:41 -0500 Subject: [PATCH 096/168] Let's just call LUAh_GameQuit in Command_ExitGame_f during its execution if you are in game and are not a dedicated server --- src/d_netcmd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c6ea974ae..582e4d0a3 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4235,6 +4235,11 @@ void Command_ExitGame_f(void) { INT32 i; +#ifdef HAVE_BLUA + if ((maptol) && (!dedicated)) + LUAh_GameQuit(); +#endif + D_QuitNetGame(); CL_Reset(); CV_ClearChangedFlags(); From 7c65577336884b69bb0a9dd509e55d7926292a1d Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sun, 15 Mar 2020 00:39:46 -0500 Subject: [PATCH 097/168] Let's just call LUAh_GameQuit in I_Quit anyways --- src/sdl/i_system.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a86af316e..ed8a55039 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -190,6 +190,8 @@ static char returnWadPath[256]; #include "../byteptr.h" #endif +#include "../lua_hook.h" + /** \brief The JoyReset function \param JoySet Joystick info to reset @@ -2279,6 +2281,9 @@ void I_Quit(void) if (quiting) goto death; SDLforceUngrabMouse(); quiting = SDL_FALSE; +#ifdef HAVE_BLUA + LUAh_GameQuit(); +#endif M_SaveConfig(NULL); //save game config, cvars.. #ifndef NONET D_SaveBan(); // save the ban list From 766ca2f5a54a82864dcdf642f5c905fa5329c756 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sun, 15 Mar 2020 00:54:06 -0500 Subject: [PATCH 098/168] Since exitgame shuts down the server if you are running a dedicated server I may as well allow the hook to run for the dedicated server as well --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 582e4d0a3..498aebad2 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4236,7 +4236,7 @@ void Command_ExitGame_f(void) INT32 i; #ifdef HAVE_BLUA - if ((maptol) && (!dedicated)) + if (maptol) LUAh_GameQuit(); #endif From 8b7f93d50aa1d36c53ce72f87bd4bbb3668ea3a7 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sun, 15 Mar 2020 10:33:24 -0500 Subject: [PATCH 099/168] Revert "Let's just call LUAh_GameQuit in I_Quit anyways" This reverts commit 7c65577336884b69bb0a9dd509e55d7926292a1d. --- src/sdl/i_system.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index ed8a55039..a86af316e 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -190,8 +190,6 @@ static char returnWadPath[256]; #include "../byteptr.h" #endif -#include "../lua_hook.h" - /** \brief The JoyReset function \param JoySet Joystick info to reset @@ -2281,9 +2279,6 @@ void I_Quit(void) if (quiting) goto death; SDLforceUngrabMouse(); quiting = SDL_FALSE; -#ifdef HAVE_BLUA - LUAh_GameQuit(); -#endif M_SaveConfig(NULL); //save game config, cvars.. #ifndef NONET D_SaveBan(); // save the ban list From 2052ee1144e4ed39c668104ae70e0a5ba102890a Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sun, 15 Mar 2020 10:34:43 -0500 Subject: [PATCH 100/168] Check if you are playing a game then execute ``LUAh_GameQuit`` if you are in Command_quit_f and Command_ExitGame_f --- src/d_netcmd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 498aebad2..b80214d8a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3574,6 +3574,10 @@ static void Command_Playintro_f(void) */ FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void) { +#ifdef HAVE_BLUA + if (Playing()) + LUAh_GameQuit(); +#endif I_Quit(); } @@ -4236,7 +4240,7 @@ void Command_ExitGame_f(void) INT32 i; #ifdef HAVE_BLUA - if (maptol) + if (Playing()) LUAh_GameQuit(); #endif From 569034d3a9be35b09fbc4c71c80b3917d4d4aba8 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sun, 15 Mar 2020 10:47:55 -0500 Subject: [PATCH 101/168] Call LUAh_GameQuit in I_GetEvent in if the event is SDL_Quit and if you are in a playing session Time for the ultimate testing to see if I get any undefined reference compiling errors --- src/sdl/i_video.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c2f492000..21fd29bb5 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -73,6 +73,7 @@ #include "../console.h" #include "../command.h" #include "../r_main.h" +#include "../lua_hook.h" #include "sdlmain.h" #ifdef HWRENDER #include "../hardware/hw_main.h" @@ -1059,6 +1060,10 @@ void I_GetEvent(void) M_SetupJoystickMenu(0); break; case SDL_QUIT: +#ifdef HAVE_BLUA + if (Playing()) + LUAh_GameQuit(); +#endif I_Quit(); M_QuitResponse('y'); break; From decce7905bc318e96daf966b174afe4f0fd0a7f4 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Tue, 24 Mar 2020 22:55:25 -0500 Subject: [PATCH 102/168] Moved LUAh_GameQuit(void) function to the end of the lua_hooklib.c --- src/lua_hooklib.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index f4860f85a..88f1b291d 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1663,29 +1663,6 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) } #endif // SEENAMES -// Hook for game quitting -void LUAh_GameQuit(void) -{ - hook_p hookp; - if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8)))) - return; - - for (hookp = roothook; hookp; hookp = hookp->next) - { - if (hookp->type != hook_GameQuit) - continue; - - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); - if (lua_pcall(gL, 0, 0, 0)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - } - } -} - boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) { hook_p hookp; @@ -1727,4 +1704,27 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) hud_running = false; return keepplaying; +} + +// Hook for game quitting +void LUAh_GameQuit(void) +{ + hook_p hookp; + if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8)))) + return; + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_GameQuit) + continue; + + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + } + } } \ No newline at end of file From 28de6b1f93d853f87b4e5d5f7a97d57923f116ff Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Fri, 3 Apr 2020 17:44:57 -0500 Subject: [PATCH 103/168] Execute LUAh_GameQuit in 2 additional places in m_menu.c --- src/m_menu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index f8240d403..0303b0de0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -44,6 +44,7 @@ #include "p_local.h" #include "p_setup.h" #include "f_finale.h" +#include "lua_hook.h" #ifdef HWRENDER #include "hardware/hw_main.h" @@ -6864,6 +6865,8 @@ static void M_SelectableClearMenus(INT32 choice) static void M_UltimateCheat(INT32 choice) { (void)choice; + if (Playing()) + LUAh_GameQuit(); I_Quit(); } @@ -12535,6 +12538,8 @@ void M_QuitResponse(INT32 ch) I_Sleep(); } } + if (Playing()) + LUAh_GameQuit(); I_Quit(); } From f6120410fb24b1ae17d6173f012c6a8e4b6fbbb9 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 23 Apr 2020 17:38:08 -0500 Subject: [PATCH 104/168] Execute LUAh_GameQuit earlier in M_QuitResponse It just feels a bit funny to execute LUAh_GameQuit if you are playing a session after the quit screen appears instead of before. --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 6ff13a19c..e4d2c9039 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -12535,6 +12535,8 @@ void M_QuitResponse(INT32 ch) if (ch != 'y' && ch != KEY_ENTER) return; + if (Playing()) + LUAh_GameQuit(); if (!(netgame || cv_debug)) { S_ResetCaptions(); @@ -12551,8 +12553,6 @@ void M_QuitResponse(INT32 ch) I_Sleep(); } } - if (Playing()) - LUAh_GameQuit(); I_Quit(); } From 0758a8caec0524e0f297885474a6b2c73a51084b Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sun, 19 Apr 2020 01:35:38 +0300 Subject: [PATCH 105/168] Optimization: Don't reset shader program at end of DrawPolygon, instead reset it in UnSetShader --- src/hardware/r_opengl/r_opengl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 63e86c7fb..27f82cc82 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1073,6 +1073,7 @@ EXPORT void HWRAPI(UnSetShader) (void) #ifdef GL_SHADERS gl_shadersenabled = false; gl_currentshaderprogram = 0; + pglUseProgram(0); #endif } @@ -2054,10 +2055,6 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI if (PolyFlags & PF_ForceWrapY) Clamp2D(GL_TEXTURE_WRAP_T); - -#ifdef GL_SHADERS - pglUseProgram(0); -#endif } typedef struct vbo_vertex_s From c0c095e1d1e4873968bcbe260992549e27b92ec6 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sun, 19 Apr 2020 01:54:46 +0300 Subject: [PATCH 106/168] Optimization: only call pglUseProgram if shader actually needs changing --- src/hardware/r_opengl/r_opengl.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 27f82cc82..bf385aead 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -583,6 +583,7 @@ static PFNglGetUniformLocation pglGetUniformLocation; static char *gl_customvertexshaders[MAXSHADERS]; static char *gl_customfragmentshaders[MAXSHADERS]; static GLuint gl_currentshaderprogram = 0; +static boolean gl_shaderprogramchanged = true; // 13062019 typedef enum @@ -1058,8 +1059,12 @@ EXPORT void HWRAPI(SetShader) (int shader) #ifdef GL_SHADERS if (gl_allowshaders) { + if ((GLuint)shader != gl_currentshaderprogram) + { + gl_currentshaderprogram = shader; + gl_shaderprogramchanged = true; + } gl_shadersenabled = true; - gl_currentshaderprogram = shader; return; } #else @@ -1868,7 +1873,11 @@ static void *Shader_Load(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat * gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram]; if (shader->program) { - pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program); + if (gl_shaderprogramchanged) + { + pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program); + gl_shaderprogramchanged = false; + } Shader_SetUniforms(Surface, poly, tint, fade); return shader; } From 78c2928b8b3e4be52642428fd202dd25b6df3a67 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sun, 19 Apr 2020 01:55:27 +0300 Subject: [PATCH 107/168] Optimization: also don't reset shader on models --- src/hardware/r_opengl/r_opengl.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index bf385aead..d80de8aad 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2856,10 +2856,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglShadeModel(GL_FLAT); } #endif - -#ifdef GL_SHADERS - pglUseProgram(0); -#endif } // -----------------+ From ff8f48647b8bb170c5b724d257174a5bd34f3743 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 25 Apr 2020 20:34:32 +0300 Subject: [PATCH 108/168] HWR_ProcessSeg skywall processing from master --- src/hardware/hw_main.c | 119 ++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 74 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6fe0d4078..5d503fb17 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1079,7 +1079,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, // HWR_DrawSkyWall // Draw walls into the depth buffer so that anything behind is culled properly -static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top) +static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf) { HWD.pfnSetTexture(NULL); // no texture @@ -1087,9 +1087,7 @@ static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf, fixed_t b wallVerts[0].t = wallVerts[1].t = 0; wallVerts[0].s = wallVerts[3].s = 0; wallVerts[2].s = wallVerts[1].s = 0; - // set top/bottom coords - wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(top); // No real way to find the correct height of this - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(bottom); // worldlow/bottom because it needs to cover up the lower thok barrier wall + // this no longer sets top/bottom coords, this should be done before caling the function HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_NoTexture, 255, NULL); // PF_Invisible so it's not drawn into the colour buffer // PF_NoTexture for no texture @@ -1643,82 +1641,37 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap); } - // Isn't this just the most lovely mess + // Sky culling + // No longer so much a mess as before! if (!gr_curline->polyseg) // Don't do it for polyobjects { - if (gr_frontsector->ceilingpic == skyflatnum || gr_backsector->ceilingpic == skyflatnum) + if (gr_frontsector->ceilingpic == skyflatnum) { - fixed_t depthwallheight; - - if (!gr_sidedef->toptexture || (gr_frontsector->ceilingpic == skyflatnum && gr_backsector->ceilingpic == skyflatnum)) // when both sectors are sky, the top texture isn't drawn - depthwallheight = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; - else - depthwallheight = gr_frontsector->ceilingheight > gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; - - if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier + if (gr_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky { - if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier - { - if (!gr_sidedef->bottomtexture) // Only extend further down if there's no texture - HWR_DrawSkyWall(wallVerts, &Surf, worldbottom < worldlow ? worldbottom : worldlow, INT32_MAX); - else - HWR_DrawSkyWall(wallVerts, &Surf, worldbottom > worldlow ? worldbottom : worldlow, INT32_MAX); - } - // behind sector is not a thok barrier - else if (gr_backsector->ceilingheight <= gr_frontsector->ceilingheight) // behind sector ceiling is lower or equal to current sector - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); - // gr_front/backsector heights need to be used here because of the worldtop being set to worldhigh earlier on - } - else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not - { - if (gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier ceiling height is equal to or greater than current sector ceiling height - || gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier ceiling height is equal to or less than current sector floor height - || gr_backsector->ceilingpic != skyflatnum) // thok barrier is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); - } - else // neither sectors are thok barriers - { - if ((gr_backsector->ceilingheight < gr_frontsector->ceilingheight && !gr_sidedef->toptexture) // no top texture and sector behind is lower - || gr_backsector->ceilingpic != skyflatnum) // behind sector is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space +#ifdef ESLOPE + wallVerts[0].y = FIXED_TO_FLOAT(worldtop); + wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); +#else + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); +#endif + HWR_DrawSkyWall(wallVerts, &Surf); } } - // And now for sky floors! - if (gr_frontsector->floorpic == skyflatnum || gr_backsector->floorpic == skyflatnum) + + if (gr_frontsector->floorpic == skyflatnum) { - fixed_t depthwallheight; - - if (!gr_sidedef->bottomtexture) - depthwallheight = worldbottom > worldlow ? worldbottom : worldlow; - else - depthwallheight = worldbottom < worldlow ? worldbottom : worldlow; - - if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier + if (gr_backsector->floorpic != skyflatnum) // don't cull if back sector is also sky { - if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier - { - if (!gr_sidedef->toptexture) // Only extend up if there's no texture - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop > worldhigh ? worldtop : worldhigh); - else - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop < worldhigh ? worldtop : worldhigh); - } - // behind sector is not a thok barrier - else if (gr_backsector->floorheight >= gr_frontsector->floorheight) // behind sector floor is greater or equal to current sector - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); - } - else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not - { - if (gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier floor height is equal to or less than current sector floor height - || gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier floor height is equal to or greater than current sector ceiling height - || gr_backsector->floorpic != skyflatnum) // thok barrier is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); - } - else // neither sectors are thok barriers - { - if (((gr_backsector->floorheight > gr_frontsector->floorheight && !gr_sidedef->bottomtexture) // no bottom texture and sector behind is higher - || gr_backsector->floorpic != skyflatnum) // behind sector is not a sky - && ABS(gr_backsector->floorheight - gr_frontsector->floorheight) > FRACUNIT*3/2) // don't draw sky walls for VERY thin differences, this makes for horrible looking slopes sometimes! - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); +#ifdef ESLOPE + wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); + wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); +#else + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); +#endif + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space + HWR_DrawSkyWall(wallVerts, &Surf); } } } @@ -1793,9 +1746,27 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (!gr_curline->polyseg) { if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector - HWR_DrawSkyWall(wallVerts, &Surf, worldtop, INT32_MAX); + { + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space +#ifdef ESLOPE + wallVerts[0].y = FIXED_TO_FLOAT(worldtop); + wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); +#else + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); +#endif + HWR_DrawSkyWall(wallVerts, &Surf); + } if (gr_frontsector->floorpic == skyflatnum) - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldbottom); + { +#ifdef ESLOPE + wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); + wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); +#else + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); +#endif + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space + HWR_DrawSkyWall(wallVerts, &Surf); + } } } From be99670a39ec936ce07fdc55ebdea67d3a2673e9 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 25 Apr 2020 21:43:20 +0300 Subject: [PATCH 109/168] More HWR_ProcessSeg sky code from master --- src/hardware/hw_main.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5d503fb17..7f640553f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1183,8 +1183,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (gr_backsector) { - INT32 gr_toptexture, gr_bottomtexture; + INT32 gr_toptexture = 0, gr_bottomtexture = 0; // two sided line + boolean bothceilingssky = false; // turned on if both back and front ceilings are sky + boolean bothfloorssky = false; // likewise, but for floors #ifdef ESLOPE SLOPEPARAMS(gr_backsector->c_slope, worldhigh, worldhighslope, gr_backsector->ceilingheight) @@ -1197,17 +1199,23 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // hack to allow height changes in outdoor areas // This is what gets rid of the upper textures if there should be sky - if (gr_frontsector->ceilingpic == skyflatnum && - gr_backsector->ceilingpic == skyflatnum) + if (gr_frontsector->ceilingpic == skyflatnum + && gr_backsector->ceilingpic == skyflatnum) { - worldtop = worldhigh; -#ifdef ESLOPE - worldtopslope = worldhighslope; -#endif + bothceilingssky = true; } - gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); - gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); + // likewise, but for floors and upper textures + if (gr_frontsector->floorpic == skyflatnum + && gr_backsector->floorpic == skyflatnum) + { + bothfloorssky = true; + } + + if (!bothceilingssky) + gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); + if (!bothfloorssky) + gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); // check TOP TEXTURE if (( From 64a153fdeecd99aa3f984fe144fd36a29f4dbc62 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sun, 19 Apr 2020 01:25:28 +0300 Subject: [PATCH 110/168] Render stats --- src/d_main.c | 73 ++++++++++++++++++++++++++++++++++++++++++ src/hardware/hw_main.c | 55 +++++++++++++++++++++++++++++++ src/hardware/hw_main.h | 21 ++++++++++++ src/i_system.h | 2 ++ src/sdl/i_system.c | 39 +++++++++++++++++++--- 5 files changed, 185 insertions(+), 5 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index c0a8eacec..09aa2d340 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -411,6 +411,7 @@ static void D_Display(void) if (!automapactive && !dedicated && cv_renderview.value) { + rs_rendercalltime = I_GetTimeMicros(); if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) { topleft = screens[0] + viewwindowy*vid.width + viewwindowx; @@ -457,6 +458,7 @@ static void D_Display(void) if (postimgtype2) V_DoPostProcessor(1, postimgtype2, postimgparam2); } + rs_rendercalltime = I_GetTimeMicros() - rs_rendercalltime; } if (lastdraw) @@ -591,6 +593,77 @@ static void D_Display(void) snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent); V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s); } + + if (cv_renderstats.value) + { + char s[50]; + int frametime = I_GetTimeMicros() - rs_prevframetime; + int divisor = 1; + rs_prevframetime = I_GetTimeMicros(); + + if (rs_rendercalltime > 10000) divisor = 1000; + + snprintf(s, sizeof s - 1, "ft %d", frametime / divisor); + V_DrawThinString(30, 10, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "rtot %d", rs_rendercalltime / divisor); + V_DrawThinString(30, 20, V_MONOSPACE | V_YELLOWMAP, s); + if (rendermode == render_opengl)// dont show unimplemented stats + { + snprintf(s, sizeof s - 1, "bsp %d", rs_bsptime / divisor); + V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "nsrt %d", rs_nodesorttime / divisor); + V_DrawThinString(30, 40, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "ndrw %d", rs_nodedrawtime / divisor); + V_DrawThinString(30, 50, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "ssrt %d", rs_spritesorttime / divisor); + V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "sdrw %d", rs_spritedrawtime / divisor); + V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); + /*snprintf(s, sizeof s - 1, "post %d", rs_posttime / divisor); + V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "flip %d", rs_swaptime / divisor); + V_DrawThinString(30, 90, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "test %d", rs_test / divisor); + V_DrawThinString(30, 100, V_MONOSPACE | V_YELLOWMAP, s);*/ + + snprintf(s, sizeof s - 1, "nbsp %d", rs_numbspcalls); + V_DrawThinString(80, 10, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "nnod %d", rs_numdrawnodes); + V_DrawThinString(80, 20, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "nspr %d", rs_numsprites); + V_DrawThinString(80, 30, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "npob %d", rs_numpolyobjects); + V_DrawThinString(80, 40, V_MONOSPACE | V_BLUEMAP, s); +/* + if (cv_enable_batching.value) + { + snprintf(s, sizeof s - 1, "bsrt %d", rs_batchsorttime / divisor); + V_DrawThinString(75, 55, V_MONOSPACE | V_REDMAP, s); + snprintf(s, sizeof s - 1, "bdrw %d", rs_batchdrawtime / divisor); + V_DrawThinString(75, 65, V_MONOSPACE | V_REDMAP, s); + + snprintf(s, sizeof s - 1, "npol %d", rs_numpolys); + V_DrawThinString(130, 10, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "ndc %d", rs_numcalls); + V_DrawThinString(130, 20, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "nshd %d", rs_numshaders); + V_DrawThinString(130, 30, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "nvrt %d", rs_numverts); + V_DrawThinString(130, 40, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "ntex %d", rs_numtextures); + V_DrawThinString(185, 10, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "npf %d", rs_numpolyflags); + V_DrawThinString(185, 20, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "ncol %d", rs_numcolors); + V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s); + }*/ + } +/* else + { + snprintf(s, sizeof s - 1, "flip %d", rs_swaptime / divisor); + V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); + }*/ + } I_FinishUpdate(); // page flip or blit buffer } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6fe0d4078..ed43ec9ae 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -146,6 +146,25 @@ static float gr_fovlud; static angle_t gr_aimingangle; static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); +// render stats +int rs_prevframetime = 0; +int rs_rendercalltime = 0; +int rs_bsptime = 0; +int rs_nodetime = 0; +int rs_nodesorttime = 0; +int rs_nodedrawtime = 0; +int rs_spritesorttime = 0; +int rs_spritedrawtime = 0; + +int rs_numdrawnodes = 0; +int rs_numbspcalls = 0; +int rs_numsprites = 0; +int rs_numpolyobjects = 0; + +//int rs_posttime = 0; +//int rs_swaptime = 0; + + // ========================================================================== // Lighting // ========================================================================== @@ -3484,6 +3503,9 @@ static void HWR_Subsector(size_t num) po = (polyobj_t *)(po->link.next); } + // for render stats + rs_numpolyobjects += numpolys; + // Sort polyobjects R_SortPolyObjects(sub); @@ -3598,6 +3620,8 @@ static void HWR_RenderBSPNode(INT32 bspnum) // Decide which side the view point is on INT32 side; + + rs_numbspcalls++; // Found a subsector? if (bspnum & NF_SUBSECTOR) @@ -4772,6 +4796,8 @@ static void HWR_CreateDrawNodes(void) // If true, swap the draw order. boolean shift = false; + + rs_nodesorttime = I_GetTimeMicros(); for (i = 0; i < numplanes; i++, p++) { @@ -4790,6 +4816,8 @@ static void HWR_CreateDrawNodes(void) sortnode[p].wall = &wallinfo[i]; sortindex[p] = p; } + + rs_numdrawnodes = p; // p is the number of stuff to sort @@ -4892,6 +4920,10 @@ static void HWR_CreateDrawNodes(void) } //i++ } // loop++ + rs_nodesorttime = I_GetTimeMicros() - rs_nodesorttime; + + rs_nodedrawtime = I_GetTimeMicros(); + // Okay! Let's draw it all! Woo! HWD.pfnSetTransform(&atransform); HWD.pfnSetShader(0); @@ -4926,6 +4958,8 @@ static void HWR_CreateDrawNodes(void) sortnode[sortindex[i]].wall->lightlevel, sortnode[sortindex[i]].wall->wallcolormap); } } + + rs_nodedrawtime = I_GetTimeMicros() - rs_nodedrawtime; numwalls = 0; numplanes = 0; @@ -6002,6 +6036,10 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_grshaders.value); HWD.pfnSetShader(0); + rs_numbspcalls = 0; + rs_numpolyobjects = 0; + rs_bsptime = I_GetTimeMicros(); + validcount++; HWR_RenderBSPNode((INT32)numnodes-1); @@ -6035,6 +6073,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) } #endif + rs_bsptime = I_GetTimeMicros() - rs_bsptime; + // Check for new console commands. NetUpdate(); @@ -6045,14 +6085,22 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) #endif // Draw MD2 and sprites + rs_numsprites = gr_visspritecount; + rs_spritesorttime = I_GetTimeMicros(); HWR_SortVisSprites(); + rs_spritesorttime = I_GetTimeMicros() - rs_spritesorttime; + rs_spritedrawtime = I_GetTimeMicros(); HWR_DrawSprites(); + rs_spritedrawtime = I_GetTimeMicros() - rs_spritedrawtime; #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? HWR_DrawCoronas(); #endif + rs_numdrawnodes = 0; + rs_nodesorttime = 0; + rs_nodedrawtime = 0; if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything { HWR_CreateDrawNodes(); @@ -6118,6 +6166,11 @@ consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotro consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +// render stats +// for now have it in here in the hw code +// could have it somewhere else since renderstats could also be a software rendering thing +consvar_t cv_renderstats = {"renderstats", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + static void CV_grfiltermode_OnChange(void) { if (rendermode == render_opengl) @@ -6155,6 +6208,8 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grfiltermode); CV_RegisterVar(&cv_grcorrecttricks); CV_RegisterVar(&cv_grsolvetjoin); + + CV_RegisterVar(&cv_renderstats); #ifndef NEWCLIP CV_RegisterVar(&cv_grclipwalls); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index aedfa9cd6..8aaa335fb 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -104,4 +104,25 @@ extern float gr_viewwindowx, gr_basewindowcentery; extern fixed_t *hwbbox; extern FTransform atransform; + +// render stats console toggle +extern consvar_t cv_renderstats; +// render stats time counter variables +extern int rs_prevframetime;// time when previous frame was rendered +extern int rs_rendercalltime; +extern int rs_bsptime; +extern int rs_nodetime; +extern int rs_nodesorttime; +extern int rs_nodedrawtime; +extern int rs_spritesorttime; +extern int rs_spritedrawtime; + +//extern int rs_posttime; +//extern int rs_swaptime; + +extern int rs_numdrawnodes; +extern int rs_numbspcalls; +extern int rs_numsprites; +extern int rs_numpolyobjects; + #endif diff --git a/src/i_system.h b/src/i_system.h index b38748244..dd0b65f6d 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -46,6 +46,8 @@ UINT32 I_GetFreeMem(UINT32 *total); */ tic_t I_GetTime(void); +int I_GetTimeMicros(void);// provides microsecond counter for render stats + /** \brief The I_Sleep function \return void diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a86af316e..9d63225cb 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2060,9 +2060,12 @@ static p_timeGetTime pfntimeGetTime = NULL; // but lower precision on Windows NT // --------- -tic_t I_GetTime(void) +DWORD TimeFunction(boolean microseconds) { - tic_t newtics = 0; + DWORD newtics = 0; + int multiplier = 1; + + if (microseconds) multiplier = 1000; if (!starttickcount) // high precision timer { @@ -2082,7 +2085,7 @@ tic_t I_GetTime(void) if (frequency.LowPart && QueryPerformanceCounter(&currtime)) { - newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * NEWTICRATE + newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * 1000 * multiplier / frequency.QuadPart); } else if (pfntimeGetTime) @@ -2090,11 +2093,11 @@ tic_t I_GetTime(void) currtime.LowPart = pfntimeGetTime(); if (!basetime.LowPart) basetime.LowPart = currtime.LowPart; - newtics = ((currtime.LowPart - basetime.LowPart)/(1000/NEWTICRATE)); + newtics = currtime.LowPart - basetime.LowPart; } } else - newtics = (GetTickCount() - starttickcount)/(1000/NEWTICRATE); + newtics = (GetTickCount() - starttickcount) * multiplier; return newtics; } @@ -2116,6 +2119,7 @@ static void I_ShutdownTimer(void) // I_GetTime // returns time in 1/TICRATE second tics // +/* tic_t I_GetTime (void) { static Uint64 basetime = 0; @@ -2132,8 +2136,33 @@ tic_t I_GetTime (void) return (tic_t)ticks; } +*/ +int TimeFunction(boolean microseconds)// this cant actually do microseconds so it fakes it +{ + static Uint64 basetime = 0; + Uint64 ticks = SDL_GetTicks(); + + if (!basetime) + basetime = ticks; + + ticks -= basetime; + + return microseconds ? ticks * 1000 : ticks; +} #endif +tic_t I_GetTime(void) +{ + //return TimeFunction(false) / (1000/NEWTICRATE); + // how about this + return (TimeFunction(false) * NEWTICRATE) / 1000; +} + +int I_GetTimeMicros(void) +{ + return TimeFunction(true); +} + // //I_StartupTimer // From 8dcc2fe20da0cebdbf31ffb0c69a34337a401cd3 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Fri, 1 May 2020 20:57:48 +0300 Subject: [PATCH 111/168] Move some render stats variables to better locations, add I_FinishUpdate timing --- src/d_main.c | 14 ++++++++------ src/hardware/hw_main.c | 10 +--------- src/hardware/hw_main.h | 6 ------ src/r_main.c | 7 +++++++ src/r_main.h | 8 ++++++++ 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 09aa2d340..28e134d65 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -620,10 +620,10 @@ static void D_Display(void) snprintf(s, sizeof s - 1, "sdrw %d", rs_spritedrawtime / divisor); V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); /*snprintf(s, sizeof s - 1, "post %d", rs_posttime / divisor); + V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s);*/ + snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor); V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "flip %d", rs_swaptime / divisor); - V_DrawThinString(30, 90, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "test %d", rs_test / divisor); + /*snprintf(s, sizeof s - 1, "test %d", rs_test / divisor); V_DrawThinString(30, 100, V_MONOSPACE | V_YELLOWMAP, s);*/ snprintf(s, sizeof s - 1, "nbsp %d", rs_numbspcalls); @@ -658,14 +658,16 @@ static void D_Display(void) V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s); }*/ } -/* else + else { - snprintf(s, sizeof s - 1, "flip %d", rs_swaptime / divisor); + snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor); V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); - }*/ + } } + rs_swaptime = I_GetTimeMicros(); I_FinishUpdate(); // page flip or blit buffer + rs_swaptime = I_GetTimeMicros() - rs_swaptime; } needpatchflush = false; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index ed43ec9ae..79cc83bba 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -146,9 +146,7 @@ static float gr_fovlud; static angle_t gr_aimingangle; static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); -// render stats -int rs_prevframetime = 0; -int rs_rendercalltime = 0; +// Render stats int rs_bsptime = 0; int rs_nodetime = 0; int rs_nodesorttime = 0; @@ -162,7 +160,6 @@ int rs_numsprites = 0; int rs_numpolyobjects = 0; //int rs_posttime = 0; -//int rs_swaptime = 0; // ========================================================================== @@ -6166,11 +6163,6 @@ consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotro consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -// render stats -// for now have it in here in the hw code -// could have it somewhere else since renderstats could also be a software rendering thing -consvar_t cv_renderstats = {"renderstats", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - static void CV_grfiltermode_OnChange(void) { if (rendermode == render_opengl) diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 8aaa335fb..f89809cc7 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -105,11 +105,6 @@ extern fixed_t *hwbbox; extern FTransform atransform; -// render stats console toggle -extern consvar_t cv_renderstats; -// render stats time counter variables -extern int rs_prevframetime;// time when previous frame was rendered -extern int rs_rendercalltime; extern int rs_bsptime; extern int rs_nodetime; extern int rs_nodesorttime; @@ -118,7 +113,6 @@ extern int rs_spritesorttime; extern int rs_spritedrawtime; //extern int rs_posttime; -//extern int rs_swaptime; extern int rs_numdrawnodes; extern int rs_numbspcalls; diff --git a/src/r_main.c b/src/r_main.c index a881e046d..17eae9495 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -98,6 +98,11 @@ lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // Hack to support extra boom colormaps. extracolormap_t *extra_colormaps = NULL; +// Render stats +int rs_prevframetime = 0; +int rs_rendercalltime = 0; +int rs_swaptime = 0; + static CV_PossibleValue_t drawdist_cons_t[] = { {256, "256"}, {512, "512"}, {768, "768"}, {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, @@ -148,6 +153,8 @@ consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL, consvar_t cv_maxportals = {"maxportals", "2", CV_SAVE, maxportals_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_renderstats = {"renderstats", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + void SplitScreen_OnChange(void) { if (!cv_debug && netgame) diff --git a/src/r_main.h b/src/r_main.h index 578eb3d54..72d340bd9 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -74,6 +74,14 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y); boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph); +// Render stats + +extern consvar_t cv_renderstats; + +extern int rs_prevframetime;// time when previous frame was rendered +extern int rs_rendercalltime; +extern int rs_swaptime; + // // REFRESH - the actual rendering functions. // From 7e8543a408c35e590ac023a88af7e902761d85d5 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 2 May 2020 20:43:53 +0300 Subject: [PATCH 112/168] More render stats for software mode, renamed and relocated some render stats variables --- src/d_main.c | 40 +++++++++++++++++++++++----------------- src/hardware/hw_main.c | 35 ++++++++++++++--------------------- src/hardware/hw_main.h | 16 +++++----------- src/r_bsp.c | 6 ++++++ src/r_main.c | 22 ++++++++++++++++++++++ src/r_main.h | 11 +++++++++++ src/r_things.c | 2 ++ 7 files changed, 83 insertions(+), 49 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 28e134d65..2e1badc69 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -607,17 +607,25 @@ static void D_Display(void) V_DrawThinString(30, 10, V_MONOSPACE | V_YELLOWMAP, s); snprintf(s, sizeof s - 1, "rtot %d", rs_rendercalltime / divisor); V_DrawThinString(30, 20, V_MONOSPACE | V_YELLOWMAP, s); - if (rendermode == render_opengl)// dont show unimplemented stats + snprintf(s, sizeof s - 1, "bsp %d", rs_bsptime / divisor); + V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "nbsp %d", rs_numbspcalls); + V_DrawThinString(80, 10, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "nspr %d", rs_numsprites); + V_DrawThinString(80, 20, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "nnod %d", rs_numdrawnodes); + V_DrawThinString(80, 30, V_MONOSPACE | V_BLUEMAP, s); + snprintf(s, sizeof s - 1, "npob %d", rs_numpolyobjects); + V_DrawThinString(80, 40, V_MONOSPACE | V_BLUEMAP, s); + if (rendermode == render_opengl) // OpenGL specific stats { - snprintf(s, sizeof s - 1, "bsp %d", rs_bsptime / divisor); - V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "nsrt %d", rs_nodesorttime / divisor); + snprintf(s, sizeof s - 1, "nsrt %d", rs_hw_nodesorttime / divisor); V_DrawThinString(30, 40, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "ndrw %d", rs_nodedrawtime / divisor); + snprintf(s, sizeof s - 1, "ndrw %d", rs_hw_nodedrawtime / divisor); V_DrawThinString(30, 50, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "ssrt %d", rs_spritesorttime / divisor); + snprintf(s, sizeof s - 1, "ssrt %d", rs_hw_spritesorttime / divisor); V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "sdrw %d", rs_spritedrawtime / divisor); + snprintf(s, sizeof s - 1, "sdrw %d", rs_hw_spritedrawtime / divisor); V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); /*snprintf(s, sizeof s - 1, "post %d", rs_posttime / divisor); V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s);*/ @@ -626,14 +634,6 @@ static void D_Display(void) /*snprintf(s, sizeof s - 1, "test %d", rs_test / divisor); V_DrawThinString(30, 100, V_MONOSPACE | V_YELLOWMAP, s);*/ - snprintf(s, sizeof s - 1, "nbsp %d", rs_numbspcalls); - V_DrawThinString(80, 10, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "nnod %d", rs_numdrawnodes); - V_DrawThinString(80, 20, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "nspr %d", rs_numsprites); - V_DrawThinString(80, 30, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "npob %d", rs_numpolyobjects); - V_DrawThinString(80, 40, V_MONOSPACE | V_BLUEMAP, s); /* if (cv_enable_batching.value) { @@ -658,10 +658,16 @@ static void D_Display(void) V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s); }*/ } - else + else // software specific stats { + snprintf(s, sizeof s - 1, "prtl %d", rs_sw_portaltime / divisor); + V_DrawThinString(30, 40, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "plns %d", rs_sw_planetime / divisor); + V_DrawThinString(30, 50, V_MONOSPACE | V_YELLOWMAP, s); + snprintf(s, sizeof s - 1, "mskd %d", rs_sw_maskedtime / divisor); + V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s); snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor); - V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s); + V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); } } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 79cc83bba..bd2c5c9f4 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -147,17 +147,10 @@ static angle_t gr_aimingangle; static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); // Render stats -int rs_bsptime = 0; -int rs_nodetime = 0; -int rs_nodesorttime = 0; -int rs_nodedrawtime = 0; -int rs_spritesorttime = 0; -int rs_spritedrawtime = 0; - -int rs_numdrawnodes = 0; -int rs_numbspcalls = 0; -int rs_numsprites = 0; -int rs_numpolyobjects = 0; +int rs_hw_nodesorttime = 0; +int rs_hw_nodedrawtime = 0; +int rs_hw_spritesorttime = 0; +int rs_hw_spritedrawtime = 0; //int rs_posttime = 0; @@ -4794,7 +4787,7 @@ static void HWR_CreateDrawNodes(void) // If true, swap the draw order. boolean shift = false; - rs_nodesorttime = I_GetTimeMicros(); + rs_hw_nodesorttime = I_GetTimeMicros(); for (i = 0; i < numplanes; i++, p++) { @@ -4917,9 +4910,9 @@ static void HWR_CreateDrawNodes(void) } //i++ } // loop++ - rs_nodesorttime = I_GetTimeMicros() - rs_nodesorttime; + rs_hw_nodesorttime = I_GetTimeMicros() - rs_hw_nodesorttime; - rs_nodedrawtime = I_GetTimeMicros(); + rs_hw_nodedrawtime = I_GetTimeMicros(); // Okay! Let's draw it all! Woo! HWD.pfnSetTransform(&atransform); @@ -4956,7 +4949,7 @@ static void HWR_CreateDrawNodes(void) } } - rs_nodedrawtime = I_GetTimeMicros() - rs_nodedrawtime; + rs_hw_nodedrawtime = I_GetTimeMicros() - rs_hw_nodedrawtime; numwalls = 0; numplanes = 0; @@ -6083,12 +6076,12 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // Draw MD2 and sprites rs_numsprites = gr_visspritecount; - rs_spritesorttime = I_GetTimeMicros(); + rs_hw_spritesorttime = I_GetTimeMicros(); HWR_SortVisSprites(); - rs_spritesorttime = I_GetTimeMicros() - rs_spritesorttime; - rs_spritedrawtime = I_GetTimeMicros(); + rs_hw_spritesorttime = I_GetTimeMicros() - rs_hw_spritesorttime; + rs_hw_spritedrawtime = I_GetTimeMicros(); HWR_DrawSprites(); - rs_spritedrawtime = I_GetTimeMicros() - rs_spritedrawtime; + rs_hw_spritedrawtime = I_GetTimeMicros() - rs_hw_spritedrawtime; #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? @@ -6096,8 +6089,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) #endif rs_numdrawnodes = 0; - rs_nodesorttime = 0; - rs_nodedrawtime = 0; + rs_hw_nodesorttime = 0; + rs_hw_nodedrawtime = 0; if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything { HWR_CreateDrawNodes(); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index f89809cc7..631593d6f 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -105,18 +105,12 @@ extern fixed_t *hwbbox; extern FTransform atransform; -extern int rs_bsptime; -extern int rs_nodetime; -extern int rs_nodesorttime; -extern int rs_nodedrawtime; -extern int rs_spritesorttime; -extern int rs_spritedrawtime; +// Render stats +extern int rs_hw_nodesorttime; +extern int rs_hw_nodedrawtime; +extern int rs_hw_spritesorttime; +extern int rs_hw_spritedrawtime; //extern int rs_posttime; -extern int rs_numdrawnodes; -extern int rs_numbspcalls; -extern int rs_numsprites; -extern int rs_numpolyobjects; - #endif diff --git a/src/r_bsp.c b/src/r_bsp.c index c0011f4b9..355d55bc6 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -812,6 +812,9 @@ static void R_AddPolyObjects(subsector_t *sub) po = (polyobj_t *)(po->link.next); } + // for render stats + rs_numpolyobjects += numpolys; + // sort polyobjects R_SortPolyObjects(sub); @@ -1363,6 +1366,9 @@ void R_RenderBSPNode(INT32 bspnum) { node_t *bsp; INT32 side; + + rs_numbspcalls++; + while (!(bspnum & NF_SUBSECTOR)) // Found a subsector? { bsp = &nodes[bspnum]; diff --git a/src/r_main.c b/src/r_main.c index 17eae9495..4d1be4b14 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -34,6 +34,7 @@ #include "m_random.h" // quake camera shake #include "r_portal.h" #include "r_main.h" +#include "i_system.h" // I_GetTimeMicros #ifdef HWRENDER #include "hardware/hw_main.h" @@ -103,6 +104,17 @@ int rs_prevframetime = 0; int rs_rendercalltime = 0; int rs_swaptime = 0; +int rs_bsptime = 0; + +int rs_sw_portaltime = 0; +int rs_sw_planetime = 0; +int rs_sw_maskedtime = 0; + +int rs_numbspcalls = 0; +int rs_numsprites = 0; +int rs_numdrawnodes = 0; +int rs_numpolyobjects = 0; + static CV_PossibleValue_t drawdist_cons_t[] = { {256, "256"}, {512, "512"}, {768, "768"}, {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, @@ -1452,7 +1464,11 @@ void R_RenderPlayerView(player_t *player) mytotal = 0; ProfZeroTimer(); #endif + rs_numbspcalls = rs_numpolyobjects = rs_numdrawnodes = 0; + rs_bsptime = I_GetTimeMicros(); R_RenderBSPNode((INT32)numnodes - 1); + rs_bsptime = I_GetTimeMicros() - rs_bsptime; + rs_numsprites = visspritecount; #ifdef TIMING RDMSR(0x10, &mycount); mytotal += mycount; // 64bit add @@ -1470,6 +1486,7 @@ void R_RenderPlayerView(player_t *player) Portal_AddSkyboxPortals(); // Portal rendering. Hijacks the BSP traversal. + rs_sw_portaltime = I_GetTimeMicros(); if (portal_base) { portal_t *portal; @@ -1509,15 +1526,20 @@ void R_RenderPlayerView(player_t *player) Portal_Remove(portal); } } + rs_sw_portaltime = I_GetTimeMicros() - rs_sw_portaltime; + rs_sw_planetime = I_GetTimeMicros(); R_DrawPlanes(); #ifdef FLOORSPLATS R_DrawVisibleFloorSplats(); #endif + rs_sw_planetime = I_GetTimeMicros() - rs_sw_planetime; // draw mid texture and sprite // And now 3D floors/sides! + rs_sw_maskedtime = I_GetTimeMicros(); R_DrawMasked(masks, nummasks); + rs_sw_maskedtime = I_GetTimeMicros() - rs_sw_maskedtime; free(masks); } diff --git a/src/r_main.h b/src/r_main.h index 72d340bd9..99a25d86e 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -82,6 +82,17 @@ extern int rs_prevframetime;// time when previous frame was rendered extern int rs_rendercalltime; extern int rs_swaptime; +extern int rs_bsptime; + +extern int rs_sw_portaltime; +extern int rs_sw_planetime; +extern int rs_sw_maskedtime; + +extern int rs_numbspcalls; +extern int rs_numsprites; +extern int rs_numdrawnodes; +extern int rs_numpolyobjects; + // // REFRESH - the actual rendering functions. // diff --git a/src/r_things.c b/src/r_things.c index d2f3b4902..02c347929 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2552,6 +2552,8 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link) node->thickseg = NULL; node->ffloor = NULL; node->sprite = NULL; + + rs_numdrawnodes++; return node; } From 724e093ce8f8dd679a5fff9cf6040fc99c313a3a Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 2 May 2020 20:45:33 +0300 Subject: [PATCH 113/168] Render stats cleanup --- src/d_main.c | 28 ---------------------------- src/hardware/hw_main.c | 2 -- src/hardware/hw_main.h | 2 -- 3 files changed, 32 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 2e1badc69..5631cb939 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -627,36 +627,8 @@ static void D_Display(void) V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s); snprintf(s, sizeof s - 1, "sdrw %d", rs_hw_spritedrawtime / divisor); V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); - /*snprintf(s, sizeof s - 1, "post %d", rs_posttime / divisor); - V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s);*/ snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor); V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s); - /*snprintf(s, sizeof s - 1, "test %d", rs_test / divisor); - V_DrawThinString(30, 100, V_MONOSPACE | V_YELLOWMAP, s);*/ - -/* - if (cv_enable_batching.value) - { - snprintf(s, sizeof s - 1, "bsrt %d", rs_batchsorttime / divisor); - V_DrawThinString(75, 55, V_MONOSPACE | V_REDMAP, s); - snprintf(s, sizeof s - 1, "bdrw %d", rs_batchdrawtime / divisor); - V_DrawThinString(75, 65, V_MONOSPACE | V_REDMAP, s); - - snprintf(s, sizeof s - 1, "npol %d", rs_numpolys); - V_DrawThinString(130, 10, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "ndc %d", rs_numcalls); - V_DrawThinString(130, 20, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "nshd %d", rs_numshaders); - V_DrawThinString(130, 30, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "nvrt %d", rs_numverts); - V_DrawThinString(130, 40, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "ntex %d", rs_numtextures); - V_DrawThinString(185, 10, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "npf %d", rs_numpolyflags); - V_DrawThinString(185, 20, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "ncol %d", rs_numcolors); - V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s); - }*/ } else // software specific stats { diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index bd2c5c9f4..88c4a7808 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -152,8 +152,6 @@ int rs_hw_nodedrawtime = 0; int rs_hw_spritesorttime = 0; int rs_hw_spritedrawtime = 0; -//int rs_posttime = 0; - // ========================================================================== // Lighting diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 631593d6f..fc49364da 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -111,6 +111,4 @@ extern int rs_hw_nodedrawtime; extern int rs_hw_spritesorttime; extern int rs_hw_spritedrawtime; -//extern int rs_posttime; - #endif From 1b6e65b91c17ee622a995a6e0cb4b40eecb0462d Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 2 May 2020 23:06:01 +0300 Subject: [PATCH 114/168] Implement I_GetTimeMicros without affecting I_GetTime behaviour details --- src/sdl/i_system.c | 49 ++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 9d63225cb..426904c63 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2060,12 +2060,11 @@ static p_timeGetTime pfntimeGetTime = NULL; // but lower precision on Windows NT // --------- -DWORD TimeFunction(boolean microseconds) +DWORD TimeFunction(int requested_frequency) { DWORD newtics = 0; - int multiplier = 1; - - if (microseconds) multiplier = 1000; + // 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 { @@ -2085,7 +2084,7 @@ DWORD TimeFunction(boolean microseconds) if (frequency.LowPart && QueryPerformanceCounter(&currtime)) { - newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * 1000 * multiplier + newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * requested_frequency / frequency.QuadPart); } else if (pfntimeGetTime) @@ -2093,11 +2092,19 @@ DWORD TimeFunction(boolean microseconds) currtime.LowPart = pfntimeGetTime(); if (!basetime.LowPart) basetime.LowPart = currtime.LowPart; - newtics = currtime.LowPart - basetime.LowPart; + if (requested_frequency > 1000) + newtics = currtime.LowPart - basetime.LowPart * excess_frequency; + else + newtics = (currtime.LowPart - basetime.LowPart)/(1000/requested_frequency); } } else - newtics = (GetTickCount() - starttickcount) * multiplier; + { + if (requested_frequency > 1000) + newtics = (GetTickCount() - starttickcount) * excess_frequency; + else + newtics = (GetTickCount() - starttickcount)/(1000/requested_frequency); + } return newtics; } @@ -2119,8 +2126,9 @@ static void I_ShutdownTimer(void) // I_GetTime // returns time in 1/TICRATE second tics // -/* -tic_t I_GetTime (void) + +// millisecond precision only +int TimeFunction(int requested_frequency) { static Uint64 basetime = 0; Uint64 ticks = SDL_GetTicks(); @@ -2130,37 +2138,22 @@ tic_t I_GetTime (void) ticks -= basetime; - ticks = (ticks*TICRATE); + ticks = (ticks*requested_frequency); ticks = (ticks/1000); - return (tic_t)ticks; -} -*/ -int TimeFunction(boolean microseconds)// this cant actually do microseconds so it fakes it -{ - static Uint64 basetime = 0; - Uint64 ticks = SDL_GetTicks(); - - if (!basetime) - basetime = ticks; - - ticks -= basetime; - - return microseconds ? ticks * 1000 : ticks; + return ticks; } #endif tic_t I_GetTime(void) { - //return TimeFunction(false) / (1000/NEWTICRATE); - // how about this - return (TimeFunction(false) * NEWTICRATE) / 1000; + return TimeFunction(NEWTICRATE); } int I_GetTimeMicros(void) { - return TimeFunction(true); + return TimeFunction(1000000); } // From c9114867cc0b3d47a30eeab096042300531df920 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 2 May 2020 23:22:58 +0300 Subject: [PATCH 115/168] Dummy I_GetTimeMicros --- src/dummy/i_system.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 5c0f7eb99..4a657ed19 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -16,6 +16,11 @@ tic_t I_GetTime(void) return 0; } +int I_GetTimeMicros(void) +{ + return 0; +} + void I_Sleep(void){} void I_GetEvent(void){} From 38c74cecc04b4cc06158b337b4ce71f45a11984d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 May 2020 17:26:27 -0300 Subject: [PATCH 116/168] Avoid a crash --- src/y_inter.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index c3a80007b..8240ce0fb 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -323,7 +323,6 @@ void Y_IntermissionDrawer(void) if (rendermode == render_none) return; - if (!usebuffer) // Lactozilla: Renderer switching if (needpatchrecache) { @@ -364,11 +363,11 @@ void Y_IntermissionDrawer(void) { if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400) V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch); - else + else if (bgpatch) V_DrawScaledPatch(0, 0, 0, bgpatch); } } - else + else if (bgtile) V_DrawPatchFill(bgtile); LUAh_IntermissionHUD(); From d593e2e1bb9ff8614c49c69bc13bb1d3d50f924e Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 14 May 2020 23:10:00 +0100 Subject: [PATCH 117/168] Introducing Marathon Run. (I was going to call it Marathon Mode, but NiGHTS Mode being right next to it on the menu looked terrible.) Basically a dedicated Record Attack-like experience for speedrunning the game as a continuous chunk rather than ILs. Has several quality of life features. Benefits include: * An unambiguous real-time bar across the bottom of the screen, always displaying the current time, ticking up until you reach the ending. * Disable the console (pausing is still allowed, but the timer will still increment). * Automatically skip intermissions as if you're holding down the spin button. * Show centiseconds on HUD automatically, like record attack. * "Live Event Backups" - a category of run fit for major events like GDQ, where recovery from crashes or chokes makes for better entertainment. Essentially a modified SP savefile, down to using the same basic functions, but has its own filename and tweaked internal layout. * "spmarathon_start" MainCfg block parameter and "marathonnext" mapheader parameter, allowing for a customised flow (makes this fit for purpose for an eventual SUGOI port). * Disabling inter-level custom cutscenes by default with a menu option to toggle this (won't show up if the mod doesn't *have* any custom cutscenes), although either way ending cutscenes (vanilla or custom) remain intact since is time is called before them. * Won't show up if you have a mod that consists of only one level (determined by spmarathon_start's nextlevel; this won't trip if you manually set its marathonnext). * Unconditional gratitude on the evaluation screen, instead of a negging "Try again..." if you didn't get all the emeralds (which you may not have been aiming for). * Gorgeous new menu (no new assets required, unless you wanna give it a header later). Changes which were required for the above but affect other areas of the game include: * "useBlackRock" MainCFG block parameter, which can be used to disable the presence of the Black Rock or Egg Rock in both the Evaluation screen and the Marathon Run menu (for total conversions with different stories). * Disabling Continues in NiGHTS mode, to match the most common singleplayer experience post 2.2.4's release (is reverted if useContinues is set to true). * Hiding the exitmove "powerup" outside of multiplayer. (Okay, this isn't really related, I just saw this bug in action a lot while doing test runs and got annoyed enough to fix it here.) * The ability to use V_DrawPromptBack (in hardcode only at the moment, but) to draw in terms of pixels rather than rows of text, by providing negative instead of positive inputs). * A refactoring of redundant game saves smattered across the ending, credits, and evaluation - in addition to saving the game slightly earlier. * Minor m_menu.c touchups and refactorings here and there. Built using feedback from the official server's #speedruns channel, among other places. --- src/console.c | 2 +- src/d_main.c | 4 + src/dehacked.c | 54 ++++- src/djgppdos/i_video.c | 3 + src/doomdef.h | 1 + src/doomstat.h | 19 +- src/f_finale.c | 26 +-- src/g_game.c | 88 ++++++-- src/hardware/hw_draw.c | 6 +- src/lua_maplib.c | 2 + src/lua_script.c | 8 +- src/m_menu.c | 502 ++++++++++++++++++++++++++++++++++++++--- src/m_menu.h | 3 + src/p_saveg.c | 4 +- src/p_setup.c | 3 +- src/screen.c | 32 +++ src/screen.h | 1 + src/sdl/i_video.c | 3 + src/st_stuff.c | 4 +- src/v_video.c | 12 +- src/win32/win_vid.c | 3 + src/y_inter.c | 8 +- 22 files changed, 692 insertions(+), 96 deletions(-) diff --git a/src/console.c b/src/console.c index 0f1ccbd33..c99203e33 100644 --- a/src/console.c +++ b/src/console.c @@ -770,7 +770,7 @@ boolean CON_Responder(event_t *ev) // check for console toggle key if (ev->type != ev_console) { - if (modeattacking || metalrecording) + if (modeattacking || metalrecording || marathonmode) return false; if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1]) diff --git a/src/d_main.c b/src/d_main.c index 07e15aec4..dd25596e1 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -815,6 +815,7 @@ void D_StartTitle(void) // In case someone exits out at the same time they start a time attack run, // reset modeattacking modeattacking = ATTACKING_NONE; + marathonmode = 0; // empty maptol so mario/etc sounds don't play in sound test when they shouldn't maptol = 0; @@ -1131,6 +1132,7 @@ void D_SRB2Main(void) // default savegame strcpy(savegamename, SAVEGAMENAME"%u.ssg"); + strcpy(liveeventbackup,"liveevent.bkp"); // intentionally not ending with .ssg { const char *userhome = D_Home(); //Alam: path to home @@ -1159,6 +1161,7 @@ void D_SRB2Main(void) // can't use sprintf since there is %u in savegamename strcatbf(savegamename, srb2home, PATHSEP); + strcatbf(liveeventbackup, srb2home, PATHSEP); snprintf(luafiledir, sizeof luafiledir, "%s" PATHSEP "luafiles", srb2home); #else // DEFAULTDIR @@ -1171,6 +1174,7 @@ void D_SRB2Main(void) // can't use sprintf since there is %u in savegamename strcatbf(savegamename, userhome, PATHSEP); + strcatbf(liveeventbackup, userhome, PATHSEP); snprintf(luafiledir, sizeof luafiledir, "%s" PATHSEP "luafiles", userhome); #endif // DEFAULTDIR diff --git a/src/dehacked.c b/src/dehacked.c index a6c73e0b4..a6ef8dae7 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1578,6 +1578,22 @@ static void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->nextlevel = (INT16)i; } + else if (fastcmp(word, "MARATHONNEXT")) + { + if (fastcmp(word2, "TITLE")) i = 1100; + else if (fastcmp(word2, "EVALUATION")) i = 1101; + else if (fastcmp(word2, "CREDITS")) i = 1102; + else if (fastcmp(word2, "ENDING")) i = 1103; + else + // Support using the actual map name, + // i.e., MarathonNext = AB, MarathonNext = FZ, etc. + + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0') + i = M_MapNumber(word2[0], word2[1]); + + mapheaderinfo[num-1]->marathonnext = (INT16)i; + } else if (fastcmp(word, "TYPEOFLEVEL")) { if (i) // it's just a number @@ -3920,7 +3936,20 @@ static void readmaincfg(MYFILE *f) else value = get_number(word2); - spstage_start = (INT16)value; + spstage_start = spmarathon_start = (INT16)value; + } + else if (fastcmp(word, "SPMARATHON_START")) + { + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. + + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + value = M_MapNumber(word2[0], word2[1]); + else + value = get_number(word2); + + spmarathon_start = (INT16)value; } else if (fastcmp(word, "SSTAGE_START")) { @@ -4014,6 +4043,17 @@ static void readmaincfg(MYFILE *f) introtoplay = 128; introchanged = true; } + else if (fastcmp(word, "CREDITSCUTSCENE")) + { + creditscutscene = (UINT8)get_number(word2); + // range check, you morons. + if (creditscutscene > 128) + creditscutscene = 128; + } + else if (fastcmp(word, "USEBLACKROCK")) + { + useBlackRock = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y'); + } else if (fastcmp(word, "LOOPTITLE")) { looptitle = (value || word2[0] == 'T' || word2[0] == 'Y'); @@ -4115,13 +4155,6 @@ static void readmaincfg(MYFILE *f) titlescrollyspeed = get_number(word2); titlechanged = true; } - else if (fastcmp(word, "CREDITSCUTSCENE")) - { - creditscutscene = (UINT8)get_number(word2); - // range check, you morons. - if (creditscutscene > 128) - creditscutscene = 128; - } else if (fastcmp(word, "DISABLESPEEDADJUST")) { disableSpeedAdjust = (value || word2[0] == 'T' || word2[0] == 'Y'); @@ -9895,6 +9928,11 @@ struct { {"TC_BLINK",TC_BLINK}, {"TC_DASHMODE",TC_DASHMODE}, + // marathonmode flags + //{"MA_INIT",MA_INIT}, -- should never see this + {"MA_RUNNING",MA_RUNNING}, + {"MA_NOCUTSCENES",MA_NOCUTSCENES}, + {NULL,0} }; diff --git a/src/djgppdos/i_video.c b/src/djgppdos/i_video.c index f525b96ca..b3363a14e 100644 --- a/src/djgppdos/i_video.c +++ b/src/djgppdos/i_video.c @@ -101,6 +101,9 @@ void I_FinishUpdate (void) if (cv_showping.value && netgame && consoleplayer != serverplayer) SCR_DisplayLocalPing(); + if (marathonmode) + SCR_DisplayMarathonInfo(); + //blast it to the screen // this code sucks //memcpy(dascreen,screens[0],screenwidth*screenheight); diff --git a/src/doomdef.h b/src/doomdef.h index 6112881fb..d5f420e3e 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -459,6 +459,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG; // Things that used to be in dstrings.h #define SAVEGAMENAME "srb2sav" char savegamename[256]; +char liveeventbackup[256]; // m_misc.h #ifdef GETTEXT diff --git a/src/doomstat.h b/src/doomstat.h index 1ec03a86c..7ef4c7f32 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -45,7 +45,18 @@ extern INT32 curWeather; extern INT32 cursaveslot; //extern INT16 lastmapsaved; extern INT16 lastmaploaded; -extern boolean gamecomplete; +extern UINT8 gamecomplete; + +// Extra abilities/settings for skins (combinable stuff) +typedef enum +{ + MA_RUNNING = 1, // In action + MA_INIT = 1<<1, // Initialisation + MA_NOCUTSCENES = 1<<2 // No cutscenes +} marathonmode_t; + +extern marathonmode_t marathonmode; +extern tic_t marathontime; #define maxgameovers 13 extern UINT8 numgameovers; @@ -127,7 +138,7 @@ extern INT32 displayplayer; extern INT32 secondarydisplayplayer; // for splitscreen // Maps of special importance -extern INT16 spstage_start; +extern INT16 spstage_start, spmarathon_start; extern INT16 sstage_start, sstage_end, smpstage_start, smpstage_end; extern INT16 titlemap; @@ -289,6 +300,7 @@ typedef struct UINT8 actnum; ///< Act number or 0 for none. UINT32 typeoflevel; ///< Combination of typeoflevel flags. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. + INT16 marathonnext; ///< See nextlevel, but for Marathon mode. Necessary to support hub worlds ala SUGOI. char keywords[33]; ///< Keywords separated by space to search for. 32 characters. char musname[7]; ///< Music track to play. "" for no music. UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. @@ -575,11 +587,12 @@ extern UINT16 nightslinktics; extern UINT8 introtoplay; extern UINT8 creditscutscene; +extern UINT8 useBlackRock; extern UINT8 use1upSound; extern UINT8 maxXtraLife; // Max extra lives from rings extern UINT8 useContinues; -#define continuesInSession (!multiplayer && (useContinues || ultimatemode || !(cursaveslot > 0))) +#define continuesInSession (!multiplayer && (ultimatemode || (useContinues && !marathonmode) || (!modeattacking && !(cursaveslot > 0)))) extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations diff --git a/src/f_finale.c b/src/f_finale.c index 825f646b0..b7ff0f8f3 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1330,10 +1330,6 @@ void F_StartCredits(void) // Just in case they're open ... somehow M_ClearMenus(true); - // Save the second we enter the credits - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0) - G_SaveGame((UINT32)cursaveslot); - if (creditscutscene) { F_StartCustomCutscene(creditscutscene - 1, false, false); @@ -1529,12 +1525,6 @@ void F_StartGameEvaluation(void) // Just in case they're open ... somehow M_ClearMenus(true); - // Save the second we enter the evaluation - // We need to do this again! Remember, it's possible a mod designed skipped - // the credits sequence! - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0) - G_SaveGame((UINT32)cursaveslot); - goodending = (ALL7EMERALDS(emeralds)); gameaction = ga_nothing; @@ -1551,13 +1541,20 @@ void F_GameEvaluationDrawer(void) angle_t fa; INT32 eemeralds_cur; char patchname[7] = "CEMGx0"; - const char* endingtext = (goodending ? "CONGRATULATIONS!" : "TRY AGAIN..."); + const char* endingtext; + + if (marathonmode) + endingtext = "THANKS FOR THE RUN!"; + else if (goodending) + endingtext = "CONGRATULATIONS!"; + else + endingtext = "TRY AGAIN..."; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // Draw all the good crap here. - if (finalecount > 0) + if (finalecount > 0 && useBlackRock) { INT32 scale = FRACUNIT; patch_t *rockpat; @@ -1841,10 +1838,6 @@ void F_StartEnding(void) // Just in case they're open ... somehow M_ClearMenus(true); - // Save before the credits sequence. - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0) - G_SaveGame((UINT32)cursaveslot); - gameaction = ga_nothing; paused = false; CON_ToggleOff(); @@ -3959,6 +3952,7 @@ static void F_AdvanceToNextScene(void) animtimer = pictime = cutscenes[cutnum]->scene[scenenum].picduration[picnum]; } +// See also G_AfterIntermission, the only other place which handles intra-map/ending transitions void F_EndCutScene(void) { cutsceneover = true; // do this first, just in case G_EndGame or something wants to turn it back false later diff --git a/src/g_game.c b/src/g_game.c index 92d71fbae..5baa257d3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -82,7 +82,10 @@ INT32 curWeather = PRECIP_NONE; INT32 cursaveslot = 0; // Auto-save 1p savegame slot //INT16 lastmapsaved = 0; // Last map we auto-saved at INT16 lastmaploaded = 0; // Last map the game loaded -boolean gamecomplete = false; +UINT8 gamecomplete = 0; + +marathonmode_t marathonmode = 0; +tic_t marathontime = 0; UINT8 numgameovers = 0; // for startinglives balance SINT8 startinglivesbalance[maxgameovers+1] = {3, 5, 7, 9, 12, 15, 20, 25, 30, 40, 50, 75, 99, 0x7F}; @@ -118,7 +121,7 @@ UINT32 ssspheres; // old special stage INT16 lastmap; // last level you were at (returning from special stages) tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) -INT16 spstage_start; +INT16 spstage_start, spmarathon_start; INT16 sstage_start, sstage_end, smpstage_start, smpstage_end; INT16 titlemap = 0; @@ -223,6 +226,7 @@ UINT8 useContinues = 0; // Set to 1 to enable continues outside of no-save scena UINT8 introtoplay; UINT8 creditscutscene; +UINT8 useBlackRock = 1; // Emerald locations mobj_t *hunt1; @@ -769,6 +773,8 @@ void G_SetGameModified(boolean silent) // If in record attack recording, cancel it. if (modeattacking) M_EndModeAttackRun(); + else if (marathonmode) + Command_ExitGame_f(); } /** Builds an original game map name from a map number. @@ -3662,8 +3668,14 @@ static void G_DoCompleted(void) // nextmap is 0-based, unlike gamemap if (nextmapoverride != 0) nextmap = (INT16)(nextmapoverride-1); + else if (marathonmode && mapheaderinfo[gamemap-1]->marathonnext) + nextmap = (INT16)(mapheaderinfo[gamemap-1]->marathonnext-1); else + { nextmap = (INT16)(mapheaderinfo[gamemap-1]->nextlevel-1); + if (marathonmode && nextmap == spmarathon_start-1) + nextmap = 1100-1; // No infinite loop for you + } // Remember last map for when you come out of the special stage. if (!spec) @@ -3687,10 +3699,12 @@ static void G_DoCompleted(void) visitedmap[cm/8] |= (1<<(cm&7)); if (!mapheaderinfo[cm]) cm = -1; // guarantee error execution + else if (marathonmode && mapheaderinfo[cm]->marathonnext) + cm = (INT16)(mapheaderinfo[cm]->marathonnext-1); else cm = (INT16)(mapheaderinfo[cm]->nextlevel-1); - if (cm >= NUMMAPS || cm < 0) // out of range (either 1100-1102 or error) + if (cm >= NUMMAPS || cm < 0) // out of range (either 1100ish or error) { cm = nextmap; //Start the loop again so that the error checking below is executed. @@ -3759,6 +3773,25 @@ static void G_DoCompleted(void) if (nextmap < NUMMAPS && !mapheaderinfo[nextmap]) P_AllocMapHeader(nextmap); + // do this before going to the intermission or starting a custom cutscene, mostly for the sake of marathon mode but it also massively reduces redundant file save events in f_finale.c + if (nextmap >= 1100-1) + { + if (!gamecomplete) + gamecomplete = 2; // special temporary mode to prevent using SP level select in pause menu until the intermission is over without restricting it in every intermission + if (cursaveslot > 0) + { + if (marathonmode) + { + // don't keep a backup around when the run is done! + if (FIL_FileExists(liveeventbackup)) + remove(liveeventbackup); + cursaveslot = 0; + } + else if ((!modifiedgame || savemoddata) && !(netgame || multiplayer)) + G_SaveGame((UINT32)cursaveslot); + } + } + if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed)) { G_UpdateVisited(); @@ -3772,6 +3805,7 @@ static void G_DoCompleted(void) } } +// See also F_EndCutscene, the only other place which handles intra-map/ending transitions void G_AfterIntermission(void) { Y_CleanupScreenBuffer(); @@ -3782,9 +3816,12 @@ void G_AfterIntermission(void) return; } + if (gamecomplete == 2) // special temporary mode to prevent using SP level select in pause menu until the intermission is over without restricting it in every intermission + gamecomplete = 1; + HU_ClearCEcho(); - if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene. + if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1 && !(marathonmode & MA_NOCUTSCENES)) // Start a custom cutscene. F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); else { @@ -3925,7 +3962,7 @@ void G_EndGame(void) void G_LoadGameSettings(void) { // defaults - spstage_start = 1; + spstage_start = spmarathon_start = 1; sstage_start = 50; sstage_end = 56; // 7 special stages in vanilla SRB2 sstage_end++; // plus one weirdo @@ -4245,7 +4282,10 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) startonmapnum = mapoverride; #endif - sprintf(savename, savegamename, slot); + if (marathonmode) + strcpy(savename, liveeventbackup); + else + sprintf(savename, savegamename, slot); length = FIL_ReadFile(savename, &savebuffer); if (!length) @@ -4257,7 +4297,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) save_p = savebuffer; memset(vcheck, 0, sizeof (vcheck)); - sprintf(vcheck, "version %d", VERSION); + sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION); if (strcmp((const char *)save_p, (const char *)vcheck)) { #ifdef SAVEGAME_OTHERVERSIONS @@ -4297,6 +4337,11 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) memset(&savedata, 0, sizeof(savedata)); return; } + if (marathonmode) + { + marathontime = READUINT32(save_p); + marathonmode |= READUINT8(save_p); + } // done Z_Free(savebuffer); @@ -4325,13 +4370,12 @@ void G_SaveGame(UINT32 slot) char savename[256] = ""; const char *backup; - sprintf(savename, savegamename, slot); + if (marathonmode) + strcpy(savename, liveeventbackup); + else + sprintf(savename, savegamename, slot); backup = va("%s",savename); - // save during evaluation or credits? game's over, folks! - if (gamestate == GS_ENDING || gamestate == GS_CREDITS || gamestate == GS_EVALUATION) - gamecomplete = true; - gameaction = ga_nothing; { char name[VERSIONSIZE]; @@ -4345,10 +4389,15 @@ void G_SaveGame(UINT32 slot) } memset(name, 0, sizeof (name)); - sprintf(name, "version %d", VERSION); + sprintf(name, (marathonmode ? "back-up %d" : "version %d"), VERSION); WRITEMEM(save_p, name, VERSIONSIZE); P_SaveGame(); + if (marathonmode) + { + WRITEUINT32(save_p, marathontime); + WRITEUINT8(save_p, (marathonmode & ~MA_INIT)); + } length = save_p - savebuffer; saved = FIL_WriteFile(backup, savebuffer, length); @@ -4361,7 +4410,7 @@ void G_SaveGame(UINT32 slot) if (cv_debug && saved) CONS_Printf(M_GetText("Game saved.\n")); else if (!saved) - CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, savegamename); + CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename)); } #define BADSAVE goto cleanup; @@ -4374,7 +4423,10 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives) char savename[255]; const char *backup; - sprintf(savename, savegamename, slot); + if (marathonmode) + strcpy(savename, liveeventbackup); + else + sprintf(savename, savegamename, slot); backup = va("%s",savename); length = FIL_ReadFile(savename, &savebuffer); @@ -4393,7 +4445,7 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives) save_p = savebuffer; // Version check memset(vcheck, 0, sizeof (vcheck)); - sprintf(vcheck, "version %d", VERSION); + sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION); if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE save_p += VERSIONSIZE; @@ -4460,7 +4512,7 @@ cleanup: if (cv_debug && saved) CONS_Printf(M_GetText("Game saved.\n")); else if (!saved) - CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, savegamename); + CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename)); Z_Free(savebuffer); save_p = savebuffer = NULL; @@ -4598,7 +4650,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean automapactive = false; imcontinuing = false; - if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking) // Start a custom cutscene. + if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking && !(marathonmode & MA_NOCUTSCENES)) // Start a custom cutscene. F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer); else G_DoLoadLevel(resetplayer); diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index d01331765..6a938a142 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -904,7 +904,11 @@ void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight) { FOutVector v[4]; FSurfaceInfo Surf; - INT32 height = (boxheight * 4) + (boxheight/2)*5; // 4 lines of space plus gaps between and some leeway + INT32 height; + if (boxheight < 0) + height = -boxheight; + else + height = (boxheight * 4) + (boxheight/2)*5; // 4 lines of space plus gaps between and some leeway // setup some neat-o translucency effect diff --git a/src/lua_maplib.c b/src/lua_maplib.c index ece42b8d3..a90b83c99 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2009,6 +2009,8 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->typeoflevel); else if (fastcmp(field,"nextlevel")) lua_pushinteger(L, header->nextlevel); + else if (fastcmp(field,"marathonnext")) + lua_pushinteger(L, header->marathonnext); else if (fastcmp(field,"keywords")) lua_pushstring(L, header->keywords); else if (fastcmp(field,"musname")) diff --git a/src/lua_script.c b/src/lua_script.c index d2069e8a7..2007b9ad4 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -115,7 +115,10 @@ int LUA_PushGlobals(lua_State *L, const char *word) lua_pushboolean(L, splitscreen); return 1; } else if (fastcmp(word,"gamecomplete")) { - lua_pushboolean(L, gamecomplete); + lua_pushboolean(L, (gamecomplete != 0)); + return 1; + } else if (fastcmp(word,"marathonmode")) { + lua_pushinteger(L, marathonmode); return 1; } else if (fastcmp(word,"devparm")) { lua_pushboolean(L, devparm); @@ -145,6 +148,9 @@ int LUA_PushGlobals(lua_State *L, const char *word) } else if (fastcmp(word,"spstage_start")) { lua_pushinteger(L, spstage_start); return 1; + } else if (fastcmp(word,"spmarathon_start")) { + lua_pushinteger(L, spmarathon_start); + return 1; } else if (fastcmp(word,"sstage_start")) { lua_pushinteger(L, sstage_start); return 1; diff --git a/src/m_menu.c b/src/m_menu.c index 2977b432f..7a17fe302 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -182,6 +182,7 @@ static tic_t keydown = 0; static void M_GoBack(INT32 choice); static void M_StopMessage(INT32 choice); +static boolean stopstopmessage = false; #ifndef NONET static void M_HandleServerPage(INT32 choice); @@ -252,6 +253,7 @@ static void M_ConfirmTeamScramble(INT32 choice); static void M_ConfirmTeamChange(INT32 choice); static void M_SecretsMenu(INT32 choice); static void M_SetupChoosePlayer(INT32 choice); +static UINT8 M_SetupChoosePlayerDirect(INT32 choice); static void M_QuitSRB2(INT32 choice); menu_t SP_MainDef, OP_MainDef; menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef; @@ -272,9 +274,14 @@ static void M_ModeAttackEndGame(INT32 choice); static void M_SetGuestReplay(INT32 choice); static void M_HandleChoosePlayerMenu(INT32 choice); static void M_ChoosePlayer(INT32 choice); +static void M_MarathonLiveEventBackup(INT32 choice); +static void M_Marathon(INT32 choice); +static void M_HandleMarathonChoosePlayer(INT32 choice); +static void M_StartMarathon(INT32 choice); menu_t SP_LevelStatsDef; static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; static menu_t SP_NightsAttackDef, SP_NightsReplayDef, SP_NightsGuestReplayDef, SP_NightsGhostDef; +static menu_t SP_MarathonDef; // Multiplayer static void M_SetupMultiPlayer(INT32 choice); @@ -354,6 +361,7 @@ static void M_DrawLoad(void); static void M_DrawLevelStats(void); static void M_DrawTimeAttackMenu(void); static void M_DrawNightsAttackMenu(void); +static void M_DrawMarathon(void); static void M_DrawSetupChoosePlayerMenu(void); static void M_DrawControlsDefMenu(void); static void M_DrawCameraOptionsMenu(void); @@ -476,6 +484,11 @@ static consvar_t cv_dummylives = {"dummylives", "0", CV_HIDEN, liveslimit_cons_t static consvar_t cv_dummycontinues = {"dummycontinues", "0", CV_HIDEN, contlimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dummymares_cons_t, Dummymares_OnChange, 0, NULL, NULL, 0, 0, NULL}; +CV_PossibleValue_t marathon_cons_t[] = {{0, "Standard"}, {1, "Live Event Backup"}, {2, "Ultimate"}, {0, NULL}}; + +consvar_t cv_dummymarathon = {"dummymarathon", "Standard", CV_HIDEN, marathon_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_dummycutscenes = {"dummycutscenes", "Off", CV_HIDEN, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + // ========================================================================== // ORGANIZATION START. // ========================================================================== @@ -746,10 +759,11 @@ static menuitem_t SR_EmblemHintMenu[] = // Single Player Main static menuitem_t SP_MainMenu[] = { - {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 84}, - {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 92}, - {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 100}, - {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 108}, + {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 76}, + {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 84}, + {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 92}, + {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 100}, + {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Marathon Run", M_Marathon, 108}, {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 116} }; @@ -759,6 +773,7 @@ enum sprecordattack, spnightsmode, sptutorial, + spmarathon, spstatistics }; @@ -901,6 +916,23 @@ enum nastart }; +// Marathon +static menuitem_t SP_MarathonMenu[] = +{ + {IT_STRING|IT_KEYHANDLER, NULL, "Character", M_HandleMarathonChoosePlayer, 100}, + {IT_STRING|IT_CVAR, NULL, "Category", &cv_dummymarathon, 110}, + {IT_STRING|IT_CVAR, NULL, "Cutscenes", &cv_dummycutscenes, 120}, + {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartMarathon, 130}, +}; + +enum +{ + marathonplayer, + marathonultimate, + marathoncutscenes, + marathonstart +}; + // Statistics static menuitem_t SP_LevelStatsMenu[] = { @@ -1908,6 +1940,18 @@ static menu_t SP_NightsGhostDef = NULL }; +static menu_t SP_MarathonDef = +{ + MTREE2(MN_SP_MAIN, MN_SP_MARATHON), + "M_ATTACK", // temporary + sizeof(SP_MarathonMenu)/sizeof(menuitem_t), + &MainDef, // Doesn't matter. + SP_MarathonMenu, + M_DrawMarathon, + 32, 40, + 0, + NULL +}; menu_t SP_PlayerDef = { @@ -2524,6 +2568,8 @@ void M_InitMenuPresTables(void) strncpy(menupres[i].musname, "_recat", 7); else if (i == MN_SP_NIGHTSATTACK) strncpy(menupres[i].musname, "_nitat", 7); + else if (i == MN_SP_MARATHON) + strncpy(menupres[i].musname, "spec8", 6); else if (i == MN_SP_PLAYER || i == MN_SR_PLAYER) strncpy(menupres[i].musname, "_chsel", 7); else if (i == MN_SR_SOUNDTEST) @@ -3018,7 +3064,7 @@ static void M_GoBack(INT32 choice) netgame = multiplayer = false; } - if ((currentMenu->prevMenu == &MainDef) && (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef)) + if ((currentMenu->prevMenu == &MainDef) && (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef || currentMenu == &SP_MarathonDef)) { // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. @@ -3403,11 +3449,14 @@ boolean M_Responder(event_t *ev) { if (currentMenu->menuitems[itemOn].alphaKey != MM_EVENTHANDLER) { - if (ch == ' ' || ch == 'n' || ch == 'y' || ch == KEY_ESCAPE || ch == KEY_ENTER) + if (ch == ' ' || ch == 'n' || ch == 'y' || ch == KEY_ESCAPE || ch == KEY_ENTER || ch == KEY_DEL) { if (routine) routine(ch); - M_StopMessage(0); + if (stopstopmessage) + stopstopmessage = false; + else + M_StopMessage(0); noFurtherInput = true; return true; } @@ -3657,7 +3706,7 @@ void M_StartControlPanel(void) { INT32 numlives = 2; - SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA) && !marathonmode) ? (IT_STRING | IT_CALL) : (IT_DISABLED); if (&players[consoleplayer]) { @@ -3675,7 +3724,7 @@ void M_StartControlPanel(void) } // We can always use level select though. :33 - SPauseMenu[spause_levelselect].status = (gamecomplete) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + SPauseMenu[spause_levelselect].status = (gamecomplete == 1) ? (IT_STRING | IT_CALL) : (IT_DISABLED); // And emblem hints. SPauseMenu[spause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); @@ -3859,6 +3908,8 @@ void M_Init(void) CV_RegisterVar(&cv_dummylives); CV_RegisterVar(&cv_dummycontinues); CV_RegisterVar(&cv_dummymares); + CV_RegisterVar(&cv_dummymarathon); + CV_RegisterVar(&cv_dummycutscenes); quitmsg[QUITMSG] = M_GetText("Eggman's tied explosives\nto your girlfriend, and\nwill activate them if\nyou press the 'Y' key!\nPress 'N' to save her!\n\n(Press 'Y' to quit)"); quitmsg[QUITMSG1] = M_GetText("What would Tails say if\nhe saw you quitting the game?\n\n(Press 'Y' to quit)"); @@ -6321,8 +6372,8 @@ static char *M_AddonsHeaderPath(void) static void M_AddonsClearName(INT32 choice) { + (void)choice; CLEARNAME; - M_StopMessage(choice); } // returns whether to do message draw @@ -6354,7 +6405,7 @@ static boolean M_AddonsRefresh(void) if (message) { - M_StartMessage(message,M_AddonsClearName,MM_EVENTHANDLER); + M_StartMessage(message,M_AddonsClearName,MM_NOTHING); return true; } @@ -8011,6 +8062,15 @@ static void M_SinglePlayerMenu(INT32 choice) SP_MainMenu[sptutorial].status = tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; + // If the FIRST stage immediately leads to the ending, or itself (which gets converted to the title screen in G_DoCompleted for marathonmode only), there's no point in having this option on the menu. You should use Record Attack in that circumstance, although if marathonnext is set this behaviour can be overridden if you make some weird mod that requires multiple playthroughs of the same map in sequence and has some in-level mechanism to break the cycle. + if (mapheaderinfo[spmarathon_start-1] + && !mapheaderinfo[spmarathon_start-1]->marathonnext + && (mapheaderinfo[spmarathon_start-1]->nextlevel == spmarathon_start + || mapheaderinfo[spmarathon_start-1]->nextlevel >= 1100)) + SP_MainMenu[spmarathon].status = IT_NOTHING|IT_DISABLED; + else + SP_MainMenu[spmarathon].status = IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED; + M_SetupNextMenu(&SP_MainDef); } @@ -8101,7 +8161,7 @@ static void M_StartTutorial(INT32 choice) emeralds = 0; memset(&luabanks, 0, sizeof(luabanks)); M_ClearMenus(true); - gamecomplete = false; + gamecomplete = 0; cursaveslot = 0; G_DeferedInitNew(false, G_BuildMapName(tutorialmap), 0, false, false); } @@ -8864,7 +8924,7 @@ static void M_CacheCharacterSelect(void) { INT32 i, skinnum; - for (i = 0; i < 32; i++) + for (i = 0; i < MAXSKINS; i++) { if (!description[i].used) continue; @@ -8876,7 +8936,7 @@ static void M_CacheCharacterSelect(void) } } -static void M_SetupChoosePlayer(INT32 choice) +static UINT8 M_SetupChoosePlayerDirect(INT32 choice) { INT32 skinnum; UINT8 i; @@ -8887,7 +8947,7 @@ static void M_SetupChoosePlayer(INT32 choice) if (!mapheaderinfo[startmap-1] || mapheaderinfo[startmap-1]->forcecharacter[0] == '\0') { - for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks. + for (i = 0; i < MAXSKINS; i++) // Handle charsels, availability, and unlocks. { if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it. { @@ -8895,7 +8955,7 @@ static void M_SetupChoosePlayer(INT32 choice) if (and) { char firstskin[SKINNAMESIZE+1]; - if (mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS) // skip tagteam characters for NiGHTS levels + if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS) // skip tagteam characters for NiGHTS levels continue; strncpy(firstskin, description[i].skinname, (and - description[i].skinname)); firstskin[(and - description[i].skinname)] = '\0'; @@ -8932,14 +8992,36 @@ static void M_SetupChoosePlayer(INT32 choice) if (firstvalid == lastvalid) // We're being forced into a specific character, so might as well just skip it. { - M_ChoosePlayer(firstvalid); - return; + return firstvalid; } // One last bit of order we can't do in the iteration above. description[firstvalid].prev = lastvalid; description[lastvalid].next = firstvalid; + if (!allowed) + { + char_on = firstvalid; + if (startchar > 0 && startchar < MAXSKINS) + { + INT16 workchar = startchar; + while (workchar--) + char_on = description[char_on].next; + } + } + + return MAXSKINS; +} + +static void M_SetupChoosePlayer(INT32 choice) +{ + UINT8 skinset = M_SetupChoosePlayerDirect(choice); + if (skinset != MAXSKINS) + { + M_ChoosePlayer(skinset); + return; + } + M_ChangeMenuMusic("_chsel", true); /* the menus suck -James */ @@ -8954,16 +9036,6 @@ static void M_SetupChoosePlayer(INT32 choice) SP_PlayerDef.prevMenu = currentMenu; M_SetupNextMenu(&SP_PlayerDef); - if (!allowed) - { - char_on = firstvalid; - if (startchar > 0 && startchar < 32) - { - INT16 workchar = startchar; - while (workchar--) - char_on = description[char_on].next; - } - } // finish scrolling the menu char_scroll = 0; @@ -9022,6 +9094,10 @@ static void M_HandleChoosePlayerMenu(INT32 choice) case KEY_ENTER: S_StartSound(NULL, sfx_menu1); + char_scroll = 0; // finish scrolling the menu + M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout + // Is this a hack? + charseltimer = 0; M_ChoosePlayer(char_on); break; @@ -9261,7 +9337,7 @@ static void M_DrawSetupChoosePlayerMenu(void) // Chose the player you want to use Tails 03-02-2002 static void M_ChoosePlayer(INT32 choice) { - boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); + boolean ultmode = (currentMenu == &SP_MarathonDef) ? (cv_dummymarathon.value == 2) : (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); UINT8 skinnum; // skip this if forcecharacter or no characters available @@ -9273,11 +9349,6 @@ static void M_ChoosePlayer(INT32 choice) // M_SetupChoosePlayer didn't call us directly, that means we've been properly set up. else { - char_scroll = 0; // finish scrolling the menu - M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout - // Is this a hack? - charseltimer = 0; - skinnum = description[choice].skinnum[0]; if ((botingame = (description[choice].skinnum[1] != -1))) { @@ -9291,11 +9362,11 @@ static void M_ChoosePlayer(INT32 choice) M_ClearMenus(true); - if (startmap != spstage_start) + if (!marathonmode && startmap != spstage_start) cursaveslot = 0; //lastmapsaved = 0; - gamecomplete = false; + gamecomplete = 0; G_DeferedInitNew(ultmode, G_BuildMapName(startmap), skinnum, false, fromlevelselect); COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this @@ -10294,6 +10365,364 @@ static void M_ModeAttackEndGame(INT32 choice) Nextmap_OnChange(); } +static void M_MarathonLiveEventBackup(INT32 choice) +{ + if (choice == 'y' || choice == KEY_ENTER) + { + marathonmode = MA_INIT; + G_LoadGame(MARATHONSLOT, 0); + cursaveslot = MARATHONSLOT; + if (!(marathonmode & MA_RUNNING)) + marathonmode = 0; + return; + } + else if (choice == KEY_DEL) + { + M_StopMessage(0); + if (FIL_FileExists(liveeventbackup)) // just in case someone deleted it while we weren't looking. + remove(liveeventbackup); + BwehHehHe(); + M_StartMessage("Live event backup erased.\n",M_Marathon,MM_NOTHING); + stopstopmessage = true; + return; + } + + M_Marathon(-1); +} + +// Going to Marathon menu... +static void M_Marathon(INT32 choice) +{ + UINT8 skinset; + INT32 mapnum = 0; + + if (choice != -1 && FIL_FileExists(liveeventbackup)) + { + M_StartMessage(\ + "\x82Live event backup detected.\n\x80\ + Do you want to resurrect the last run?\n\ + (Fs in chat if we crashed on stream.)\n\ + \n\ + Press 'Y' or 'Enter' to resume,\n\ + 'Del' to delete, or any other\n\ + key to continue to Marathon Run.",M_MarathonLiveEventBackup,MM_YESNO); + return; + } + + fromlevelselect = false; + + startmap = spmarathon_start; + CV_SetValue(&cv_newgametype, GT_COOP); // Graue 09-08-2004 + + skinset = M_SetupChoosePlayerDirect(-1); + + SP_MarathonMenu[marathonplayer].status = (skinset == MAXSKINS) ? IT_KEYHANDLER|IT_STRING : IT_NOTHING|IT_DISABLED; + + while (mapnum < NUMMAPS) + { + if (mapheaderinfo[mapnum]) + { + if (mapheaderinfo[mapnum]->cutscenenum || mapheaderinfo[mapnum]->precutscenenum) + break; + } + mapnum++; + } + + SP_MarathonMenu[marathoncutscenes].status = (mapnum < NUMMAPS) ? IT_CVAR |IT_STRING : IT_NOTHING|IT_DISABLED; + + M_ChangeMenuMusic("spec8", true); + + SP_MarathonDef.prevMenu = &MainDef; + G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching + titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please + M_SetupNextMenu(&SP_MarathonDef); + itemOn = marathonstart; // "Start" is selected. + recatkdrawtimer = 50-8; + char_scroll = 0; +} + +static void M_HandleMarathonChoosePlayer(INT32 choice) +{ + INT32 selectval; + + if (keydown > 1) + return; + + switch (choice) + { + case KEY_DOWNARROW: + M_NextOpt(); + break; + case KEY_UPARROW: + M_PrevOpt(); + break; + + case KEY_LEFTARROW: + if ((selectval = description[char_on].prev) == char_on) + return; + char_on = selectval; + break; + case KEY_RIGHTARROW: + if ((selectval = description[char_on].next) == char_on) + return; + char_on = selectval; + break; + + case KEY_ESCAPE: + noFurtherInput = true; + M_GoBack(0); + return; + + default: + return; + } + S_StartSound(NULL, sfx_menu1); +} + +static void M_StartMarathon(INT32 choice) +{ + (void)choice; + marathontime = 0; + marathonmode = MA_RUNNING|MA_INIT; + if (cv_dummymarathon.value == 1) + cursaveslot = MARATHONSLOT; + if (!cv_dummycutscenes.value) + marathonmode |= MA_NOCUTSCENES; + M_ChoosePlayer(char_on); +} + +// Drawing function for Marathon menu +void M_DrawMarathon(void) +{ + INT32 i, x, y, cursory = 0, cnt, soffset = 0, w; + UINT16 dispstatus; + consvar_t *cv; + const char *cvstring; + char *work; + angle_t fa; + INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy), xspan = (vid.width/dupz), yspan = (vid.height/dupz), diffx = (xspan - BASEVIDWIDTH)/2, diffy = (yspan - BASEVIDHEIGHT)/2, maxy = BASEVIDHEIGHT + diffy; + + // lactozilla: the renderer changed so recache patches + if (needpatchrecache) + M_CacheCharacterSelect(); + + curbgxspeed = 0; + curbgyspeed = 18; + + M_ChangeMenuMusic("spec8", true); // Eww, but needed for when user hits escape during demo playback + + V_DrawFill(-diffx, -diffy, diffx+(BASEVIDWIDTH-190)/2, yspan, 158); + V_DrawFill((BASEVIDWIDTH-190)/2, -diffy, 190, yspan, 31); + V_DrawFill((BASEVIDWIDTH+190)/2, -diffy, diffx+(BASEVIDWIDTH-190)/2, yspan, 158); + //M_DrawRecordAttackForeground(); + if (curfadevalue) + V_DrawFadeScreen(0xFF00, curfadevalue); + + x = (((BASEVIDWIDTH-82)/2)+11)<>ANGLETOFINESHIFT) & FINEMASK; + y -= (10*FINECOSINE(fa)); + + recatkdrawtimer++; + + soffset = cnt = (recatkdrawtimer%50); + if (!useBlackRock) + { + if (cnt > 8) + cnt = 8; + V_DrawFixedPatch(x+(6< 8) + { + cnt = 8; + V_DrawFixedPatch(x, y, FRACUNIT, V_TRANSLUCENT, W_CachePatchName("ENDEGRK5", PU_PATCH), NULL); + } + else + { + V_DrawFixedPatch(x, y, FRACUNIT, cnt<= 160) + col = 253; + V_DrawFill(((BASEVIDWIDTH-190)/2)-cursory-w, -diffy, w, yspan, col); + V_DrawFill(((BASEVIDWIDTH+190)/2)+cursory, -diffy, w, yspan, col); + cursory += w; + w *= 2; + } + } + + w = char_scroll + (((8-cnt)*(8-cnt))<<(FRACBITS-5)); + if (soffset == 50-1) + w += FRACUNIT/2; + + { + patch_t *fg = W_CachePatchName("RECATKFG", PU_PATCH); + INT32 trans = V_60TRANS+((cnt&~3)<<(V_ALPHASHIFT-2)); + INT32 height = (SHORT(fg->height)/2); + char patchname[7] = "CEMGx0"; + + dupz = (w*7)/6; //(w*42*120)/(360*6); -- I don't know why this works but I'm not going to complain. + dupz = ((dupz>>FRACBITS) % height); + y = height/2; + while (y+dupz >= -diffy) + y -= height; + while (y-2-dupz < maxy) + { + V_DrawFixedPatch(((BASEVIDWIDTH-190)<<(FRACBITS-1)), (y-2-dupz)<>ANGLETOFINESHIFT) & FINEMASK; + x = (BASEVIDWIDTH<<(FRACBITS-1)) + (60*FINESINE(fa)); + y = ((BASEVIDHEIGHT+16-20)<<(FRACBITS-1)) - (60*FINECOSINE(fa)); + w += (360<>FRACBITS) % height); + y = dupz+(height/4); + x = 105+dupz; + while (y >= -diffy) + { + x -= height; + y -= height; + } + while (y-dupz < maxy && x < (xspan/2)) + { + V_DrawFill((BASEVIDWIDTH/2)-x-height, -diffy, height, diffy+y+height, 153); + V_DrawFill((BASEVIDWIDTH/2)+x, (maxy-y)-height, height, height+y, 153); + y += height; + x += height; + } + } + + if (!soffset) + { + char_scroll += (360<= 360< (10*TICRATE)) + recatkdrawtimer -= (10*TICRATE); + } + + //M_DrawMenuTitle(); + + // draw menu (everything else goes on top of it) + // Sadly we can't just use generic mode menus because we need some extra hacks + x = currentMenu->x; + y = currentMenu->y; + + dispstatus = (currentMenu->menuitems[marathonplayer].status & IT_DISPLAY); + if (dispstatus == IT_STRING || dispstatus == IT_WHITESTRING) + { + soffset = 68; + if (description[char_on].charpic->width >= 256) + V_DrawTinyScaledPatch(224, 120, 0, description[char_on].charpic); + else + V_DrawSmallScaledPatch(224, 120, 0, description[char_on].charpic); + } + else + soffset = 0; + + for (i = 0; i < currentMenu->numitems; ++i) + { + dispstatus = (currentMenu->menuitems[i].status & IT_DISPLAY); + if (dispstatus != IT_STRING && dispstatus != IT_WHITESTRING) + continue; + + y = currentMenu->y+currentMenu->menuitems[i].alphaKey; + if (i == itemOn) + cursory = y; + + V_DrawString(x, y, (dispstatus == IT_WHITESTRING) ? V_YELLOWMAP : 0 , currentMenu->menuitems[i].text); + + cv = NULL; + cvstring = NULL; + work = NULL; + if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_CVAR) + { + cv = (consvar_t *)currentMenu->menuitems[i].itemaction; + cvstring = cv->string; + } + else if (i == marathonplayer) + { + if (description[char_on].displayname[0]) + { + work = Z_StrDup(description[char_on].displayname); + cnt = 0; + while (work[cnt]) + { + if (work[cnt] == '\n') + work[cnt] = ' '; + cnt++; + } + cvstring = work; + } + else + cvstring = description[char_on].skinname; + } + + // Cvar specific handling + if (cvstring) + { + INT32 flags = V_YELLOWMAP; + if (cv == &cv_dummymarathon && cv->value == 2) // ultimate_selectable + flags = V_REDMAP; + + // Should see nothing but strings + if (cv == &cv_dummymarathon && cv->value == 1) + { + w = V_ThinStringWidth(cvstring, 0); + V_DrawThinString(BASEVIDWIDTH - x - soffset - w, y+1, flags, cvstring); + } + else + { + w = V_StringWidth(cvstring, 0); + V_DrawString(BASEVIDWIDTH - x - soffset - w, y, flags, cvstring); + } + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - w - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } + if (work) + Z_Free(work); + } + } + + // DRAW THE SKULL CURSOR + V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_PATCH)); + V_DrawString(currentMenu->x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text); + + // Draw press ESC to exit string on main record attack menu + V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit")); +} + // ======== // END GAME // ======== @@ -12578,6 +13007,7 @@ void M_QuitResponse(INT32 ch) if (!(netgame || cv_debug)) { S_ResetCaptions(); + marathonmode = 0; mrand = M_RandomKey(sizeof(quitsounds)/sizeof(INT32)); if (quitsounds[mrand]) S_StartSound(NULL, quitsounds[mrand]); diff --git a/src/m_menu.h b/src/m_menu.h index 565b98945..c04ab5ab7 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -61,6 +61,8 @@ typedef enum MN_SP_NIGHTS_REPLAY, MN_SP_NIGHTS_GHOST, + MN_SP_MARATHON, + // Multiplayer MN_MP_MAIN, MN_MP_SPLITSCREEN, // SplitServer @@ -419,6 +421,7 @@ extern INT16 char_on, startchar; #define MAXSAVEGAMES 31 #define NOSAVESLOT 0 //slot where Play Without Saving appears +#define MARATHONSLOT 420 // just has to be nonzero, but let's use one that'll show up as an obvious error if something goes wrong while not using our existing saves #define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he diff --git a/src/p_saveg.c b/src/p_saveg.c index 34bd3724b..77a44dc94 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3807,10 +3807,10 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride) if (mapoverride != 0) { gamemap = mapoverride; - gamecomplete = true; + gamecomplete = 1; } else - gamecomplete = false; + gamecomplete = 0; // gamemap changed; we assume that its map header is always valid, // so make it so diff --git a/src/p_setup.c b/src/p_setup.c index b4a5f2c3c..46296f789 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -217,6 +217,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->actnum = 0; mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->nextlevel = (INT16)(i + 1); + mapheaderinfo[num]->marathonnext = 0; mapheaderinfo[num]->startrings = 0; mapheaderinfo[num]->sstimer = 90; mapheaderinfo[num]->ssspheres = 1; @@ -3181,7 +3182,7 @@ static boolean CanSaveLevel(INT32 mapnum) // Any levels that have the savegame flag can save normally. // If the game is complete for this save slot, then any level can save! // On the other side of the spectrum, if lastmaploaded is 0, then the save file has only just been created and needs to save ASAP! - return (mapheaderinfo[mapnum-1]->levelflags & LF_SAVEGAME || gamecomplete || !lastmaploaded); + return (mapheaderinfo[mapnum-1]->levelflags & LF_SAVEGAME || (gamecomplete != 0) || marathonmode || !lastmaploaded); } static void P_RunSpecialStageWipe(void) diff --git a/src/screen.c b/src/screen.c index e01d1a81a..44d98f024 100644 --- a/src/screen.c +++ b/src/screen.c @@ -622,3 +622,35 @@ void SCR_ClosedCaptions(void) va("%c [%s]", dot, (closedcaptions[i].s->caption[0] ? closedcaptions[i].s->caption : closedcaptions[i].s->name))); } } + +void SCR_DisplayMarathonInfo(void) +{ + INT32 flags = V_SNAPTOBOTTOM; + static tic_t entertic, oldentertics = 0; + const char *str; +#if 0 // eh, this probably isn't going to be a problem + if (((signed)marathontime) < 0) + { + flags |= V_REDMAP; + str = "No waiting out the clock to submit a bogus time."; + } + else +#endif + { + entertic = I_GetTime(); + if (gamecomplete) + flags |= V_YELLOWMAP; + else if (marathonmode & MA_INIT) + marathonmode &= ~MA_INIT; + else + marathontime += entertic - oldentertics; + str = va("%i:%02i:%02i.%02i", + G_TicsToHours(marathontime), + G_TicsToMinutes(marathontime, false), + G_TicsToSeconds(marathontime), + G_TicsToCentiseconds(marathontime)); + oldentertics = entertic; + } + V_DrawPromptBack(-8, cons_backcolor.value); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-8, flags, str); +} diff --git a/src/screen.h b/src/screen.h index ddbd499bb..91ec175f4 100644 --- a/src/screen.h +++ b/src/screen.h @@ -206,5 +206,6 @@ FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height); void SCR_DisplayTicRate(void); void SCR_ClosedCaptions(void); void SCR_DisplayLocalPing(void); +void SCR_DisplayMarathonInfo(void); #undef DNWH #endif //__SCREEN_H__ diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index ec7bfc1c4..f35769e3c 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1214,6 +1214,9 @@ void I_FinishUpdate(void) if (cv_showping.value && netgame && consoleplayer != serverplayer) SCR_DisplayLocalPing(); + if (marathonmode) + SCR_DisplayMarathonInfo(); + if (rendermode == render_soft && screens[0]) { SDL_Rect rect; diff --git a/src/st_stuff.c b/src/st_stuff.c index b6226d085..12dcae360 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -763,7 +763,7 @@ static void ST_drawTime(void) ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds - if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! + if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking || marathonmode) { ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod, V_HUDTRANS); // Period ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2, V_HUDTRANS); // Tics @@ -1445,7 +1445,7 @@ static void ST_drawPowerupHUD(void) // --------- // Let's have a power-like icon to represent finishing the level! - if (stplyr->pflags & PF_FINISHED && cv_exitmove.value) + if (stplyr->pflags & PF_FINISHED && cv_exitmove.value && multiplayer) { finishoffs[q] = ICONSEP; V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, fnshico); diff --git a/src/v_video.c b/src/v_video.c index 3ce0e79f5..142e85c68 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1870,7 +1870,10 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color) if (color >= 256 && color < 512) { - boxheight = ((boxheight * 4) + (boxheight/2)*5); + if (boxheight < 0) + boxheight = -boxheight; + else // 4 lines of space plus gaps between and some leeway + boxheight = ((boxheight * 4) + (boxheight/2)*5); V_DrawFill((BASEVIDWIDTH-(vid.width/vid.dupx))/2, BASEVIDHEIGHT-boxheight, (vid.width/vid.dupx),boxheight, (color-256)|V_SNAPTOBOTTOM); return; } @@ -1917,8 +1920,11 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color) // heavily simplified -- we don't need to know x or y position, // just the start and stop positions - deststop = screens[0] + vid.rowbytes * vid.height; - buf = deststop - vid.rowbytes * ((boxheight * 4) + (boxheight/2)*5); // 4 lines of space plus gaps between and some leeway + buf = deststop = screens[0] + vid.rowbytes * vid.height; + if (boxheight < 0) + buf += vid.rowbytes * boxheight; + else // 4 lines of space plus gaps between and some leeway + buf -= vid.rowbytes * ((boxheight * 4) + (boxheight/2)*5); for (; buf < deststop; ++buf) *buf = promptbgmap[*buf]; } diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index 5fa219586..eccec10bc 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -377,6 +377,9 @@ void I_FinishUpdate(void) if (cv_showping.value && netgame && consoleplayer != serverplayer) SCR_DisplayLocalPing(); + if (marathonmode) + SCR_DisplayMarathonInfo(); + // if (bDIBMode) { diff --git a/src/y_inter.c b/src/y_inter.c index f1764a816..bfd8e7aa5 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -392,7 +392,7 @@ dontdrawbg: if (gottoken) // first to be behind everything else Y_IntermissionTokenDrawer(); - if (!splitscreen) + if (!splitscreen) // there's not enough room in splitscreen, don't even bother trying! { // draw score ST_DrawPatchFromHud(HUD_SCORE, sboscore); @@ -414,7 +414,7 @@ dontdrawbg: ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon); // Colon ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2); // Seconds - if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! + if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking || marathonmode) { ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics @@ -1004,7 +1004,7 @@ void Y_Ticker(void) { INT32 i; UINT32 oldscore = data.coop.score; - boolean skip = false; + boolean skip = (marathonmode) ? true : false; boolean anybonuses = false; if (!intertic) // first time only @@ -1080,7 +1080,7 @@ void Y_Ticker(void) { INT32 i; UINT32 oldscore = data.spec.score; - boolean skip = false, super = false, anybonuses = false; + boolean skip = (marathonmode) ? true : false, super = false, anybonuses = false; if (!intertic) // first time only { From e99d38ffafad389eb848938c24ee196810c02045 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 May 2020 13:19:52 +0100 Subject: [PATCH 118/168] Make a falsy useBlackRoc prevent doing Black Rock sparkle calculations and Egg Rock pulse sounds. --- src/f_finale.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index b7ff0f8f3..d00e4a1d1 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1681,7 +1681,9 @@ void F_GameEvaluationTicker(void) return; } - if (!goodending) + if (!useBlackRock) + ; + else if (!goodending) { if (sparklloop) sparklloop--; From 4348ebdfa8bc29bee564d2624ac374e93163e1e8 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 May 2020 13:37:06 +0100 Subject: [PATCH 119/168] Make live event backup files savedata specific (new format: `live%s.bkp`, where %s is the time attack folder name/savegame name - so vanilla's is `livesrb2sav.bkp`). --- src/d_main.c | 2 +- src/dehacked.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index a779aa0bf..06373355d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1135,7 +1135,7 @@ void D_SRB2Main(void) // default savegame strcpy(savegamename, SAVEGAMENAME"%u.ssg"); - strcpy(liveeventbackup,"liveevent.bkp"); // intentionally not ending with .ssg + strcpy(liveeventbackup, "live"SAVEGAMENAME".bkp"); // intentionally not ending with .ssg { const char *userhome = D_Home(); //Alam: path to home diff --git a/src/dehacked.c b/src/dehacked.c index ff3e118c4..c92fc3412 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4211,6 +4211,9 @@ static void readmaincfg(MYFILE *f) // can't use sprintf since there is %u in savegamename strcatbf(savegamename, srb2home, PATHSEP); + strcpy(liveeventbackup, va("live%s.bkp", timeattackfolder)); + strcatbf(liveeventbackup, srb2home, PATHSEP); + gamedataadded = true; titlechanged = true; } From 271c6d354bbdeb6066b7948dc45b851ade204589 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 May 2020 13:39:27 +0100 Subject: [PATCH 120/168] Re-order Marathon bar to be drawn before FPS and captions if applicable. --- src/djgppdos/i_video.c | 6 +++--- src/sdl/i_video.c | 6 +++--- src/win32/win_vid.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/djgppdos/i_video.c b/src/djgppdos/i_video.c index b3363a14e..d2483e318 100644 --- a/src/djgppdos/i_video.c +++ b/src/djgppdos/i_video.c @@ -90,6 +90,9 @@ static unsigned long nombre = NEWTICRATE*10; static void I_BlitScreenVesa1(void); //see later void I_FinishUpdate (void) { + if (marathonmode) + SCR_DisplayMarathonInfo(); + // draw captions if enabled if (cv_closedcaptioning.value) SCR_ClosedCaptions(); @@ -101,9 +104,6 @@ void I_FinishUpdate (void) if (cv_showping.value && netgame && consoleplayer != serverplayer) SCR_DisplayLocalPing(); - if (marathonmode) - SCR_DisplayMarathonInfo(); - //blast it to the screen // this code sucks //memcpy(dascreen,screens[0],screenwidth*screenheight); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index e8fe020f0..b591bc4df 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1203,6 +1203,9 @@ void I_FinishUpdate(void) if (I_SkipFrame()) return; + if (marathonmode) + SCR_DisplayMarathonInfo(); + // draw captions if enabled if (cv_closedcaptioning.value) SCR_ClosedCaptions(); @@ -1213,9 +1216,6 @@ void I_FinishUpdate(void) if (cv_showping.value && netgame && consoleplayer != serverplayer) SCR_DisplayLocalPing(); - if (marathonmode) - SCR_DisplayMarathonInfo(); - if (rendermode == render_soft && screens[0]) { SDL_Rect rect; diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index eccec10bc..0f1144a84 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -366,6 +366,9 @@ void I_FinishUpdate(void) if (I_SkipFrame()) return; + if (marathonmode) + SCR_DisplayMarathonInfo(); + // draw captions if enabled if (cv_closedcaptioning.value) SCR_ClosedCaptions(); @@ -377,9 +380,6 @@ void I_FinishUpdate(void) if (cv_showping.value && netgame && consoleplayer != serverplayer) SCR_DisplayLocalPing(); - if (marathonmode) - SCR_DisplayMarathonInfo(); - // if (bDIBMode) { From f06206cd5f95dc39b15600e922ae9ae9b30bfc67 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 May 2020 14:24:29 +0100 Subject: [PATCH 121/168] Fix "press any other key" sending you to HOM hell. --- src/m_menu.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index fae17608b..310a02420 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10376,14 +10376,16 @@ static void M_MarathonLiveEventBackup(INT32 choice) marathonmode = 0; return; } - else if (choice == KEY_DEL) + + M_StopMessage(0); + stopstopmessage = true; + + if (choice == KEY_DEL) { - M_StopMessage(0); if (FIL_FileExists(liveeventbackup)) // just in case someone deleted it while we weren't looking. remove(liveeventbackup); BwehHehHe(); M_StartMessage("Live event backup erased.\n",M_Marathon,MM_NOTHING); - stopstopmessage = true; return; } From 47419ce0dfead5fc2400d845eb79bc01686a81e0 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 May 2020 15:08:45 +0100 Subject: [PATCH 122/168] Introducing "antisplice" - a pair of small highlights on the Marathon bar that is based on the real time the executable has been open for and *isn't* restored with the Live Event Backup, making spliced runs basically intractable. --- src/screen.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index 44d98f024..04dd73c46 100644 --- a/src/screen.c +++ b/src/screen.c @@ -626,7 +626,7 @@ void SCR_ClosedCaptions(void) void SCR_DisplayMarathonInfo(void) { INT32 flags = V_SNAPTOBOTTOM; - static tic_t entertic, oldentertics = 0; + static tic_t entertic, oldentertics = 0, antisplice[2] = {48,0}; const char *str; #if 0 // eh, this probably isn't going to be a problem if (((signed)marathontime) < 0) @@ -644,6 +644,13 @@ void SCR_DisplayMarathonInfo(void) marathonmode &= ~MA_INIT; else marathontime += entertic - oldentertics; + // Create a sequence of primes such that their LCM is nice and big. +#define PRIMEV1 13 +#define PRIMEV2 17 // I can't believe it! I'm on TV! + antisplice[0] += (entertic - oldentertics)*PRIMEV2; + antisplice[0] %= PRIMEV1*((vid.width/vid.dupx)+1); + antisplice[1] += (entertic - oldentertics)*PRIMEV1; + antisplice[1] %= PRIMEV1*((vid.width/vid.dupx)+1); str = va("%i:%02i:%02i.%02i", G_TicsToHours(marathontime), G_TicsToMinutes(marathontime, false), @@ -651,6 +658,12 @@ void SCR_DisplayMarathonInfo(void) G_TicsToCentiseconds(marathontime)); oldentertics = entertic; } + V_DrawFill((antisplice[0]/PRIMEV1)-1, BASEVIDHEIGHT-8, 1, 8, V_SNAPTOBOTTOM|V_SNAPTOLEFT); + V_DrawFill((antisplice[0]/PRIMEV1), BASEVIDHEIGHT-8, 1, 8, V_SNAPTOBOTTOM|V_SNAPTOLEFT|31); + V_DrawFill(BASEVIDWIDTH-((antisplice[1]/PRIMEV1)-1), BASEVIDHEIGHT-8, 1, 8, V_SNAPTOBOTTOM|V_SNAPTORIGHT); + V_DrawFill(BASEVIDWIDTH-((antisplice[1]/PRIMEV1)), BASEVIDHEIGHT-8, 1, 8, V_SNAPTOBOTTOM|V_SNAPTORIGHT|31); +#undef PRIMEV1 +#undef PRIMEV2 V_DrawPromptBack(-8, cons_backcolor.value); V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-8, flags, str); } From 1e3e9c81acd3af5223419cd2d4870d4f62461132 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 May 2020 15:23:18 +0100 Subject: [PATCH 123/168] Remove emblem hints from Marathon Run (I think Options is good just for the sake of live events, though). --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 310a02420..f07bbf703 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3727,7 +3727,7 @@ void M_StartControlPanel(void) SPauseMenu[spause_levelselect].status = (gamecomplete == 1) ? (IT_STRING | IT_CALL) : (IT_DISABLED); // And emblem hints. - SPauseMenu[spause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + SPauseMenu[spause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS) && !marathonmode) ? (IT_STRING | IT_CALL) : (IT_DISABLED); // Shift up Pandora's Box if both pandora and levelselect are active /*if (SPauseMenu[spause_pandora].status != (IT_DISABLED) From 9686ad2d7042e90650979146a5d7bca00fdded94 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 May 2020 16:33:20 +0100 Subject: [PATCH 124/168] * In-game timer option! Doesn't tick in intermission or in lag, only when a frame is actually run. Realtime option remains default. * Tweak retry behaviour to restart timer and not subtract life if you're on the first level and haven't hit a checkpoint yet. --- src/dehacked.c | 3 ++- src/doomstat.h | 3 ++- src/g_game.c | 13 +++++++++++-- src/m_menu.c | 18 +++++++++++++++--- src/p_tick.c | 6 ++++++ src/screen.c | 3 +++ 6 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c92fc3412..031ba39d8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9933,9 +9933,10 @@ struct { {"TC_DASHMODE",TC_DASHMODE}, // marathonmode flags - //{"MA_INIT",MA_INIT}, -- should never see this + {"MA_INIT",MA_INIT}, {"MA_RUNNING",MA_RUNNING}, {"MA_NOCUTSCENES",MA_NOCUTSCENES}, + {"MA_INGAME",MA_INGAME}, {NULL,0} }; diff --git a/src/doomstat.h b/src/doomstat.h index f407d7add..05512df9b 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -52,7 +52,8 @@ typedef enum { MA_RUNNING = 1, // In action MA_INIT = 1<<1, // Initialisation - MA_NOCUTSCENES = 1<<2 // No cutscenes + MA_NOCUTSCENES = 1<<2, // No cutscenes + MA_INGAME = 1<<3 // Timer ignores loads } marathonmode_t; extern marathonmode_t marathonmode; diff --git a/src/g_game.c b/src/g_game.c index e6a6d851c..b46e9cfc0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2167,6 +2167,10 @@ void G_Ticker(boolean run) UINT32 i; INT32 buf; + // see also SCR_DisplayMarathonInfo + if ((marathonmode & (MA_INIT|MA_INGAME)) == MA_INGAME && gamestate == GS_LEVEL) + marathontime++; + P_MapStart(); // do player reborns if needed if (gamestate == GS_LEVEL) @@ -2183,8 +2187,13 @@ void G_Ticker(boolean run) } else { - // Costs a life to retry ... unless the player in question is dead already. - if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES) + // 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) + { + marathonmode |= MA_INIT; + marathontime = 0; + } + else if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES) players[consoleplayer].lives -= 1; G_DoReborn(consoleplayer); diff --git a/src/m_menu.c b/src/m_menu.c index f07bbf703..8e9bb87fd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -485,9 +485,11 @@ static consvar_t cv_dummycontinues = {"dummycontinues", "0", CV_HIDEN, contlimit static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dummymares_cons_t, Dummymares_OnChange, 0, NULL, NULL, 0, 0, NULL}; CV_PossibleValue_t marathon_cons_t[] = {{0, "Standard"}, {1, "Live Event Backup"}, {2, "Ultimate"}, {0, NULL}}; +CV_PossibleValue_t loadless_cons_t[] = {{0, "Realtime"}, {1, "In-game"}, {0, NULL}}; consvar_t cv_dummymarathon = {"dummymarathon", "Standard", CV_HIDEN, marathon_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_dummycutscenes = {"dummycutscenes", "Off", CV_HIDEN, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_dummyloadless = {"dummyloadless", "Realtime", CV_HIDEN, loadless_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // ========================================================================== // ORGANIZATION START. @@ -919,8 +921,9 @@ enum // Marathon static menuitem_t SP_MarathonMenu[] = { - {IT_STRING|IT_KEYHANDLER, NULL, "Character", M_HandleMarathonChoosePlayer, 100}, - {IT_STRING|IT_CVAR, NULL, "Category", &cv_dummymarathon, 110}, + {IT_STRING|IT_KEYHANDLER, NULL, "Character", M_HandleMarathonChoosePlayer, 90}, + {IT_STRING|IT_CVAR, NULL, "Category", &cv_dummymarathon, 100}, + {IT_STRING|IT_CVAR, NULL, "Timer", &cv_dummyloadless, 110}, {IT_STRING|IT_CVAR, NULL, "Cutscenes", &cv_dummycutscenes, 120}, {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartMarathon, 130}, }; @@ -929,6 +932,7 @@ enum { marathonplayer, marathonultimate, + marathonloadless, marathoncutscenes, marathonstart }; @@ -3909,6 +3913,7 @@ void M_Init(void) CV_RegisterVar(&cv_dummycontinues); CV_RegisterVar(&cv_dummymares); CV_RegisterVar(&cv_dummymarathon); + CV_RegisterVar(&cv_dummyloadless); CV_RegisterVar(&cv_dummycutscenes); quitmsg[QUITMSG] = M_GetText("Eggman's tied explosives\nto your girlfriend, and\nwill activate them if\nyou press the 'Y' key!\nPress 'N' to save her!\n\n(Press 'Y' to quit)"); @@ -6910,6 +6915,11 @@ static void M_RetryResponse(INT32 ch) static void M_Retry(INT32 choice) { (void)choice; + if (marathonmode) + { + M_RetryResponse(KEY_ENTER); + return; + } M_StartMessage(M_GetText("Retry this act from the last starpost?\n\n(Press 'Y' to confirm)\n"),M_RetryResponse,MM_YESNO); } @@ -10430,7 +10440,7 @@ static void M_Marathon(INT32 choice) mapnum++; } - SP_MarathonMenu[marathoncutscenes].status = (mapnum < NUMMAPS) ? IT_CVAR |IT_STRING : IT_NOTHING|IT_DISABLED; + SP_MarathonMenu[marathoncutscenes].status = (mapnum < NUMMAPS) ? IT_CVAR|IT_STRING : IT_NOTHING|IT_DISABLED; M_ChangeMenuMusic("spec8", true); @@ -10490,6 +10500,8 @@ static void M_StartMarathon(INT32 choice) cursaveslot = MARATHONSLOT; if (!cv_dummycutscenes.value) marathonmode |= MA_NOCUTSCENES; + if (cv_dummyloadless.value) + marathonmode |= MA_INGAME; M_ChoosePlayer(char_on); } diff --git a/src/p_tick.c b/src/p_tick.c index 7ea6edb2d..0f8440960 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -755,6 +755,9 @@ void P_PreTicker(INT32 frames) postimgtype = postimgtype2 = postimg_none; + if (marathonmode & MA_INGAME) + marathonmode |= MA_INIT; + for (framecnt = 0; framecnt < frames; ++framecnt) { P_MapStart(); @@ -797,4 +800,7 @@ void P_PreTicker(INT32 frames) P_MapEnd(); } + + if (marathonmode & MA_INGAME) + marathonmode &= ~MA_INIT; } diff --git a/src/screen.c b/src/screen.c index 04dd73c46..e7ff9e735 100644 --- a/src/screen.c +++ b/src/screen.c @@ -640,10 +640,13 @@ void SCR_DisplayMarathonInfo(void) entertic = I_GetTime(); if (gamecomplete) flags |= V_YELLOWMAP; + else if (marathonmode & MA_INGAME) + ; // see also G_Ticker else if (marathonmode & MA_INIT) marathonmode &= ~MA_INIT; else marathontime += entertic - oldentertics; + // Create a sequence of primes such that their LCM is nice and big. #define PRIMEV1 13 #define PRIMEV2 17 // I can't believe it! I'm on TV! From a615de3504c4385866309bb35b29288be3b30238 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 May 2020 21:17:57 +0100 Subject: [PATCH 125/168] Correctly reset map/timer for retries where the first map in Marathon Run is LF_NORELOAD (by forcing a reload when the retry option is used). --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index b46e9cfc0..c1e0f53d4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2944,7 +2944,7 @@ void G_DoReborn(INT32 playernum) players[i].starpostnum = 0; } } - if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD)) + if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD) && !(marathonmode & MA_INIT)) { P_RespawnThings(); From a5150e07fdeb1ab941e9f9d55ffe25ed0e671476 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 May 2020 21:32:54 +0100 Subject: [PATCH 126/168] * Swap location of Tutorial and Marathon Run, per sphere's suggestion. * Lock Marathon Run if Record Attack isn't available, to avoid confusing new players. --- src/m_menu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 8e9bb87fd..e71c2cad4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -764,8 +764,8 @@ static menuitem_t SP_MainMenu[] = {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 76}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 84}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 92}, - {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 100}, - {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Marathon Run", M_Marathon, 108}, + {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Marathon Run", M_Marathon, 100}, + {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 108}, {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 116} }; @@ -774,8 +774,8 @@ enum sploadgame, sprecordattack, spnightsmode, - sptutorial, spmarathon, + sptutorial, spstatistics }; @@ -8073,10 +8073,11 @@ static void M_SinglePlayerMenu(INT32 choice) SP_MainMenu[sptutorial].status = tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; // If the FIRST stage immediately leads to the ending, or itself (which gets converted to the title screen in G_DoCompleted for marathonmode only), there's no point in having this option on the menu. You should use Record Attack in that circumstance, although if marathonnext is set this behaviour can be overridden if you make some weird mod that requires multiple playthroughs of the same map in sequence and has some in-level mechanism to break the cycle. - if (mapheaderinfo[spmarathon_start-1] + if (!M_SecretUnlocked(SECRET_RECORDATTACK) // also if record attack is locked + || (mapheaderinfo[spmarathon_start-1] && !mapheaderinfo[spmarathon_start-1]->marathonnext && (mapheaderinfo[spmarathon_start-1]->nextlevel == spmarathon_start - || mapheaderinfo[spmarathon_start-1]->nextlevel >= 1100)) + || mapheaderinfo[spmarathon_start-1]->nextlevel >= 1100))) SP_MainMenu[spmarathon].status = IT_NOTHING|IT_DISABLED; else SP_MainMenu[spmarathon].status = IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED; From 37d2796b916adad65114aad25ba15ea4acfc89e1 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 18 May 2020 12:35:55 +0200 Subject: [PATCH 127/168] Increase the length of the player input buffer even more --- src/d_clisrv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 583c3c8db..d33d30156 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -33,7 +33,7 @@ applications may follow different packet versions. // be transmitted. // Networking and tick handling related. -#define BACKUPTICS 96 +#define BACKUPTICS 1024 #define CLIENTBACKUPTICS 32 #define MAXTEXTCMD 256 // From 530d0e342127733d6281d8e51cb94a68be4cf379 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Mon, 18 May 2020 14:56:10 -0500 Subject: [PATCH 128/168] Remove redundant M_QuitResponse call --- src/sdl/i_video.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index cff73e068..8835a763b 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1064,7 +1064,6 @@ void I_GetEvent(void) if (Playing()) LUAh_GameQuit(); I_Quit(); - M_QuitResponse('y'); break; } } From bb1e3fdf13816da0af01ba7704fbb5764ad95432 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 27 May 2020 14:58:10 +0200 Subject: [PATCH 129/168] Add a few missing calls to GameQuit hook --- src/d_clisrv.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index ed0b8e528..184e0e800 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3036,6 +3036,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) if (pnum == consoleplayer) { + if (Playing()) + LUAh_GameQuit(); #ifdef DUMPCONSISTENCY if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); #endif @@ -3701,6 +3703,8 @@ static void HandleConnect(SINT8 node) static void HandleShutdown(SINT8 node) { (void)node; + if (Playing()) + LUAh_GameQuit(); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -3715,6 +3719,8 @@ static void HandleShutdown(SINT8 node) static void HandleTimeout(SINT8 node) { (void)node; + if (Playing()) + LUAh_GameQuit(); D_QuitNetGame(); CL_Reset(); D_StartTitle(); From ca66c5e7ee624a43551c055042ff35aa69fba329 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Fri, 5 Jun 2020 13:18:22 -0500 Subject: [PATCH 130/168] Updated LUAh_GameQuit --- src/lua_hooklib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 62bb5b663..0d8aa1ffb 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1783,8 +1783,7 @@ void LUAh_GameQuit(void) if (hookp->type != hook_GameQuit) continue; - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); if (lua_pcall(gL, 0, 0, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); From abe13651d00790c0395e6315266336d471a4f39d Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sun, 7 Jun 2020 21:20:52 +0300 Subject: [PATCH 131/168] OpenGL draw call batching system --- src/CMakeLists.txt | 2 + src/Makefile | 2 +- src/d_main.c | 22 ++ src/hardware/hw_batching.c | 450 +++++++++++++++++++++++++++ src/hardware/hw_batching.h | 37 +++ src/hardware/hw_cache.c | 35 ++- src/hardware/hw_drv.h | 2 + src/hardware/hw_main.c | 74 +++-- src/hardware/hw_main.h | 13 + src/hardware/r_opengl/r_opengl.c | 34 +- src/sdl/Srb2SDL-vc10.vcxproj | 2 + src/sdl/Srb2SDL-vc10.vcxproj.filters | 6 + src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + 14 files changed, 639 insertions(+), 42 deletions(-) create mode 100644 src/hardware/hw_batching.c create mode 100644 src/hardware/hw_batching.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b0a593bb1..7a3f0564d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -418,6 +418,7 @@ endif() if(${SRB2_CONFIG_HWRENDER}) add_definitions(-DHWRENDER) set(SRB2_HWRENDER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c @@ -433,6 +434,7 @@ if(${SRB2_CONFIG_HWRENDER}) ) set (SRB2_HWRENDER_HEADERS + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h diff --git a/src/Makefile b/src/Makefile index d2dd4757a..e00c84bc9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -225,7 +225,7 @@ else OPTS+=-DHWRENDER OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \ $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o \ - $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o + $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o endif ifdef NOHS diff --git a/src/d_main.c b/src/d_main.c index fe06be2a4..e4978205c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -634,6 +634,28 @@ static void D_Display(void) V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s); snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor); V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s); + if (cv_grbatching.value) + { + snprintf(s, sizeof s - 1, "bsrt %d", rs_hw_batchsorttime / divisor); + V_DrawThinString(80, 55, V_MONOSPACE | V_REDMAP, s); + snprintf(s, sizeof s - 1, "bdrw %d", rs_hw_batchdrawtime / divisor); + V_DrawThinString(80, 65, V_MONOSPACE | V_REDMAP, s); + + snprintf(s, sizeof s - 1, "npol %d", rs_hw_numpolys); + V_DrawThinString(130, 10, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "ndc %d", rs_hw_numcalls); + V_DrawThinString(130, 20, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "nshd %d", rs_hw_numshaders); + V_DrawThinString(130, 30, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "nvrt %d", rs_hw_numverts); + V_DrawThinString(130, 40, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "ntex %d", rs_hw_numtextures); + V_DrawThinString(185, 10, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "npf %d", rs_hw_numpolyflags); + V_DrawThinString(185, 20, V_MONOSPACE | V_PURPLEMAP, s); + snprintf(s, sizeof s - 1, "ncol %d", rs_hw_numcolors); + V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s); + } } else // software specific stats { diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c new file mode 100644 index 000000000..4e11b0ab7 --- /dev/null +++ b/src/hardware/hw_batching.c @@ -0,0 +1,450 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file hw_batching.c +/// \brief Draw call batching and related things. + +#ifdef HWRENDER +#include "hw_glob.h" +#include "hw_batching.h" +#include "../i_system.h" + +// The texture for the next polygon given to HWR_ProcessPolygon. +// Set with HWR_SetCurrentTexture. +GLMipmap_t *current_texture = NULL; + +boolean currently_batching = false; + +FOutVector* finalVertexArray = NULL;// contains subset of sorted vertices and texture coordinates to be sent to gpu +UINT32* finalVertexIndexArray = NULL;// contains indexes for glDrawElements, taking into account fan->triangles conversion +// NOTE have this alloced as 3x finalVertexArray size +int finalVertexArrayAllocSize = 65536; +//GLubyte* colorArray = NULL;// contains color data to be sent to gpu, if needed +//int colorArrayAllocSize = 65536; +// not gonna use this for now, just sort by color and change state when it changes +// later maybe when using vertex attributes if it's needed + +PolygonArrayEntry* polygonArray = NULL;// contains the polygon data from DrawPolygon, waiting to be processed +int polygonArraySize = 0; +unsigned int* polygonIndexArray = NULL;// contains sorting pointers for polygonArray +int polygonArrayAllocSize = 65536; + +FOutVector* unsortedVertexArray = NULL;// contains unsorted vertices and texture coordinates from DrawPolygon +int unsortedVertexArraySize = 0; +int unsortedVertexArrayAllocSize = 65536; + +// Enables batching mode. HWR_ProcessPolygon will collect polygons instead of passing them directly to the rendering backend. +// Call HWR_RenderBatches to render all the collected geometry. +void HWR_StartBatching(void) +{ + if (currently_batching) + I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches"); + + // init arrays if that has not been done yet + if (!finalVertexArray) + { + finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector)); + finalVertexIndexArray = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32)); + polygonArray = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry)); + polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(unsigned int)); + unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector)); + } + + currently_batching = true; +} + +// This replaces the direct calls to pfnSetTexture in cases where batching is available. +// The texture selection is saved for the next HWR_ProcessPolygon call. +// Doing this was easier than getting a texture pointer to HWR_ProcessPolygon. +void HWR_SetCurrentTexture(GLMipmap_t *texture) +{ + if (currently_batching) + { + current_texture = texture; + } + else + { + HWD.pfnSetTexture(texture); + } +} + +// If batching is enabled, this function collects the polygon data and the chosen texture +// for later use in HWR_RenderBatches. Otherwise the rendering backend is used to +// render the polygon immediately. +void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial) +{ + if (currently_batching) + { + if (!pSurf) + I_Error("Got a null FSurfaceInfo in batching");// nulls should not come in the stuff that batching currently applies to + if (polygonArraySize == polygonArrayAllocSize) + { + PolygonArrayEntry* new_array; + // ran out of space, make new array double the size + polygonArrayAllocSize *= 2; + new_array = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry)); + memcpy(new_array, polygonArray, polygonArraySize * sizeof(PolygonArrayEntry)); + free(polygonArray); + polygonArray = new_array; + // also need to redo the index array, dont need to copy it though + free(polygonIndexArray); + polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(unsigned int)); + } + + while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize) + { + FOutVector* new_array; + // need more space for vertices in unsortedVertexArray + unsortedVertexArrayAllocSize *= 2; + new_array = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector)); + memcpy(new_array, unsortedVertexArray, unsortedVertexArraySize * sizeof(FOutVector)); + free(unsortedVertexArray); + unsortedVertexArray = new_array; + } + + // add the polygon data to the arrays + + polygonArray[polygonArraySize].surf = *pSurf; + polygonArray[polygonArraySize].vertsIndex = unsortedVertexArraySize; + polygonArray[polygonArraySize].numVerts = iNumPts; + polygonArray[polygonArraySize].polyFlags = PolyFlags; + polygonArray[polygonArraySize].texture = current_texture; + polygonArray[polygonArraySize].shader = shader; + polygonArray[polygonArraySize].horizonSpecial = horizonSpecial; + polygonArraySize++; + + memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector)); + unsortedVertexArraySize += iNumPts; + } + else + { + if (shader) + HWD.pfnSetShader(shader); + HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags); + } +} + +static int comparePolygons(const void *p1, const void *p2) +{ + unsigned int index1 = *(const unsigned int*)p1; + unsigned int index2 = *(const unsigned int*)p2; + PolygonArrayEntry* poly1 = &polygonArray[index1]; + PolygonArrayEntry* poly2 = &polygonArray[index2]; + int diff; + INT64 diff64; + + int shader1 = poly1->shader; + int shader2 = poly2->shader; + // make skywalls and horizon lines first in order + if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) + shader1 = -1; + if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) + shader2 = -1; + diff = shader1 - shader2; + if (diff != 0) return diff; + + // skywalls and horizon lines must retain their order for horizon lines to work + if (shader1 == -1 && shader2 == -1) + return index1 - index2; + + diff64 = poly1->texture - poly2->texture; + if (diff64 != 0) return diff64; + + diff = poly1->polyFlags - poly2->polyFlags; + if (diff != 0) return diff; + + diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba; + if (diff64 < 0) return -1; else if (diff64 > 0) return 1; + diff64 = poly1->surf.TintColor.rgba - poly2->surf.TintColor.rgba; + if (diff64 < 0) return -1; else if (diff64 > 0) return 1; + diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba; + if (diff64 < 0) return -1; else if (diff64 > 0) return 1; + + diff = poly1->surf.LightInfo.light_level - poly2->surf.LightInfo.light_level; + if (diff != 0) return diff; + diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start; + if (diff != 0) return diff; + diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end; + return diff; +} + +static int comparePolygonsNoShaders(const void *p1, const void *p2) +{ + unsigned int index1 = *(const unsigned int*)p1; + unsigned int index2 = *(const unsigned int*)p2; + PolygonArrayEntry* poly1 = &polygonArray[index1]; + PolygonArrayEntry* poly2 = &polygonArray[index2]; + int diff; + INT64 diff64; + + GLMipmap_t *texture1 = poly1->texture; + GLMipmap_t *texture2 = poly2->texture; + if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) + texture1 = NULL; + if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) + texture2 = NULL; + diff64 = texture1 - texture2; + if (diff64 != 0) return diff64; + + // skywalls and horizon lines must retain their order for horizon lines to work + if (texture1 == NULL && texture2 == NULL) + return index1 - index2; + + diff = poly1->polyFlags - poly2->polyFlags; + if (diff != 0) return diff; + + diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba; + if (diff64 < 0) return -1; else if (diff64 > 0) return 1; + + return 0; +} + +// This function organizes the geometry collected by HWR_ProcessPolygon calls into batches and uses +// the rendering backend to draw them. +void HWR_RenderBatches(void) +{ + int finalVertexWritePos = 0;// position in finalVertexArray + int finalIndexWritePos = 0;// position in finalVertexIndexArray + + int polygonReadPos = 0;// position in polygonIndexArray + + int currentShader; + GLMipmap_t *currentTexture; + FBITFIELD currentPolyFlags; + FSurfaceInfo currentSurfaceInfo; + + int i; + + if (!currently_batching) + I_Error("HWR_RenderBatches called without starting batching"); + + currently_batching = false;// no longer collecting batches + if (!polygonArraySize) + { + rs_hw_numpolys = rs_hw_numcalls = rs_hw_numshaders = rs_hw_numtextures = rs_hw_numpolyflags = rs_hw_numcolors = 0; + return;// nothing to draw + } + // init stats vars + rs_hw_numpolys = polygonArraySize; + rs_hw_numcalls = rs_hw_numverts = 0; + rs_hw_numshaders = rs_hw_numtextures = rs_hw_numpolyflags = rs_hw_numcolors = 1; + // init polygonIndexArray + for (i = 0; i < polygonArraySize; i++) + { + polygonIndexArray[i] = i; + } + + // sort polygons + rs_hw_batchsorttime = I_GetTimeMicros(); + if (cv_grshaders.value) // TODO also have the shader availability check here when its done + qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons); + else + qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders); + rs_hw_batchsorttime = I_GetTimeMicros() - rs_hw_batchsorttime; + // sort order + // 1. shader + // 2. texture + // 3. polyflags + // 4. colors + light level + // not sure about what order of the last 2 should be, or if it even matters + + rs_hw_batchdrawtime = I_GetTimeMicros(); + + currentShader = polygonArray[polygonIndexArray[0]].shader; + currentTexture = polygonArray[polygonIndexArray[0]].texture; + currentPolyFlags = polygonArray[polygonIndexArray[0]].polyFlags; + currentSurfaceInfo = polygonArray[polygonIndexArray[0]].surf; + // For now, will sort and track the colors. Vertex attributes could be used instead of uniforms + // and a color array could replace the color calls. + + // set state for first batch + + if (cv_grshaders.value) // TODO also have the shader availability check here when its done + { + HWD.pfnSetShader(currentShader); + } + + if (currentPolyFlags & PF_NoTexture) + currentTexture = NULL; + else + HWD.pfnSetTexture(currentTexture); + + while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons) + { + int firstIndex; + int lastIndex; + + boolean stopFlag = false; + boolean changeState = false; + boolean changeShader = false; + int nextShader; + boolean changeTexture = false; + GLMipmap_t *nextTexture; + boolean changePolyFlags = false; + FBITFIELD nextPolyFlags; + boolean changeSurfaceInfo = false; + FSurfaceInfo nextSurfaceInfo; + + // steps: + // write vertices + // check for changes or end, otherwise go back to writing + // changes will affect the next vars and the change bools + // end could set flag for stopping + // execute draw call + // could check ending flag here + // change states according to next vars and change bools, updating the current vars and reseting the bools + // reset write pos + // repeat loop + + int index = polygonIndexArray[polygonReadPos++]; + int numVerts = polygonArray[index].numVerts; + // before writing, check if there is enough room + // using 'while' instead of 'if' here makes sure that there will *always* be enough room. + // probably never will this loop run more than once though + while (finalVertexWritePos + numVerts > finalVertexArrayAllocSize) + { + FOutVector* new_array; + unsigned int* new_index_array; + finalVertexArrayAllocSize *= 2; + new_array = malloc(finalVertexArrayAllocSize * sizeof(FOutVector)); + memcpy(new_array, finalVertexArray, finalVertexWritePos * sizeof(FOutVector)); + free(finalVertexArray); + finalVertexArray = new_array; + // also increase size of index array, 3x of vertex array since + // going from fans to triangles increases vertex count to 3x + new_index_array = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32)); + memcpy(new_index_array, finalVertexIndexArray, finalIndexWritePos * sizeof(UINT32)); + free(finalVertexIndexArray); + finalVertexIndexArray = new_index_array; + } + // write the vertices of the polygon + memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[polygonArray[index].vertsIndex], + numVerts * sizeof(FOutVector)); + // write the indexes, pointing to the fan vertexes but in triangles format + firstIndex = finalVertexWritePos; + lastIndex = finalVertexWritePos + numVerts; + finalVertexWritePos += 2; + while (finalVertexWritePos < lastIndex) + { + finalVertexIndexArray[finalIndexWritePos++] = firstIndex; + finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos - 1; + finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos++; + } + + if (polygonReadPos >= polygonArraySize) + { + stopFlag = true; + } + else + { + // check if a state change is required, set the change bools and next vars + int nextIndex = polygonIndexArray[polygonReadPos]; + nextShader = polygonArray[nextIndex].shader; + nextTexture = polygonArray[nextIndex].texture; + nextPolyFlags = polygonArray[nextIndex].polyFlags; + nextSurfaceInfo = polygonArray[nextIndex].surf; + if (nextPolyFlags & PF_NoTexture) + nextTexture = 0; + if (currentShader != nextShader) + { + changeState = true; + changeShader = true; + } + if (currentTexture != nextTexture) + { + changeState = true; + changeTexture = true; + } + if (currentPolyFlags != nextPolyFlags) + { + changeState = true; + changePolyFlags = true; + } + if (cv_grshaders.value) // TODO also have the shader availability check here when its done + { + if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba || + currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba || + currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba || + currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level || + currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start || + currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end) + { + changeState = true; + changeSurfaceInfo = true; + } + } + else + { + if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba) + { + changeState = true; + changeSurfaceInfo = true; + } + } + } + + if (changeState || stopFlag) + { + // execute draw call + HWD.pfnDrawIndexedTriangles(¤tSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray); + // update stats + rs_hw_numcalls++; + rs_hw_numverts += finalIndexWritePos; + // reset write positions + finalVertexWritePos = 0; + finalIndexWritePos = 0; + } + else continue; + + // if we're here then either its time to stop or time to change state + if (stopFlag) break; + + // change state according to change bools and next vars, update current vars and reset bools + if (changeShader) + { + HWD.pfnSetShader(nextShader); + currentShader = nextShader; + changeShader = false; + + rs_hw_numshaders++; + } + if (changeTexture) + { + // texture should be already ready for use from calls to SetTexture during batch collection + HWD.pfnSetTexture(nextTexture); + currentTexture = nextTexture; + changeTexture = false; + + rs_hw_numtextures++; + } + if (changePolyFlags) + { + currentPolyFlags = nextPolyFlags; + changePolyFlags = false; + + rs_hw_numpolyflags++; + } + if (changeSurfaceInfo) + { + currentSurfaceInfo = nextSurfaceInfo; + changeSurfaceInfo = false; + + rs_hw_numcolors++; + } + // and that should be it? + } + // reset the arrays (set sizes to 0) + polygonArraySize = 0; + unsortedVertexArraySize = 0; + + rs_hw_batchdrawtime = I_GetTimeMicros() - rs_hw_batchdrawtime; +} + + +#endif // HWRENDER diff --git a/src/hardware/hw_batching.h b/src/hardware/hw_batching.h new file mode 100644 index 000000000..7c108a4bd --- /dev/null +++ b/src/hardware/hw_batching.h @@ -0,0 +1,37 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file hw_batching.h +/// \brief Draw call batching and related things. + +#ifndef __HWR_BATCHING_H__ +#define __HWR_BATCHING_H__ + +#include "hw_defs.h" +#include "hw_data.h" +#include "hw_drv.h" + +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 + FUINT numVerts; + FBITFIELD polyFlags; + GLMipmap_t *texture; + int shader; + // this tells batching that the plane belongs to a horizon line and must be drawn in correct order with the skywalls + boolean horizonSpecial; +} PolygonArrayEntry; + +void HWR_StartBatching(void); +void HWR_SetCurrentTexture(GLMipmap_t *texture); +void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial); +void HWR_RenderBatches(void); + +#endif diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index a64feab08..ab9a50dd5 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -15,6 +15,7 @@ #ifdef HWRENDER #include "hw_glob.h" #include "hw_drv.h" +#include "hw_batching.h" #include "../doomstat.h" //gamemode #include "../i_video.h" //rendermode @@ -738,8 +739,11 @@ GLTexture_t *HWR_GetTexture(INT32 tex) if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) HWR_GenerateTexture(tex, grtex); - // Tell the hardware driver to bind the current texture to the flat's mipmap - HWD.pfnSetTexture(&grtex->mipmap); + // If hardware does not have the texture, then call pfnSetTexture to upload it + if (!grtex->mipmap.downloaded) + HWD.pfnSetTexture(&grtex->mipmap); + + HWR_SetCurrentTexture(&grtex->mipmap); // The system-memory data can be purged now. Z_ChangeTag(grtex->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED); @@ -818,7 +822,11 @@ void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum) if (!grmip->downloaded && !grmip->grInfo.data) HWR_CacheFlat(grmip, flatlumpnum); - HWD.pfnSetTexture(grmip); + // If hardware does not have the texture, then call pfnSetTexture to upload it + if (!grmip->downloaded) + HWD.pfnSetTexture(grmip); + + HWR_SetCurrentTexture(grmip); // The system-memory data can be purged now. Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED); @@ -852,14 +860,17 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) HWR_CacheTextureAsFlat(&grtex->mipmap, texturenum); - // Tell the hardware driver to bind the current texture to the flat's mipmap - HWD.pfnSetTexture(&grtex->mipmap); + // If hardware does not have the texture, then call pfnSetTexture to upload it + if (!grtex->mipmap.downloaded) + HWD.pfnSetTexture(&grtex->mipmap); + + HWR_SetCurrentTexture(&grtex->mipmap); // The system-memory data can be purged now. Z_ChangeTag(grtex->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED); } else // set no texture - HWD.pfnSetTexture(NULL); + HWR_SetCurrentTexture(NULL); } // @@ -881,7 +892,11 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) Z_Free(patch); } - HWD.pfnSetTexture(grmip); + // If hardware does not have the texture, then call pfnSetTexture to upload it + if (!grmip->downloaded) + HWD.pfnSetTexture(grmip); + + HWR_SetCurrentTexture(grmip); // The system-memory data can be purged now. Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED); @@ -908,7 +923,11 @@ void HWR_GetPatch(GLPatch_t *gpatch) Z_Free(ptr); } - HWD.pfnSetTexture(gpatch->mipmap); + // If hardware does not have the texture, then call pfnSetTexture to upload it + if (!gpatch->mipmap->downloaded) + HWD.pfnSetTexture(gpatch->mipmap); + + HWR_SetCurrentTexture(gpatch->mipmap); // The system-memory patch data can be purged now. Z_ChangeTag(gpatch->mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED); diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index a09f3f224..6cc45a363 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -36,6 +36,7 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal); EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl); EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color); EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags); +EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray); EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform); EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); @@ -89,6 +90,7 @@ struct hwdriver_s FinishUpdate pfnFinishUpdate; Draw2DLine pfnDraw2DLine; DrawPolygon pfnDrawPolygon; + DrawIndexedTriangles pfnDrawIndexedTriangles; RenderSkyDome pfnRenderSkyDome; SetBlend pfnSetBlend; ClearBuffer pfnClearBuffer; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7186f732f..3163b701a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -18,6 +18,7 @@ #include "hw_glob.h" #include "hw_light.h" #include "hw_drv.h" +#include "hw_batching.h" #include "../i_video.h" // for rendermode == render_glide #include "../v_video.h" @@ -150,6 +151,17 @@ int rs_hw_nodedrawtime = 0; int rs_hw_spritesorttime = 0; int rs_hw_spritedrawtime = 0; +// Render stats for batching +int rs_hw_numpolys = 0; +int rs_hw_numverts = 0; +int rs_hw_numcalls = 0; +int rs_hw_numshaders = 0; +int rs_hw_numtextures = 0; +int rs_hw_numpolyflags = 0; +int rs_hw_numcolors = 0; +int rs_hw_batchsorttime = 0; +int rs_hw_batchdrawtime = 0; + // ========================================================================== // Lighting @@ -351,6 +363,8 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; + int shader; + // no convex poly were generated for this subsector if (!xsub->planepoly) return; @@ -433,7 +447,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool } } else // set no texture - HWD.pfnSetTexture(NULL); + HWR_SetCurrentTexture(NULL); // reference point for flat texture coord for each vertex around the polygon flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatwidth); @@ -543,13 +557,13 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool PolyFlags |= PF_Masked|PF_Modulated; if (PolyFlags & PF_Fog) - HWD.pfnSetShader(6); // fog shader + shader = 6; // fog shader else if (PolyFlags & PF_Ripple) - HWD.pfnSetShader(5); // water shader + shader = 5; // water shader else - HWD.pfnSetShader(1); // floor shader + shader = 1; // floor shader - HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags); + HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false); if (subsector) { @@ -618,7 +632,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool horizonpts[4].y = gr_viewz; // Draw - HWD.pfnDrawPolygon(&Surf, horizonpts, 6, PolyFlags); + HWR_ProcessPolygon(&Surf, horizonpts, 6, PolyFlags, shader, true); } } } @@ -780,8 +794,7 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL { HWR_Lighting(pSurf, lightlevel, wallcolormap); - HWD.pfnSetShader(2); // wall shader - HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude); + HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude, 2, false); // wall shader #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) @@ -1009,7 +1022,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, // Draw walls into the depth buffer so that anything behind is culled properly static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf) { - HWD.pfnSetTexture(NULL); + HWR_SetCurrentTexture(NULL); // no texture wallVerts[3].t = wallVerts[2].t = 0; wallVerts[0].t = wallVerts[1].t = 0; @@ -2739,7 +2752,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, } } else // set no texture - HWD.pfnSetTexture(NULL); + HWR_SetCurrentTexture(NULL); // reference point for flat texture coord for each vertex around the polygon flatxref = (float)((polysector->origVerts[0].x & (~flatflag)) / fflatwidth); @@ -2837,8 +2850,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, else blendmode |= PF_Masked|PF_Modulated|PF_Clip; - HWD.pfnSetShader(1); // floor shader - HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode); + HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, 1, false); // floor shader } static void HWR_AddPolyObjectPlanes(void) @@ -3625,8 +3637,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) HWR_Lighting(&sSurf, 0, colormap); sSurf.PolyColor.s.alpha = alpha; - HWD.pfnSetShader(3); // sprite shader - HWD.pfnDrawPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); + HWR_ProcessPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated|PF_Clip, 3, false); // sprite shader } // This is expecting a pointer to an array containing 4 wallVerts for a sprite @@ -3889,8 +3900,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) Surf.PolyColor.s.alpha = alpha; - HWD.pfnSetShader(3); // sprite shader - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader top = bot; endtop = endbot; @@ -3916,8 +3926,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) Surf.PolyColor.s.alpha = alpha; - HWD.pfnSetShader(3); // sprite shader - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader } // -----------------+ @@ -4062,8 +4071,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) blend = PF_Translucent|PF_Occlude; } - HWD.pfnSetShader(3); // sprite shader - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader } } @@ -4162,8 +4170,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) blend = PF_Translucent|PF_Occlude; } - HWD.pfnSetShader(3); // sprite shader - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader } #endif @@ -5450,6 +5457,9 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) validcount++; + if (cv_grbatching.value) + HWR_StartBatching(); + HWR_RenderBSPNode((INT32)numnodes-1); #ifndef NEWCLIP @@ -5481,6 +5491,9 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) } #endif + if (cv_grbatching.value) + HWR_RenderBatches(); + // Check for new console commands. NetUpdate(); @@ -5661,6 +5674,9 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) validcount++; + if (cv_grbatching.value) + HWR_StartBatching(); + HWR_RenderBSPNode((INT32)numnodes-1); #ifndef NEWCLIP @@ -5694,6 +5710,9 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) rs_bsptime = I_GetTimeMicros() - rs_bsptime; + if (cv_grbatching.value) + HWR_RenderBatches(); + // Check for new console commands. NetUpdate(); @@ -5785,6 +5804,8 @@ consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotro consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grbatching = {"gr_batching", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + static void CV_grfiltermode_OnChange(void) { if (rendermode == render_opengl) @@ -5824,6 +5845,7 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grsolvetjoin); CV_RegisterVar(&cv_renderstats); + CV_RegisterVar(&cv_grbatching); #ifndef NEWCLIP CV_RegisterVar(&cv_grclipwalls); @@ -5949,12 +5971,14 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, FBITFIELD blendmode = blend; UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha + int shader; + // Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting HWR_Lighting(pSurf, lightlevel, wallcolormap); pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting - HWD.pfnSetShader(2); // wall shader + shader = 2; // wall shader if (blend & PF_Environment) blendmode |= PF_Occlude; // PF_Occlude must be used for solid objects @@ -5962,12 +5986,12 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, if (fogwall) { blendmode |= PF_Fog; - HWD.pfnSetShader(6); // fog shader + shader = 6; // fog shader } blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency - HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode); + HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode, shader, false); #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index fc49364da..4aadc2c39 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -96,6 +96,8 @@ extern consvar_t cv_grskydome; extern consvar_t cv_grfakecontrast; extern consvar_t cv_grslopecontrast; +extern consvar_t cv_grbatching; + extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy; extern float gr_viewwindowx, gr_basewindowcentery; @@ -111,4 +113,15 @@ extern int rs_hw_nodedrawtime; extern int rs_hw_spritesorttime; extern int rs_hw_spritedrawtime; +// Render stats for batching +extern int rs_hw_numpolys; +extern int rs_hw_numverts; +extern int rs_hw_numcalls; +extern int rs_hw_numshaders; +extern int rs_hw_numtextures; +extern int rs_hw_numpolyflags; +extern int rs_hw_numcolors; +extern int rs_hw_batchsorttime; +extern int rs_hw_batchdrawtime; + #endif diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d80de8aad..bbeec6e0b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1945,10 +1945,9 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF #endif } -// -----------------+ -// DrawPolygon : Render a polygon, set the texture, set render mode -// -----------------+ -EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags) +// code that is common between DrawPolygon and DrawIndexedTriangles +// the corona thing is there too, i have no idea if that stuff works with DrawIndexedTriangles and batching +static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD PolyFlags) { static GLRGBAFloat poly = {0,0,0,0}; static GLRGBAFloat tint = {0,0,0,0}; @@ -2013,10 +2012,10 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI //GL_DBG_Printf("Projection: (%f, %f, %f)\n", px, py, pz); if ((pz < 0.0l) || - (px < -8.0l) || - (py < viewport[1]-8.0l) || - (px > viewport[2]+8.0l) || - (py > viewport[1]+viewport[3]+8.0l)) + (px < -8.0l) || + (py < viewport[1]-8.0l) || + (px > viewport[2]+8.0l) || + (py > viewport[1]+viewport[3]+8.0l)) return; // the damned slow glReadPixels functions :( @@ -2051,6 +2050,14 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI } Shader_Load(pSurf, &poly, &tint, &fade); +} + +// -----------------+ +// DrawPolygon : Render a polygon, set the texture, set render mode +// -----------------+ +EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags) +{ + PreparePolygon(pSurf, pOutVerts, PolyFlags); pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s); @@ -2066,6 +2073,17 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI Clamp2D(GL_TEXTURE_WRAP_T); } +EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray) +{ + PreparePolygon(pSurf, pOutVerts, PolyFlags); + + pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); + pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s); + pglDrawElements(GL_TRIANGLES, iNumPts, GL_UNSIGNED_INT, IndexArray); + + // the DrawPolygon variant of this has some code about polyflags and wrapping here but havent noticed any problems from omitting it? +} + typedef struct vbo_vertex_s { float x, y, z; diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index 6a55ac2d6..c24104b92 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -220,6 +220,7 @@ + @@ -370,6 +371,7 @@ + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index 89ba1b588..2f0aec7ca 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -219,6 +219,9 @@ Hw_Hardware + + Hw_Hardware + Hw_Hardware @@ -636,6 +639,9 @@ Hw_Hardware + + Hw_Hardware + Hw_Hardware diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 974ac5edd..416c8d2f5 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -80,6 +80,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(Init); GETFUNC(Draw2DLine); GETFUNC(DrawPolygon); + GETFUNC(DrawIndexedTriangles); GETFUNC(RenderSkyDome); GETFUNC(SetBlend); GETFUNC(ClearBuffer); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index f06e10124..8bff5690f 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1824,6 +1824,7 @@ void VID_StartupOpenGL(void) HWD.pfnFinishUpdate = NULL; HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnDrawIndexedTriangles = hwSym("DrawIndexedTriangles",NULL); HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",NULL); HWD.pfnSetBlend = hwSym("SetBlend",NULL); HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); From 0e521922c65787bea07d5fb3bdf198bade290e40 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sun, 7 Jun 2020 21:32:52 +0300 Subject: [PATCH 132/168] Change some unsigned ints to UINT32 --- src/hardware/hw_batching.c | 6 +++--- src/hardware/hw_drv.h | 2 +- src/hardware/r_opengl/r_opengl.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 4e11b0ab7..8abbccce0 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -32,7 +32,7 @@ int finalVertexArrayAllocSize = 65536; PolygonArrayEntry* polygonArray = NULL;// contains the polygon data from DrawPolygon, waiting to be processed int polygonArraySize = 0; -unsigned int* polygonIndexArray = NULL;// contains sorting pointers for polygonArray +UINT32* polygonIndexArray = NULL;// contains sorting pointers for polygonArray int polygonArrayAllocSize = 65536; FOutVector* unsortedVertexArray = NULL;// contains unsorted vertices and texture coordinates from DrawPolygon @@ -52,7 +52,7 @@ void HWR_StartBatching(void) finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector)); finalVertexIndexArray = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32)); polygonArray = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry)); - polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(unsigned int)); + polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(UINT32)); unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector)); } @@ -94,7 +94,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt polygonArray = new_array; // also need to redo the index array, dont need to copy it though free(polygonIndexArray); - polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(unsigned int)); + polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(UINT32)); } while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 6cc45a363..50ac6cbec 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -36,7 +36,7 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal); EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl); EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color); EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags); -EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray); +EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, UINT32 *IndexArray); EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform); EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index bbeec6e0b..f08fae105 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2073,7 +2073,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI Clamp2D(GL_TEXTURE_WRAP_T); } -EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray) +EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, UINT32 *IndexArray) { PreparePolygon(pSurf, pOutVerts, PolyFlags); From 3dd89f67fae188d49c1cf23d2bbcdb210ede1b44 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 8 Jun 2020 19:56:24 -0400 Subject: [PATCH 133/168] Fix no previous prototype for TimeFunction --- src/sdl/i_system.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index cd6555f55..191268011 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -54,6 +54,12 @@ 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 From 2abdc865377c2a80c76b0b39983d1702848da5dd Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 8 Jun 2020 20:18:32 -0400 Subject: [PATCH 134/168] Fix these "may be used uninitialized in this function" errors with batching --- src/hardware/hw_batching.c | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 8abbccce0..8a19ee0e6 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -138,7 +138,7 @@ static int comparePolygons(const void *p1, const void *p2) PolygonArrayEntry* poly2 = &polygonArray[index2]; int diff; INT64 diff64; - + int shader1 = poly1->shader; int shader2 = poly2->shader; // make skywalls and horizon lines first in order @@ -152,20 +152,20 @@ static int comparePolygons(const void *p1, const void *p2) // skywalls and horizon lines must retain their order for horizon lines to work if (shader1 == -1 && shader2 == -1) return index1 - index2; - + diff64 = poly1->texture - poly2->texture; if (diff64 != 0) return diff64; - + diff = poly1->polyFlags - poly2->polyFlags; if (diff != 0) return diff; - + diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba; if (diff64 < 0) return -1; else if (diff64 > 0) return 1; diff64 = poly1->surf.TintColor.rgba - poly2->surf.TintColor.rgba; if (diff64 < 0) return -1; else if (diff64 > 0) return 1; diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba; if (diff64 < 0) return -1; else if (diff64 > 0) return 1; - + diff = poly1->surf.LightInfo.light_level - poly2->surf.LightInfo.light_level; if (diff != 0) return diff; diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start; @@ -182,7 +182,7 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2) PolygonArrayEntry* poly2 = &polygonArray[index2]; int diff; INT64 diff64; - + GLMipmap_t *texture1 = poly1->texture; GLMipmap_t *texture2 = poly2->texture; if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) @@ -195,10 +195,10 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2) // skywalls and horizon lines must retain their order for horizon lines to work if (texture1 == NULL && texture2 == NULL) return index1 - index2; - + diff = poly1->polyFlags - poly2->polyFlags; if (diff != 0) return diff; - + diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba; if (diff64 < 0) return -1; else if (diff64 > 0) return 1; @@ -262,19 +262,19 @@ void HWR_RenderBatches(void) currentSurfaceInfo = polygonArray[polygonIndexArray[0]].surf; // For now, will sort and track the colors. Vertex attributes could be used instead of uniforms // and a color array could replace the color calls. - + // set state for first batch - + if (cv_grshaders.value) // TODO also have the shader availability check here when its done { HWD.pfnSetShader(currentShader); } - + if (currentPolyFlags & PF_NoTexture) currentTexture = NULL; else HWD.pfnSetTexture(currentTexture); - + while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons) { int firstIndex; @@ -283,13 +283,13 @@ void HWR_RenderBatches(void) boolean stopFlag = false; boolean changeState = false; boolean changeShader = false; - int nextShader; + int nextShader = 0; boolean changeTexture = false; - GLMipmap_t *nextTexture; + GLMipmap_t *nextTexture = NULL; boolean changePolyFlags = false; - FBITFIELD nextPolyFlags; + FBITFIELD nextPolyFlags = 0; boolean changeSurfaceInfo = false; - FSurfaceInfo nextSurfaceInfo; + FSurfaceInfo nextSurfaceInfo = {0}; // steps: // write vertices @@ -301,7 +301,7 @@ void HWR_RenderBatches(void) // change states according to next vars and change bools, updating the current vars and reseting the bools // reset write pos // repeat loop - + int index = polygonIndexArray[polygonReadPos++]; int numVerts = polygonArray[index].numVerts; // before writing, check if there is enough room @@ -336,7 +336,7 @@ void HWR_RenderBatches(void) finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos - 1; finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos++; } - + if (polygonReadPos >= polygonArraySize) { stopFlag = true; @@ -388,7 +388,7 @@ void HWR_RenderBatches(void) } } } - + if (changeState || stopFlag) { // execute draw call @@ -401,10 +401,10 @@ void HWR_RenderBatches(void) finalIndexWritePos = 0; } else continue; - + // if we're here then either its time to stop or time to change state if (stopFlag) break; - + // change state according to change bools and next vars, update current vars and reset bools if (changeShader) { @@ -442,7 +442,7 @@ void HWR_RenderBatches(void) // reset the arrays (set sizes to 0) polygonArraySize = 0; unsortedVertexArraySize = 0; - + rs_hw_batchdrawtime = I_GetTimeMicros() - rs_hw_batchdrawtime; } From 0d70e16b0bf13fc80fc8e43c309f47a51c837c5c Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 11 Jun 2020 15:11:01 -0500 Subject: [PATCH 135/168] Updated LUAh_GameQuit to use new error handler --- src/lua_hooklib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 0d8aa1ffb..854f3ddfe 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1778,13 +1778,15 @@ void LUAh_GameQuit(void) if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8)))) return; + lua_pushcfunction(gL, LUA_GetErrorMessage); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_GameQuit) continue; PushHook(gL, hookp); - if (lua_pcall(gL, 0, 0, 0)) { + if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); From 6eccc7030d8afccec76f285b70f2aa5a1ddf1897 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Fri, 12 Jun 2020 07:50:57 -0500 Subject: [PATCH 136/168] I forgot to pop the error handler --- src/lua_hooklib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 854f3ddfe..5cfd1bd3d 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1793,4 +1793,6 @@ void LUAh_GameQuit(void) hookp->error = true; } } -} \ No newline at end of file + + lua_pop(gL, 1); // Pop error handler +} From d3d5496a7834da0864897c9d005b2a372017b2fa Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 17 Jun 2020 14:09:49 -0400 Subject: [PATCH 137/168] Fix facecolor may be used uninitialized. --- src/p_enemy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 146c8f1aa..578874574 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5106,9 +5106,11 @@ void A_SignPlayer(mobj_t *actor) INT32 locvar2 = var2; skin_t *skin = NULL; mobj_t *ov; - UINT16 facecolor, signcolor = (UINT16)locvar2; + UINT16 facecolor, signcolor = 0; UINT32 signframe = states[actor->info->raisestate].frame; + facecolor = signcolor = (UINT16)locvar2; + if (LUA_CallAction("A_SignPlayer", actor)) return; From a34be0e370f1a443c991f76ce04565cf48168715 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 17 Jun 2020 14:19:19 -0400 Subject: [PATCH 138/168] Reduce code duplication by creating get_zlib_error function Reduce calls to gme_set_equalizer in I_LoadSong by moving it to I_PlaySong Return false if it fails to decompress VGZ data in some form. --- src/sdl/mixer_sound.c | 126 +++++++++++------------------------------- 1 file changed, 33 insertions(+), 93 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 5a086880a..c5b1455a2 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -219,6 +219,28 @@ static void var_cleanup(void) internal_volume = 100; } + +static const char* get_zlib_error(int zErr) +{ + switch (zErr) + { + case Z_ERRNO: + return "Z_ERRNO"; + case Z_STREAM_ERROR: + return "Z_STREAM_ERROR"; + case Z_DATA_ERROR: + return "Z_DATA_ERROR"; + case Z_MEM_ERROR: + return "Z_MEM_ERROR"; + case Z_BUF_ERROR: + return "Z_BUF_ERROR"; + case Z_VERSION_ERROR: + return "Z_VERSION_ERROR"; + default: + return "unknown error"; + } +} + /// ------------------------ /// Audio System /// ------------------------ @@ -498,51 +520,11 @@ void *I_GetSfx(sfxinfo_t *sfx) } } else - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", get_zlib_error(zErr), stream.msg); (void)inflateEnd(&stream); } else // Hold up, zlib's got a problem - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", get_zlib_error(zErr), stream.msg); Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up #else return NULL; // No zlib support @@ -1175,77 +1157,33 @@ boolean I_LoadSong(char *data, size_t len) if (zErr == Z_OK) // We're good to go { zErr = inflate(&stream, Z_FINISH); - if (zErr == Z_STREAM_END) { + if (zErr == Z_STREAM_END) + { // Run GME on new data if (!gme_open_data(inflatedData, inflatedLen, &gme, 44100)) { - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; gme_start_track(gme, 0); current_track = 0; - gme_set_equalizer(gme, &eq); Mix_HookMusic(mix_gme, gme); Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around return true; } } else - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR, "Encountered %s when running inflate: %s\n", get_zlib_error(zErr), stream.msg); (void)inflateEnd(&stream); } else // Hold up, zlib's got a problem - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR, "Encountered %s when running inflateInit: %s\n", get_zlib_error(zErr), stream.msg); Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up + return false; #else - CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); - return true; + CONS_Alert(CONS_ERROR, "Cannot decompress VGZ; no zlib support\n"); + return false; #endif } else if (!gme_open_data(data, len, &gme, 44100)) - { - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - gme_set_equalizer(gme, &eq); return true; - } #endif #ifdef HAVE_MIXERX @@ -1360,6 +1298,8 @@ boolean I_PlaySong(boolean looping) #ifdef HAVE_LIBGME if (gme) { + gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; + gme_set_equalizer(gme, &eq); gme_start_track(gme, 0); current_track = 0; Mix_HookMusic(mix_gme, gme); From f626b9f4d9f7500c59eb64488c89fd5b4559d48d Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 17 Jun 2020 14:31:49 -0400 Subject: [PATCH 139/168] Fix VGZ sometimes causing SRB2 to crash by not playing the song early in I_LoadSong --- src/sdl/mixer_sound.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index c5b1455a2..c512c7ac5 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -1162,9 +1162,6 @@ boolean I_LoadSong(char *data, size_t len) // Run GME on new data if (!gme_open_data(inflatedData, inflatedLen, &gme, 44100)) { - gme_start_track(gme, 0); - current_track = 0; - Mix_HookMusic(mix_gme, gme); Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around return true; } From 5708325d2b24f08661cd2b10119c422ee0b7be38 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 17 Jun 2020 14:50:22 -0400 Subject: [PATCH 140/168] Use SAMPLERATE for consistency with the rest of the code --- src/sdl/mixer_sound.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index c512c7ac5..ef34b266d 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -497,7 +497,7 @@ void *I_GetSfx(sfxinfo_t *sfx) zErr = inflate(&stream, Z_FINISH); if (zErr == Z_STREAM_END) { // Run GME on new data - if (!gme_open_data(inflatedData, inflatedLen, &emu, 44100)) + if (!gme_open_data(inflatedData, inflatedLen, &emu, SAMPLERATE)) { short *mem; UINT32 len; @@ -531,7 +531,7 @@ void *I_GetSfx(sfxinfo_t *sfx) #endif } // Try to read it as a GME sound - else if (!gme_open_data(lump, sfx->length, &emu, 44100)) + else if (!gme_open_data(lump, sfx->length, &emu, SAMPLERATE)) { short *mem; UINT32 len; @@ -1160,7 +1160,7 @@ boolean I_LoadSong(char *data, size_t len) if (zErr == Z_STREAM_END) { // Run GME on new data - if (!gme_open_data(inflatedData, inflatedLen, &gme, 44100)) + if (!gme_open_data(inflatedData, inflatedLen, &gme, SAMPLERATE)) { Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around return true; @@ -1179,7 +1179,7 @@ boolean I_LoadSong(char *data, size_t len) return false; #endif } - else if (!gme_open_data(data, len, &gme, 44100)) + else if (!gme_open_data(data, len, &gme, SAMPLERATE)) return true; #endif From 1e655fb2c14920076ce5102af5c7b7382411d0f3 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 17 Jun 2020 18:23:54 -0400 Subject: [PATCH 141/168] Better fix for may be used uninitialized, maybe fixes GCC 4.x --- src/hardware/hw_batching.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 8a19ee0e6..a574c7879 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -215,9 +215,13 @@ void HWR_RenderBatches(void) int polygonReadPos = 0;// position in polygonIndexArray int currentShader; + int nextShader; GLMipmap_t *currentTexture; + GLMipmap_t *nextTexture; FBITFIELD currentPolyFlags; + FBITFIELD nextPolyFlags; FSurfaceInfo currentSurfaceInfo; + FSurfaceInfo nextSurfaceInfo; int i; @@ -283,13 +287,9 @@ void HWR_RenderBatches(void) boolean stopFlag = false; boolean changeState = false; boolean changeShader = false; - int nextShader = 0; boolean changeTexture = false; - GLMipmap_t *nextTexture = NULL; boolean changePolyFlags = false; - FBITFIELD nextPolyFlags = 0; boolean changeSurfaceInfo = false; - FSurfaceInfo nextSurfaceInfo = {0}; // steps: // write vertices From 8365d975d3cba63dd2e96187bab785c73112a6ee Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 17 Jun 2020 18:40:56 -0400 Subject: [PATCH 142/168] A even more better fix for this --- src/hardware/hw_batching.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index a574c7879..67cda0305 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -215,11 +215,11 @@ void HWR_RenderBatches(void) int polygonReadPos = 0;// position in polygonIndexArray int currentShader; - int nextShader; + int nextShader = 0; GLMipmap_t *currentTexture; - GLMipmap_t *nextTexture; - FBITFIELD currentPolyFlags; - FBITFIELD nextPolyFlags; + GLMipmap_t *nextTexture = NULL; + FBITFIELD currentPolyFlags = 0; + FBITFIELD nextPolyFlags = 0; FSurfaceInfo currentSurfaceInfo; FSurfaceInfo nextSurfaceInfo; @@ -228,6 +228,10 @@ void HWR_RenderBatches(void) if (!currently_batching) I_Error("HWR_RenderBatches called without starting batching"); + nextSurfaceInfo.LightInfo.fade_end = 0; + nextSurfaceInfo.LightInfo.fade_start = 0; + nextSurfaceInfo.LightInfo.light_level = 0; + currently_batching = false;// no longer collecting batches if (!polygonArraySize) { From 9477d372b9d237ec0c0cff0ebad2a4dc65c235cb Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Thu, 18 Jun 2020 17:39:34 +0300 Subject: [PATCH 143/168] Backwards compatibility for shaderless hardware --- src/hardware/hw_batching.c | 10 +++++----- src/hardware/hw_drv.h | 4 ++-- src/hardware/hw_main.c | 13 ++++++++----- src/hardware/hw_main.h | 4 +++- src/hardware/r_opengl/r_opengl.c | 15 +++++++++------ 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 67cda0305..5c5379f6d 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -250,7 +250,7 @@ void HWR_RenderBatches(void) // sort polygons rs_hw_batchsorttime = I_GetTimeMicros(); - if (cv_grshaders.value) // TODO also have the shader availability check here when its done + if (cv_grshaders.value && gr_shadersavailable) qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons); else qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders); @@ -272,8 +272,8 @@ void HWR_RenderBatches(void) // and a color array could replace the color calls. // set state for first batch - - if (cv_grshaders.value) // TODO also have the shader availability check here when its done + + if (cv_grshaders.value && gr_shadersavailable) { HWD.pfnSetShader(currentShader); } @@ -355,7 +355,7 @@ void HWR_RenderBatches(void) nextSurfaceInfo = polygonArray[nextIndex].surf; if (nextPolyFlags & PF_NoTexture) nextTexture = 0; - if (currentShader != nextShader) + if (currentShader != nextShader && cv_grshaders.value && gr_shadersavailable) { changeState = true; changeShader = true; @@ -370,7 +370,7 @@ void HWR_RenderBatches(void) changeState = true; changePolyFlags = true; } - if (cv_grshaders.value) // TODO also have the shader availability check here when its done + if (cv_grshaders.value && gr_shadersavailable) { if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba || currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba || diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 50ac6cbec..2e4ea10cc 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -68,14 +68,14 @@ EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height); EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); // jimita -EXPORT void HWRAPI(LoadShaders) (void); +EXPORT boolean HWRAPI(LoadShaders) (void); EXPORT void HWRAPI(KillShaders) (void); EXPORT void HWRAPI(SetShader) (int shader); EXPORT void HWRAPI(UnSetShader) (void); EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value); EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment); -EXPORT void HWRAPI(InitCustomShaders) (void); +EXPORT boolean HWRAPI(InitCustomShaders) (void); // ========================================================================== // HWR DRIVER OBJECT, FOR CLIENT PROGRAM diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3163b701a..b89ffe9e6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -162,6 +162,8 @@ int rs_hw_numcolors = 0; int rs_hw_batchsorttime = 0; int rs_hw_batchdrawtime = 0; +boolean gr_shadersavailable = true; + // ========================================================================== // Lighting @@ -176,7 +178,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : GL_DEFAULTFOG; // Crappy backup coloring if you can't do shaders - if (!cv_grshaders.value) + if (!cv_grshaders.value || !gr_shadersavailable) { // be careful, this may get negative for high lightlevel values. float tint_alpha, fade_alpha; @@ -227,7 +229,7 @@ UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if realcolor.rgba = (colormap != NULL) ? colormap->rgba : GL_DEFAULTMIX; - if (cv_grshaders.value) + if (cv_grshaders.value && gr_shadersavailable) { surfcolor.s.alpha = (255 - light); } @@ -5887,7 +5889,8 @@ void HWR_Startup(void) // read every custom shader for (i = 0; i < numwadfiles; i++) HWR_ReadShaders(i, (wadfiles[i]->type == RET_PK3)); - HWR_LoadShaders(); + if (!HWR_LoadShaders()) + gr_shadersavailable = false; } if (rendermode == render_opengl) @@ -6190,9 +6193,9 @@ static inline UINT16 HWR_CheckShader(UINT16 wadnum) return INT16_MAX; } -void HWR_LoadShaders(void) +boolean HWR_LoadShaders(void) { - HWD.pfnInitCustomShaders(); + return HWD.pfnInitCustomShaders(); } void HWR_ReadShaders(UINT16 wadnum, boolean PK3) diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 4aadc2c39..21bd7ddb3 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -70,7 +70,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work void HWR_ReadShaders(UINT16 wadnum, boolean PK3); -void HWR_LoadShaders(void); +boolean HWR_LoadShaders(void); extern CV_PossibleValue_t granisotropicmode_cons_t[]; @@ -124,4 +124,6 @@ extern int rs_hw_numcolors; extern int rs_hw_batchsorttime; extern int rs_hw_batchdrawtime; +extern boolean gr_shadersavailable; + #endif diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6fe9f7a36..41ec703bc 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -866,12 +866,14 @@ void SetupGLFunc4(void) } // jimita -EXPORT void HWRAPI(LoadShaders) (void) +EXPORT boolean HWRAPI(LoadShaders) (void) { #ifdef GL_SHADERS GLuint gl_vertShader, gl_fragShader; GLint i, result; + if (!pglUseProgram) return false; + gl_customvertexshaders[0] = NULL; gl_customfragmentshaders[0] = NULL; @@ -993,6 +995,7 @@ EXPORT void HWRAPI(LoadShaders) (void) #undef GETUNI } #endif + return true; } // @@ -1023,6 +1026,7 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value) EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment) { #ifdef GL_SHADERS + if (!pglUseProgram) return; if (number < 1 || number > MAXSHADERS) I_Error("LoadCustomShader(): cannot load shader %d (max %d)", number, MAXSHADERS); @@ -1046,11 +1050,11 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boo #endif } -EXPORT void HWRAPI(InitCustomShaders) (void) +EXPORT boolean HWRAPI(InitCustomShaders) (void) { #ifdef GL_SHADERS KillShaders(); - LoadShaders(); + return LoadShaders(); #endif } @@ -1078,6 +1082,7 @@ EXPORT void HWRAPI(UnSetShader) (void) #ifdef GL_SHADERS gl_shadersenabled = false; gl_currentshaderprogram = 0; + if (!pglUseProgram) return; pglUseProgram(0); #endif } @@ -1868,7 +1873,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) static void *Shader_Load(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade) { #ifdef GL_SHADERS - if (gl_shadersenabled) + if (gl_shadersenabled && pglUseProgram) { gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram]; if (shader->program) @@ -1884,8 +1889,6 @@ static void *Shader_Load(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat * else pglUseProgram(0); } - else - pglUseProgram(0); #else (void)Surface; (void)poly; From 7b2e54b426b744db66bcefed5e4ff3d6049d63e3 Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 19 Jun 2020 00:52:24 +0800 Subject: [PATCH 144/168] Fix Dragonbomber z positioning --- src/info.c | 2 +- src/p_mobj.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index f0272fc79..123269656 100644 --- a/src/info.c +++ b/src/info.c @@ -5292,7 +5292,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_BOUNCE|MF_RUNSPAWNFUNC, // flags + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_SLIDEME|MF_RUNSPAWNFUNC, // flags S_NULL // raisestate }, diff --git a/src/p_mobj.c b/src/p_mobj.c index f690ad894..44091d4ef 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9206,10 +9206,11 @@ static void P_DragonbomberThink(mobj_t *mobj) mobj->angle += DRAGONTURNSPEED; else { + boolean flip = mobj->spawnpoint->options & MTF_OBJECTFLIP; fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale); fixed_t x = mobj->spawnpoint->x << FRACBITS; fixed_t y = mobj->spawnpoint->y << FRACBITS; - fixed_t z = mobj->spawnpoint->z << FRACBITS; + fixed_t z = (flip ? P_GetSectorCeilingZAt : P_GetSectorFloorZAt)(R_PointInSubsector(x, y)->sector, x, y) + (flip ? -1 : 1)*(mobj->spawnpoint->z << FRACBITS); angle_t diff = R_PointToAngle2(mobj->x, mobj->y, x, y) - mobj->angle; if (diff > ANGLE_180) mobj->angle -= DRAGONTURNSPEED; From ffaffdf3e1a24e60daaad99056ef11e9bf68f64a Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Thu, 18 Jun 2020 19:40:14 +0300 Subject: [PATCH 145/168] Faster and more correct OGL transparent surface sorting --- src/hardware/hw_main.c | 172 +++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 101 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3163b701a..97e0d46ed 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4400,28 +4400,66 @@ void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polyse numpolyplanes++; } +// putting sortindex and sortnode here so the comparator function can see them +gr_drawnode_t *sortnode; +size_t *sortindex; + +static int CompareDrawNodes(const void *p1, const void *p2) +{ + size_t n1 = *(const size_t*)p1; + size_t n2 = *(const size_t*)p2; + INT32 v1 = 0; + INT32 v2 = 0; + INT32 diff; + if (sortnode[n1].plane) + v1 = sortnode[n1].plane->drawcount; + else if (sortnode[n1].polyplane) + v1 = sortnode[n1].polyplane->drawcount; + else if (sortnode[n1].wall) + v1 = sortnode[n1].wall->drawcount; + else I_Error("CompareDrawNodes: n1 unknown"); + + if (sortnode[n2].plane) + v2 = sortnode[n2].plane->drawcount; + else if (sortnode[n2].polyplane) + v2 = sortnode[n2].polyplane->drawcount; + else if (sortnode[n2].wall) + v2 = sortnode[n2].wall->drawcount; + else I_Error("CompareDrawNodes: n2 unknown"); + + diff = v2 - v1; + if (diff == 0) I_Error("CompareDrawNodes: diff is zero"); + return diff; +} + +static int CompareDrawNodePlanes(const void *p1, const void *p2) +{ + size_t n1 = *(const size_t*)p1; + size_t n2 = *(const size_t*)p2; + if (!sortnode[n1].plane) I_Error("CompareDrawNodePlanes: Uh.. This isn't a plane! (n1)"); + if (!sortnode[n2].plane) I_Error("CompareDrawNodePlanes: Uh.. This isn't a plane! (n2)"); + return ABS(sortnode[n2].plane->fixedheight - viewz) - ABS(sortnode[n1].plane->fixedheight - viewz); +} + // // HWR_CreateDrawNodes // Creates and sorts a list of drawnodes for the scene being rendered. static void HWR_CreateDrawNodes(void) { - UINT32 i = 0, p = 0, prev = 0, loop; - const fixed_t pviewz = dup_viewz; + UINT32 i = 0, p = 0; + size_t run_start = 0; // Dump EVERYTHING into a huge drawnode list. Then we'll sort it! // Could this be optimized into _AddTransparentWall/_AddTransparentPlane? // Hell yes! But sort algorithm must be modified to use a linked list. - gr_drawnode_t *sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes) - + (sizeof(polyplaneinfo_t)*numpolyplanes) - + (sizeof(wallinfo_t)*numwalls) - ,PU_STATIC, NULL); + sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes) + + (sizeof(polyplaneinfo_t)*numpolyplanes) + + (sizeof(wallinfo_t)*numwalls) + ,PU_STATIC, NULL); // todo: // However, in reality we shouldn't be re-copying and shifting all this information // that is already lying around. This should all be in some sort of linked list or lists. - size_t *sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); - - // If true, swap the draw order. - boolean shift = false; + sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); rs_hw_nodesorttime = I_GetTimeMicros(); @@ -4447,104 +4485,36 @@ static void HWR_CreateDrawNodes(void) // p is the number of stuff to sort - // Add the 3D floors, thicksides, and masked textures... - // Instead of going through drawsegs, we need to iterate - // through the lists of masked textures and - // translucent ffloors being drawn. + // sort the list based on the value of the 'drawcount' member of the drawnodes. + qsort(sortindex, p, sizeof(size_t), CompareDrawNodes); - // This is a bubble sort! Wahoo! - - // Stuff is sorted: - // sortnode[sortindex[0]] = farthest away - // sortnode[sortindex[p-1]] = closest - // "i" should be closer. "prev" should be further. - // The lower drawcount is, the further it is from the screen. - - for (loop = 0; loop < p; loop++) + // an additional pass is needed to correct the order of consecutive planes in the list. + // for each consecutive run of planes in the list, sort that run based on plane height and view height. + while (run_start < p-1)// p-1 because a 1 plane run at the end of the list does not count { - for (i = 1; i < p; i++) + // locate run start + if (sortnode[sortindex[run_start]].plane) { - prev = i-1; - if (sortnode[sortindex[i]].plane) + // found it, now look for run end + size_t run_end;// (inclusive) + for (i = run_start+1; i < p; i++)// size_t and UINT32 being used mixed here... shouldnt break anything though.. { - // What are we comparing it with? - if (sortnode[sortindex[prev]].plane) - { - // Plane (i) is further away than plane (prev) - if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz)) - shift = true; - } - if (sortnode[sortindex[prev]].polyplane) - { - // Plane (i) is further away than polyplane (prev) - if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].polyplane->fixedheight - pviewz)) - shift = true; - } - else if (sortnode[sortindex[prev]].wall) - { - // Plane (i) is further than wall (prev) - if (sortnode[sortindex[i]].plane->drawcount > sortnode[sortindex[prev]].wall->drawcount) - shift = true; - } + if (!sortnode[sortindex[i]].plane) break; } - else if (sortnode[sortindex[i]].polyplane) + run_end = i-1; + if (run_end > run_start)// if there are multiple consecutive planes, not just one { - // What are we comparing it with? - if (sortnode[sortindex[prev]].plane) - { - // Plane (i) is further away than plane (prev) - if (ABS(sortnode[sortindex[i]].polyplane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz)) - shift = true; - } - if (sortnode[sortindex[prev]].polyplane) - { - // Plane (i) is further away than polyplane (prev) - if (ABS(sortnode[sortindex[i]].polyplane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].polyplane->fixedheight - pviewz)) - shift = true; - } - else if (sortnode[sortindex[prev]].wall) - { - // Plane (i) is further than wall (prev) - if (sortnode[sortindex[i]].polyplane->drawcount > sortnode[sortindex[prev]].wall->drawcount) - shift = true; - } + // consecutive run of planes found, now sort it + qsort(sortindex + run_start, run_end - run_start + 1, sizeof(size_t), CompareDrawNodePlanes); } - else if (sortnode[sortindex[i]].wall) - { - // What are we comparing it with? - if (sortnode[sortindex[prev]].plane) - { - // Wall (i) is further than plane(prev) - if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].plane->drawcount) - shift = true; - } - if (sortnode[sortindex[prev]].polyplane) - { - // Wall (i) is further than polyplane(prev) - if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].polyplane->drawcount) - shift = true; - } - else if (sortnode[sortindex[prev]].wall) - { - // Wall (i) is further than wall (prev) - if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].wall->drawcount) - shift = true; - } - } - - if (shift) - { - size_t temp; - - temp = sortindex[prev]; - sortindex[prev] = sortindex[i]; - sortindex[i] = temp; - - shift = false; - } - - } //i++ - } // loop++ + run_start = run_end + 1;// continue looking for runs coming right after this one + } + else + { + // this wasnt the run start, try next one + run_start++; + } + } rs_hw_nodesorttime = I_GetTimeMicros() - rs_hw_nodesorttime; From 47d9d876547a4a3713ccaa52a97ed887734cba5f Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 19 Jun 2020 15:49:24 +0800 Subject: [PATCH 146/168] Fix the Eggman signpost's background color --- src/info.c | 2 +- src/p_enemy.c | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/info.c b/src/info.c index f0272fc79..bb76b538f 100644 --- a/src/info.c +++ b/src/info.c @@ -21691,7 +21691,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET {"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC {"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM - {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 15, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY + {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY {"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY // super diff --git a/src/p_enemy.c b/src/p_enemy.c index 578874574..1693d6e55 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5142,12 +5142,10 @@ void A_SignPlayer(mobj_t *actor) ; else if (!skin->sprites[SPR2_SIGN].numframes) signcolor = facecolor; - else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? + else if ((facecolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? signcolor = skin->prefoppositecolor; - else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor. - signcolor = skincolors[actor->target->player->skincolor].invcolor; - else - signcolor = SKINCOLOR_NONE; + else if (facecolor) // Set the sign to be an appropriate background color for this player's skincolor. + signcolor = skincolors[facecolor].invcolor; } else if (locvar1 != -3) // set to a defined skin { @@ -5205,12 +5203,12 @@ void A_SignPlayer(mobj_t *actor) } else // Eggman face { - ov->color = SKINCOLOR_NONE; ov->skin = NULL; if ((statenum_t)(ov->state-states) != actor->info->meleestate) P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN if (!signcolor) signcolor = SKINCOLOR_CARBON; + ov->color = signcolor; } actor->tracer->color = signcolor; From cab87b46320c7d0133e14f6670d0ca6a0be235b5 Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 19 Jun 2020 15:59:09 +0800 Subject: [PATCH 147/168] lol should have tested before pushing --- src/p_enemy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 1693d6e55..a9c160254 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5203,12 +5203,13 @@ void A_SignPlayer(mobj_t *actor) } else // Eggman face { + ov->color = SKINCOLOR_NONE; ov->skin = NULL; if ((statenum_t)(ov->state-states) != actor->info->meleestate) P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN if (!signcolor) signcolor = SKINCOLOR_CARBON; - ov->color = signcolor; + facecolor = signcolor; } actor->tracer->color = signcolor; From 6f9b9aacf49770a8087b4426c3249a88be2621b4 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Fri, 19 Jun 2020 14:32:34 +0300 Subject: [PATCH 148/168] Faster OGL sprite sorting algorithm --- src/hardware/hw_glob.h | 3 - src/hardware/hw_main.c | 170 ++++++++++++++--------------------------- 2 files changed, 56 insertions(+), 117 deletions(-) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 861c2f382..d8ea7c7a3 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -61,9 +61,6 @@ typedef struct // equivalent of the software renderer's vissprites typedef struct gr_vissprite_s { - // Doubly linked list - struct gr_vissprite_s *prev; - struct gr_vissprite_s *next; float x1, x2; float tz, ty; //lumpnum_t patchlumpnum; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b89ffe9e6..54f172046 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4179,96 +4179,45 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) // -------------------------------------------------------------------------- // Sort vissprites by distance // -------------------------------------------------------------------------- -static gr_vissprite_t gr_vsprsortedhead; +gr_vissprite_t* gr_vsprorder[MAXVISSPRITES]; -static void HWR_SortVisSprites(void) +// Note: For more correct transparency the transparent sprites would need to be +// sorted and drawn together with transparent surfaces. +static int CompareVisSprites(const void *p1, const void *p2) { - UINT32 i; - gr_vissprite_t *ds, *dsprev, *dsnext, *dsfirst; - gr_vissprite_t *best = NULL; - gr_vissprite_t unsorted; - float bestdist = 0.0f; - INT32 bestdispoffset = 0; - - if (!gr_visspritecount) - return; - - dsfirst = HWR_GetVisSprite(0); - - for (i = 0, dsnext = dsfirst, ds = NULL; i < gr_visspritecount; i++) - { - dsprev = ds; - ds = dsnext; - if (i < gr_visspritecount - 1) dsnext = HWR_GetVisSprite(i + 1); - - ds->next = dsnext; - ds->prev = dsprev; - } - - // Fix first and last. ds still points to the last one after the loop - dsfirst->prev = &unsorted; - unsorted.next = dsfirst; - if (ds) - ds->next = &unsorted; - unsorted.prev = ds; - - // pull the vissprites out by scale - gr_vsprsortedhead.next = gr_vsprsortedhead.prev = &gr_vsprsortedhead; - for (i = 0; i < gr_visspritecount; i++) - { - best = NULL; - for (ds = unsorted.next; ds != &unsorted; ds = ds->next) - { - if (!best || ds->tz > bestdist) - { - bestdist = ds->tz; - bestdispoffset = ds->dispoffset; - best = ds; - } - // order visprites of same scale by dispoffset, smallest first - else if (fabsf(ds->tz - bestdist) < 1.0E-36f && ds->dispoffset < bestdispoffset) - { - bestdispoffset = ds->dispoffset; - best = ds; - } - } - if (best) - { - best->next->prev = best->prev; - best->prev->next = best->next; - best->next = &gr_vsprsortedhead; - best->prev = gr_vsprsortedhead.prev; - } - gr_vsprsortedhead.prev->next = best; - gr_vsprsortedhead.prev = best; - } - + gr_vissprite_t* spr1 = *(gr_vissprite_t*const*)p1; + gr_vissprite_t* spr2 = *(gr_vissprite_t*const*)p2; + int idiff; + float fdiff; + + // Make transparent sprites last. Comment from the previous sort implementation: // Sryder: Oh boy, while it's nice having ALL the sprites sorted properly, it fails when we bring MD2's into the // mix and they want to be translucent. So let's place all the translucent sprites and MD2's AFTER // everything else, but still ordered of course, the depth buffer can handle the opaque ones plenty fine. // We just need to move all translucent ones to the end in order // TODO: Fully sort all sprites and MD2s with walls and floors, this part will be unnecessary after that - best = gr_vsprsortedhead.next; + int transparency1 = (spr1->mobj->flags2 & MF2_SHADOW) || (spr1->mobj->frame & FF_TRANSMASK); + int transparency2 = (spr2->mobj->flags2 & MF2_SHADOW) || (spr2->mobj->frame & FF_TRANSMASK); + idiff = transparency1 - transparency2; + if (idiff != 0) return idiff; + + fdiff = spr2->tz - spr1->tz; // this order seems correct when checking with apitrace. Back to front. + if (fabsf(fdiff) < 1.0E-36f) + return spr1->dispoffset - spr2->dispoffset; // smallest dispoffset first if sprites are at (almost) same location. + else if (fdiff > 0) + return 1; + else + return -1; +} + +static void HWR_SortVisSprites(void) +{ + UINT32 i; for (i = 0; i < gr_visspritecount; i++) { - if ((best->mobj->flags2 & MF2_SHADOW) || (best->mobj->frame & FF_TRANSMASK)) - { - if (best == gr_vsprsortedhead.next) - { - gr_vsprsortedhead.next = best->next; - } - best->prev->next = best->next; - best->next->prev = best->prev; - best->prev = gr_vsprsortedhead.prev; - gr_vsprsortedhead.prev->next = best; - gr_vsprsortedhead.prev = best; - ds = best; - best = best->next; - ds->next = &gr_vsprsortedhead; - } - else - best = best->next; + gr_vsprorder[i] = HWR_GetVisSprite(i); } + qsort(gr_vsprorder, gr_visspritecount, sizeof(gr_vissprite_t*), CompareVisSprites); } // A drawnode is something that points to a 3D floor, 3D side, or masked @@ -4605,52 +4554,45 @@ static void HWR_CreateDrawNodes(void) // added the stransform so they can be switched as drawing happenes so MD2s and sprites are sorted correctly with each other static void HWR_DrawSprites(void) { - if (gr_visspritecount > 0) + UINT32 i; + HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value); + for (i = 0; i < gr_visspritecount; i++) { - gr_vissprite_t *spr; - HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value); - - // draw all vissprites back to front - for (spr = gr_vsprsortedhead.next; - spr != &gr_vsprsortedhead; - spr = spr->next) - { + gr_vissprite_t *spr = gr_vsprorder[i]; #ifdef HWPRECIP - if (spr->precip) - HWR_DrawPrecipitationSprite(spr); - else + if (spr->precip) + HWR_DrawPrecipitationSprite(spr); + else #endif + { + if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value) { - if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value) - { - HWR_DrawDropShadow(spr->mobj, spr->mobj->shadowscale); - } + HWR_DrawDropShadow(spr->mobj, spr->mobj->shadowscale); + } - if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - { - if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) - HWR_DrawSprite(spr); - else - { - if (!HWR_DrawModel(spr)) - HWR_DrawSprite(spr); - } - } + if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + { + if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) + HWR_DrawSprite(spr); else { - if (!cv_grmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + if (!HWR_DrawModel(spr)) + HWR_DrawSprite(spr); + } + } + else + { + if (!cv_grmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + HWR_DrawSprite(spr); + else + { + if (!HWR_DrawModel(spr)) HWR_DrawSprite(spr); - else - { - if (!HWR_DrawModel(spr)) - HWR_DrawSprite(spr); - } } } } - - HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, 0); } + HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, 0); } // -------------------------------------------------------------------------- From f3212746d280c27fc7fee85953ec1b782cc185a0 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Fri, 19 Jun 2020 16:18:04 +0300 Subject: [PATCH 149/168] Don't repeatedly look for model texture files --- src/hardware/hw_md2.c | 14 ++++++++++++-- src/hardware/hw_md2.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 76c7f89b4..68b426f0c 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -375,7 +375,10 @@ static void md2_loadTexture(md2_t *model) #endif grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch); if (grpatch->mipmap->grInfo.format == 0) + { + model->notexturefile = true; // mark it so its not searched for again repeatedly return; + } grpatch->mipmap->downloaded = 0; grpatch->mipmap->flags = 0; @@ -430,6 +433,7 @@ static void md2_loadBlendTexture(md2_t *model) grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch); if (grpatch->mipmap->grInfo.format == 0) { + model->noblendfile = true; // mark it so its not searched for again repeatedly Z_Free(filename); return; } @@ -465,6 +469,8 @@ void HWR_InitModels(void) md2_playermodels[s].scale = -1.0f; md2_playermodels[s].model = NULL; md2_playermodels[s].grpatch = NULL; + md2_playermodels[s].notexturefile = false; + md2_playermodels[s].noblendfile = false; md2_playermodels[s].skin = -1; md2_playermodels[s].notfound = true; md2_playermodels[s].error = false; @@ -474,6 +480,8 @@ void HWR_InitModels(void) md2_models[i].scale = -1.0f; md2_models[i].model = NULL; md2_models[i].grpatch = NULL; + md2_models[i].notexturefile = false; + md2_models[i].noblendfile = false; md2_models[i].skin = -1; md2_models[i].notfound = true; md2_models[i].error = false; @@ -1298,12 +1306,14 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) finalscale = md2->scale; //Hurdler: arf, I don't like that implementation at all... too much crappy gpatch = md2->grpatch; - if (!gpatch || !gpatch->mipmap->grInfo.format || !gpatch->mipmap->downloaded) + if (!gpatch || ((!gpatch->mipmap->grInfo.format || !gpatch->mipmap->downloaded) && !md2->notexturefile)) md2_loadTexture(md2); gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... if ((gpatch && gpatch->mipmap->grInfo.format) // don't load the blend texture if the base texture isn't available - && (!md2->blendgrpatch || !((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded)) + && (!md2->blendgrpatch + || ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded) + && !md2->noblendfile))) md2_loadBlendTexture(md2); if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index faa91caee..42a9d7c63 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -28,7 +28,9 @@ typedef struct float offset; model_t *model; void *grpatch; + boolean notexturefile; // true if texture file was not found void *blendgrpatch; + boolean noblendfile; // true if blend texture file was not found boolean notfound; INT32 skin; boolean error; From cad1f57b1e4d063e581853d40272f3272d39be34 Mon Sep 17 00:00:00 2001 From: kaysrishaq <62462173+kaysrishaq@users.noreply.github.com> Date: Sun, 7 Jun 2020 16:11:36 -0400 Subject: [PATCH 150/168] FF_HORIZONTALFLIP and mobj->mirrored (sprite enhancements) --- src/dehacked.c | 1 + src/hardware/hw_drv.h | 2 +- src/hardware/hw_main.c | 6 ++++++ src/hardware/hw_md2.c | 3 ++- src/hardware/r_opengl/r_opengl.c | 19 +++++++++++-------- src/lua_mobjlib.c | 8 ++++++++ src/p_mobj.h | 1 + src/p_pspr.h | 4 +++- src/p_saveg.c | 11 +++++++++-- src/r_things.c | 8 ++++++++ 10 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 61775bd56..98990b399 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9504,6 +9504,7 @@ struct { {"FF_GLOBALANIM",FF_GLOBALANIM}, {"FF_FULLBRIGHT",FF_FULLBRIGHT}, {"FF_VERTICALFLIP",FF_VERTICALFLIP}, + {"FF_HORIZONTALFLIP",FF_HORIZONTALFLIP}, {"FF_PAPERSPRITE",FF_PAPERSPRITE}, {"FF_TRANSMASK",FF_TRANSMASK}, {"FF_TRANSSHIFT",FF_TRANSSHIFT}, diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 2e4ea10cc..6f039cc3a 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -50,7 +50,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); //Hurdler: added for new development -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface); +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface); EXPORT void HWRAPI(CreateModelVBOs) (model_t *model); EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b89ffe9e6..bab5f625b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4724,6 +4724,8 @@ static void HWR_ProjectSprite(mobj_t *thing) unsigned rot; UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); + boolean mirrored = thing->mirrored; + boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored); angle_t ang; INT32 heightsec, phs; @@ -4812,6 +4814,8 @@ static void HWR_ProjectSprite(mobj_t *thing) #endif ang = R_PointToAngle (thing->x, thing->y) - mobjangle; + if (mirrored) + ang = InvAngle(ang); if (sprframe->rotate == SRF_SINGLE) { @@ -4884,6 +4888,8 @@ static void HWR_ProjectSprite(mobj_t *thing) rightcos = FIXED_TO_FLOAT(FINECOSINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); } + flip = !flip != !hflip; + if (flip) { x1 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_scale); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 76c7f89b4..42af89fd3 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1234,6 +1234,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) //mdlframe_t *next = NULL; const boolean papersprite = (spr->mobj->frame & FF_PAPERSPRITE); const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP)); + const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !(spr->mobj->frame & FF_HORIZONTALFLIP)); spritedef_t *sprdef; spriteframe_t *sprframe; spriteinfo_t *sprinfo; @@ -1504,7 +1505,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) #endif HWD.pfnSetShader(4); // model shader - HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, &Surf); + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf); } return true; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 41ec703bc..d3fc43e7b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2615,7 +2615,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) #define BUFFER_OFFSET(i) ((void*)(i)) -static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface) +static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) { static GLRGBAFloat poly = {0,0,0,0}; static GLRGBAFloat tint = {0,0,0,0}; @@ -2708,20 +2708,21 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglEnable(GL_NORMALIZE); #ifdef USE_FTRANSFORM_MIRROR - // flipped is if the object is flipped + // flipped is if the object is vertically flipped + // hflipped is if the object is horizontally flipped // pos->flip is if the screen is flipped vertically // pos->mirror is if the screen is flipped horizontally // XOR all the flips together to figure out what culling to use! { - boolean reversecull = (flipped ^ pos->flip ^ pos->mirror); + boolean reversecull = (flipped ^ hflipped ^ pos->flip ^ pos->mirror); if (reversecull) - pglCullFace(GL_FRONT); - else pglCullFace(GL_BACK); + else + pglCullFace(GL_FRONT); } #else // pos->flip is if the screen is flipped too - if (flipped != pos->flip) // If either are active, but not both, invert the model's culling + if (flipped ^ hflipped ^ pos->flip) // If one or three of these are active, but not two, invert the model's culling { pglCullFace(GL_FRONT); } @@ -2736,6 +2737,8 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglTranslatef(pos->x, pos->z, pos->y); if (flipped) scaley = -scaley; + if (hflipped) + scalez = -scalez; #ifdef USE_FTRANSFORM_ANGLEZ pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart @@ -2882,9 +2885,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 // -----------------+ // HWRAPI DrawModel : Draw a model // -----------------+ -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface) +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) { - DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, Surface); + DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface); } // -----------------+ diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 4d0efa9e2..129339b96 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -86,6 +86,7 @@ enum mobj_e { mobj_cvmem, mobj_standingslope, mobj_colorized, + mobj_mirrored, mobj_shadowscale }; @@ -152,6 +153,7 @@ static const char *const mobj_opt[] = { "cvmem", "standingslope", "colorized", + "mirrored", "shadowscale", NULL}; @@ -385,6 +387,9 @@ static int mobj_get(lua_State *L) case mobj_colorized: lua_pushboolean(L, mo->colorized); break; + case mobj_mirrored: + lua_pushboolean(L, mo->mirrored); + break; case mobj_shadowscale: lua_pushfixed(L, mo->shadowscale); break; @@ -713,6 +718,9 @@ static int mobj_set(lua_State *L) case mobj_colorized: mo->colorized = luaL_checkboolean(L, 3); break; + case mobj_mirrored: + mo->mirrored = luaL_checkboolean(L, 3); + break; case mobj_shadowscale: mo->shadowscale = luaL_checkfixed(L, 3); break; diff --git a/src/p_mobj.h b/src/p_mobj.h index dae8c8a86..c94dbd650 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -373,6 +373,7 @@ typedef struct mobj_s struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) boolean colorized; // Whether the mobj uses the rainbow colormap + boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius // WARNING: New fields must be added separately to savegame and Lua. diff --git a/src/p_pspr.h b/src/p_pspr.h index 3c10e9be4..231262beb 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -64,8 +64,10 @@ #define FF_FULLBRIGHT 0x00100000 /// \brief Frame flags: Flip sprite vertically (relative to what it should be for its gravity) #define FF_VERTICALFLIP 0x00200000 +/// \brief Frame flags: Flip sprite horizontally +#define FF_HORIZONTALFLIP 0x00400000 /// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION) -#define FF_PAPERSPRITE 0x00400000 +#define FF_PAPERSPRITE 0x00800000 /// \brief Frame flags - Animate: Simple stateless animation #define FF_ANIMATE 0x01000000 diff --git a/src/p_saveg.c b/src/p_saveg.c index b4d7ef838..c66d058f5 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1294,8 +1294,9 @@ typedef enum MD2_CEILINGROVER = 1<<10, MD2_SLOPE = 1<<11, MD2_COLORIZED = 1<<12, - MD2_ROLLANGLE = 1<<13, - MD2_SHADOWSCALE = 1<<14, + MD2_MIRRORED = 1<<13, + MD2_ROLLANGLE = 1<<14, + MD2_SHADOWSCALE = 1<<15, } mobj_diff2_t; typedef enum @@ -1500,6 +1501,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_SLOPE; if (mobj->colorized) diff2 |= MD2_COLORIZED; + if (mobj->mirrored) + diff2 |= MD2_MIRRORED; if (mobj->rollangle) diff2 |= MD2_ROLLANGLE; if (mobj->shadowscale) @@ -1638,6 +1641,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT16(save_p, mobj->standingslope->id); if (diff2 & MD2_COLORIZED) WRITEUINT8(save_p, mobj->colorized); + if (diff2 & MD2_MIRRORED) + WRITEUINT8(save_p, mobj->mirrored); if (diff2 & MD2_ROLLANGLE) WRITEANGLE(save_p, mobj->rollangle); if (diff2 & MD2_SHADOWSCALE) @@ -2641,6 +2646,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->standingslope = P_SlopeById(READUINT16(save_p)); if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); + if (diff2 & MD2_MIRRORED) + mobj->mirrored = READUINT8(save_p); if (diff2 & MD2_ROLLANGLE) mobj->rollangle = READANGLE(save_p); if (diff2 & MD2_SHADOWSCALE) diff --git a/src/r_things.c b/src/r_things.c index de5eb208f..d2647b811 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1367,6 +1367,8 @@ static void R_ProjectSprite(mobj_t *thing) size_t frame, rot; UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); + boolean mirrored = thing->mirrored; + boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored); INT32 lindex; @@ -1477,7 +1479,11 @@ static void R_ProjectSprite(mobj_t *thing) #endif if (sprframe->rotate != SRF_SINGLE || papersprite) + { ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle); + if (mirrored) + ang = InvAngle(ang); + } if (sprframe->rotate == SRF_SINGLE) { @@ -1537,6 +1543,8 @@ static void R_ProjectSprite(mobj_t *thing) } #endif + flip = !flip != !hflip; + // calculate edges of the shape if (flip) offset = spr_offset - spr_width; From c74a607c54c9b7a2f45bb12c11dda382311f4bc0 Mon Sep 17 00:00:00 2001 From: kaysrishaq <62462173+kaysrishaq@users.noreply.github.com> Date: Mon, 8 Jun 2020 06:30:01 -0400 Subject: [PATCH 151/168] Whoops, switched these for no reason --- src/hardware/r_opengl/r_opengl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d3fc43e7b..e5f6ff3cf 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2716,9 +2716,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 { boolean reversecull = (flipped ^ hflipped ^ pos->flip ^ pos->mirror); if (reversecull) - pglCullFace(GL_BACK); - else pglCullFace(GL_FRONT); + else + pglCullFace(GL_BACK); } #else // pos->flip is if the screen is flipped too From 5655db11abc113b0e7075070116e5cfaebb4e44e Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sun, 21 Jun 2020 09:30:55 +0200 Subject: [PATCH 152/168] Tweak display of hidden items in "1 Player" menu If an option in the "1 Player" menu is unavailable in an add-on, lower the above options to close the gap from the invisible option Also make Marathon Run display as question marks if locked And also change "sploadgame" to "spstartgame" --- src/m_menu.c | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 61b41d75b..e9c214019 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -761,14 +761,14 @@ static menuitem_t SP_MainMenu[] = {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 76}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 84}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 92}, - {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Marathon Run", M_Marathon, 100}, + {IT_SECRET, NULL, "Marathon Run", M_Marathon, 100}, {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 108}, {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 116} }; enum { - sploadgame, + spstartgame, sprecordattack, spnightsmode, spmarathon, @@ -8040,29 +8040,55 @@ static void M_SinglePlayerMenu(INT32 choice) { (void)choice; + levellistmode = LLM_RECORDATTACK; if (M_GametypeHasLevels(-1)) SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; - else - SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED; + else // If Record Attack is nonexistent in the current add-on... + { + SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED; // ...hide and disable the Record Attack option... + SP_MainMenu[spstartgame].alphaKey += 8; // ...and lower Start Game by 8 pixels to close the gap + } + levellistmode = LLM_NIGHTSATTACK; if (M_GametypeHasLevels(-1)) SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; - else - SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED; + else // If NiGHTS Mode is nonexistent in the current add-on... + { + SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED; // ...hide and disable the NiGHTS Mode option... + // ...and lower the above options' display positions by 8 pixels to close the gap + SP_MainMenu[spstartgame] .alphaKey += 8; + SP_MainMenu[sprecordattack].alphaKey += 8; + } - SP_MainMenu[sptutorial].status = tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; // If the FIRST stage immediately leads to the ending, or itself (which gets converted to the title screen in G_DoCompleted for marathonmode only), there's no point in having this option on the menu. You should use Record Attack in that circumstance, although if marathonnext is set this behaviour can be overridden if you make some weird mod that requires multiple playthroughs of the same map in sequence and has some in-level mechanism to break the cycle. - if (!M_SecretUnlocked(SECRET_RECORDATTACK) // also if record attack is locked - || (mapheaderinfo[spmarathon_start-1] + if (mapheaderinfo[spmarathon_start-1] && !mapheaderinfo[spmarathon_start-1]->marathonnext && (mapheaderinfo[spmarathon_start-1]->nextlevel == spmarathon_start - || mapheaderinfo[spmarathon_start-1]->nextlevel >= 1100))) - SP_MainMenu[spmarathon].status = IT_NOTHING|IT_DISABLED; - else - SP_MainMenu[spmarathon].status = IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED; + || mapheaderinfo[spmarathon_start-1]->nextlevel >= 1100)) + { + SP_MainMenu[spmarathon].status = IT_NOTHING|IT_DISABLED; // Hide and disable the Marathon Run option... + // ...and lower the above options' display positions by 8 pixels to close the gap + SP_MainMenu[spstartgame] .alphaKey += 8; + SP_MainMenu[sprecordattack].alphaKey += 8; + SP_MainMenu[spnightsmode] .alphaKey += 8; + } + else if (M_SecretUnlocked(SECRET_RECORDATTACK)) // Otherwise, if Marathon Run is allowed and Record Attack is unlocked... + SP_MainMenu[spmarathon].status = IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED; // ...unlock Marathon Run! + + + if (!tutorialmap) // If there's no tutorial available in the current add-on... + { + SP_MainMenu[sptutorial].status = IT_NOTHING|IT_DISABLED; // ...hide and disable the Tutorial option... + // ...and lower the above options' display positions by 8 pixels to close the gap + SP_MainMenu[spstartgame] .alphaKey += 8; + SP_MainMenu[sprecordattack].alphaKey += 8; + SP_MainMenu[spnightsmode] .alphaKey += 8; + SP_MainMenu[spmarathon] .alphaKey += 8; + } + M_SetupNextMenu(&SP_MainDef); } From e9e9cd61330ddb81fa4653c89c7a0ccdf56f0452 Mon Sep 17 00:00:00 2001 From: sphere Date: Sun, 21 Jun 2020 16:01:24 +0200 Subject: [PATCH 153/168] Give ACZ3 boss MF_NOCLIP(HEIGHT) when entering pinch phase, to prevent softlocking. --- src/dehacked.c | 2 ++ src/info.c | 12 +++++++----- src/info.h | 4 +++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 61775bd56..78120c5c4 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5756,10 +5756,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FANG_PINCHPATHINGSTART1", "S_FANG_PINCHPATHINGSTART2", "S_FANG_PINCHPATHING", + "S_FANG_PINCHBOUNCE0", "S_FANG_PINCHBOUNCE1", "S_FANG_PINCHBOUNCE2", "S_FANG_PINCHBOUNCE3", "S_FANG_PINCHBOUNCE4", + "S_FANG_PINCHFALL0", "S_FANG_PINCHFALL1", "S_FANG_PINCHFALL2", "S_FANG_PINCHSKID1", diff --git a/src/info.c b/src/info.c index f0272fc79..48c2cd666 100644 --- a/src/info.c +++ b/src/info.c @@ -1430,11 +1430,13 @@ state_t states[NUMSTATES] = {SPR_FANG, 8, 0, {A_PrepareRepeat}, 1, 0, S_FANG_PINCHPATHINGSTART2}, // S_FANG_PINCHPATHINGSTART1 {SPR_FANG, 8, 0, {A_PlayActiveSound}, 0, 0, S_FANG_PINCHPATHING}, // S_FANG_PINCHPATHINGSTART2 - {SPR_FANG, 8, 0, {A_Boss5FindWaypoint}, 1, 0, S_FANG_PINCHBOUNCE1}, // S_FANG_PINCHPATHING + {SPR_FANG, 8, 0, {A_Boss5FindWaypoint}, 1, 0, S_FANG_PINCHBOUNCE0}, // S_FANG_PINCHPATHING + {SPR_FANG, 8, 0, {A_SetObjectFlags}, MF_NOCLIP|MF_NOCLIPHEIGHT, 2, S_FANG_PINCHBOUNCE1}, // S_FANG_PINCHBOUNCE0 {SPR_FANG, 8, 2, {A_Thrust}, 0, 1, S_FANG_PINCHBOUNCE2}, // S_FANG_PINCHBOUNCE1 {SPR_FANG, 9, 2, {NULL}, 0, 0, S_FANG_PINCHBOUNCE3}, // S_FANG_PINCHBOUNCE2 {SPR_FANG, 10, 2, {A_Boss5Jump}, 0, 0, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE3 - {SPR_FANG, 10, 1, {A_Boss5CheckFalling}, S_FANG_PINCHSKID1, S_FANG_PINCHFALL1, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE4 + {SPR_FANG, 10, 1, {A_Boss5CheckFalling}, S_FANG_PINCHSKID1, S_FANG_PINCHFALL0, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE4 + {SPR_FANG, 12, 0, {A_SetObjectFlags}, MF_NOCLIP|MF_NOCLIPHEIGHT, 1, S_FANG_PINCHFALL1}, // S_FANG_PINCHFALL0 {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_PINCHSKID1, 0, S_FANG_PINCHFALL2}, // S_FANG_PINCHFALL1 {SPR_FANG, 13, 1, {A_Boss5CheckOnGround}, S_FANG_PINCHSKID1, 0, S_FANG_PINCHFALL1}, // S_FANG_PINCHFALL2 {SPR_FANG, 4, 0, {A_PlayAttackSound}, 0, 0, S_FANG_PINCHSKID2}, // S_FANG_PINCHSKID1 @@ -3362,7 +3364,7 @@ state_t states[NUMSTATES] = // CTF Sign {SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG - + // Finish flag {SPR_FNSF, FF_TRANS30, -1, {NULL}, 0, 0, S_NULL}, // S_FINISHFLAG @@ -18010,7 +18012,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - + { // MT_FINISHFLAG -1, // doomednum S_FINISHFLAG, // spawnstate @@ -19855,7 +19857,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, - + { // MT_FLINGNIGHTSSTAR -1, // doomednum S_NIGHTSSTAR, // spawnstate diff --git a/src/info.h b/src/info.h index 79af9bbbb..476ad2b73 100644 --- a/src/info.h +++ b/src/info.h @@ -1608,10 +1608,12 @@ typedef enum state S_FANG_PINCHPATHINGSTART1, S_FANG_PINCHPATHINGSTART2, S_FANG_PINCHPATHING, + S_FANG_PINCHBOUNCE0, S_FANG_PINCHBOUNCE1, S_FANG_PINCHBOUNCE2, S_FANG_PINCHBOUNCE3, S_FANG_PINCHBOUNCE4, + S_FANG_PINCHFALL0, S_FANG_PINCHFALL1, S_FANG_PINCHFALL2, S_FANG_PINCHSKID1, @@ -3498,7 +3500,7 @@ typedef enum state // Got Flag Sign S_GOTFLAG, - + // Finish flag S_FINISHFLAG, From ae474b6945f3aae3f5d289207d5b655d011f0d03 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sun, 21 Jun 2020 16:16:12 +0200 Subject: [PATCH 154/168] Fix re-opening 1 Player menu re-lowering options If an add-on disabled an option, re-opening the 1 Player menu multiple times would lower the above options multiple times Also fix Marathon Run and Tutorial being "perma-(un)lock"-able --- src/m_menu.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index e9c214019..ed04d402b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -758,6 +758,7 @@ static menuitem_t SR_EmblemHintMenu[] = // Single Player Main static menuitem_t SP_MainMenu[] = { + // Note: If changing the positions here, also change them in M_SinglePlayerMenu() {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 76}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 84}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 92}, @@ -8041,6 +8042,16 @@ static void M_SinglePlayerMenu(INT32 choice) (void)choice; + // Reset the item positions, to avoid them sinking farther down every time the menu is opened if one is unavailable + // Note that they're reset, not simply "not moved again", in case mid-game add-ons re-enable an option + SP_MainMenu[spstartgame] .alphaKey = 76; + SP_MainMenu[sprecordattack].alphaKey = 84; + SP_MainMenu[spnightsmode] .alphaKey = 92; + SP_MainMenu[spmarathon] .alphaKey = 100; + //SP_MainMenu[sptutorial] .alphaKey = 108; // Not needed + //SP_MainMenu[spstatistics].alphaKey = 116; // Not needed + + levellistmode = LLM_RECORDATTACK; if (M_GametypeHasLevels(-1)) SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; @@ -8075,11 +8086,13 @@ static void M_SinglePlayerMenu(INT32 choice) SP_MainMenu[sprecordattack].alphaKey += 8; SP_MainMenu[spnightsmode] .alphaKey += 8; } - else if (M_SecretUnlocked(SECRET_RECORDATTACK)) // Otherwise, if Marathon Run is allowed and Record Attack is unlocked... - SP_MainMenu[spmarathon].status = IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED; // ...unlock Marathon Run! + else // Otherwise, if Marathon Run is allowed and Record Attack is unlocked, unlock Marathon Run! + SP_MainMenu[spmarathon].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET; - if (!tutorialmap) // If there's no tutorial available in the current add-on... + if (tutorialmap) // If there's a tutorial available in the current add-on... + SP_MainMenu[sptutorial].status = IT_CALL | IT_STRING; // ...always unlock Tutorial + else // But if there's no tutorial available in the current add-on... { SP_MainMenu[sptutorial].status = IT_NOTHING|IT_DISABLED; // ...hide and disable the Tutorial option... // ...and lower the above options' display positions by 8 pixels to close the gap From 45026040074f61405dbd4b8b909356c38b8b9a6c Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 22 Jun 2020 19:00:47 +0100 Subject: [PATCH 155/168] Special saves! All this refactoring, just to resolve #162. Specifically, it engages savegame events not at level load (except for savefile start) but on level completion, just after you've gotten all the intermission bonuses but before the intermission actually starts. Also fixes a never-before-discovered bug where if the titlemap has LF_SAVEGAME, your save file will be overwritten upon returning to the title screen. This game is a mess of hacks, I swear... One unintended side effect: It may actually be faster in some speedrun circumstances in mods with cutscenes to complete the map, exit back to the title screen, and reload the file. It's a common feature of optimal runs in games with cutscenes, though, and Marathon Run has a toggle for cutscenes, so I'm not particularly bothered. --- src/g_game.c | 140 +++++++++++++++++++++++++++++--------------------- src/g_game.h | 2 +- src/p_saveg.c | 17 +++--- src/p_saveg.h | 2 +- src/p_setup.c | 33 +++++------- 5 files changed, 104 insertions(+), 90 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 73d21ad54..aea88988d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3676,6 +3676,24 @@ static void G_UpdateVisited(void) } } +static boolean CanSaveLevel(INT32 mapnum) +{ + // You can never save in a special stage. + if (G_IsSpecialStage(mapnum)) + return false; + + // If the game is complete for this save slot, then any level can save! + if (gamecomplete) + return true; + + // Be kind with Marathon Mode live event backups. + if (marathonmode) + return true; + + // Any levels that have the savegame flag can save normally. + return (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->levelflags & LF_SAVEGAME)); +} + // // G_DoCompleted // @@ -3720,65 +3738,65 @@ static void G_DoCompleted(void) nextmap = 1100-1; // No infinite loop for you } - // Remember last map for when you come out of the special stage. - if (!spec) - lastmap = nextmap; - // If nextmap is actually going to get used, make sure it points to // a map of the proper gametype -- skip levels that don't support // the current gametype. (Helps avoid playing boss levels in Race, // for instance). - if (!token && !spec - && (nextmap >= 0 && nextmap < NUMMAPS)) + if (!spec) { - register INT16 cm = nextmap; - UINT32 tolflag = G_TOLFlag(gametype); - UINT8 visitedmap[(NUMMAPS+7)/8]; - - memset(visitedmap, 0, sizeof (visitedmap)); - - while (!mapheaderinfo[cm] || !(mapheaderinfo[cm]->typeoflevel & tolflag)) + if (nextmap >= 0 && nextmap < NUMMAPS) { - visitedmap[cm/8] |= (1<<(cm&7)); - if (!mapheaderinfo[cm]) - cm = -1; // guarantee error execution - else if (marathonmode && mapheaderinfo[cm]->marathonnext) - cm = (INT16)(mapheaderinfo[cm]->marathonnext-1); - else - cm = (INT16)(mapheaderinfo[cm]->nextlevel-1); + register INT16 cm = nextmap; + UINT32 tolflag = G_TOLFlag(gametype); + UINT8 visitedmap[(NUMMAPS+7)/8]; - if (cm >= NUMMAPS || cm < 0) // out of range (either 1100ish or error) + memset(visitedmap, 0, sizeof (visitedmap)); + + while (!mapheaderinfo[cm] || !(mapheaderinfo[cm]->typeoflevel & tolflag)) { - cm = nextmap; //Start the loop again so that the error checking below is executed. + visitedmap[cm/8] |= (1<<(cm&7)); + if (!mapheaderinfo[cm]) + cm = -1; // guarantee error execution + else if (marathonmode && mapheaderinfo[cm]->marathonnext) + cm = (INT16)(mapheaderinfo[cm]->marathonnext-1); + else + cm = (INT16)(mapheaderinfo[cm]->nextlevel-1); - //Make sure the map actually exists before you try to go to it! - if ((W_CheckNumForName(G_BuildMapName(cm + 1)) == LUMPERROR)) + if (cm >= NUMMAPS || cm < 0) // out of range (either 1100ish or error) { - CONS_Alert(CONS_ERROR, M_GetText("Next map given (MAP %d) doesn't exist! Reverting to MAP01.\n"), cm+1); - cm = 0; + cm = nextmap; //Start the loop again so that the error checking below is executed. + + //Make sure the map actually exists before you try to go to it! + if ((W_CheckNumForName(G_BuildMapName(cm + 1)) == LUMPERROR)) + { + CONS_Alert(CONS_ERROR, M_GetText("Next map given (MAP %d) doesn't exist! Reverting to MAP01.\n"), cm+1); + cm = 0; + break; + } + } + + if (visitedmap[cm/8] & (1<<(cm&7))) // smells familiar + { + // We got stuck in a loop, came back to the map we started on + // without finding one supporting the current gametype. + // Thus, print a warning, and just use this map anyways. + CONS_Alert(CONS_WARNING, M_GetText("Can't find a compatible map after map %d; using map %d anyway\n"), prevmap+1, cm+1); break; } } - - if (visitedmap[cm/8] & (1<<(cm&7))) // smells familiar - { - // We got stuck in a loop, came back to the map we started on - // without finding one supporting the current gametype. - // Thus, print a warning, and just use this map anyways. - CONS_Alert(CONS_WARNING, M_GetText("Can't find a compatible map after map %d; using map %d anyway\n"), prevmap+1, cm+1); - break; - } + nextmap = cm; } - nextmap = cm; + + // wrap around in race + if (nextmap >= 1100-1 && nextmap <= 1102-1 && !(gametyperules & GTR_CAMPAIGN)) + nextmap = (INT16)(spstage_start-1); + + if (nextmap < 0 || (nextmap >= NUMMAPS && nextmap < 1100-1) || nextmap > 1103-1) + I_Error("Followed map %d to invalid map %d\n", prevmap + 1, nextmap + 1); + + lastmap = nextmap; // Remember last map for when you come out of the special stage. } - if (nextmap < 0 || (nextmap >= NUMMAPS && nextmap < 1100-1) || nextmap > 1103-1) - I_Error("Followed map %d to invalid map %d\n", prevmap + 1, nextmap + 1); - - // wrap around in race - if (nextmap >= 1100-1 && nextmap <= 1102-1 && !(gametyperules & GTR_CAMPAIGN)) - nextmap = (INT16)(spstage_start-1); - if ((gottoken = ((gametyperules & GTR_SPECIALSTAGES) && token))) { token--; @@ -3816,7 +3834,19 @@ static void G_DoCompleted(void) if (nextmap < NUMMAPS && !mapheaderinfo[nextmap]) P_AllocMapHeader(nextmap); - // do this before going to the intermission or starting a custom cutscene, mostly for the sake of marathon mode but it also massively reduces redundant file save events in f_finale.c + if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed)) + { + G_UpdateVisited(); + G_AfterIntermission(); + } + else + { + G_SetGamestate(GS_INTERMISSION); + Y_StartIntermission(); + G_UpdateVisited(); + } + + // do this before running the intermission or custom cutscene, mostly for the sake of marathon mode but it also massively reduces redundant file save events in f_finale.c if (nextmap >= 1100-1) { if (!gamecomplete) @@ -3831,21 +3861,13 @@ static void G_DoCompleted(void) cursaveslot = 0; } else if ((!modifiedgame || savemoddata) && !(netgame || multiplayer)) - G_SaveGame((UINT32)cursaveslot); + G_SaveGame((UINT32)cursaveslot, spstage_start); } } - - if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed)) - { - G_UpdateVisited(); - G_AfterIntermission(); - } - else - { - G_SetGamestate(GS_INTERMISSION); - Y_StartIntermission(); - G_UpdateVisited(); - } + // and doing THIS here means you don't lose your progress if you close the game mid-intermission + else if (!(ultimatemode || netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) + && (!modifiedgame || savemoddata) && cursaveslot > 0 && CanSaveLevel(lastmap+1)) + G_SaveGame((UINT32)cursaveslot, lastmap+1); // not nextmap+1 to route around special stages } // See also F_EndCutscene, the only other place which handles intra-map/ending transitions @@ -4407,7 +4429,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) // G_SaveGame // Saves your game. // -void G_SaveGame(UINT32 slot) +void G_SaveGame(UINT32 slot, INT16 mapnum) { boolean saved; char savename[256] = ""; @@ -4435,7 +4457,7 @@ void G_SaveGame(UINT32 slot) sprintf(name, (marathonmode ? "back-up %d" : "version %d"), VERSION); WRITEMEM(save_p, name, VERSIONSIZE); - P_SaveGame(); + P_SaveGame(mapnum); if (marathonmode) { WRITEUINT32(save_p, marathontime); diff --git a/src/g_game.h b/src/g_game.h index 21fa682b7..36d6759bf 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -166,7 +166,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride); void G_SaveGameData(void); -void G_SaveGame(UINT32 slot); +void G_SaveGame(UINT32 slot, INT16 mapnum); void G_SaveGameOver(UINT32 slot, boolean modifylives); diff --git a/src/p_saveg.c b/src/p_saveg.c index b4d7ef838..6f5446795 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3785,16 +3785,15 @@ static void P_NetUnArchiveSpecials(void) // ======================================================================= // Misc // ======================================================================= -static inline void P_ArchiveMisc(void) +static inline void P_ArchiveMisc(INT16 mapnum) { + //lastmapsaved = mapnum; + lastmaploaded = mapnum; + if (gamecomplete) - WRITEINT16(save_p, gamemap | 8192); - else - WRITEINT16(save_p, gamemap); - - //lastmapsaved = gamemap; - lastmaploaded = gamemap; + mapnum |= 8192; + WRITEINT16(save_p, mapnum); WRITEUINT16(save_p, emeralds+357); WRITESTRINGN(save_p, timeattackfolder, sizeof(timeattackfolder)); } @@ -4035,9 +4034,9 @@ static inline boolean P_UnArchiveLuabanksAndConsistency(void) return true; } -void P_SaveGame(void) +void P_SaveGame(INT16 mapnum) { - P_ArchiveMisc(); + P_ArchiveMisc(mapnum); P_ArchivePlayer(); P_ArchiveLuabanksAndConsistency(); } diff --git a/src/p_saveg.h b/src/p_saveg.h index 012e7023b..d8756a7a9 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -21,7 +21,7 @@ // Persistent storage/archiving. // These are the load / save game routines. -void P_SaveGame(void); +void P_SaveGame(INT16 mapnum); void P_SaveNetGame(void); boolean P_LoadGame(INT16 mapoverride); boolean P_LoadNetGame(void); diff --git a/src/p_setup.c b/src/p_setup.c index ffb68b1b0..e4be1bc63 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3297,21 +3297,6 @@ static void P_InitCamera(void) } } -static boolean CanSaveLevel(INT32 mapnum) -{ - if (ultimatemode) // never save in ultimate (probably redundant with cursaveslot also being checked) - return false; - - if (G_IsSpecialStage(mapnum) // don't save in special stages - || mapnum == lastmaploaded) // don't save if the last map loaded was this one - return false; - - // Any levels that have the savegame flag can save normally. - // If the game is complete for this save slot, then any level can save! - // On the other side of the spectrum, if lastmaploaded is 0, then the save file has only just been created and needs to save ASAP! - return (mapheaderinfo[mapnum-1]->levelflags & LF_SAVEGAME || (gamecomplete != 0) || marathonmode || !lastmaploaded); -} - static void P_RunSpecialStageWipe(void) { tic_t starttime = I_GetTime(); @@ -3748,11 +3733,19 @@ boolean P_LoadLevel(boolean fromnetsave) P_RunCachedActions(); - if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0) - && (!modifiedgame || savemoddata) && cursaveslot > 0 && CanSaveLevel(gamemap)) - G_SaveGame((UINT32)cursaveslot); - - lastmaploaded = gamemap; // HAS to be set after saving!! + // Took me 3 hours to figure out why my progression kept on getting overwritten with the titlemap... + if (!titlemapinaction) + { + if (!lastmaploaded) // Start a new game? + { + // I'd love to do this in the menu code instead of here, but everything's a mess and I can't guarantee saving proper player struct info before the first act's started. You could probably refactor it, but it'd be a lot of effort. Easier to just work off known good code. ~toast 22/06/2020 + if (!(ultimatemode || netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) + && (!modifiedgame || savemoddata) && cursaveslot > 0) + G_SaveGame((UINT32)cursaveslot, gamemap); + // If you're looking for saving sp file progression (distinct from G_SaveGameOver), check G_DoCompleted. + } + lastmaploaded = gamemap; // HAS to be set after saving!! + } if (!fromnetsave) // uglier hack { // to make a newly loaded level start on the second frame. From 80e0d353913cefbb47a0980b868bd62a734e79ea Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Mon, 22 Jun 2020 21:11:33 +0200 Subject: [PATCH 156/168] Fix missing bruh string in lua side options. This is stupid. --- src/lua_maplib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index ece42b8d3..b7a779ed6 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -139,6 +139,7 @@ static const char *const side_opt[] = { "toptexture", "bottomtexture", "midtexture", + "line", "sector", "special", "repeatcnt", From fbbfe3b3b1e2569862ce1979cf082543f5c33af4 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 25 Jun 2020 13:43:07 -0700 Subject: [PATCH 157/168] Add back the int_none check It got removed by 864e7033552cbb966f378cfbaf56aa116c1f97e8 but he forget how it was before the hook was there. :( --- src/y_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index cd197c5cf..58e0c4a88 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -320,7 +320,7 @@ void Y_IntermissionDrawer(void) // Bonus loops INT32 i; - if (rendermode == render_none) + if (intertype == int_none || rendermode == render_none) return; // Lactozilla: Renderer switching From 82dbe95e22d64bcea08ae04fa36a6589989015d2 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 26 Jun 2020 15:34:26 +0200 Subject: [PATCH 158/168] Fix computation of very high pings --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 95927710a..a7661dc7f 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5499,7 +5499,7 @@ void NetUpdate(void) // update node latency values so we can take an average later. for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && playernode[i] != UINT8_MAX) - realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); + realpingtable[i] += GetLag(playernode[i]) * (1000.00f / TICRATE); pingmeasurecount++; } From c96e07b61cdaa7b92479b151ae996414d2865588 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sat, 27 Jun 2020 02:01:16 +0200 Subject: [PATCH 159/168] Delete CLIENT_CONNECTIONSCREEN and JOININGAME defines --- src/d_clisrv.c | 49 ++++++++++++++++++--------------------------- src/d_netfil.c | 6 +++--- src/d_netfil.h | 2 +- src/doomdef.h | 5 ----- src/win32/win_vid.c | 2 +- 5 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 53a2fb235..b1f674a5f 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -45,7 +45,7 @@ #include "lua_hook.h" #include "md5.h" -#ifdef CLIENT_LOADINGSCREEN +#ifndef NONET // cl loading screen #include "v_video.h" #include "f_finale.h" @@ -1107,19 +1107,13 @@ static void SV_AcknowledgeResynchAck(INT32 node, UINT8 rsg) static INT16 Consistancy(void); -#ifndef NONET -#define JOININGAME -#endif - typedef enum { CL_SEARCHING, CL_DOWNLOADFILES, CL_ASKJOIN, CL_WAITJOINRESPONSE, -#ifdef JOININGAME CL_DOWNLOADSAVEGAME, -#endif CL_CONNECTED, CL_ABORTED } cl_mode_t; @@ -1162,7 +1156,7 @@ static void CV_LoadPlayerNames(UINT8 **p) } } -#ifdef CLIENT_LOADINGSCREEN +#ifndef NONET #define SNAKE_SPEED 5 #define SNAKE_NUM_BLOCKS_X 20 @@ -1684,7 +1678,6 @@ static inline void CL_DrawConnectionStatus(void) switch (cl_mode) { -#ifdef JOININGAME case CL_DOWNLOADSAVEGAME: if (lastfilenum != -1) { @@ -1710,7 +1703,6 @@ static inline void CL_DrawConnectionStatus(void) else cltext = M_GetText("Waiting to download game state..."); break; -#endif case CL_ASKJOIN: case CL_WAITJOINRESPONSE: cltext = M_GetText("Requesting to join..."); @@ -2048,7 +2040,7 @@ static boolean SV_SendServerConfig(INT32 node) return waspacketsent; } -#ifdef JOININGAME +#ifndef NONET #define SAVEGAMESIZE (768*1024) static void SV_SendSaveGame(INT32 node) @@ -2494,7 +2486,9 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) if (CL_SendFileRequest()) { cl_mode = CL_DOWNLOADFILES; +#ifndef NONET Snake_Initialise(); +#endif } } } @@ -2559,18 +2553,20 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic if (waitmore) break; // exit the case +#ifndef NONET if (snake) { free(snake); snake = NULL; } +#endif cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now /* FALLTHRU */ case CL_ASKJOIN: CL_LoadServerFiles(); -#ifdef JOININGAME +#ifndef NONET // prepare structures to save the file // WARNING: this can be useless in case of server not in GS_LEVEL // but since the network layer doesn't provide ordered packets... @@ -2580,7 +2576,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic cl_mode = CL_WAITJOINRESPONSE; break; -#ifdef JOININGAME +#ifndef NONET case CL_DOWNLOADSAVEGAME: // At this state, the first (and only) needed file is the gamestate if (fileneeded[0].status == FS_FOUND) @@ -2620,11 +2616,13 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic CONS_Printf(M_GetText("Network game synchronization aborted.\n")); // M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING); +#ifndef NONET if (snake) { free(snake); snake = NULL; } +#endif D_QuitNetGame(); CL_Reset(); @@ -2632,8 +2630,10 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic memset(gamekeydown, 0, NUMKEYS); return false; } +#ifndef NONET else if (cl_mode == CL_DOWNLOADFILES && snake) Snake_Handle(); +#endif if (client && (cl_mode == CL_DOWNLOADFILES || cl_mode == CL_DOWNLOADSAVEGAME)) FileReceiveTicker(); @@ -2644,7 +2644,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic //FileSendTicker(); *oldtic = I_GetTime(); -#ifdef CLIENT_LOADINGSCREEN +#ifndef NONET if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED) { if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_DOWNLOADSAVEGAME) @@ -2683,20 +2683,16 @@ static void CL_ConnectToServer(boolean viams) tic_t oldtic; #ifndef NONET tic_t asksent; -#endif -#ifdef JOININGAME char tmpsave[256]; sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); + + lastfilenum = -1; #endif cl_mode = CL_SEARCHING; -#ifdef CLIENT_LOADINGSCREEN - lastfilenum = -1; -#endif - -#ifdef JOININGAME +#ifndef NONET // Don't get a corrupt savegame error because tmpsave already exists if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1) I_Error("Can't delete %s\n", tmpsave); @@ -4217,7 +4213,7 @@ static void HandleConnect(SINT8 node) G_SetGamestate(backupstate); DEBFILE("new node joined\n"); } -#ifdef JOININGAME +#ifndef NONET if (nodewaiting[node]) { if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) && newnode) @@ -4229,11 +4225,6 @@ static void HandleConnect(SINT8 node) joindelay += cv_joindelay.value * TICRATE; player_joining = true; } -#else -#ifndef NONET - // I guess we have no use for this if we aren't doing mid-level joins? - (void)newnode; -#endif #endif } } @@ -4415,7 +4406,7 @@ static void HandlePacketFromAwayNode(SINT8 node) playernode[(UINT8)serverplayer] = servernode; if (netgame) -#ifdef JOININGAME +#ifndef NONET CONS_Printf(M_GetText("Join accepted, waiting for complete game state...\n")); #else CONS_Printf(M_GetText("Join accepted, waiting for next level change...\n")); @@ -4439,7 +4430,7 @@ static void HandlePacketFromAwayNode(SINT8 node) scp = netbuffer->u.servercfg.varlengthinputs; CV_LoadPlayerNames(&scp); CV_LoadNetVars(&scp); -#ifdef JOININGAME +#ifndef NONET /// \note Wait. What if a Lua script uses some global custom variables synched with the NetVars hook? /// Shouldn't them be downloaded even at intermission time? /// Also, according to HandleConnect, the server will send the savegame even during intermission... diff --git a/src/d_netfil.c b/src/d_netfil.c index 7b99fddfb..8f661bb5f 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -106,7 +106,7 @@ typedef struct } pauseddownload_t; static pauseddownload_t *pauseddownload = NULL; -#ifdef CLIENT_LOADINGSCREEN +#ifndef NONET // for cl loading screen INT32 lastfilenum = -1; #endif @@ -188,7 +188,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr) void CL_PrepareDownloadSaveGame(const char *tmpsave) { -#ifdef CLIENT_LOADINGSCREEN +#ifndef NONET lastfilenum = -1; #endif @@ -1360,7 +1360,7 @@ void PT_FileFragment(void) I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s); } -#ifdef CLIENT_LOADINGSCREEN +#ifndef NONET lastfilenum = filenum; #endif } diff --git a/src/d_netfil.h b/src/d_netfil.h index 2225157cb..1b399be75 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -58,7 +58,7 @@ extern INT32 fileneedednum; extern fileneeded_t fileneeded[MAX_WADFILES]; extern char downloaddir[512]; -#ifdef CLIENT_LOADINGSCREEN +#ifndef NONET extern INT32 lastfilenum; #endif diff --git a/src/doomdef.h b/src/doomdef.h index 0b76cebc7..1f90a6f7f 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -617,11 +617,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// memory that never gets touched. #define ALLOW_RESETDATA -#ifndef NONET -/// Display a connection screen on join attempts. -#define CLIENT_LOADINGSCREEN -#endif - /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.) //#define REDSANALOG diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index 0f1144a84..716f38089 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -326,7 +326,7 @@ static inline boolean I_SkipFrame(void) if (!paused) return false; //case GS_TIMEATTACK: -- sorry optimisation but now we have a cool level platter and that being laggardly looks terrible -#ifndef CLIENT_LOADINGSCREEN +#ifndef NONET /* FALLTHRU */ case GS_WAITINGPLAYERS: #endif From 93cc48054af5792a0f9d572a354f86056e1e49c4 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sat, 27 Jun 2020 15:30:23 +0200 Subject: [PATCH 160/168] Expose "server" and "dedicated" to Lua scripts Careful! Both are local variables and are always false for clients, and therefore should obviously not be used in anything gamelogic-related. --- src/lua_script.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lua_script.c b/src/lua_script.c index a295256da..5fb153c0e 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -326,6 +326,12 @@ int LUA_PushGlobals(lua_State *L, const char *word) return 0; LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); return 1; + } else if (fastcmp(word,"isserver")) { + lua_pushboolean(L, server); + return 1; + } else if (fastcmp(word,"isdedicatedserver")) { + lua_pushboolean(L, dedicated); + return 1; // end local player variables } else if (fastcmp(word,"server")) { if ((!multiplayer || !netgame) && !playeringame[serverplayer]) From 3f3ff0688ba18dcfb5e83a3b2f865380d384ac43 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 28 Jun 2020 16:59:36 -0400 Subject: [PATCH 161/168] Add support for saving/loading per-skin NiGHTS replays --- src/g_game.c | 6 +++--- src/m_menu.c | 37 ++++++++++++++++++++----------------- src/p_setup.c | 40 ++++++++++++++++++++++++++++++++++------ 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index a927f8ef2..692dbf439 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -720,14 +720,14 @@ void G_SetNightsRecords(void) I_Error("Out of memory for replay filepath\n"); sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); - snprintf(lastdemo, 255, "%s-last.lmp", gpath); + snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name); if (FIL_FileExists(lastdemo)) { UINT8 *buf; size_t len = FIL_ReadFile(lastdemo, &buf); - snprintf(bestdemo, 255, "%s-time-best.lmp", gpath); + snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);; if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1) { // Better time, save this demo. if (FIL_FileExists(bestdemo)) @@ -736,7 +736,7 @@ void G_SetNightsRecords(void) CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo); } - snprintf(bestdemo, 255, "%s-score-best.lmp", gpath); + snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name); if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1))) { // Better score, save this demo. if (FIL_FileExists(bestdemo)) diff --git a/src/m_menu.c b/src/m_menu.c index f684354a5..a470b4021 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2300,7 +2300,7 @@ void Nextmap_OnChange(void) SP_NightsAttackMenu[naghost].status = IT_DISABLED; // Check if file exists, if not, disable REPLAY option - sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); + sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name); for (i = 0; i < 4; i++) { SP_NightsReplayMenu[i].status = IT_DISABLED; SP_NightsGuestReplayMenu[i].status = IT_DISABLED; @@ -2320,7 +2320,7 @@ void Nextmap_OnChange(void) SP_NightsGuestReplayMenu[2].status = IT_WHITESTRING|IT_CALL; active = true; } - if (FIL_FileExists(va("%s-guest.lmp", tabase))) { + if (FIL_FileExists(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)))) { SP_NightsReplayMenu[3].status = IT_WHITESTRING|IT_CALL; SP_NightsGuestReplayMenu[3].status = IT_WHITESTRING|IT_CALL; active = true; @@ -10126,6 +10126,8 @@ static void M_NightsAttack(INT32 choice) // Player has selected the "START" from the nights attack screen static void M_ChooseNightsAttack(INT32 choice) { + char *gpath; + const size_t glen = strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; char nameofdemo[256]; (void)choice; emeralds = 0; @@ -10136,14 +10138,18 @@ static void M_ChooseNightsAttack(INT32 choice) I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755); - snprintf(nameofdemo, sizeof nameofdemo, "replay"PATHSEP"%s"PATHSEP"%s-last", timeattackfolder, G_BuildMapName(cv_nextmap.value)); + if ((gpath = malloc(glen)) == NULL) + I_Error("Out of memory for replay filepath\n"); + + sprintf(gpath,"replay"PATHSEP"%s"PATHSEP"%s", timeattackfolder, G_BuildMapName(cv_nextmap.value)); + snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-last", gpath, skins[cv_chooseskin.value-1].name); if (!cv_autorecord.value) remove(va("%s"PATHSEP"%s.lmp", srb2home, nameofdemo)); else G_RecordDemo(nameofdemo); - G_DeferedInitNew(false, G_BuildMapName(cv_nextmap.value), 0, false, false); + G_DeferedInitNew(false, G_BuildMapName(cv_nextmap.value), (UINT8)(cv_chooseskin.value-1), false, false); } // Player has selected the "START" from the time attack screen @@ -10220,11 +10226,10 @@ static void M_ReplayTimeAttack(INT32 choice) which = "last"; break; case 3: // guest - which = "guest"; - break; + G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); + return; } - // srb2/replay/main/map01-score-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which)); + G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which)); } } @@ -10242,15 +10247,13 @@ static void M_EraseGuest(INT32 choice) M_StartMessage(M_GetText("Guest replay data erased.\n"),NULL,MM_NOTHING); } -static void M_OverwriteGuest(const char *which, boolean nights) +static void M_OverwriteGuest(const char *which) { char *rguest = Z_StrDup(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); UINT8 *buf; size_t len; - if (!nights) - len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which), &buf); - else - len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which), &buf); + len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which), &buf); + if (!len) { return; } @@ -10271,25 +10274,25 @@ static void M_OverwriteGuest(const char *which, boolean nights) static void M_OverwriteGuest_Time(INT32 choice) { (void)choice; - M_OverwriteGuest("time-best", currentMenu == &SP_NightsGuestReplayDef); + M_OverwriteGuest("time-best"); } static void M_OverwriteGuest_Score(INT32 choice) { (void)choice; - M_OverwriteGuest("score-best", currentMenu == &SP_NightsGuestReplayDef); + M_OverwriteGuest("score-best"); } static void M_OverwriteGuest_Rings(INT32 choice) { (void)choice; - M_OverwriteGuest("rings-best", false); + M_OverwriteGuest("rings-best"); } static void M_OverwriteGuest_Last(INT32 choice) { (void)choice; - M_OverwriteGuest("last", currentMenu == &SP_NightsGuestReplayDef); + M_OverwriteGuest("last"); } static void M_SetGuestReplay(INT32 choice) diff --git a/src/p_setup.c b/src/p_setup.c index 5027bab0c..d088f3a20 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3157,6 +3157,7 @@ static void P_LoadNightsGhosts(void) { const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; char *gpath = malloc(glen); + INT32 i; if (!gpath) return; @@ -3164,16 +3165,43 @@ static void P_LoadNightsGhosts(void) sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); // Best Score ghost - if (cv_ghost_bestscore.value && FIL_FileExists(va("%s-score-best.lmp", gpath))) - G_AddGhost(va("%s-score-best.lmp", gpath)); + if (cv_ghost_bestscore.value) + { + for (i = 0; i < numskins; ++i) + { + if (cv_ghost_bestscore.value == 1 && players[consoleplayer].skin != i) + continue; + + if (FIL_FileExists(va("%s-%s-score-best.lmp", gpath, skins[i].name))) + G_AddGhost(va("%s-%s-score-best.lmp", gpath, skins[i].name)); + } + } // Best Time ghost - if (cv_ghost_besttime.value && FIL_FileExists(va("%s-time-best.lmp", gpath))) - G_AddGhost(va("%s-time-best.lmp", gpath)); + if (cv_ghost_besttime.value) + { + for (i = 0; i < numskins; ++i) + { + if (cv_ghost_besttime.value == 1 && players[consoleplayer].skin != i) + continue; + + if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i].name))) + G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i].name)); + } + } // Last ghost - if (cv_ghost_last.value && FIL_FileExists(va("%s-last.lmp", gpath))) - G_AddGhost(va("%s-last.lmp", gpath)); + if (cv_ghost_last.value) + { + for (i = 0; i < numskins; ++i) + { + if (cv_ghost_last.value == 1 && players[consoleplayer].skin != i) + continue; + + if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i].name))) + G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i].name)); + } + } // Guest ghost if (cv_ghost_guest.value && FIL_FileExists(va("%s-guest.lmp", gpath))) From e6418952685ce1829ff1a7a512ed07ddc4fbdceb Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 29 Jun 2020 23:54:45 -0400 Subject: [PATCH 162/168] Address compat with old-style names --- src/m_menu.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/m_menu.h | 3 +++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index a470b4021..490e2081b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2276,6 +2276,9 @@ void Nextmap_OnChange(void) { char *leveltitle; char tabase[256]; +#ifdef OLDNREPLAYNAME + char tabaseold[256]; +#endif short i; boolean active; @@ -2301,10 +2304,16 @@ void Nextmap_OnChange(void) // Check if file exists, if not, disable REPLAY option sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name); + +#ifdef OLDNREPLAYNAME + sprintf(tabaseold,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); +#endif + for (i = 0; i < 4; i++) { SP_NightsReplayMenu[i].status = IT_DISABLED; SP_NightsGuestReplayMenu[i].status = IT_DISABLED; } + if (FIL_FileExists(va("%s-score-best.lmp", tabase))) { SP_NightsReplayMenu[0].status = IT_WHITESTRING|IT_CALL; SP_NightsGuestReplayMenu[0].status = IT_WHITESTRING|IT_CALL; @@ -2325,11 +2334,32 @@ void Nextmap_OnChange(void) SP_NightsGuestReplayMenu[3].status = IT_WHITESTRING|IT_CALL; active = true; } + + // Old style name compatibility +#ifdef OLDNREPLAYNAME + if (FIL_FileExists(va("%s-score-best.lmp", tabaseold))) { + SP_NightsReplayMenu[0].status = IT_WHITESTRING|IT_CALL; + SP_NightsGuestReplayMenu[0].status = IT_WHITESTRING|IT_CALL; + active = true; + } + if (FIL_FileExists(va("%s-time-best.lmp", tabaseold))) { + SP_NightsReplayMenu[1].status = IT_WHITESTRING|IT_CALL; + SP_NightsGuestReplayMenu[1].status = IT_WHITESTRING|IT_CALL; + active = true; + } + if (FIL_FileExists(va("%s-last.lmp", tabaseold))) { + SP_NightsReplayMenu[2].status = IT_WHITESTRING|IT_CALL; + SP_NightsGuestReplayMenu[2].status = IT_WHITESTRING|IT_CALL; + active = true; + } +#endif + if (active) { SP_NightsAttackMenu[naguest].status = IT_WHITESTRING|IT_SUBMENU; SP_NightsAttackMenu[nareplay].status = IT_WHITESTRING|IT_SUBMENU; SP_NightsAttackMenu[naghost].status = IT_WHITESTRING|IT_SUBMENU; } + else if(itemOn == nareplay) // Reset lastOn so replay isn't still selected when not available. { currentMenu->lastOn = itemOn; @@ -10185,6 +10215,7 @@ static void M_ChooseTimeAttack(INT32 choice) static void M_ReplayTimeAttack(INT32 choice) { const char *which; + char *demoname; M_ClearMenus(true); modeattacking = ATTACKING_RECORD; // set modeattacking before G_DoPlayDemo so the map loader knows @@ -10229,7 +10260,15 @@ static void M_ReplayTimeAttack(INT32 choice) G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); return; } - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which)); + + demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which); + +#ifdef OLDNREPLAYNAME // Check for old style named NiGHTS replay, since the new style replay doesn't exist. + if (!FIL_FileExists(demoname)) + demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which); +#endif + + G_DoPlayDemo(demoname); } } diff --git a/src/m_menu.h b/src/m_menu.h index 221f1fd3f..52bdb0dea 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -21,6 +21,9 @@ #include "r_skins.h" // for SKINNAMESIZE #include "f_finale.h" // for ttmode_enum +// Compatibility with old-style named NiGHTS replay files. +#define OLDNREPLAYNAME + // // MENUS // From 612386aef0783458ddeaa644487ff7c922a76d95 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 29 Jun 2020 23:57:39 -0400 Subject: [PATCH 163/168] Correct comment --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 490e2081b..a9bb1fda9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10263,7 +10263,7 @@ static void M_ReplayTimeAttack(INT32 choice) demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which); -#ifdef OLDNREPLAYNAME // Check for old style named NiGHTS replay, since the new style replay doesn't exist. +#ifdef OLDNREPLAYNAME // Check for old style named NiGHTS replay if a new style replay doesn't exist. if (!FIL_FileExists(demoname)) demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which); #endif From 40e98e57123753230bd9035ad08507759884cf8c Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 30 Jun 2020 18:37:21 +0200 Subject: [PATCH 164/168] Fix crash when a polyobject rotates a non-player mobj --- src/p_polyobj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 5bd963940..ccf8519f6 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1159,7 +1159,8 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, if (turnthings == 2 || (turnthings == 1 && !mo->player)) { mo->angle += delta; - P_SetPlayerAngle(mo->player, (angle_t)(mo->player->angleturn << 16) + delta); + if (mo->player) + P_SetPlayerAngle(mo->player, (angle_t)(mo->player->angleturn << 16) + delta); } } } From fae583915a42dff159469ac44d7186e566b647d8 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jul 2020 16:04:46 -0700 Subject: [PATCH 165/168] Remove Producer role from the credits --- src/f_finale.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index a41005b43..24ace29d0 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1118,9 +1118,6 @@ static const char *credits[] = { "\1Sonic Robo Blast II", "\1Credits", "", - "\1Producer", - "Rob Tisdell", - "", "\1Game Design", "Ben \"Mystic\" Geyer", "\"SSNTails\"", From 99a9c935f915b3cc693565afeb2b319f1b60c98e Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jul 2020 16:23:26 -0700 Subject: [PATCH 166/168] Credits: add back fickle, add Chrispy and Hannu --- src/f_finale.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/f_finale.c b/src/f_finale.c index 24ace29d0..cd55ff42d 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1148,11 +1148,13 @@ static const char *credits[] = { "", "\1Programming", "\1Assistance", + "Colette \"fickleheart\" Bordelon", "\"chi.miru\"", // helped port slope drawing code from ZDoom "Andrew \"orospakr\" Clunis", "Sally \"TehRealSalt\" Cochenour", "Gregor \"Oogaland\" Dick", "Julio \"Chaos Zero 64\" Guir", + "\"Hannu_Hanhi\"", // For many OpenGL performance improvements! "\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog "\"Lat'\"", // SRB2-CHAT, the chat window from Kart "Matthew \"Shuffle\" Marsalko", @@ -1171,6 +1173,7 @@ static const char *credits[] = { "\1Art", "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: "Ryan \"Blaze Hedgehog\" Bloom", + "\"ChrispyPixels\"", "Paul \"Boinciel\" Clempson", "Sally \"TehRealSalt\" Cochenour", "\"Dave Lite\"", @@ -1217,6 +1220,7 @@ static const char *credits[] = { "\"SSNTails\"", "", "\1Level Design", + "Colette \"fickleheart\" Bordelon", "Hank \"FuriousFox\" Brannock", "Matthew \"Fawfulfan\" Chapman", "Paul \"Boinciel\" Clempson", From e1996a437d6356de4901eb7758655a36c22879d9 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jul 2020 16:28:59 -0700 Subject: [PATCH 167/168] Add "Discord Community Testers" to the Testing section --- src/f_finale.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/f_finale.c b/src/f_finale.c index cd55ff42d..2ce8fd101 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1256,6 +1256,7 @@ static const char *credits[] = { "Johnny \"Sonikku\" Wallbank", "", "\1Testing", + "Discord Community Testers", "Hank \"FuriousFox\" Brannock", "Cody \"SRB2 Playah\" Koester", "Skye \"OmegaVelocity\" Meredith", From 2cbf7ac27d816288ba3df876cd123cee88ee2988 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jul 2020 16:35:38 -0700 Subject: [PATCH 168/168] Cheese mode activate! --- src/locale/en.po | 2 +- src/locale/srb2.pot | 2 +- src/m_cheat.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/locale/en.po b/src/locale/en.po index 83e118772..30ebe4368 100644 --- a/src/locale/en.po +++ b/src/locale/en.po @@ -2068,7 +2068,7 @@ msgstr "" #: m_cheat.c:292 #, c-format -msgid "Sissy Mode %s\n" +msgid "Cheese Mode %s\n" msgstr "" #: m_cheat.c:315 m_cheat.c:349 m_cheat.c:514 m_cheat.c:538 m_cheat.c:557 diff --git a/src/locale/srb2.pot b/src/locale/srb2.pot index 087c8720c..960c36dbe 100644 --- a/src/locale/srb2.pot +++ b/src/locale/srb2.pot @@ -2145,7 +2145,7 @@ msgstr "" #: m_cheat.c:294 #, c-format -msgid "Sissy Mode %s\n" +msgid "Cheese Mode %s\n" msgstr "" #: m_cheat.c:314 diff --git a/src/m_cheat.c b/src/m_cheat.c index 9d904f52d..c42763afd 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -288,7 +288,7 @@ void Command_CheatGod_f(void) plyr = &players[consoleplayer]; plyr->pflags ^= PF_GODMODE; - CONS_Printf(M_GetText("Sissy Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off")); + CONS_Printf(M_GetText("Cheese Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off")); G_SetGameModified(multiplayer); }