diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index b9198ea77..540969a08 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -1032,6 +1032,7 @@ void HWR_GetPatch(patch_t *patch) { if (!patch->hardware) Patch_CreateGL(patch); + HWR_LoadPatchMipmap(patch, ((GLPatch_t *)patch->hardware)->mipmap); } @@ -1055,7 +1056,7 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap) Patch_CreateGL(patch); grPatch = patch->hardware; - if (colormap == colormaps || colormap == NULL) + if (colormap == colormaps || colormap == NULL || patch->format == PATCH_FORMAT_RGBA) { // Load the default (green) color in hardware cache HWR_GetPatch(patch); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 82e30da18..481d4bb77 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4973,15 +4973,13 @@ static void HWR_ProjectSprite(mobj_t *thing) float spritexscale, spriteyscale; float shadowheight = 1.0f, shadowscale = 1.0f; float gz, gzt; - spritedef_t *sprdef; - spriteframe_t *sprframe; + spriteframe_t *sprframe = NULL; #ifdef ROTSPRITE - spriteinfo_t *sprinfo; + spriteinfo_t *sprinfo = NULL; #endif md2_t *md2; - size_t lumpoff; unsigned rot; - UINT16 flip; + UINT16 flip = 0; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(thing)); boolean mirrored = thing->mirrored; boolean hflip = (!R_ThingHorizontallyFlipped(thing) != !mirrored); @@ -4993,6 +4991,7 @@ static void HWR_ProjectSprite(mobj_t *thing) const boolean papersprite = (R_ThingIsPaperSprite(thing) && !splat); float z1, z2; + patch_t *gpatch = NULL; fixed_t spr_width, spr_height; fixed_t spr_offset, spr_topoffset; #ifdef ROTSPRITE @@ -5022,7 +5021,6 @@ static void HWR_ProjectSprite(mobj_t *thing) dispoffset = thing->dispoffset; - if (R_UsingFrameInterpolation() && !paused) { R_InterpolateMobjState(thing, rendertimefrac, &interp); @@ -5067,51 +5065,73 @@ static void HWR_ProjectSprite(mobj_t *thing) tr_x = FIXED_TO_FLOAT(interp.x); tr_y = FIXED_TO_FLOAT(interp.y); - // decide which patch to use for sprite relative to player -#ifdef RANGECHECK - if ((unsigned)thing->sprite >= numsprites) - I_Error("HWR_ProjectSprite: invalid sprite number %i ", thing->sprite); -#endif + boolean using_sprite = thing->image == NULL; + boolean use_single_rotation = false; - rot = thing->frame&FF_FRAMEMASK; - - //Fab : 02-08-98: 'skin' override spritedef currently used for skin - if (thing->skin && thing->sprite == SPR_PLAY) + if (!using_sprite) { - sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; -#ifdef ROTSPRITE - sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2]; -#endif + gpatch = (patch_t*)thing->image; + + if (Patch_NeedsUpdate(gpatch, false)) + Patch_DoDynamicUpdate(gpatch, false); + + spr_width = gpatch->width << FRACBITS; + spr_height = gpatch->height << FRACBITS; + spr_offset = gpatch->leftoffset << FRACBITS; + spr_topoffset = gpatch->topoffset << FRACBITS; + + use_single_rotation = true; } else { - sprdef = &sprites[thing->sprite]; -#ifdef ROTSPRITE - sprinfo = &spriteinfo[thing->sprite]; -#endif - } + spritedef_t *sprdef; - if (rot >= sprdef->numframes) - { - CONS_Alert(CONS_ERROR, M_GetText("HWR_ProjectSprite: invalid sprite frame %s/%s for %s\n"), - sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]); - thing->sprite = states[S_UNKNOWN].sprite; - thing->frame = states[S_UNKNOWN].frame; - sprdef = &sprites[thing->sprite]; -#ifdef ROTSPRITE - sprinfo = &spriteinfo[thing->sprite]; + // decide which patch to use for sprite relative to player +#ifdef RANGECHECK + if ((unsigned)thing->sprite >= numsprites) + I_Error("HWR_ProjectSprite: invalid sprite number %i ", thing->sprite); #endif + rot = thing->frame&FF_FRAMEMASK; - thing->state->sprite = thing->sprite; - thing->state->frame = thing->frame; - } - sprframe = &sprdef->spriteframes[rot]; + //Fab : 02-08-98: 'skin' override spritedef currently used for skin + if (thing->skin && thing->sprite == SPR_PLAY) + { + sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; +#ifdef ROTSPRITE + sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2]; +#endif + } + else + { + sprdef = &sprites[thing->sprite]; +#ifdef ROTSPRITE + sprinfo = &spriteinfo[thing->sprite]; +#endif + } + + if (rot >= sprdef->numframes) + { + CONS_Alert(CONS_ERROR, M_GetText("HWR_ProjectSprite: invalid sprite frame %s/%s for %s\n"), + sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]); + thing->sprite = states[S_UNKNOWN].sprite; + thing->frame = states[S_UNKNOWN].frame; + sprdef = &sprites[thing->sprite]; +#ifdef ROTSPRITE + sprinfo = &spriteinfo[thing->sprite]; +#endif + rot = thing->frame&FF_FRAMEMASK; + thing->state->sprite = thing->sprite; + thing->state->frame = thing->frame; + } + + sprframe = &sprdef->spriteframes[rot]; #ifdef PARANOIA - if (!sprframe) - I_Error("sprframes NULL for sprite %d\n", thing->sprite); + if (!sprframe) + I_Error("sprframes NULL for sprite %d\n", thing->sprite); #endif + } if (splat) { @@ -5124,47 +5144,54 @@ static void HWR_ProjectSprite(mobj_t *thing) ang = InvAngle(ang); } - if (sprframe->rotate == SRF_SINGLE) + if (sprframe) { - // use single rotation for all views - rot = 0; //Fab: for vis->patch below - lumpoff = sprframe->lumpid[0]; //Fab: see note above - flip = sprframe->flip; // Will only be 0x00 or 0xFF + size_t lumpoff; - if (papersprite && ang < ANGLE_180) - flip ^= 0xFFFF; - } - else - { - // choose a different rotation based on player view - if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right - rot = 6; // F7 slot - else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left - rot = 2; // F3 slot - else if (sprframe->rotate & SRF_3DGE) // 16-angle mode + if (use_single_rotation) { - rot = (ang+ANGLE_180+ANGLE_11hh)>>28; - rot = ((rot & 1)<<3)|(rot>>1); + // use single rotation for all views + rot = 0; //Fab: for vis->patch below + lumpoff = sprframe->lumpid[0]; //Fab: see note above + flip = sprframe->flip; // Will only be 0x00 or 0xFF + + if (papersprite && ang < ANGLE_180) + flip ^= 0xFFFF; } - else // Normal behaviour - rot = (ang+ANGLE_202h)>>29; + else + { + // choose a different rotation based on player view + if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right + rot = 6; // F7 slot + else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left + rot = 2; // F3 slot + else if (sprframe->rotate & SRF_3DGE) // 16-angle mode + { + rot = (ang+ANGLE_180+ANGLE_11hh)>>28; + rot = ((rot & 1)<<3)|(rot>>1); + } + else // Normal behaviour + rot = (ang+ANGLE_202h)>>29; - //Fab: lumpid is the index for spritewidth,spriteoffset... tables - lumpoff = sprframe->lumpid[rot]; - flip = sprframe->flip & (1<lumpid[rot]; + flip = sprframe->flip & (1<lumppat[rot], PU_SPRITE); + + spr_width = spritecachedinfo[lumpoff].width; + spr_height = spritecachedinfo[lumpoff].height; + spr_offset = spritecachedinfo[lumpoff].offset; + spr_topoffset = spritecachedinfo[lumpoff].topoffset; } if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) this_scale *= FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale); - spr_width = spritecachedinfo[lumpoff].width; - spr_height = spritecachedinfo[lumpoff].height; - spr_offset = spritecachedinfo[lumpoff].offset; - spr_topoffset = spritecachedinfo[lumpoff].topoffset; - #ifdef ROTSPRITE spriterotangle = R_SpriteRotationAngle(&interp); @@ -5181,10 +5208,15 @@ static void HWR_ProjectSprite(mobj_t *thing) rollangle = R_GetRollAngle(spriterotangle); } - rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); + if (using_sprite) + rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); + else + rotsprite = Patch_GetRotated(gpatch, rollangle, flip); if (rotsprite != NULL) { + gpatch = rotsprite; + spr_width = rotsprite->width << FRACBITS; spr_height = rotsprite->height << FRACBITS; spr_offset = rotsprite->leftoffset << FRACBITS; @@ -5386,7 +5418,7 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->tracertz = tracertz; vis->renderflags = thing->renderflags; - vis->rotateflags = sprframe->rotate; + vis->rotateflags = sprframe ? sprframe->rotate : SRF_3D; vis->shadowheight = shadowheight; vis->shadowscale = shadowscale; @@ -5399,19 +5431,15 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->spritexoffset = FIXED_TO_FLOAT(spr_offset); vis->spriteyoffset = FIXED_TO_FLOAT(spr_topoffset); - vis->rotated = false; - #ifdef ROTSPRITE - if (rotsprite) - { - vis->gpatch = (patch_t *)rotsprite; - vis->rotated = true; - } - else + vis->rotated = rotsprite != NULL; +#else + vis->rotated = false; #endif - vis->gpatch = (patch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE); + vis->gpatch = gpatch; vis->mobj = thing; + if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer && thing->color == SKINCOLOR_NONE) vis->color = thing->tracer->color; else diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index fddf958be..d9aea4f0e 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -43,6 +43,7 @@ enum mobj_e { mobj_spriteyscale, mobj_spritexoffset, mobj_spriteyoffset, + mobj_image, mobj_floorspriteslope, mobj_drawonlyforplayer, mobj_dontdrawforviewmobj, @@ -123,6 +124,7 @@ static const char *const mobj_opt[] = { "spriteyscale", "spritexoffset", "spriteyoffset", + "image", "floorspriteslope", "drawonlyforplayer", "dontdrawforviewmobj", @@ -263,6 +265,11 @@ static int mobj_get(lua_State *L) case mobj_spriteyoffset: lua_pushfixed(L, mo->spriteyoffset); break; + case mobj_image: + if (!mo->image) + return 0; + LUA_PushUserdata(L, mo->image, META_PATCH); + break; case mobj_floorspriteslope: LUA_PushUserdata(L, mo->floorspriteslope, META_SLOPE); break; @@ -564,6 +571,12 @@ static int mobj_set(lua_State *L) case mobj_spriteyoffset: mo->spriteyoffset = luaL_checkfixed(L, 3); break; + case mobj_image: + if (lua_isnil(L, 3)) + mo->image = NULL; + else + mo->image = *((patch_t **)luaL_checkudata(L, 3, META_PATCH)); + break; case mobj_floorspriteslope: return NOSET; case mobj_drawonlyforplayer: diff --git a/src/p_mobj.c b/src/p_mobj.c index 4b17b7c11..ef155c5d8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10709,6 +10709,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->spritexscale = mobj->spriteyscale = mobj->scale; mobj->spritexoffset = mobj->spriteyoffset = 0; mobj->floorspriteslope = NULL; + mobj->image = NULL; // set subsector and/or block links P_SetThingPosition(mobj); diff --git a/src/p_mobj.h b/src/p_mobj.h index a980691be..3d5bdc248 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -306,6 +306,8 @@ typedef struct mobj_s fixed_t old_spritexoffset, old_spriteyoffset; struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by + void *image; + struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears struct subsector_s *subsector; // Subsector the mobj resides in. @@ -445,6 +447,8 @@ typedef struct precipmobj_s fixed_t old_spritexoffset, old_spriteyoffset; struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by + void *image; + struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears struct subsector_s *subsector; // Subsector the mobj resides in. diff --git a/src/r_draw.c b/src/r_draw.c index df9e1a460..68f57d266 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -107,6 +107,7 @@ INT32 ds_waterofs, ds_bgofs; UINT16 ds_flatwidth, ds_flatheight; boolean ds_powersoftwo, ds_solidcolor; +UINT32 ds_fillcolor; UINT8 *ds_source; // points to the start of a flat UINT8 *ds_transmap; // one of the translucency tables @@ -884,6 +885,9 @@ void R_DrawViewBorder(void) } #endif +#define SPANSIZE 16 +#define INVSPAN 0.0625f + // R_CalcTiltedLighting // Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. static INT32 tiltlighting[MAXVIDWIDTH]; @@ -923,6 +927,7 @@ static void R_CalcTiltedLighting(fixed_t start, fixed_t end) #include "r_draw8.c" #include "r_draw8_npo2.c" +#include "r_draw8_rgba.c" // ========================================================================== // INCLUDE 16bpp DRAWING CODE HERE diff --git a/src/r_draw.h b/src/r_draw.h index 0103ed827..aedaed2ae 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -168,16 +168,20 @@ void R_DrawViewBorder(void); // ----------------- void R_DrawColumn_8(void); -void R_DrawShadeColumn_8(void); void R_DrawTranslucentColumn_8(void); -void R_DrawDropShadowColumn_8(void); void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void); +void R_DrawShadeColumn_8(void); +void R_DrawDropShadowColumn_8(void); void R_Draw2sMultiPatchColumn_8(void); void R_Draw2sMultiPatchTranslucentColumn_8(void); void R_DrawFogColumn_8(void); void R_DrawColumnShadowed_8(void); +void R_DrawColumn_8_RGBA(void); +void R_DrawBlendedColumn_8_RGBA(void); +void R_DrawTranslucentColumn_8_RGBA(void); + #define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan)) void R_DrawSpan_8(void); @@ -194,6 +198,11 @@ void R_DrawTranslucentFloorSprite_8(void); void R_DrawTiltedFloorSprite_8(void); void R_DrawTiltedTranslucentFloorSprite_8(void); +void R_DrawFloorSprite_8_RGBA(void); +void R_DrawTranslucentFloorSprite_8_RGBA(void); +void R_DrawTiltedFloorSprite_8_RGBA(void); +void R_DrawTiltedTranslucentFloorSprite_8_RGBA(void); + void R_DrawWaterSpan_8(void); void R_DrawTiltedWaterSpan_8(void); @@ -215,6 +224,11 @@ void R_DrawTranslucentFloorSprite_NPO2_8(void); void R_DrawTiltedFloorSprite_NPO2_8(void); void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void); +void R_DrawFloorSprite_NPO2_8_RGBA(void); +void R_DrawTranslucentFloorSprite_NPO2_8_RGBA(void); +void R_DrawTiltedFloorSprite_NPO2_8_RGBA(void); +void R_DrawTiltedTranslucentFloorSprite_NPO2_8_RGBA(void); + void R_DrawWaterSpan_NPO2_8(void); void R_DrawTiltedWaterSpan_NPO2_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index b80a47984..3ba9d8725 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -569,9 +569,6 @@ void R_DrawTranslatedColumn_8(void) // SPANS // ========================================================================== -#define SPANSIZE 16 -#define INVSPAN 0.0625f - /** \brief The R_DrawSpan_8 function Draws the actual span. */ @@ -2032,7 +2029,7 @@ void R_DrawSolidColorSpan_8(void) { size_t count = (ds_x2 - ds_x1 + 1); - UINT8 source = ds_colormap[ds_source[0]]; + UINT8 source = ds_colormap[ds_fillcolor & 0xFF]; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; memset(dest, source, count); @@ -2045,7 +2042,7 @@ void R_DrawTransSolidColorSpan_8(void) { size_t count = (ds_x2 - ds_x1 + 1); - UINT8 source = ds_colormap[ds_source[0]]; + UINT8 source = ds_colormap[ds_fillcolor & 0xFF]; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; @@ -2064,7 +2061,7 @@ void R_DrawTiltedSolidColorSpan_8(void) { int width = ds_x2 - ds_x1; - UINT8 source = ds_source[0]; + UINT8 source = ds_fillcolor; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); @@ -2085,7 +2082,7 @@ void R_DrawTiltedTransSolidColorSpan_8(void) { int width = ds_x2 - ds_x1; - UINT8 source = ds_source[0]; + UINT8 source = ds_fillcolor; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); @@ -2105,7 +2102,7 @@ void R_DrawTiltedTransSolidColorSpan_8(void) */ void R_DrawWaterSolidColorSpan_8(void) { - UINT8 source = ds_source[0]; + UINT8 source = ds_fillcolor; UINT8 *colormap = ds_colormap; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; UINT8 *dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; @@ -2127,7 +2124,7 @@ void R_DrawTiltedWaterSolidColorSpan_8(void) { int width = ds_x2 - ds_x1; - UINT8 source = ds_source[0]; + UINT8 source = ds_fillcolor; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; UINT8 *dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index 91f3b06c4..ce6db27f4 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -15,9 +15,6 @@ // SPANS // ========================================================================== -#define SPANSIZE 16 -#define INVSPAN 0.0625f - #if defined(__GNUC__) || defined(__clang__) // Suppress intentional libdivide compiler warnings - Also added to libdivide.h #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Waggregate-return" diff --git a/src/r_draw8_rgba.c b/src/r_draw8_rgba.c new file mode 100644 index 000000000..5a4d67907 --- /dev/null +++ b/src/r_draw8_rgba.c @@ -0,0 +1,325 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2023 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 r_draw8_rgba.c +/// \brief 8bpp span/column drawer functions for RGBA sources + +// ========================================================================== +// COLUMNS +// ========================================================================== + +// A column is a vertical slice/span of a wall texture that uses +// a has a constant z depth from top to bottom. +// + +#include "v_video.h" + +void R_DrawColumn_8_RGBA(void) +{ +INT32 count; + register UINT8 *dest; + register fixed_t frac; + fixed_t fracstep; + + count = dc_yh - dc_yl; + + if (count < 0) // Zero length, column does not exceed a pixel. + return; + +#ifdef RANGECHECK + if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) + return; +#endif + + // Framebuffer destination address. + // Use ylookup LUT to avoid multiply with ScreenWidth. + // Use columnofs LUT for subwindows? + + //dest = ylookup[dc_yl] + columnofs[dc_x]; + dest = &topleft[dc_yl*vid.width + dc_x]; + + count++; + + // Determine scaling, which is the only mapping to be done. + fracstep = dc_iscale; + //frac = dc_texturemid + (dc_yl - centery)*fracstep; + frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + + // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. + // This is as fast as it gets. + { + register const RGBA_t *source = (RGBA_t *)dc_source; + register const lighttable_t *colormap = dc_colormap; + register INT32 heightmask = dc_texheight-1; + RGBA_t color; + if (dc_texheight & heightmask) // not a power of 2 -- killough + { + heightmask++; + heightmask <<= FRACBITS; + + if (frac < 0) + while ((frac += heightmask) < 0); + else + while (frac >= heightmask) + frac -= heightmask; + + do + { + // Re-map color indices from wall texture column + // using a lighting/special effects LUT. + // heightmask is the Tutti-Frutti fix + color = source[frac>>FRACBITS]; + *dest = colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]; + dest += vid.width; + + // Avoid overflow. + if (fracstep > 0x7FFFFFFF - frac) + frac += fracstep - heightmask; + else + frac += fracstep; + + while (frac >= heightmask) + frac -= heightmask; + } while (--count); + } + else + { + while ((count -= 2) >= 0) // texture height is a power of 2 + { + color = source[(frac>>FRACBITS) & heightmask]; + *dest = colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]; + dest += vid.width; + frac += fracstep; + color = source[(frac>>FRACBITS) & heightmask]; + *dest = colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]; + dest += vid.width; + frac += fracstep; + } + if (count & 1) + { + color = source[(frac>>FRACBITS) & heightmask]; + *dest = colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]; + } + } + } +} + +void R_DrawBlendedColumn_8_RGBA(void) +{ +INT32 count; + register UINT8 *dest; + register fixed_t frac; + fixed_t fracstep; + + count = dc_yh - dc_yl; + + if (count < 0) // Zero length, column does not exceed a pixel. + return; + +#ifdef RANGECHECK + if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) + return; +#endif + + // Framebuffer destination address. + // Use ylookup LUT to avoid multiply with ScreenWidth. + // Use columnofs LUT for subwindows? + + //dest = ylookup[dc_yl] + columnofs[dc_x]; + dest = &topleft[dc_yl*vid.width + dc_x]; + + count++; + + // Determine scaling, which is the only mapping to be done. + fracstep = dc_iscale; + //frac = dc_texturemid + (dc_yl - centery)*fracstep; + frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + + // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. + // This is as fast as it gets. + { + register const RGBA_t *source = (RGBA_t *)dc_source; + register const lighttable_t *colormap = dc_colormap; + register INT32 heightmask = dc_texheight-1; + RGBA_t color; + if (dc_texheight & heightmask) // not a power of 2 -- killough + { + heightmask++; + heightmask <<= FRACBITS; + + if (frac < 0) + while ((frac += heightmask) < 0); + else + while (frac >= heightmask) + frac -= heightmask; + + do + { + // Re-map color indices from wall texture column + // using a lighting/special effects LUT. + // heightmask is the Tutti-Frutti fix + color.rgba = ASTBlendPixel(pMasterPalette[*dest], source[frac>>FRACBITS], AST_TRANSLUCENT, 255); + *dest = colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]; + dest += vid.width; + + // Avoid overflow. + if (fracstep > 0x7FFFFFFF - frac) + frac += fracstep - heightmask; + else + frac += fracstep; + + while (frac >= heightmask) + frac -= heightmask; + } while (--count); + } + else + { + while ((count -= 2) >= 0) // texture height is a power of 2 + { + color.rgba = ASTBlendPixel(pMasterPalette[*dest], source[frac>>FRACBITS], AST_TRANSLUCENT, 255); + *dest = colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]; + dest += vid.width; + frac += fracstep; + color.rgba = ASTBlendPixel(pMasterPalette[*dest], source[frac>>FRACBITS], AST_TRANSLUCENT, 255); + *dest = colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]; + dest += vid.width; + frac += fracstep; + } + if (count & 1) + { + color.rgba = ASTBlendPixel(pMasterPalette[*dest], source[frac>>FRACBITS], AST_TRANSLUCENT, 255); + *dest = colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]; + } + } + } +} + +void R_DrawTranslucentColumn_8_RGBA(void) +{ +register INT32 count; + register UINT8 *dest; + register fixed_t frac, fracstep; + + count = dc_yh - dc_yl + 1; + + if (count <= 0) // Zero length, column does not exceed a pixel. + return; + +#ifdef RANGECHECK + if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) + I_Error("R_DrawTranslucentColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x); +#endif + + // FIXME. As above. + //dest = ylookup[dc_yl] + columnofs[dc_x]; + dest = &topleft[dc_yl*vid.width + dc_x]; + + // Looks familiar. + fracstep = dc_iscale; + //frac = dc_texturemid + (dc_yl - centery)*fracstep; + frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + + // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. + // This is as fast as it gets. + { + register const RGBA_t *source = (RGBA_t *)dc_source; + register const UINT8 *transmap = dc_transmap; + register const lighttable_t *colormap = dc_colormap; + register INT32 heightmask = dc_texheight - 1; + RGBA_t color; + if (dc_texheight & heightmask) + { + heightmask++; + heightmask <<= FRACBITS; + + if (frac < 0) + while ((frac += heightmask) < 0) + ; + else + while (frac >= heightmask) + frac -= heightmask; + + do + { + // Re-map color indices from wall texture column + // using a lighting/special effects LUT. + // heightmask is the Tutti-Frutti fix + color = source[frac>>FRACBITS]; + *dest = *(transmap + (colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]<<8) + (*dest)); + dest += vid.width; + if ((frac += fracstep) >= heightmask) + frac -= heightmask; + } + while (--count); + } + else + { + while ((count -= 2) >= 0) // texture height is a power of 2 + { + color = source[(frac>>FRACBITS) & heightmask]; + *dest = *(transmap + (colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]<<8) + (*dest)); + dest += vid.width; + frac += fracstep; + color = source[(frac>>FRACBITS) & heightmask]; + *dest = *(transmap + (colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]<<8) + (*dest)); + dest += vid.width; + frac += fracstep; + } + if (count & 1) + { + color = source[(frac>>FRACBITS) & heightmask]; + *dest = *(transmap + (colormap[GetColorLUT(&r_colorlookup, color.s.red, color.s.green, color.s.blue)]<<8) + (*dest)); + } + } + } +} + +// ========================================================================== +// SPANS +// ========================================================================== + +void R_DrawFloorSprite_8_RGBA(void) +{ + // TODO +} + +void R_DrawTranslucentFloorSprite_8_RGBA(void) +{ + // TODO +} + +void R_DrawTiltedFloorSprite_8_RGBA(void) +{ + // TODO +} + +void R_DrawTiltedTranslucentFloorSprite_8_RGBA(void) +{ + // TODO +} + +void R_DrawFloorSprite_NPO2_8_RGBA(void) +{ + // TODO +} + +void R_DrawTranslucentFloorSprite_NPO2_8_RGBA(void) +{ + // TODO +} + +void R_DrawTiltedFloorSprite_NPO2_8_RGBA(void) +{ + // TODO +} + +void R_DrawTiltedTranslucentFloorSprite_NPO2_8_RGBA(void) +{ + // TODO +} diff --git a/src/r_patch.c b/src/r_patch.c index 9ed7c5c51..fb7f5d579 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -890,11 +890,11 @@ void Patch_FreeTags(INT32 lowtag, INT32 hightag) void Patch_GenerateFlat(patch_t *patch, pictureflags_t flags) { - UINT8 flip = (flags & (PICFLAGS_XFLIP | PICFLAGS_YFLIP)); + UINT8 flip = flags & (PICFLAGS_XFLIP | PICFLAGS_YFLIP); if (patch->flats[flip] == NULL) { if (patch->format == PATCH_FORMAT_RGBA) - patch->flats[flip] = Picture_Convert(PICFMT_PATCH32, patch->pixels, PICFMT_FLAT32, 0, NULL, 0, 0, 0, 0, flags); + patch->flats[flip] = Picture_Convert(PICFMT_PATCH32, patch, PICFMT_FLAT32, 0, NULL, 0, 0, 0, 0, flags); else patch->flats[flip] = Picture_Convert(PICFMT_PATCH, patch, PICFMT_FLAT16, 0, NULL, 0, 0, 0, 0, flags); } diff --git a/src/r_plane.c b/src/r_plane.c index 9c17fb952..7facf8d29 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -978,7 +978,10 @@ void R_DrawSinglePlane(visplane_t *pl) ds_flatheight = texture->height; if (R_CheckSolidColorFlat()) + { ds_solidcolor = true; + ds_fillcolor = ds_source[0]; + } else if (R_CheckPowersOfTwo()) { R_SetFlatVars(ds_flatwidth * ds_flatheight); diff --git a/src/r_segs.c b/src/r_segs.c index e838902f7..11667433c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -124,7 +124,7 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) if (colfunc == colfuncs[BASEDRAWFUNC]) (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + else if (colfunc == colfuncs[COLDRAWFUNC_TRANSLU]) (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(); else colfunc(); @@ -178,12 +178,12 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_transmap = R_GetBlendTable(ldef->blendmode, 0); else dc_transmap = R_GetBlendTable(ldef->blendmode, R_GetLinedefTransTable(ldef->alpha)); - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + colfunc = colfuncs[COLDRAWFUNC_TRANSLU]; } else if (ldef->alpha > 0 && ldef->alpha < FRACUNIT) { dc_transmap = R_GetTranslucencyTable(R_GetLinedefTransTable(ldef->alpha)); - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + colfunc = colfuncs[COLDRAWFUNC_TRANSLU]; } else colfunc = colfuncs[BASEDRAWFUNC]; @@ -194,7 +194,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) return; dc_transmap = R_GetTranslucencyTable(curline->polyseg->translucency); - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + colfunc = colfuncs[COLDRAWFUNC_TRANSLU]; } range = max(ds->x2-ds->x1, 1); @@ -254,7 +254,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) rlight->extra_colormap = *light->extra_colormap; rlight->flags = light->flags; - if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY]) + if ((colfunc != colfuncs[COLDRAWFUNC_TRANSLU]) || (rlight->flags & FOF_FOG) || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG))) lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); @@ -273,7 +273,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } else { - if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY]) + if ((colfunc != colfuncs[COLDRAWFUNC_TRANSLU]) || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); else @@ -575,7 +575,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) } if (fuzzy) - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + colfunc = colfuncs[COLDRAWFUNC_TRANSLU]; } else if (pfloor->fofflags & FOF_FOG) colfunc = colfuncs[COLDRAWFUNC_FOG]; @@ -688,7 +688,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); else if (pfloor->fofflags & FOF_FOG) lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + else if (colfunc == colfuncs[COLDRAWFUNC_TRANSLU]) lightnum = LIGHTLEVELS-1; else lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) diff --git a/src/r_splats.c b/src/r_splats.c index 0b482d798..e0cafaf2b 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -15,6 +15,7 @@ #include "r_main.h" #include "r_splats.h" #include "r_bsp.h" +#include "v_video.h" #include "p_local.h" #include "p_slopes.h" #include "w_wad.h" @@ -423,18 +424,32 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr ds_transmap = vis->transmap; // Determine which R_DrawWhatever to use + boolean source_rgba = patch->format == PATCH_FORMAT_RGBA; // Solid color if (ds_solidcolor) { - UINT16 px = *(UINT16 *)ds_source; + if (source_rgba) + { + RGBA_t px = *(RGBA_t *)ds_source; - // Uh, it's not visible. - if (!(px & 0xFF00)) - return; + // Uh, it's not visible. + if (px.s.alpha == 0) + return; - // Pixel color is contained in the lower 8 bits (upper 8 are the opacity), so advance the pointer - ds_source++; + ds_fillcolor = GetColorLUT(&r_colorlookup, px.s.red, px.s.green, px.s.blue); + } + else + { + UINT16 px = *(UINT16 *)ds_source; + + // Uh, it's not visible. + if (!(px & 0xFF00)) + return; + + // Pixel color is contained in the lower 8 bits (upper 8 are the opacity), so advance the pointer + ds_fillcolor = ds_source[1]; + } if (pSplat->slope) { @@ -468,7 +483,14 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr spanfunctype = SPANDRAWFUNC_SPRITE; } - if (ds_powersoftwo || ds_solidcolor) + if (source_rgba && !ds_solidcolor) + { + if (ds_powersoftwo) + spanfunc = spanfuncs_rgba[spanfunctype]; + else + spanfunc = spanfuncs_npo2_rgba[spanfunctype]; + } + else if (ds_powersoftwo || ds_solidcolor) spanfunc = spanfuncs[spanfunctype]; else spanfunc = spanfuncs_npo2[spanfunctype]; diff --git a/src/r_things.c b/src/r_things.c index 8d6b1d8d4..dfcea4da6 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -31,6 +31,7 @@ #include "r_plane.h" #include "r_portal.h" #include "r_splats.h" +#include "v_video.h" #include "p_tick.h" #include "p_local.h" #include "p_slopes.h" @@ -812,6 +813,7 @@ static void R_DrawVisSprite(vissprite_t *vis) fixed_t this_scale = vis->thingscale; INT32 x1, x2; INT64 overflow_test; + boolean source_paletted; if (!patch) return; @@ -837,26 +839,49 @@ static void R_DrawVisSprite(vissprite_t *vis) return; } + source_paletted = patch->format == PATCH_FORMAT_PALETTE; + + if (!source_paletted) + { + InitColorLUT(&r_colorlookup, pMasterPalette, false); + } + else + { + dc_translation = R_GetSpriteTranslation(vis); + } + colfunc = colfuncs[BASEDRAWFUNC]; // hack: this isn't resetting properly somewhere. dc_colormap = vis->colormap; - dc_translation = R_GetSpriteTranslation(vis); - if (R_SpriteIsFlashing(vis)) // Bosses "flash" - colfunc = colfuncs[COLDRAWFUNC_TRANS]; // translate certain pixels to white - else if (vis->color && vis->transmap) // Color mapping + if (source_paletted) { - colfunc = colfuncs[COLDRAWFUNC_TRANSTRANS]; - dc_transmap = vis->transmap; + if (R_SpriteIsFlashing(vis)) // Bosses "flash" + colfunc = colfuncs[COLDRAWFUNC_MAPPED]; // translate certain pixels to white + else if (vis->color && vis->transmap) // Color mapping + { + colfunc = colfuncs[COLDRAWFUNC_TRANSLU_MAPPED]; + dc_transmap = vis->transmap; + } + else if (vis->transmap) + { + colfunc = colfuncs[COLDRAWFUNC_TRANSLU]; + dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table + } + else if (vis->color) // translate green skin to another color + colfunc = colfuncs[COLDRAWFUNC_MAPPED]; + else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome. + colfunc = colfuncs[COLDRAWFUNC_MAPPED]; } - else if (vis->transmap) + else { - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; - dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table + if (vis->transmap) + { + colfunc = colfuncs_rgba[COLDRAWFUNC_TRANSLU]; + dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table + } + else + colfunc = colfuncs_rgba[BASEDRAWFUNC]; } - else if (vis->color) // translate green skin to another color - colfunc = colfuncs[COLDRAWFUNC_TRANS]; - else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome. - colfunc = colfuncs[COLDRAWFUNC_TRANS]; // Hack: Use a special column function for drop shadows that bypasses // invalid memory access crashes caused by R_ProjectDropShadow putting wrong values @@ -999,7 +1024,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) if (vis->transmap) { - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + colfunc = colfuncs[COLDRAWFUNC_TRANSLU]; dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table } @@ -1526,15 +1551,13 @@ static void R_ProjectSprite(mobj_t *thing) INT32 x1, x2; - spritedef_t *sprdef; - spriteframe_t *sprframe; + spriteframe_t *sprframe = NULL; #ifdef ROTSPRITE - spriteinfo_t *sprinfo; + spriteinfo_t *sprinfo = NULL; #endif - size_t lump; - size_t frame, rot; - UINT16 flip; + size_t rot = 0; + UINT16 flip = 0; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(thing)); boolean mirrored = thing->mirrored; boolean hflip = (!R_ThingHorizontallyFlipped(thing) != !mirrored); @@ -1618,119 +1641,148 @@ static void R_ProjectSprite(mobj_t *thing) xscale = FixedDiv(projection, tz); sortscale = FixedDiv(projectiony, tz); - // decide which patch to use for sprite relative to player -#ifdef RANGECHECK - if ((size_t)(thing->sprite) >= numsprites) - I_Error("R_ProjectSprite: invalid sprite number %d ", thing->sprite); -#endif + boolean using_sprite = thing->image == NULL; + boolean use_single_rotation = false; - frame = thing->frame&FF_FRAMEMASK; - - //Fab : 02-08-98: 'skin' override spritedef currently used for skin - if (thing->skin && thing->sprite == SPR_PLAY) + if (!using_sprite) { - sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; -#ifdef ROTSPRITE - sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2]; -#endif - if (frame >= sprdef->numframes) { - CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(frame)); - thing->sprite = states[S_UNKNOWN].sprite; - thing->frame = states[S_UNKNOWN].frame; - sprdef = &sprites[thing->sprite]; -#ifdef ROTSPRITE - sprinfo = &spriteinfo[thing->sprite]; -#endif - frame = thing->frame&FF_FRAMEMASK; - } + patch = (patch_t*)thing->image; + + if (Patch_NeedsUpdate(patch, true)) + Patch_DoDynamicUpdate(patch, true); + + if (patch->columns == NULL) + return; + + spr_width = patch->width << FRACBITS; + spr_height = patch->height << FRACBITS; + spr_offset = patch->leftoffset << FRACBITS; + spr_topoffset = patch->topoffset << FRACBITS; + + use_single_rotation = true; } else { - sprdef = &sprites[thing->sprite]; -#ifdef ROTSPRITE - sprinfo = &spriteinfo[thing->sprite]; + size_t frame = thing->frame & FF_FRAMEMASK; + + spritedef_t *sprdef; + + // decide which patch to use for sprite relative to player +#ifdef RANGECHECK + if ((size_t)(thing->sprite) >= numsprites) + I_Error("R_ProjectSprite: invalid sprite number %d ", thing->sprite); #endif - if (frame >= sprdef->numframes) + //Fab : 02-08-98: 'skin' override spritedef currently used for skin + if (thing->skin && thing->sprite == SPR_PLAY) { - CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"), - sizeu1(frame), sizeu2(sprdef->numframes), sprnames[thing->sprite]); - if (thing->sprite == thing->state->sprite && thing->frame == thing->state->frame) - { - thing->state->sprite = states[S_UNKNOWN].sprite; - thing->state->frame = states[S_UNKNOWN].frame; + sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; +#ifdef ROTSPRITE + sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2]; +#endif + if (frame >= sprdef->numframes) { + CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(frame)); + thing->sprite = states[S_UNKNOWN].sprite; + thing->frame = states[S_UNKNOWN].frame; + sprdef = &sprites[thing->sprite]; +#ifdef ROTSPRITE + sprinfo = &spriteinfo[thing->sprite]; +#endif + frame = thing->frame&FF_FRAMEMASK; } - thing->sprite = states[S_UNKNOWN].sprite; - thing->frame = states[S_UNKNOWN].frame; - sprdef = &sprites[thing->sprite]; - sprinfo = &spriteinfo[thing->sprite]; - frame = thing->frame&FF_FRAMEMASK; } - } + else + { + sprdef = &sprites[thing->sprite]; +#ifdef ROTSPRITE + sprinfo = &spriteinfo[thing->sprite]; +#endif - sprframe = &sprdef->spriteframes[frame]; + if (frame >= sprdef->numframes) + { + CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"), + sizeu1(frame), sizeu2(sprdef->numframes), sprnames[thing->sprite]); + if (thing->sprite == thing->state->sprite && thing->frame == thing->state->frame) + { + thing->state->sprite = states[S_UNKNOWN].sprite; + thing->state->frame = states[S_UNKNOWN].frame; + } + thing->sprite = states[S_UNKNOWN].sprite; + thing->frame = states[S_UNKNOWN].frame; + sprdef = &sprites[thing->sprite]; + sprinfo = &spriteinfo[thing->sprite]; + frame = thing->frame&FF_FRAMEMASK; + } + } + + sprframe = &sprdef->spriteframes[frame]; #ifdef PARANOIA - if (!sprframe) - I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); + if (!sprframe) + I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); #endif + use_single_rotation = sprframe->rotate == SRF_SINGLE; + } + if (splat) { ang = R_PointToAngle2(0, viewz, 0, interp.z); } - else if (sprframe->rotate != SRF_SINGLE || papersprite) + else if (!use_single_rotation || papersprite) { ang = R_PointToAngle (interp.x, interp.y) - interp.angle; if (mirrored) ang = InvAngle(ang); } - if (sprframe->rotate == SRF_SINGLE) + if (sprframe) { - // use single rotation for all views - rot = 0; //Fab: for vis->patch below - lump = sprframe->lumpid[0]; //Fab: see note above - flip = sprframe->flip; // Will only be 0 or 0xFFFF - } - else - { - // choose a different rotation based on player view - //ang = R_PointToAngle (interp.x, interp.y) - interpangle; + size_t lump; - if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right - rot = 6; // F7 slot - else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left - rot = 2; // F3 slot - else if (sprframe->rotate & SRF_3DGE) // 16-angle mode + if (use_single_rotation) { - rot = (ang+ANGLE_180+ANGLE_11hh)>>28; - rot = ((rot & 1)<<3)|(rot>>1); + // use single rotation for all views + rot = 0; //Fab: for vis->patch below + lump = sprframe->lumpid[0]; //Fab: see note above + flip = sprframe->flip; // Will only be 0 or 0xFFFF } - else // Normal behaviour - rot = (ang+ANGLE_202h)>>29; + else + { + // choose a different rotation based on player view + if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right + rot = 6; // F7 slot + else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left + rot = 2; // F3 slot + else if (sprframe->rotate & SRF_3DGE) // 16-angle mode + { + rot = (ang+ANGLE_180+ANGLE_11hh)>>28; + rot = ((rot & 1)<<3)|(rot>>1); + } + else // Normal behaviour + rot = (ang+ANGLE_202h)>>29; - //Fab: lumpid is the index for spritewidth,spriteoffset... tables - lump = sprframe->lumpid[rot]; - flip = sprframe->flip & (1<lumpid[rot]; + flip = sprframe->flip & (1<lumppat[rot], PU_SPRITE); + + spr_width = spritecachedinfo[lump].width; + spr_height = spritecachedinfo[lump].height; + spr_offset = spritecachedinfo[lump].offset; + spr_topoffset = spritecachedinfo[lump].topoffset; } - I_Assert(lump < max_spritelumps); - - spr_width = spritecachedinfo[lump].width; - spr_height = spritecachedinfo[lump].height; - spr_offset = spritecachedinfo[lump].offset; - spr_topoffset = spritecachedinfo[lump].topoffset; - - //Fab: lumppat is the lump number of the patch to use, this is different - // than lumpid for sprites-in-pwad : the graphics are patched - patch = W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE); - #ifdef ROTSPRITE spriterotangle = R_SpriteRotationAngle(&interp); - if (spriterotangle != 0 - && !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE))) + if (spriterotangle != 0 && !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE))) { if (papersprite && ang >= ANGLE_180) { @@ -1742,7 +1794,10 @@ static void R_ProjectSprite(mobj_t *thing) rollangle = R_GetRollAngle(spriterotangle); } - rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); + if (using_sprite) + rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); + else + rotsprite = Patch_GetRotated(patch, rollangle, flip); if (rotsprite != NULL) { @@ -2148,7 +2203,7 @@ static void R_ProjectSprite(mobj_t *thing) // store information in a vissprite vis = R_NewVisSprite(); vis->renderflags = thing->renderflags; - vis->rotateflags = sprframe->rotate; + vis->rotateflags = sprframe ? sprframe->rotate : SRF_3D; vis->heightsec = heightsec; //SoM: 3/17/2000 vis->mobjflags = thing->flags; vis->sortscale = sortscale; diff --git a/src/screen.c b/src/screen.c index 0719da83c..37c9dcb71 100644 --- a/src/screen.c +++ b/src/screen.c @@ -49,6 +49,7 @@ // -------------------------------------------- void (*colfunc)(void); void (*colfuncs[COLDRAWFUNC_MAX])(void); +void (*colfuncs_rgba[COLDRAWFUNC_MAX])(void); void (*spanfunc)(void); void (*spanfuncs[SPANDRAWFUNC_MAX])(void); @@ -119,15 +120,20 @@ void SCR_SetDrawFuncs(void) colfunc = colfuncs[BASEDRAWFUNC]; spanfunc = spanfuncs[BASEDRAWFUNC]; - colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8; - colfuncs[COLDRAWFUNC_TRANS] = R_DrawTranslatedColumn_8; + colfuncs[COLDRAWFUNC_TRANSLU] = R_DrawTranslucentColumn_8; + colfuncs[COLDRAWFUNC_MAPPED] = R_DrawTranslatedColumn_8; colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8; colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_8; - colfuncs[COLDRAWFUNC_TRANSTRANS] = R_DrawTranslatedTranslucentColumn_8; + colfuncs[COLDRAWFUNC_TRANSLU_MAPPED] = R_DrawTranslatedTranslucentColumn_8; colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8; colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8; colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8; + colfuncs_rgba[BASEDRAWFUNC] = R_DrawBlendedColumn_8_RGBA; + colfuncs_rgba[COLDRAWFUNC_TRANSLU] = R_DrawTranslucentColumn_8_RGBA; + colfuncs_rgba[COLDRAWFUNC_MAPPED] = R_DrawBlendedColumn_8_RGBA; + colfuncs_rgba[COLDRAWFUNC_TRANSLU_MAPPED] = R_DrawTranslucentColumn_8_RGBA; + spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8; spanfuncs[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_8; spanfuncs[SPANDRAWFUNC_TILTEDTRANS] = R_DrawTiltedTranslucentSpan_8; @@ -149,6 +155,11 @@ void SCR_SetDrawFuncs(void) spanfuncs[SPANDRAWFUNC_FOG] = R_DrawFogSpan_8; spanfuncs[SPANDRAWFUNC_TILTEDFOG] = R_DrawTiltedFogSpan_8; + spanfuncs_rgba[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_8_RGBA; + spanfuncs_rgba[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_8_RGBA; + spanfuncs_rgba[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_8_RGBA; + spanfuncs_rgba[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_8_RGBA; + // Lactozilla: Non-powers-of-two spanfuncs_npo2[BASEDRAWFUNC] = R_DrawSpan_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_NPO2_8; @@ -164,25 +175,13 @@ void SCR_SetDrawFuncs(void) spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawWaterSpan_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedWaterSpan_NPO2_8; + spanfuncs_npo2_rgba[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_NPO2_8_RGBA; + spanfuncs_npo2_rgba[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_NPO2_8_RGBA; + spanfuncs_npo2_rgba[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_NPO2_8_RGBA; + spanfuncs_npo2_rgba[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_NPO2_8_RGBA; } -/* else if (vid.bpp > 1) - { - I_OutputMsg("using highcolor mode\n"); - spanfunc = basespanfunc = R_DrawSpan_16; - transcolfunc = R_DrawTranslatedColumn_16; - transtransfunc = R_DrawTranslucentColumn_16; // No 16bit operation for this function - - colfunc = basecolfunc = R_DrawColumn_16; - shadecolfunc = NULL; // detect error if used somewhere.. - fuzzcolfunc = R_DrawTranslucentColumn_16; - walldrawerfunc = R_DrawWallColumn_16; - }*/ else I_Error("unknown bytes per pixel mode %d\n", vid.bpp); -/* - if (SCR_IsAspectCorrect(vid.width, vid.height)) - CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT); -*/ } void SCR_SetMode(void) diff --git a/src/screen.h b/src/screen.h index 46c1b99c6..eb243c96b 100644 --- a/src/screen.h +++ b/src/screen.h @@ -121,11 +121,11 @@ extern vmode_t specialmodes[NUMSPECIALMODES]; enum { COLDRAWFUNC_BASE = BASEDRAWFUNC, - COLDRAWFUNC_FUZZY, - COLDRAWFUNC_TRANS, + COLDRAWFUNC_TRANSLU, + COLDRAWFUNC_MAPPED, COLDRAWFUNC_SHADE, COLDRAWFUNC_SHADOWED, - COLDRAWFUNC_TRANSTRANS, + COLDRAWFUNC_TRANSLU_MAPPED, COLDRAWFUNC_TWOSMULTIPATCH, COLDRAWFUNC_TWOSMULTIPATCHTRANS, COLDRAWFUNC_FOG, @@ -135,6 +135,7 @@ enum extern void (*colfunc)(void); extern void (*colfuncs[COLDRAWFUNC_MAX])(void); +extern void (*colfuncs_rgba[COLDRAWFUNC_MAX])(void); enum { @@ -171,6 +172,8 @@ enum extern void (*spanfunc)(void); extern void (*spanfuncs[SPANDRAWFUNC_MAX])(void); extern void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void); +extern void (*spanfuncs_rgba[SPANDRAWFUNC_MAX])(void); +extern void (*spanfuncs_npo2_rgba[SPANDRAWFUNC_MAX])(void); // ----- // CPUID