diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5a0d997fa..40f17301b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2825,7 +2825,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) } HWR_Lighting(&sSurf, 0, colormap); - sSurf.PolyColor.s.alpha = alpha; + sSurf.PolyColor.s.alpha = FixedMul(thing->alpha, alpha); if (HWR_UseShader()) { @@ -2999,11 +2999,16 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) // baseWallVerts is used to know the final shape to easily get the vertex // co-ordinates memcpy(wallVerts, baseWallVerts, sizeof(baseWallVerts)); + + UINT32 newalpha = spr->mobj->alpha; // if sprite has linkdraw, then dont write to z-buffer (by not using PF_Occlude) // this will result in sprites drawn afterwards to be drawn on top like intended when using linkdraw. if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer) + { + newalpha = spr->mobj->tracer->alpha; occlusion = 0; + } else occlusion = PF_Occlude; @@ -3039,6 +3044,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) blend = HWR_GetBlendModeFlag(blendmode)|occlusion; if (!occlusion) use_linkdraw_hack = true; } + + Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha); if (HWR_UseShader()) { @@ -3488,11 +3495,15 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) FBITFIELD blend = 0; FBITFIELD occlusion; boolean use_linkdraw_hack = false; + UINT32 newalpha = spr->mobj->alpha; // if sprite has linkdraw, then dont write to z-buffer (by not using PF_Occlude) // this will result in sprites drawn afterwards to be drawn on top like intended when using linkdraw. if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer) + { occlusion = 0; + newalpha = spr->mobj->tracer->alpha; + } else occlusion = PF_Occlude; @@ -3528,6 +3539,8 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) blend = HWR_GetBlendModeFlag(blendmode)|occlusion; if (!occlusion) use_linkdraw_hack = true; } + + Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha); if (spr->renderflags & RF_SHADOWEFFECTS) { diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 7fd16b32b..79d839677 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -69,6 +69,7 @@ enum mobj_e { mobj_color, mobj_translation, mobj_blendmode, + mobj_alpha, mobj_bnext, mobj_bprev, mobj_hnext, @@ -150,6 +151,7 @@ static const char *const mobj_opt[] = { "color", "translation", "blendmode", + "alpha", "bnext", "bprev", "hnext", @@ -354,6 +356,9 @@ static int mobj_get(lua_State *L) case mobj_blendmode: lua_pushinteger(L, mo->blendmode); break; + case mobj_alpha: + lua_pushinteger(L, mo->alpha); + break; case mobj_bnext: if (mo->blocknode && mo->blocknode->bnext) { LUA_PushUserdata(L, mo->blocknode->bnext->mobj, META_MOBJ); @@ -733,6 +738,14 @@ static int mobj_set(lua_State *L) mo->blendmode = blendmode; break; } + case mobj_alpha: + INT32 alpha = (INT32)luaL_checkinteger(L, 3); + if (alpha < 0) + alpha = 0; + else if (alpha > FRACUNIT) + alpha = FRACUNIT; + mo->alpha = alpha; + break; case mobj_bnext: return NOSETPOS; case mobj_bprev: diff --git a/src/p_mobj.c b/src/p_mobj.c index 8bc6abc54..72a4c1ddb 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10503,6 +10503,9 @@ void P_MobjThinker(mobj_t *mobj) mobj->frame &= ~FF_TRANSMASK; mobj->frame |= value << FF_TRANSSHIFT; + + // TODO: Consider replacing the above with the commented-out line of code below + //mobj->alpha = FixedDiv(mobj->fuse, mobj->info->damage); } break; default: @@ -10838,6 +10841,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) // Sprite rendering mobj->blendmode = AST_TRANSLUCENT; + mobj->alpha = FRACUNIT; mobj->spritexscale = mobj->spriteyscale = mobj->scale; mobj->spritexoffset = mobj->spriteyoffset = 0; mobj->floorspriteslope = NULL; diff --git a/src/p_mobj.h b/src/p_mobj.h index f833415ed..401071295 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -313,6 +313,7 @@ typedef struct mobj_s UINT32 renderflags; // render flags INT32 blendmode; // blend mode + UINT32 alpha; // alpha fixed_t spritexscale, spriteyscale; fixed_t spritexoffset, spriteyoffset; fixed_t old_spritexscale, old_spriteyscale; diff --git a/src/p_saveg.c b/src/p_saveg.c index 6c6548c56..c8b812a3e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1742,7 +1742,8 @@ typedef enum MD2_DISPOFFSET = 1<<23, MD2_DRAWONLYFORPLAYER = 1<<24, MD2_DONTDRAWFORVIEWMOBJ = 1<<25, - MD2_TRANSLATION = 1<<26 + MD2_TRANSLATION = 1<<26, + MD2_ALPHA = 1<<27 } mobj_diff2_t; typedef enum @@ -1985,6 +1986,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_DONTDRAWFORVIEWMOBJ; if (mobj->dispoffset != mobj->info->dispoffset) diff2 |= MD2_DISPOFFSET; + if (mobj->alpha < FRACUNIT) + diff2 |= MD2_ALPHA; if (diff2 != 0) diff |= MD_MORE; @@ -2168,6 +2171,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, mobj->dispoffset); if (diff2 & MD2_TRANSLATION) WRITEUINT16(save_p, mobj->translation); + if (diff2 & MD2_ALPHA) + WRITEUINT32(save_p, mobj->alpha); WRITEUINT32(save_p, mobj->mobjnum); } @@ -3234,6 +3239,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->dispoffset = mobj->info->dispoffset; if (diff2 & MD2_TRANSLATION) mobj->translation = READUINT16(save_p); + if (diff2 & MD2_ALPHA) + mobj->alpha = READUINT32(save_p); if (diff & MD_REDFLAG) { diff --git a/src/p_user.c b/src/p_user.c index 9d0eed288..2f73db272 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2065,6 +2065,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->renderflags = mobj->renderflags; ghost->blendmode = mobj->blendmode; + ghost->alpha = mobj->alpha; ghost->spritexscale = mobj->spritexscale; ghost->spriteyscale = mobj->spriteyscale; diff --git a/src/r_things.c b/src/r_things.c index 57078b4a6..a27a03e77 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -763,6 +763,14 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans return NULL; } +transnum_t R_GetTransmapFromAlpha(UINT32 alpha, transnum_t transmap) +{ + INT32 value = 10 - transmap; + value = 10 - (FixedCeil(alpha * value)>>FRACBITS); + + return value; +} + // // R_DrawVisSprite // mfloorclip and mceilingclip should also be set. @@ -1268,6 +1276,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, floordiff = abs((isflipped ? interp.height : 0) + interp.z - groundz); trans = floordiff / (100*FRACUNIT) + 3; + trans = R_GetTransmapFromAlpha(thing->alpha, trans); if (trans >= 9) return; scalemul = FixedMul(FRACUNIT - floordiff/640, scale); @@ -1952,6 +1961,11 @@ static void R_ProjectSprite(mobj_t *thing) } else trans = 0; + + if ((oldthing->flags2 & MF2_LINKDRAW) && oldthing->tracer) + trans = R_GetTransmapFromAlpha(oldthing->tracer->alpha, trans); + else + trans = R_GetTransmapFromAlpha(oldthing->alpha, trans); // Check if this sprite needs to be rendered like a shadow shadowdraw = (!!(thing->renderflags & RF_SHADOWDRAW) && !(papersprite || splat)); @@ -3414,6 +3428,10 @@ boolean R_ThingVisible (mobj_t *thing) (thing->sprite == SPR_NULL) || // Don't draw null-sprites (thing->flags2 & MF2_DONTDRAW) || // Don't draw MF2_LINKDRAW objects (thing->drawonlyforplayer && thing->drawonlyforplayer != viewplayer) || // Don't draw other players' personal objects + //(thing->alpha == 0) || // Don't draw objects with an alpha of 0 + ((rendermode == render_soft && R_GetTransmapFromAlpha(thing->alpha, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT) >= 10) || + (rendermode == render_opengl && thing->alpha == 0)) || // TODO: Maybe rethink this + //(rendermode == render_soft && R_GetTransmapFromAlpha(thing->alpha, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT) >= 10) || (!P_MobjWasRemoved(r_viewmobj) && ( (r_viewmobj == thing) || // Don't draw first-person players or awayviewmobj objects (r_viewmobj->player && r_viewmobj->player->followmobj == thing) || // Don't draw first-person players' followmobj diff --git a/src/r_things.h b/src/r_things.h index 043b454b0..086dd8b55 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -90,6 +90,7 @@ boolean R_ThingIsFullDark (mobj_t *thing); boolean R_ThingIsFlashing (mobj_t *thing); UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 translation); +transnum_t R_GetTransmapFromAlpha(UINT32 alpha, transnum_t transmap); void R_ThingOffsetOverlay (mobj_t *thing, fixed_t *outx, fixed_t *outy);