diff --git a/src/Makefile b/src/Makefile index 4df4e1fe8..ccfe7603e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -298,7 +298,7 @@ else $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o $(OBJDIR)/hw_shaders.o endif -OPTS += -DCOMPVERSION -fwrapv +OPTS += -DCOMPVERSION ifndef NONX86 ifndef GCC29 diff --git a/src/console.c b/src/console.c index 9781078fa..f36b3b7cb 100644 --- a/src/console.c +++ b/src/console.c @@ -1236,7 +1236,7 @@ void CONS_Printf(const char *fmt, ...) txt = malloc(8192); va_start(argptr, fmt); - vsprintf(txt, fmt, argptr); + vsnprintf(txt, 8192, fmt, argptr); va_end(argptr); // echo console prints to log file diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 652e1e903..b058bde99 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -54,10 +54,10 @@ static INT32 format2bpp(GLTextureFormat_t format) // It is now split from it for my sanity! (and the sanity of others) // -- Monster Iestyn (13/02/19) static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, - INT32 pblockheight, INT32 blockmodulo, - fixed_t yfracstep, fixed_t scale_y, - texpatch_t *originPatch, INT32 patchheight, - INT32 bpp, RGBA_t *palette) + INT32 pblockheight, INT32 blockmodulo, + fixed_t yfracstep, fixed_t scale_y, + texpatch_t *originPatch, INT32 patchheight, + INT32 bpp, RGBA_t *palette) { fixed_t yfrac, position, count; UINT8 *dest; @@ -73,9 +73,6 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm (void)patchheight; // This parameter is unused - if (!mipmap || mipmap == NULL) - return; - if (originPatch) // originPatch can be NULL here, unlike in the software version originy = originPatch->originy; @@ -111,10 +108,10 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm count--; texel = source[yfrac>>FRACBITS]; - alpha = 0xff; + alpha = 0xFF; - //Hurdler: not perfect, but better than holes - if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) + // Make pixel transparent if chroma keyed + if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) alpha = 0x00; //Hurdler: 25/04/2000: now support colormap in hardware mode @@ -126,7 +123,8 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm // Alam: SRB2 uses Mingw, HUGS switch (bpp) { - case 2 : texelu16 = (UINT16)((alpha<<8) | texel); + case 2 : // uhhhhhhhh.......... + texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; case 3 : colortemp = palette[texel]; @@ -144,6 +142,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm dest += blockmodulo; yfrac += yfracstep; } + patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4); } } @@ -185,6 +184,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, if (bpp < 1 || bpp > 4) I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); + // NOTE: should this actually be pblockwidth*bpp? blockmodulo = pblockwidth*bpp; // Draw each column to the block cache @@ -263,6 +263,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, if (bpp < 1 || bpp > 4) I_Error("HWR_DrawTexturePatchInCache: no drawer defined for this bpp (%d)\n",bpp); + // NOTE: should this actually be pblockwidth*bpp? blockmodulo = pblockwidth*bpp; // Draw each column to the block cache @@ -336,8 +337,8 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe else gltex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY; - gltex->mipmap.width = SHORT(texture->width); - gltex->mipmap.height = SHORT(texture->height); + gltex->mipmap.width = (UINT16)(texture->width); + gltex->mipmap.height = (UINT16)(texture->height); if (skyspecial) gltex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ... @@ -362,14 +363,17 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe RGBA_t col; col = palette[HWR_CHROMAKEY_EQUIVALENTCOLORINDEX]; + for (j = 0; j < blockheight; j++) { for (i = 0; i < blockwidth; i++) { - block[4*(j*blockwidth+i)+0] = col.s.red; - block[4*(j*blockwidth+i)+1] = col.s.green; - block[4*(j*blockwidth+i)+2] = col.s.blue; - block[4*(j*blockwidth+i)+3] = 0xff; + int idx = (j*blockwidth+i); + + block[4*idx+0] = col.s.red; + block[4*idx+1] = col.s.green; + block[4*idx+2] = col.s.blue; + block[4*idx+3] = 0xff; } } } @@ -378,15 +382,12 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); - HWR_DrawTexturePatchInCache(&gltex->mipmap, - blockwidth, blockheight, - texture, patch, - realpatch); + HWR_DrawTexturePatchInCache(&gltex->mipmap, blockwidth, blockheight, texture, patch, realpatch); Z_ChangeTag(realpatch, PU_HWRCACHE_UNLOCKED); } //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( - if (format2bpp(gltex->mipmap.format)==4) + if (format2bpp(gltex->mipmap.format) == 4) { for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp { @@ -437,6 +438,7 @@ void HWR_MakePatch (patch_t *patch, GLPatch_t *glPatch, GLMipmap_t *glMipmap, bo if (makebitmap) { MakeBlock(glMipmap); + HWR_DrawPatchInCache(glMipmap, glMipmap->width, glMipmap->height, glPatch->width, glPatch->height, diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5e24e6eae..73407874a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -141,6 +141,8 @@ static void HWR_TogglePaletteRendering(void); // ========================================================================== // Commands and console variables // ========================================================================== +static void HWR_RegisterCommands(void); +static void COM_HWR_glinfo(void); // // Onchanges @@ -505,7 +507,6 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool if (!xsub->planepoly) return; - pv = xsub->planepoly->pts; nrPlaneVerts = xsub->planepoly->numpts; if (nrPlaneVerts < 3) //not even a triangle ? @@ -575,6 +576,8 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool break; } + pv = xsub->planepoly->pts; + // reference point for flat texture coord for each vertex around the polygon flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatsize); flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatsize); @@ -942,7 +945,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, for (INT32 i = 0; i < sector->numlights; i++) { - if (endtop < endrealbot && top < realbot) + if ((endtop < endrealbot) && (top < realbot)) return; lightlist_t *list = sector->lightlist; @@ -1008,20 +1011,16 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, endbheight = endrealbot; } - if (endbheight > endtop) - endbot = endtop; + if (endbheight >= endtop) + continue; if (bheight >= top) continue; // Found a break // The heights are clamped to ensure the polygon doesn't cross itself. - bot = bheight; - - if (bot < realbot) - bot = realbot; - - endbot = min(max(endbheight, endrealbot), endtop); + bot = CLAMP(bheight, realbot, top); + endbot = CLAMP(endbheight, endrealbot, endtop); Surf->PolyColor.s.alpha = alpha; @@ -1049,7 +1048,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, bot = realbot; endbot = endrealbot; - if (endtop <= endrealbot && top <= realbot) + if ((endtop <= endrealbot) && (top <= realbot)) return; Surf->PolyColor.s.alpha = alpha; @@ -1150,7 +1149,7 @@ static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf) } // Returns true if the midtexture is visible, and false if... it isn't... -static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf) +static inline boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf) { FUINT blendmode = PF_Masked; @@ -1188,23 +1187,16 @@ static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf) case 908: blendmode = HWR_TranstableToAlpha(tr_trans90, pSurf); break; - // Translucent + // Translucent linedef types case 102: - case 121: - case 123: - case 124: - case 125: - case 141: - case 142: - case 144: - case 145: + case 121 ... 125: + case 141 ... 145: case 174: case 175: case 192: case 195: case 221: - case 253: - case 256: + case 253 ... 256: blendmode = PF_Translucent; break; default: @@ -1216,9 +1208,10 @@ static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf) { // Polyobject translucency is shared between all of its lines if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn + { + pSurf->PolyColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode return false; - //Surf.PolyColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode - //blendmode = PF_Masked; + } else blendmode = HWR_TranstableToAlpha(gl_curline->polyseg->translucency, pSurf); } @@ -1315,7 +1308,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gl_curline); FSurfaceInfo Surf; - Surf.PolyColor.s.alpha = 255; + + if (gl_frontsector) + Surf.PolyColor.s.alpha = 255; INT32 gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture); GLMapTexture_t *glTex = NULL; @@ -1711,6 +1706,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // Single sided line... Deal only with the middletexture (if one exists) if (gl_midtexture && gl_linedef->special != HORIZONSPECIAL) // Ignore horizon line for OGL { + glTex = HWR_GetTexture(gl_midtexture, noencore); + fixed_t texturevpeg; // PEGGING @@ -1721,8 +1718,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else texturevpeg = gl_sidedef->rowoffset; // top of texture at top - glTex = HWR_GetTexture(gl_midtexture, noencore); - wallVerts[3].t = wallVerts[2].t = texturevpeg * glTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * glTex->scaleY; wallVerts[0].s = wallVerts[3].s = cliplow * glTex->scaleX; @@ -3379,9 +3374,9 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, GLPatch_t *gpatch) } // This is expecting a pointer to an array containing 4 wallVerts for a sprite -static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean precip) +static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean precip, const boolean papersprite) { - if (!cv_glspritebillboarding.value || !spr || !spr->mobj || !wallVerts) + if (!cv_glspritebillboarding.value || !spr || !spr->mobj || !wallVerts || papersprite) { return; } @@ -3450,24 +3445,7 @@ static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts static inline void HWR_ApplyDispoffset(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean papersprite) { - // dont push papersprites near the cam unless they have a dispoffset - if (papersprite) - { - // if it has a dispoffset, push it a little towards the camera - if (spr->dispoffset) - { - float co = -gl_viewcos*(0.05f*spr->dispoffset); - float si = -gl_viewsin*(0.05f*spr->dispoffset); - wallVerts[0].z = wallVerts[3].z = wallVerts[0].z+si; - wallVerts[1].z = wallVerts[2].z = wallVerts[1].z+si; - wallVerts[0].x = wallVerts[3].x = wallVerts[0].x+co; - wallVerts[1].x = wallVerts[2].x = wallVerts[1].x+co; - } - - return; - } - - HWR_RotateSpritePolyToAim(spr, wallVerts, false); + HWR_RotateSpritePolyToAim(spr, wallVerts, false, papersprite); float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz)); float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist; @@ -3631,7 +3609,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite) for (i = 0; i < sector->numlights; i++) { - if (endtop < endrealbot && top < realbot) + if ((endtop < endrealbot) && (top < realbot)) return; // even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite @@ -3655,18 +3633,16 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite) endbheight = endrealbot; } - if (endbheight >= endtop && bheight >= top) + if (endbheight >= endtop) continue; - bot = bheight; + if (bheight >= top) + continue; - if (bot < realbot) - bot = realbot; - - endbot = endbheight; - - if (endbot < endrealbot) - endbot = endrealbot; + // Found a break + // The heights are clamped to ensure the polygon doesn't cross itself. + bot = CLAMP(bheight, realbot, top); + endbot = CLAMP(endbheight, endrealbot, endtop); wallVerts[3].t = towtop + ((realtop - top) * towmult); wallVerts[2].t = towtop + ((endrealtop - endtop) * towmult); @@ -3714,7 +3690,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite) bot = realbot; endbot = endrealbot; - if (endtop <= endrealbot && top <= realbot) + if ((endtop <= endrealbot) && (top <= realbot)) return; // If we're ever down here, somehow the above loop hasn't draw all the light levels of sprite @@ -3908,7 +3884,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) wallVerts[0].z = wallVerts[3].z = spr->z1; wallVerts[1].z = wallVerts[2].z = spr->z2; - HWR_RotateSpritePolyToAim(spr, wallVerts, true); + HWR_RotateSpritePolyToAim(spr, wallVerts, true, false); wallVerts[0].s = wallVerts[3].s = 0; wallVerts[2].s = wallVerts[1].s = gpatch->max_s; @@ -4605,18 +4581,10 @@ static void HWR_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE if (shouldrotate) { - if (papersprite) - { - // a positive rollangle should should pitch papersprites upwards relative to their facing angle - rollangle = InvAngle(thing->rollangle); - } - else - { - // this is very messy, but it on-the-fly calculates rotations for all the - // pitch and roll variables - pitchnroll = R_RotationAngle(ang, camang, &interp); - rollangle = thing->rollangle; - } + // this is very messy, but it on-the-fly calculates rotations for all the + // pitch and roll variables + pitchnroll = R_RotationAngle(ang, camang, &interp); + rollangle = thing->rollangle; if (rollangle || pitchnroll || sliprollrotate) { @@ -5592,10 +5560,80 @@ void HWR_Startup(void) if (msaa) HWD.pfnSetSpecialState(HWD_SET_MSAA, a2c ? 2 : 1); + + HWR_RegisterCommands(); } startupdone = true; } +/** + * Register renderer commands. + */ +static void HWR_RegisterCommands(void) +{ + COM_AddCommand("gr_glinfo", COM_HWR_glinfo); +} + +static void COM_HWR_glinfo(void) +{ + if (vid.glstate != VID_GL_LIBRARY_LOADED) + { + CONS_Printf("Currently not using the OpenGL renderer.\n"); + return; + } + + int list_extensions = 0; + size_t argc = COM_Argc(); + const char *argv; + for (size_t i = 1; i < argc; i++) + { + argv = COM_Argv(i); + + if (strcmp(argv, "--list-extensions") == 0 || strcmp(argv, "-l") == 0) + { + list_extensions = 1; + } + else + { + CONS_Printf("Unrecognized argument: %s\n", argv); + return; + } + + } + + CONS_Printf("\x88OpenGL %s\x80\n", gl_version); + CONS_Printf("Renderer: %s\n", gl_renderer); + CONS_Printf("Vendor: %s\n", gl_vendor); + + CONS_Printf("%u GL extensions present.\n", gl_num_extensions); + if (list_extensions) + { + // We need this strtok loop because we cannot write the extensions list directly + // to the output buffer, because it will overflow the output buffer of CONS_Printf + // if the GPU is super new and supports a bajillion extensions - xyzzy + + char *copy = strdup((const char*)gl_extensions); + char *ext = strtok(copy, " "); + + if (copy == NULL) + { + CONS_Printf("Ran out of memory listing extensions?!?!"); + return; + } + + do + { + CONS_Printf(" - %s\n", ext); + } while ((ext = strtok(NULL, " ")) != NULL); + + free(copy); + } + else + { + CONS_Printf("Use --list-extensions to view the list of extensions.\n"); + } +} + // -------------------------------------------------------------------------- // Free resources allocated by the hardware renderer // -------------------------------------------------------------------------- diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 19c03a7be..f411f9202 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -116,6 +116,8 @@ static FTransform md2_transform; const GLubyte *gl_version = NULL; const GLubyte *gl_renderer = NULL; const GLubyte *gl_extensions = NULL; +const GLubyte *gl_vendor = NULL; +GLuint gl_num_extensions; // Loaded OpenGL version int majorGL = 0, minorGL = 0; diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index c461258d0..0762afde0 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -119,6 +119,8 @@ extern boolean supportFBO; extern const GLubyte *gl_version; extern const GLubyte *gl_renderer; extern const GLubyte *gl_extensions; +extern const GLubyte *gl_vendor; +extern GLuint gl_num_extensions; extern int majorGL, minorGL; diff --git a/src/k_kart.c b/src/k_kart.c index 2a348a85b..b27789cfc 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6039,10 +6039,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_SetScale(overlay, player->mo->scale); } player->kartstuff[k_invincibilitytimer] = itemtime+(2*TICRATE); // 10 seconds + if (P_IsLocalPlayer(player) && cv_supermusic.value == 1 && cv_birdmusic.value) S_ChangeMusicSpecial("kinvnc"); else S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmi : sfx_kinvnc)); + P_RestoreMusic(player); K_PlayPowerGloatSound(player->mo); player->kartstuff[k_itemamount]--; @@ -8942,28 +8944,21 @@ static void K_drawKartBumpersOrKarma(void) static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *target, fixed_t hofs, boolean dontclip) { fixed_t distfact; - fixed_t dist; - fixed_t xres; - fixed_t yres; - fixed_t fov; - fixed_t fovratio; fixed_t offset; - boolean srcflip; - boolean targflip; fixed_t y; fixed_t x; // this should never happen but its also kart so ¯\_(ツ)_/¯ - if (!player || !target) + if (!player || P_MobjWasRemoved(target)) return false; - xres = vid.width<<(FRACBITS-1); - yres = vid.height<<(FRACBITS-1); - fov = FixedDiv(xres, FINETANGENT(((FixedAngle(cv_fov.value/2)+ANGLE_90)>>ANGLETOFINESHIFT) & 4095)); + const fixed_t xres = vid.width<<(FRACBITS-1); + const fixed_t yres = vid.height<<(FRACBITS-1); + const fixed_t fov = FixedDiv(xres, FINETANGENT(((FixedAngle(cv_fov.value/2)+ANGLE_90)>>ANGLETOFINESHIFT) & 4095)); - fixed_t targx = lerp(target->old_x, target->x); - fixed_t targy = lerp(target->old_y, target->y); - fixed_t targz = lerp(target->old_z, target->z); + const fixed_t targx = lerp(target->old_x, target->x); + const fixed_t targy = lerp(target->old_y, target->y); + const fixed_t targz = lerp(target->old_z, target->z); // X coordinate // get difference between camangle and angle towards target @@ -8978,8 +8973,8 @@ static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *targe return false; // flipping - targflip = target->eflags & MFE_VERTICALFLIP; - srcflip = player->pflags & PF_FLIPCAM && player->mo->eflags & MFE_VERTICALFLIP; + const boolean targflip = target->eflags & MFE_VERTICALFLIP; + const boolean srcflip = player->pflags & PF_FLIPCAM && player->mo->eflags & MFE_VERTICALFLIP; // Y coordinate // getting the angle difference here is a bit more involved... @@ -8989,7 +8984,7 @@ static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *targe y = y - (targflip ? -hofs : hofs); // then get the distance between camera and target - dist = R_PointToDist(targx, targy); + const fixed_t dist = R_PointToDist(targx, targy); #ifdef HWRENDER // NOW we can get the angle differnce @@ -9011,7 +9006,7 @@ static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *targe else #endif { - fovratio = FixedDiv(90*FRACUNIT, 180*FRACUNIT - FixedMul(cv_fov.value, 4*FRACUNIT/3)-FRACUNIT*-30); + const fixed_t fovratio = FixedDiv(90*FRACUNIT, 180*FRACUNIT - FixedMul(cv_fov.value, 4*FRACUNIT/3)-FRACUNIT*-30); y = FixedDiv(y, FixedMul(dist, distfact)); if (srcflip) @@ -9081,33 +9076,27 @@ static void K_drawNameTags(void) fixed_t tagwidth; fixed_t tagwidthsmall; fixed_t namex,namey; - int dup = 0; - int tagcolor = 0; - int vflags = 0; - int flipped = 0; int tagsdisplayed = 0; char *tag; patch_t *icon; - INT32 hudtransflag = V_LocalTransFlag(); - boolean flipcam; + const INT32 hudtransflag = V_LocalTransFlag(); - if (!stplyr->mo || (stplyr->spectator && !cv_shownametagspectator.value) || (stplyr->exiting && !cv_shownametagfinish.value)) + if (P_MobjWasRemoved(stplyr->mo) || (stplyr->spectator && !cv_shownametagspectator.value) || (stplyr->exiting && !cv_shownametagfinish.value)) return; // True if currently viewed player is flipped and has flipcam on - flipcam = (stplyr->pflags & PF_FLIPCAM) && (stplyr->mo->eflags & MFE_VERTICALFLIP); + const boolean flipcam = ((stplyr->pflags & PF_FLIPCAM) && (stplyr->mo->eflags & MFE_VERTICALFLIP)); for (i = 0; i < MAXPLAYERS; i++) { - UINT8 *cm; fixed_t distance = 0; - fixed_t maxdistance = (10*cv_nametagdist.value)* mapobjectscale; - flipped = 0; + const fixed_t maxdistance = ((10*cv_nametagdist.value)* mapobjectscale); + boolean flipped = 0; fixed_t z; if (i > PLAYERSMASK) continue; - if (!players[i].mo || P_MobjWasRemoved(players[i].mo) || players[i].spectator || !playeringame[i]) + if (P_MobjWasRemoved(players[i].mo) || players[i].spectator || !playeringame[i]) continue; if (i == displayplayers[stplyrnum] && !cv_showownnametag.value && !(leveltime < 130)) continue; @@ -9115,10 +9104,11 @@ static void K_drawNameTags(void) continue; if (players[i].kartstuff[k_hyudorotimer]) // player is invisible continue; - distance = R_PointToDist(players[i].mo->x, players[i].mo->y); + if (maxdistance) + distance = R_PointToDist(players[i].mo->x, players[i].mo->y); if (distance > maxdistance) continue; - if (!P_CheckSight(stplyr->mo, players[i].mo)) + if (!P_CheckSightFast(stplyr->mo, players[i].mo)) continue; switch (cv_nametagtrans.value) @@ -9156,7 +9146,7 @@ static void K_drawNameTags(void) break; } - dup = vid.dupx; + const INT32 dup = vid.dupx; // If flipcam is on, other player is flipped relative to us when we have different // verticalflip flag value. Otherwise, they are simply flipped when verticalflip flag says @@ -9186,9 +9176,9 @@ static void K_drawNameTags(void) tag = va("%s%s ", HU_SkinColorToConsoleColor(players[i].mo->color),player_names[i]); icon = R_GetSkinFaceMini(players[i].mo->player); - cm = R_GetTranslationColormap(players[i].skin, players[i].mo->color, GTC_CACHE); - tagcolor = colortranslations[players[i].mo->color][7]; - vflags = trans | V_NOSCALESTART; + const UINT8 *cm = R_GetTranslationColormap(players[i].skin, players[i].mo->color, GTC_CACHE); + const INT32 tagcolor = colortranslations[players[i].mo->color][7]; + const INT32 vflags = trans | V_NOSCALESTART; tagwidth = cv_smallnametags.value ? dup*V_SmallStringWidth(player_names[i], V_ALLOWLOWERCASE) : dup*V_ThinStringWidth(player_names[i], V_ALLOWLOWERCASE); tagwidthsmall = cv_smallnametags.value ? V_SmallStringWidth(player_names[i], V_ALLOWLOWERCASE) : V_ThinStringWidth(player_names[i], V_ALLOWLOWERCASE); @@ -9301,13 +9291,10 @@ static void K_drawNameTags(void) // Based on Driftgauge refactor by GenericHeroGuy ported from lua and expanded by NepDisk static void K_drawDriftGauge(void) { - INT32 driftval = K_GetKartDriftSparkValue(stplyr); - INT32 driftcharge = min(driftval*4, stplyr->kartstuff[k_driftcharge]); vector2_t pos = {0}; - fixed_t basex,basey; - INT32 drifttrans = 0; - INT32 hudtransflag = V_LocalTransFlag(); - int dup = vid.dupx; + fixed_t basex, basey; + const INT32 hudtransflag = V_LocalTransFlag(); + const int dup = vid.dupx; int i; UINT8 driftcolors[3][4] = { @@ -9329,7 +9316,7 @@ static void K_drawDriftGauge(void) if (demo.playback && demo.freecam) return; - if (!stplyr->mo || (!splitscreen && !camera->chase)) + if (P_MobjWasRemoved(stplyr->mo) || (!splitscreen && !camera->chase)) return; if (forceshowhud) @@ -9343,6 +9330,9 @@ skipcrap: if (!K_GetScreenCoords(&pos, stplyr, stplyr->mo, FixedMul(cv_driftgaugeofs.value, cv_driftgaugeofs.value > 0 ? stplyr->mo->scale : mapobjectscale), false)) return; + const INT32 driftval = K_GetKartDriftSparkValue(stplyr); + const INT32 driftcharge = min(driftval*4, stplyr->kartstuff[k_driftcharge]); + basex = pos.x>>FRACBITS; basey = pos.y>>FRACBITS; @@ -9350,19 +9340,18 @@ skipcrap: fixed_t bary; INT32 BAR_WIDTH; - if (cv_driftgaugetrans.value) - drifttrans = hudtransflag; - else - drifttrans = 0; + const INT32 drifttrans = ((cv_driftgaugetrans.value) ? hudtransflag : 0); switch (cv_driftgaugestyle.value) { case 1: case 2: case 3: - if (driftgaugegfx) { - if (cv_driftgaugestyle.value == 1 || cv_driftgaugestyle.value == 3) + if (!driftgaugegfx) + break; + + if (cv_driftgaugestyle.value == 1 || cv_driftgaugestyle.value == 3 || (cv_driftgaugestyle.value == 5 && xtra_speedo3)) { barx = basex - dup*23; BAR_WIDTH = dup*47; @@ -9375,10 +9364,10 @@ skipcrap: bary = basey - dup*2; - INT32 limit = driftval * (driftcharge >= driftval*2 ? 2 : 1); - INT32 width = ((driftcharge - (driftcharge >= driftval ? limit : 0)) * BAR_WIDTH) / limit; - INT32 level = min(driftcharge / driftval, 2); UINT8 *cmap; + const INT32 limit = driftval * (driftcharge >= driftval*2 ? 2 : 1); + const INT32 width = ((driftcharge - (driftcharge >= driftval ? limit : 0)) * BAR_WIDTH) / limit; + const INT32 level = min(driftcharge / driftval, 2); if (!K_UseColorHud()) V_DrawMappedPatch(cv_driftgaugestyle.value == 2 ? basex + dup*11 : basex, basey, V_NOSCALESTART|V_OFFSET|drifttrans, cv_driftgaugestyle.value == 2 ? driftgaugesmall : driftgauge, NULL); @@ -9397,7 +9386,7 @@ skipcrap: else // none/blue/red { cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[level],GTC_CACHE); - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { if (driftcharge >= driftval) V_DrawFill(barx, bary+dup*1+dup*i, BAR_WIDTH, dup, driftcolors[level-1][i] | V_NOSCALESTART|drifttrans); @@ -9417,7 +9406,7 @@ skipcrap: case 4: { UINT8 *cmap; - INT32 level = min(driftcharge / driftval, 2); + const INT32 level = min(driftcharge / driftval, 2); if (driftcharge >= driftval*4) cmap = R_GetTranslationColormap(TC_RAINBOW, 1 + leveltime % (MAXSKINCOLORS-1),GTC_CACHE); else diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 13e578d5c..b1d77d737 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1102,6 +1102,18 @@ static int lib_pCheckSight(lua_State *L) return 1; } +// DONT USE THIS FOR ANYTHING GAMEPLAY, THIS WILL DESYNCH! +static int lib_pCheckSightFast(lua_State *L) +{ + mobj_t *t1 = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *t2 = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + //HUDSAFE? + if (!t1 || !t2) + return LUA_ErrInvalid(L, "mobj_t"); + lua_pushboolean(L, P_CheckSightFast(t1, t2)); + return 1; +} + static int lib_pCheckHoopPosition(lua_State *L) { mobj_t *hoopthing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -3154,6 +3166,7 @@ static luaL_Reg lib[] = { {"P_SlideMove",lib_pSlideMove}, {"P_BounceMove",lib_pBounceMove}, {"P_CheckSight", lib_pCheckSight}, + {"P_CheckSightFast", lib_pCheckSightFast}, {"P_CheckHoopPosition",lib_pCheckHoopPosition}, {"P_RadiusAttack",lib_pRadiusAttack}, {"P_FloorzAtPos",lib_pFloorzAtPos}, diff --git a/src/p_local.h b/src/p_local.h index 7cf7c4389..08323e052 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -364,7 +364,11 @@ boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); void P_SlideMove(mobj_t *mo, boolean forceslide); void P_BouncePlayerMove(mobj_t *mo); void P_BounceMove(mobj_t *mo); -boolean P_CheckSight(mobj_t *t1, mobj_t *t2); + +#define P_CheckSight(t1, t2) P_CheckSight2(t1, t2, false) +#define P_CheckSightFast(t1, t2) P_CheckSight2(t1, t2, true) +boolean P_CheckSight2(mobj_t *t1, mobj_t *t2, boolean fast); + void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fixed_t radius); boolean P_CheckSector(sector_t *sector, boolean crunch); diff --git a/src/p_mobj.c b/src/p_mobj.c index d2ed232e1..b7c86cbd5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3294,7 +3294,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled if (player->pflags & PF_TIMEOVER) player->kartstuff[k_timeovercam] = (2*TICRATE)+1; - if (!resetcalled && !(player->pflags & PF_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead. + if (!resetcalled && !(player->pflags & PF_NOCLIP || leveltime < introtime) && !P_CheckSightFast(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead. P_ResetCamera(player, thiscam); else P_SlideCameraMove(thiscam); @@ -10201,19 +10201,26 @@ void P_SpawnPrecipitation(void) if (dedicated || !cv_drawdist_precip.value || curWeather == PRECIP_NONE) // SRB2Kart return; + fixed_t density = (cv_mobjscaleprecip.value ? mapobjectscale : FRACUNIT); + + if (cv_lessprecip.value) + density *= 2; // just spawn half the precip + // Use the blockmap to narrow down our placing patterns for (i = 0; i < bmapwidth*bmapheight; ++i) { basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE; basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE; - for (j = 0; j < FRACUNIT; j += cv_mobjscaleprecip.value ? mapobjectscale : FRACUNIT) + // If mobjscale < FRACUNIT, each blockmap cell covers + // more area so spawn more precipitation in that area. + for (j = 0; j < FRACUNIT; j += density) { INT32 floorz; INT32 ceilingz; - x = ((cv_lessprecip.value ? basex*1.5 : basex) + ((M_RandomKey(MAPBLOCKUNITS<<3)<>3)); - y = ((cv_lessprecip.value ? basey*1.5 : basey) + ((M_RandomKey(MAPBLOCKUNITS<<3)<>3)); + x = basex + ((M_RandomKey(MAPBLOCKUNITS << 3) << FRACBITS) >> 3); + y = basey + ((M_RandomKey(MAPBLOCKUNITS << 3) << FRACBITS) >> 3); precipsector = R_IsPointInSubsector(x, y); diff --git a/src/p_sight.c b/src/p_sight.c index b482403cb..1d71e5553 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -38,66 +38,21 @@ static INT32 sightcounts[2]; // // Returns side 0 (front), 1 (back), or 2 (on). // -static INT32 P_DivlineSide(fixed_t x, fixed_t y, divline_t *node) +// killough 4/19/98: made static, cleaned up +static INT32 P_DivlineSide(fixed_t x, fixed_t y, const divline_t *node) { - fixed_t dx, dy, left, right; - - if (!node->dx) - { - if (x == node->x) - return 2; - - if (x <= node->x) - return (node->dy > 0); - - return (node->dy < 0); - } - - if (!node->dy) - { - if (y == node->y) - return 2; - - if (y <= node->y) - return (node->dx < 0); - - return (node->dx > 0); - } - - dx = x - node->x; - dy = y - node->y; - - left = (node->dy>>FRACBITS) * (dx>>FRACBITS); - right = (dy>>FRACBITS) * (node->dx>>FRACBITS); - - if (right < left) - return 0; // front side - - if (left == right) - return 2; - - return 1; // back side + fixed_t left, right; + return + !node->dx ? x == node->x ? 2 : x <= node->x ? node->dy > 0 : node->dy < 0 : + !node->dy ? y == node->y ? 2 : y <= node->y ? node->dx < 0 : node->dx > 0 : + (right = ((y - node->y) >> FRACBITS) * (node->dx >> FRACBITS)) < + (left = ((x - node->x) >> FRACBITS) * (node->dy >> FRACBITS)) ? 0 : + right == left ? 2 : 1; } -// -// P_InterceptVector2 -// -// Returns the fractional intercept point along the first divline. -// This is only called by the addthings and addlines traversers. -// -static fixed_t P_InterceptVector2(divline_t *v2, divline_t *v1) +static INT32 P_DivlineCrossed(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, const divline_t *node) { - fixed_t frac, num, den; - - den = FixedMul(v1->dy>>8, v2->dx) - FixedMul(v1->dx>>8, v2->dy); - - if (!den) - return 0; - - num = FixedMul((v1->x - v2->x)>>8, v1->dy) + FixedMul((v2->y - v1->y)>>8, v1->dx); - frac = FixedDiv(num, den); - - return frac; + return (P_DivlineSide(x1, y1, node) == P_DivlineSide(x2, y2, node)); } static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) @@ -135,23 +90,21 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) v2 = line->v2; // line isn't crossed? - if (P_DivlineSide(v1->x, v1->y, &los->strace) == - P_DivlineSide(v2->x, v2->y, &los->strace)) + if (P_DivlineCrossed(v1->x, v1->y, v2->x, v2->y, &los->strace)) continue; divl.dx = v2->x - (divl.x = v1->x); divl.dy = v2->y - (divl.y = v1->y); // line isn't crossed? - if (P_DivlineSide(los->strace.x, los->strace.y, &divl) == - P_DivlineSide(los->t2x, los->t2y, &divl)) + if (P_DivlineCrossed(los->strace.x, los->strace.y, los->t2x, los->t2y, &divl)) continue; // stop because it is not two sided //if (!(po->flags & POF_TESTHEIGHT)) //return false; - frac = P_InterceptVector2(&los->strace, &divl); + frac = P_InterceptVector(&los->strace, &divl); // get slopes of top and bottom of this polyobject line topslope = FixedDiv(polysec->ceilingheight - los->sightzstart , frac); @@ -232,16 +185,14 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) v2 = line->v2; // line isn't crossed? - if (P_DivlineSide(v1->x, v1->y, &los->strace) == - P_DivlineSide(v2->x, v2->y, &los->strace)) + if (P_DivlineCrossed(v1->x, v1->y, v2->x, v2->y, &los->strace)) continue; divl.dx = v2->x - (divl.x = v1->x); divl.dy = v2->y - (divl.y = v1->y); // line isn't crossed? - if (P_DivlineSide(los->strace.x, los->strace.y, &divl) == - P_DivlineSide(los->t2x, los->t2y, &divl)) + if (P_DivlineCrossed(los->strace.x, los->strace.y, los->t2x, los->t2y, &divl)) continue; // stop because it is not two sided anyway @@ -249,7 +200,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) return false; // calculate fractional intercept (how far along we are divided by how far we are from t2) - frac = P_InterceptVector2(&los->strace, &divl); + frac = P_InterceptVector(&los->strace, &divl); front = seg->frontsector; back = seg->backsector; @@ -348,25 +299,34 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) // if strace crosses the given node successfully. // // killough 4/20/98: rewritten to remove tail recursion, clean up, and optimize - -static boolean P_CrossBSPNode(INT32 bspnum, register los_t *los) +static boolean P_CrossBSPNode(INT32 bspnum, register los_t *los, boolean fast) { while (!(bspnum & NF_SUBSECTOR)) { register node_t *bsp = nodes + bspnum; - INT32 side = P_DivlineSide(los->strace.x,los->strace.y,(divline_t *)bsp)&1; - if (side == P_DivlineSide(los->t2x, los->t2y, (divline_t *) bsp)) - bspnum = bsp->children[side]; // doesn't touch the other side - else // the partition plane is crossed here + + INT32 side = (fast ? R_PointOnSideFast(los->strace.x, los->strace.y, bsp) : (P_DivlineSide(los->strace.x,los->strace.y, (divline_t *)bsp) & 1)); + INT32 side2 = (fast ? R_PointOnSideFast(los->t2x, los->t2y, bsp) : P_DivlineSide(los->t2x, los->t2y, (divline_t *) bsp)); + + if (side == side2) { - if (!P_CrossBSPNode(bsp->children[side], los)) - return 0; // cross the starting side + bspnum = bsp->children[side]; // doesn't touch the other side + } + else + { + // the partition plane is crossed here + if (!P_CrossBSPNode(bsp->children[side], los, fast)) + { + return false; // cross the starting side + } else - bspnum = bsp->children[side^1]; // cross the ending side + { + bspnum = bsp->children[side^1]; // cross the ending side + } } } - return - P_CrossSubsector((bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR), los); + + return P_CrossSubsector((bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR), los); } // @@ -375,7 +335,7 @@ static boolean P_CrossBSPNode(INT32 bspnum, register los_t *los) // Returns true if a straight line between t1 and t2 is unobstructed. // Uses REJECT. // -boolean P_CheckSight(mobj_t *t1, mobj_t *t2) +boolean P_CheckSight2(mobj_t *t1, mobj_t *t2, boolean fast) { const sector_t *s1, *s2; size_t pnum; @@ -492,5 +452,5 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) } // the head node is the last node output - return P_CrossBSPNode((INT32)numnodes - 1, &los); -} \ No newline at end of file + return (P_CrossBSPNode((INT32)numnodes - 1, &los, fast)); +} diff --git a/src/p_spec.c b/src/p_spec.c index 2ab2c20df..2472c5dbf 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1807,27 +1807,23 @@ void P_SwitchWeather(INT32 weathernum) precipmobj = (precipmobj_t *)think; + mobjtype_t type = 0; + INT32 z = 0; + + if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse. + { + precipmobj->precipflags |= PCF_INVISIBLE; + continue; + } + if (swap == PRECIP_RAIN) // Snow To Rain { - precipmobj->type = MT_RAIN; // proper set the type - precipmobj->info = &mobjinfo[MT_RAIN]; - precipmobj->flags = mobjinfo[MT_RAIN].flags; - st = &states[mobjinfo[MT_RAIN].spawnstate]; - precipmobj->state = st; - precipmobj->tics = st->tics; - precipmobj->sprite = st->sprite; - precipmobj->frame = st->frame; - precipmobj->momz = cv_mobjscaleprecip.value ? FixedMul(mobjinfo[MT_RAIN].speed, mapobjectscale) : mobjinfo[MT_RAIN].speed; - - precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_SPLASH); // P_PrecipThinker will add this again if it needs to + type = MT_RAIN; } else if (swap == PRECIP_SNOW) // Rain To Snow { - INT32 z; + type = MT_SNOWFLAKE; - precipmobj->type = MT_SNOWFLAKE; // proper set the type - precipmobj->info = &mobjinfo[MT_SNOWFLAKE]; - precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags; z = M_RandomByte(); if (z < 64) @@ -1836,92 +1832,69 @@ void P_SwitchWeather(INT32 weathernum) z = 1; else z = 0; - - st = &states[mobjinfo[MT_SNOWFLAKE].spawnstate+z]; - precipmobj->state = st; - precipmobj->tics = st->tics; - precipmobj->sprite = st->sprite; - precipmobj->frame = st->frame; - precipmobj->momz = cv_mobjscaleprecip.value ? FixedMul(mobjinfo[MT_SNOWFLAKE].speed, mapobjectscale) : mobjinfo[MT_SNOWFLAKE].speed; - - precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_SPLASH); // P_PrecipThinker will add this again if it needs to - } - else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse. - { - precipmobj->precipflags |= PCF_INVISIBLE; } + + precipmobj->type = type; // proper set the type + precipmobj->info = &mobjinfo[type]; + precipmobj->flags = mobjinfo[type].flags; + + st = &states[mobjinfo[type].spawnstate+z]; + + precipmobj->state = st; + precipmobj->tics = st->tics; + precipmobj->sprite = st->sprite; + precipmobj->frame = st->frame; + precipmobj->momz = (cv_mobjscaleprecip.value ? FixedMul(mobjinfo[type].speed, mapobjectscale) : mobjinfo[type].speed); + + precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_SPLASH); // P_PrecipThinker will add this again if it needs to } } + boolean dontspawn = false; + switch (weathernum) { case PRECIP_SNOW: // snow curWeather = PRECIP_SNOW; - - if (!swap) - P_SpawnPrecipitation(); - break; case PRECIP_RAIN: // rain { - boolean dontspawn = false; - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) dontspawn = true; curWeather = PRECIP_RAIN; - - if (!dontspawn && !swap) - P_SpawnPrecipitation(); - break; } case PRECIP_STORM: // storm { - boolean dontspawn = false; - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) dontspawn = true; curWeather = PRECIP_STORM; - - if (!dontspawn && !swap) - P_SpawnPrecipitation(); - break; } case PRECIP_STORM_NOSTRIKES: // storm w/o lightning { - boolean dontspawn = false; - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) dontspawn = true; curWeather = PRECIP_STORM_NOSTRIKES; - - if (!dontspawn && !swap) - P_SpawnPrecipitation(); - break; } case PRECIP_STORM_NORAIN: // storm w/o rain curWeather = PRECIP_STORM_NORAIN; - - if (!swap) - P_SpawnPrecipitation(); - break; case PRECIP_BLANK: curWeather = PRECIP_BLANK; - - if (!swap) - P_SpawnPrecipitation(); - break; default: + dontspawn = true; curWeather = PRECIP_NONE; break; } + + if (!dontspawn && !swap) + P_SpawnPrecipitation(); } /** Gets an object. diff --git a/src/p_tick.c b/src/p_tick.c index 266defd74..3b0cadde8 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -720,12 +720,12 @@ void P_Ticker(boolean run) continue; const boolean skybox = (skyboxmo[0] && cv_skybox.value); - boolean isSkyVisibleForPlayer = skyVisiblePerPlayer[i]; - if (isSkyVisibleForPlayer && skybox) + if (skyVisiblePerPlayer[i] && skybox) { R_SkyboxFrame(i); } + R_SetupFrame(i, skybox); } } diff --git a/src/r_fps.c b/src/r_fps.c index 4dd7fa044..b861dea56 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -91,19 +91,24 @@ static levelinterpolator_t **levelinterpolators; static size_t levelinterpolators_len; static size_t levelinterpolators_size; +static inline fixed_t R_LerpFixedView(fixed_t from, fixed_t to, fixed_t frac) +{ + return from + FixedMul(frac, to - from); +} + +static inline angle_t R_LerpAngleView(angle_t from, angle_t to, fixed_t frac) +{ + return from + FixedMul(frac, to - from); +} static inline fixed_t R_LerpFixed(fixed_t from, fixed_t to, fixed_t frac) { - if (from == to) - return to; - return from + FixedMul(frac, to - from); + return ((from == to) ? to : (from + FixedMul(frac, to - from))); } static inline angle_t R_LerpAngle(angle_t from, angle_t to, fixed_t frac) { - if (from == to) - return to; - return from + FixedMul(frac, to - from); + return ((from == to) ? to : (from + FixedMul(frac, to - from))); } /*static vector2_t *R_LerpVector2(const vector2_t *from, const vector2_t *to, fixed_t frac, vector2_t *out) @@ -153,7 +158,7 @@ static void R_SetupFreelook(void) void R_InterpolateViewRollAngle(fixed_t frac) { - viewroll = R_LerpAngle(oldview->roll, newview->roll, frac); + viewroll = R_LerpAngleView(oldview->roll, newview->roll, frac); } void R_InterpolateView(fixed_t frac, boolean forceinvalid) @@ -181,13 +186,13 @@ void R_InterpolateView(fixed_t frac, boolean forceinvalid) prevview = newview; } - viewx = R_LerpFixed(prevview->x, newview->x, frac); - viewy = R_LerpFixed(prevview->y, newview->y, frac); - viewz = R_LerpFixed(prevview->z, newview->z, frac); + viewx = R_LerpFixedView(prevview->x, newview->x, frac); + viewy = R_LerpFixedView(prevview->y, newview->y, frac); + viewz = R_LerpFixedView(prevview->z, newview->z, frac); - viewangle = R_LerpAngle(prevview->angle, newview->angle, frac); - aimingangle = R_LerpAngle(prevview->aim, newview->aim, frac); - viewroll = R_LerpAngle(prevview->roll, newview->roll, frac); + viewangle = R_LerpAngleView(prevview->angle, newview->angle, frac); + aimingangle = R_LerpAngleView(prevview->aim, newview->aim, frac); + viewroll = R_LerpAngleView(prevview->roll, newview->roll, frac); viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); @@ -301,7 +306,7 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) out->y = mobj->y; out->z = mobj->z; out->scale = mobj->scale; - out->subsector = mobj->subsector; + //out->subsector = mobj->subsector; out->angle = mobj->player ? mobj->player->frameangle : mobj->angle; out->pitch = mobj->pitch; out->roll = mobj->roll; @@ -322,8 +327,7 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) out->spritexoffset = mobj->resetinterp ? mobj->spritexoffset : R_LerpFixed(mobj->old_spritexoffset, mobj->spritexoffset, frac); out->spriteyoffset = mobj->resetinterp ? mobj->spriteyoffset : R_LerpFixed(mobj->old_spriteyoffset, mobj->spriteyoffset, frac); out->scale = mobj->resetinterp ? mobj->scale : R_LerpFixed(mobj->old_scale, mobj->scale, frac); - //out->subsector = R_PointInSubsector(out->x, out->y); // why was this even done? - out->subsector = mobj->subsector; + //out->subsector = R_PointInSubsector(out->x, out->y); // this is unused if (mobj->player) out->angle = mobj->resetinterp ? mobj->player->frameangle : R_LerpAngle(mobj->player->old_frameangle, mobj->player->frameangle, frac); @@ -359,7 +363,7 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst out->y = mobj->y; out->z = mobj->z; out->scale = cv_mobjscaleprecip.value ? mapobjectscale : FRACUNIT; - out->subsector = mobj->subsector; + //out->subsector = mobj->subsector; out->angle = mobj->angle; out->spritexscale = mobj->spritexscale; out->spriteyscale = mobj->spriteyscale; @@ -376,9 +380,8 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst out->spriteyscale = mobj->spriteyscale; out->spritexoffset = mobj->spritexoffset; out->spriteyoffset = mobj->spriteyoffset; + //out->subsector = R_PointInSubsector(out->x, out->y); // this is unused - //out->subsector = R_PointInSubsector(out->x, out->y); // i dont understand lol - out->subsector = mobj->subsector; out->angle = R_LerpAngle(mobj->old_angle, mobj->angle, frac); } diff --git a/src/r_fps.h b/src/r_fps.h index a4aef71cd..5ac6cfe90 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -59,7 +59,7 @@ typedef struct { fixed_t x; fixed_t y; fixed_t z; - subsector_t *subsector; + //subsector_t *subsector; angle_t angle; fixed_t scale; fixed_t spritexscale; diff --git a/src/s_sound.c b/src/s_sound.c index 122b07525..119b0cbb9 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1854,10 +1854,7 @@ void S_StopMusic(void) || demo.title) // SRB2Kart: Demos don't interrupt title screen music return; - if (cv_birdmusic.value && (strcasecmp(music_name, mapmusname) == 0)) - mapmusresume = I_GetSongPosition(); - else - mapmusresume = 0; + mapmusresume = (cv_birdmusic.value && (strcasecmp(music_name, mapmusname) == 0)) ? I_GetSongPosition() : 0; if (I_SongPaused()) I_ResumeSong(); diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 20cd3107c..ced911eba 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -615,6 +615,7 @@ Countstutter (int len) } else bytes = ( music_bytes - music_stutter_bytes ); + I_SetSongPosition((int)( bytes/4/44100.0*1000 )); } } diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index e1e484bcc..fa18c0b1b 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -149,6 +149,8 @@ boolean OglSdlSurface(INT32 w, INT32 h) gl_version = pglGetString(GL_VERSION); gl_renderer = pglGetString(GL_RENDERER); gl_extensions = pglGetString(GL_EXTENSIONS); + pglGetIntegerv(GL_NUM_EXTENSIONS, (GLint*)&gl_num_extensions); + gl_vendor = pglGetString(GL_VENDOR); GL_DBG_Printf("OpenGL %s\n", gl_version); GL_DBG_Printf("GPU: %s\n", gl_renderer);