diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e52473241..270229ad0 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -45,7 +45,7 @@ #include "hw_md2.h" #define R_FAKEFLOORS -//#define HWPRECIP +#define HWPRECIP #define SORTING //#define POLYSKY @@ -4401,7 +4401,6 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) FOutVector *wv; GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; - sector_t *sector; if (!spr->mobj) return; @@ -4455,19 +4454,38 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) //Hurdler: 25/04/2000: now support colormap in hardware mode HWR_GetMappedPatch(gpatch, spr->colormap); - sector = spr->mobj->subsector->sector; - - if (sector->ffloors) + // colormap test { - ffloor_t *caster = sector->lightlist[R_GetPlaneLight(sector, spr->mobj->z, false)].caster; - sector = caster ? §ors[caster->secnum] : sector; - } + sector_t *sector = spr->mobj->subsector->sector; + UINT8 lightlevel = 255; + extracolormap_t *colormap = sector->extra_colormap; - // sprite lighting by modulating the RGB components - if (sector->extra_colormap) - Surf.FlatColor.rgba = HWR_Lighting(spr->sectorlight,sector->extra_colormap->rgba,sector->extra_colormap->fadergba, false, false); + if (sector->numlights) + { + INT32 light; + + light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before + + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *sector->lightlist[light].lightlevel; + + if (sector->lightlist[light].extra_colormap) + colormap = sector->lightlist[light].extra_colormap; + } else - Surf.FlatColor.rgba = HWR_Lighting(spr->sectorlight,NORMALFOG,FADEFOG, false, false); + { + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = sector->lightlevel; + + if (sector->extra_colormap) + 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); + } if (spr->mobj->flags2 & MF2_SHADOW) { @@ -5295,6 +5313,11 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) // vis = HWR_NewVisSprite(); vis->x1 = x1; +#if 0 + vis->x2 = x2; +#else + (void)x2; +#endif vis->x2 = tx; vis->tz = tz; vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST @@ -5307,7 +5330,6 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) // set top/bottom coords vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset) - gr_viewz; - vis->sectorlight = 0xff; vis->precip = true; } #endif diff --git a/src/m_cheat.c b/src/m_cheat.c index 1b0bdabd1..ce9519799 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -452,7 +452,7 @@ void Command_RTeleport_f(void) else inty = 0; - ss = R_PointInSubsector(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT); + ss = R_IsPointInSubsector(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT); if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height) { CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n")); diff --git a/src/p_map.c b/src/p_map.c index 24bb32b41..6ac48a7c8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1115,18 +1115,24 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - topz = thing->z - FixedMul(FRACUNIT, thing->scale); + topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways // block only when jumping not high enough, // (dont climb max. 24units while already in air) - // if not in air, let P_TryMove() decide if it's not too high + // since return false doesn't handle momentum properly, + // we lie to P_TryMove() so it's always too high if (tmthing->player && tmthing->z + tmthing->height > topz && tmthing->z + tmthing->height < tmthing->ceilingz) - return false; // block while in air - - if (thing->flags & MF_SPRING) + { + tmfloorz = tmceilingz = INT32_MIN; // block while in air +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + tmfloorthing = thing; // needed for side collision + } + else if (thing->flags & MF_SPRING) ; - else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) + else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height) { tmceilingz = topz; #ifdef ESLOPE @@ -1152,17 +1158,24 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - topz = thing->z + thing->height + FixedMul(FRACUNIT, thing->scale); + topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways // block only when jumping not high enough, // (dont climb max. 24units while already in air) - // if not in air, let P_TryMove() decide if it's not too high - if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz) - return false; // block while in air - - if (thing->flags & MF_SPRING) + // since return false doesn't handle momentum properly, + // we lie to P_TryMove() so it's always too high + if (tmthing->player && tmthing->z < topz + && tmthing->z > tmthing->floorz) + { + tmfloorz = tmceilingz = INT32_MAX; // block while in air +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + tmfloorthing = thing; // needed for side collision + } + else if (thing->flags & MF_SPRING) ; - else if (topz > tmfloorz && tmthing->z >= thing->z) + else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z) { tmfloorz = topz; #ifdef ESLOPE diff --git a/src/p_mobj.c b/src/p_mobj.c index eb52bca74..2f82f3cb9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6448,6 +6448,8 @@ void P_RunOverlays(void) P_UnsetThingPosition(mo); mo->x = destx; mo->y = desty; + mo->radius = mo->target->radius; + mo->height = mo->target->height; if (mo->eflags & MFE_VERTICALFLIP) mo->z = (mo->target->z + mo->target->height - mo->height) - zoffs; else diff --git a/src/p_setup.c b/src/p_setup.c index abf8bd7b3..a364b1c8e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2588,10 +2588,6 @@ boolean P_SetupLevel(boolean skipprecip) R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette); CON_ReSetupBackColormap(mapheaderinfo[gamemap-1]->palette); - // now part of level loading since in future each level may have - // its own anim texture sequences, switches etc. - P_InitPicAnims(); - // SRB2 determines the sky texture to be used depending on the map header. P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true); @@ -3002,6 +2998,9 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) else R_FlushTextureCache(); // just reload it from file + // Reload ANIMATED / ANIMDEFS + P_InitPicAnims(); + // Flush and reload HUD graphics ST_UnloadGraphics(); HU_LoadGraphics(); diff --git a/src/p_spec.c b/src/p_spec.c index 57bcb19d4..6e0ac7486 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -221,8 +221,8 @@ static animdef_t harddefs[] = static animdef_t *animdefs = NULL; // A prototype; here instead of p_spec.h, so they're "private" -void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i); -void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i); +void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum); +void P_ParseAnimationDefintion(SINT8 istexture); /** Sets up texture and flat animations. * @@ -232,24 +232,21 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i); * Issues an error if any animation cycles are invalid. * * \sa P_FindAnimatedFlat, P_SetupLevelFlatAnims - * \author Steven McGranahan (original), Shadow Hog (had to rewrite it to handle multiple WADs) + * \author Steven McGranahan (original), Shadow Hog (had to rewrite it to handle multiple WADs), JTE (had to rewrite it to handle multiple WADs _correctly_) */ void P_InitPicAnims(void) { // Init animation - INT32 i; // Position in the animdefs array INT32 w; // WAD - UINT8 *wadAnimdefs; // not to be confused with animdefs, the combined total of every ANIMATED lump in every WAD, or ANIMDEFS, the ZDoom lump I intend to implement later + UINT8 *animatedLump; UINT8 *currentPos; + size_t i; + + I_Assert(animdefs == NULL); if (W_CheckNumForName("ANIMATED") != LUMPERROR || W_CheckNumForName("ANIMDEFS") != LUMPERROR) { - if (animdefs) - { - Z_Free(animdefs); - animdefs = NULL; - } - for (w = 0, i = 0, maxanims = 0; w < numwadfiles; w++) + for (w = numwadfiles-1, maxanims = 0; w >= 0; w--) { UINT16 animatedLumpNum; UINT16 animdefsLumpNum; @@ -258,20 +255,20 @@ void P_InitPicAnims(void) animatedLumpNum = W_CheckNumForNamePwad("ANIMATED", w, 0); if (animatedLumpNum != INT16_MAX) { - wadAnimdefs = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC); + animatedLump = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC); // Get the number of animations in the file - for (currentPos = wadAnimdefs; *currentPos != UINT8_MAX; maxanims++, currentPos+=23); + i = maxanims; + for (currentPos = animatedLump; *currentPos != UINT8_MAX; maxanims++, currentPos+=23); // Resize animdefs (or if it hasn't been created, create it) animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); // Sanity check it - if (!animdefs) { + if (!animdefs) I_Error("Not enough free memory for ANIMATED data"); - } // Populate the new array - for (currentPos = wadAnimdefs; *currentPos != UINT8_MAX; i++, currentPos+=23) + for (currentPos = animatedLump; *currentPos != UINT8_MAX; i++, currentPos+=23) { M_Memcpy(&(animdefs[i].istexture), currentPos, 1); // istexture, 1 byte M_Memcpy(animdefs[i].endname, (currentPos + 1), 9); // endname, 9 bytes @@ -279,15 +276,13 @@ void P_InitPicAnims(void) M_Memcpy(&(animdefs[i].speed), (currentPos + 19), 4); // speed, 4 bytes } - Z_Free(wadAnimdefs); + Z_Free(animatedLump); } // Now find ANIMDEFS animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); if (animdefsLumpNum != INT16_MAX) - { - P_ParseANIMDEFSLump(w, animdefsLumpNum, &i); - } + P_ParseANIMDEFSLump(w, animdefsLumpNum); } // Define the last one animdefs[maxanims].istexture = -1; @@ -347,16 +342,20 @@ void P_InitPicAnims(void) lastanim->istexture = -1; R_ClearTextureNumCache(false); + // Clear animdefs now that we're done with it. + // We'll only be using anims from now on. if (animdefs != harddefs) - Z_ChangeTag(animdefs, PU_CACHE); + Z_Free(animdefs); + animdefs = NULL; } -void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i) +void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum) { char *animdefsLump; size_t animdefsLumpLength; char *animdefsText; char *animdefsToken; + char *p; // Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll // need to make a space of memory where I can ensure that it will terminate @@ -376,18 +375,19 @@ void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i) Z_Free(animdefsLump); // Now, let's start parsing this thing - animdefsToken = M_GetToken(animdefsText); + p = animdefsText; + animdefsToken = M_GetToken(p); while (animdefsToken != NULL) { if (stricmp(animdefsToken, "TEXTURE") == 0) { Z_Free(animdefsToken); - P_ParseAnimationDefintion(1, i); + P_ParseAnimationDefintion(1); } else if (stricmp(animdefsToken, "FLAT") == 0) { Z_Free(animdefsToken); - P_ParseAnimationDefintion(0, i); + P_ParseAnimationDefintion(0); } else if (stricmp(animdefsToken, "OSCILLATE") == 0) { @@ -398,23 +398,22 @@ void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum, INT32 *i) { I_Error("Error parsing ANIMDEFS lump: Expected \"TEXTURE\" or \"FLAT\", got \"%s\"",animdefsToken); } - animdefsToken = M_GetToken(NULL); + // parse next line + while (*p != '\0' && *p != '\n') ++p; + if (*p == '\n') ++p; + animdefsToken = M_GetToken(p); } Z_Free(animdefsToken); Z_Free((void *)animdefsText); } -void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) +void P_ParseAnimationDefintion(SINT8 istexture) { char *animdefsToken; size_t animdefsTokenLength; char *endPos; INT32 animSpeed; - - // Increase the size to make room for the new animation definition - maxanims++; - animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); - animdefs[*i].istexture = istexture; + size_t i; // Startname animdefsToken = M_GetToken(NULL); @@ -448,14 +447,39 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) { I_Error("Error parsing ANIMDEFS lump: lump name \"%s\" exceeds 8 characters", animdefsToken); } - strncpy(animdefs[*i].startname, animdefsToken, 9); + + // Search for existing animdef + for (i = 0; i < maxanims; i++) + if (stricmp(animdefsToken, animdefs[i].startname) == 0) + { + //CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken); + + // If we weren't parsing in reverse order, we would `break` here and parse the new data into the existing slot we found. + // Instead, we're just going to skip parsing the rest of this line entirely. + Z_Free(animdefsToken); + return; + } + + // Not found + if (i == maxanims) + { + // Increase the size to make room for the new animation definition + maxanims++; + animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); + strncpy(animdefs[i].startname, animdefsToken, 9); + } + + // animdefs[i].startname is now set to animdefsToken either way. Z_Free(animdefsToken); + // set texture type + animdefs[i].istexture = istexture; + // "RANGE" animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"RANGE\" after \"%s\"'s startname should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"RANGE\" after \"%s\"'s startname should be", animdefs[i].startname); } if (stricmp(animdefsToken, "ALLOWDECALS") == 0) { @@ -470,7 +494,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) } if (stricmp(animdefsToken, "RANGE") != 0) { - I_Error("Error parsing ANIMDEFS lump: Expected \"RANGE\" after \"%s\"'s startname, got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected \"RANGE\" after \"%s\"'s startname, got \"%s\"", animdefs[i].startname, animdefsToken); } Z_Free(animdefsToken); @@ -478,21 +502,21 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s end texture/flat name should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s end texture/flat name should be", animdefs[i].startname); } animdefsTokenLength = strlen(animdefsToken); if (animdefsTokenLength>8) { I_Error("Error parsing ANIMDEFS lump: lump name \"%s\" exceeds 8 characters", animdefsToken); } - strncpy(animdefs[*i].endname, animdefsToken, 9); + strncpy(animdefs[i].endname, animdefsToken, 9); Z_Free(animdefsToken); // "TICS" animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s \"TICS\" should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s \"TICS\" should be", animdefs[i].startname); } if (stricmp(animdefsToken, "RAND") == 0) { @@ -501,7 +525,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) } if (stricmp(animdefsToken, "TICS") != 0) { - I_Error("Error parsing ANIMDEFS lump: Expected \"TICS\" in animation definition for \"%s\", got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected \"TICS\" in animation definition for \"%s\", got \"%s\"", animdefs[i].startname, animdefsToken); } Z_Free(animdefsToken); @@ -509,7 +533,7 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) animdefsToken = M_GetToken(NULL); if (animdefsToken == NULL) { - I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[*i].startname); + I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[i].startname); } endPos = NULL; #ifndef AVOID_ERRNO @@ -523,13 +547,10 @@ void P_ParseAnimationDefintion(SINT8 istexture, INT32 *i) #endif || animSpeed < 0) // Number is not positive { - I_Error("Error parsing ANIMDEFS lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[*i].startname, animdefsToken); + I_Error("Error parsing ANIMDEFS lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[i].startname, animdefsToken); } - animdefs[*i].speed = animSpeed; + animdefs[i].speed = animSpeed; Z_Free(animdefsToken); - - // Increment i before we go, so this doesn't cause issues later - (*i)++; } diff --git a/src/p_user.c b/src/p_user.c index 0de7e46d3..45a55d76b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2289,14 +2289,13 @@ static void P_DoClimbing(player_t *player) fixed_t platy; subsector_t *glidesector; boolean climb = true; - boolean onesided = ((player->lastsidehit != -1 && player->lastlinehit != -1) && !(lines[player->lastlinehit].backsector)); platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); + glidesector = R_IsPointInSubsector(player->mo->x + platx, player->mo->y + platy); - if (onesided || glidesector->sector != player->mo->subsector->sector) + if (!glidesector || glidesector->sector != player->mo->subsector->sector) { boolean floorclimb = false; boolean thrust = false; @@ -2304,7 +2303,7 @@ static void P_DoClimbing(player_t *player) boolean skyclimber = false; fixed_t floorheight, ceilingheight; // ESLOPE - if (onesided) + if (!glidesector) floorclimb = true; else { diff --git a/src/r_data.c b/src/r_data.c index cb5cf3591..87b6b1193 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1499,6 +1499,9 @@ void R_InitData(void) CONS_Printf("R_LoadTextures()...\n"); R_LoadTextures(); + CONS_Printf("P_InitPicAnims()...\n"); + P_InitPicAnims(); + CONS_Printf("R_InitSprites()...\n"); R_InitSpriteLumps(); R_InitSprites(); diff --git a/src/r_main.c b/src/r_main.c index 79ee803e1..b05e37b53 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -771,7 +771,7 @@ subsector_t *R_PointInSubsector(fixed_t x, fixed_t y) } // -// R_IsPointInSubsector, same as above but returns 0 if not in subsector - this does not work in opengl because of polyvertex_t +// R_IsPointInSubsector, same as above but returns 0 if not in subsector // subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) { @@ -795,7 +795,8 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) ret = &subsectors[nodenum & ~NF_SUBSECTOR]; for (i = 0; i < ret->numlines; i++) - if (R_PointOnSegSide(x, y, &segs[ret->firstline + i])) + //if (R_PointOnSegSide(x, y, &segs[ret->firstline + i])) -- breaks in ogl because polyvertex_t cast over vertex pointers + if (P_PointOnLineSide(x, y, segs[ret->firstline + i].linedef) != segs[ret->firstline + i].side) return 0; return ret;