diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ba574f414..9c2326399 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -129,6 +129,7 @@ set(SRB2_CORE_RENDER_SOURCES r_things.c r_textures.c r_patch.c + r_patchrotation.c r_picformats.c r_portal.c diff --git a/src/Makefile b/src/Makefile index f50840920..bdbb35363 100644 --- a/src/Makefile +++ b/src/Makefile @@ -519,6 +519,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/r_things.o \ $(OBJDIR)/r_textures.o \ $(OBJDIR)/r_patch.o \ + $(OBJDIR)/r_patchrotation.o \ $(OBJDIR)/r_picformats.o \ $(OBJDIR)/r_portal.o \ $(OBJDIR)/screen.o \ diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e60645eb6..fe0aa2f35 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4754,7 +4754,9 @@ static void HWR_ProjectSprite(mobj_t *thing) float gz, gzt; spritedef_t *sprdef; spriteframe_t *sprframe; +#ifdef ROTSPRITE spriteinfo_t *sprinfo; +#endif md2_t *md2; size_t lumpoff; unsigned rot; @@ -4824,12 +4826,16 @@ static void HWR_ProjectSprite(mobj_t *thing) 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]; - sprinfo = NULL; +#ifdef ROTSPRITE + sprinfo = &spriteinfo[thing->sprite]; +#endif } if (rot >= sprdef->numframes) @@ -4839,7 +4845,9 @@ static void HWR_ProjectSprite(mobj_t *thing) thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; - sprinfo = NULL; +#ifdef ROTSPRITE + sprinfo = &spriteinfo[thing->sprite]; +#endif rot = thing->frame&FF_FRAMEMASK; thing->state->sprite = thing->sprite; thing->state->frame = thing->frame; @@ -4901,9 +4909,7 @@ static void HWR_ProjectSprite(mobj_t *thing) if (thing->rollangle) { rollangle = R_GetRollAngle(thing->rollangle); - if (sprframe->rotsprite.patch[rot][rollangle] == NULL) - R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, rollangle, flip); - rotsprite = sprframe->rotsprite.patch[rot][rollangle]; + rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, sprinfo, rollangle); if (rotsprite != NULL) { spr_width = SHORT(rotsprite->width) << FRACBITS; diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index ba3342b44..335e6cfbc 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -458,9 +458,8 @@ static int libd_getSpritePatch(lua_State *L) INT32 rot = R_GetRollAngle(rollangle); if (rot) { - if (sprframe->rotsprite.patch[angle][rot] == NULL) - R_CacheRotSprite(i, frame, NULL, sprframe, angle, rot, sprframe->flip & (1<rotsprite.patch[angle][rot], META_PATCH); + patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<rotsprite.patch[angle][rot] == NULL) - R_CacheRotSprite(SPR_PLAY, frame, &skins[i].sprinfo[j], sprframe, angle, rot, sprframe->flip & (1<rotsprite.patch[angle][rot], META_PATCH); + patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<height = source->height; patch->leftoffset = source->leftoffset; patch->topoffset = source->topoffset; - patch->columnofs = Z_Calloc(size, PU_PATCH, NULL); + patch->columnofs = Z_Calloc(size, PU_PATCH_DATA, NULL); for (col = 0; col < source->width; col++) { @@ -53,7 +53,7 @@ patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest) if (colsize <= 0) I_Error("R_CreatePatch: no column data!"); - patch->columns = Z_Calloc(colsize, PU_PATCH, NULL); + patch->columns = Z_Calloc(colsize, PU_PATCH_DATA, NULL); M_Memcpy(patch->columns, ((UINT8 *)source + LONG(source->columnofs[0])), colsize); } @@ -71,6 +71,23 @@ static void Patch_FreeData(patch_t *patch) HWR_FreeTexture(patch); #endif +#ifdef ROTSPRITE + if (patch->rotated) + { + rotsprite_t *rotsprite = patch->rotated; + INT32 i = 0; + + for (; i < rotsprite->angles; i++) + { + if (rotsprite->patches[i]) + Patch_Free(rotsprite->patches[i]); + } + + Z_Free(rotsprite->patches); + Z_Free(rotsprite); + } +#endif + if (patch->columnofs) Z_Free(patch->columnofs); if (patch->columns) diff --git a/src/r_patch.h b/src/r_patch.h index c460e7d09..71f185c9d 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -27,4 +27,12 @@ void *Patch_AllocateHardwarePatch(patch_t *patch); void *Patch_CreateGL(patch_t *patch); #endif +#ifdef ROTSPRITE +void Patch_Rotate(patch_t *patch, INT32 angle, INT32 xpivot, INT32 ypivot, boolean flip); +patch_t *Patch_GetRotated(patch_t *patch, INT32 angle, boolean flip); +patch_t *Patch_GetRotatedSprite(spriteframe_t *sprite, size_t frame, size_t spriteangle, boolean flip, void *info, INT32 rotationangle);INT32 R_GetRollAngle(angle_t rollangle); +extern fixed_t rollcosang[ROTANGLES]; +extern fixed_t rollsinang[ROTANGLES]; +#endif + #endif // __R_PATCH__ diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c new file mode 100644 index 000000000..77544c3ac --- /dev/null +++ b/src/r_patchrotation.c @@ -0,0 +1,248 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2018-2020 by Jaime "Lactozilla" Passos. +// +// 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_patchrotation.c +/// \brief Patch rotation. + +#include "r_patch.h" +#include "r_picformats.h" +#include "r_things.h" // FEETADJUST +#include "z_zone.h" +#include "w_wad.h" + +#ifdef ROTSPRITE + +static rotsprite_t *RotatedPatch_Create(INT32 numangles); +static void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle, INT32 xpivot, INT32 ypivot, boolean flip); + +fixed_t rollcosang[ROTANGLES]; +fixed_t rollsinang[ROTANGLES]; + +INT32 R_GetRollAngle(angle_t rollangle) +{ + INT32 ra = AngleFixed(rollangle)>>FRACBITS; +#if (ROTANGDIFF > 1) + ra += (ROTANGDIFF/2); +#endif + ra /= ROTANGDIFF; + ra %= ROTANGLES; + return ra; +} + +patch_t *Patch_GetRotated(patch_t *patch, INT32 angle, boolean flip) +{ + rotsprite_t *rotsprite = patch->rotated; + if (rotsprite == NULL || angle < 1 || angle >= ROTANGLES) + return NULL; + + if (flip) + angle += rotsprite->angles; + + return rotsprite->patches[angle]; +} + +patch_t *Patch_GetRotatedSprite(spriteframe_t *sprite, size_t frame, size_t spriteangle, boolean flip, void *info, INT32 rotationangle) +{ + rotsprite_t *rotsprite = sprite->rotated[spriteangle]; + spriteinfo_t *sprinfo = (spriteinfo_t *)info; + INT32 idx = rotationangle; + + if (rotationangle < 1 || rotationangle >= ROTANGLES) + return NULL; + + if (rotsprite == NULL) + { + rotsprite = RotatedPatch_Create(ROTANGLES); + sprite->rotated[spriteangle] = rotsprite; + } + + if (flip) + idx += rotsprite->angles; + + if (rotsprite->patches[idx] == NULL) + { + patch_t *patch; + INT32 xpivot = 0, ypivot = 0; + lumpnum_t lump = sprite->lumppat[spriteangle]; + + if (lump == LUMPERROR) + return NULL; + + patch = W_CachePatchNum(lump, PU_SPRITE); + + if (sprinfo->available) + { + xpivot = sprinfo->pivot[frame].x; + ypivot = sprinfo->pivot[frame].y; + } + else + { + xpivot = patch->leftoffset; + ypivot = patch->height / 2; + } + + RotatedPatch_DoRotation(rotsprite, patch, rotationangle, xpivot, ypivot, flip); + } + + return rotsprite->patches[idx]; +} + +void Patch_Rotate(patch_t *patch, INT32 angle, INT32 xpivot, INT32 ypivot, boolean flip) +{ + if (patch->rotated == NULL) + patch->rotated = RotatedPatch_Create(ROTANGLES); + RotatedPatch_DoRotation(patch->rotated, patch, angle, xpivot, ypivot, flip); +} + +rotsprite_t *RotatedPatch_Create(INT32 numangles) +{ + rotsprite_t *rotsprite = Z_Calloc(sizeof(rotsprite_t), PU_STATIC, NULL); + rotsprite->angles = numangles; + rotsprite->patches = Z_Calloc(rotsprite->angles * 2 * sizeof(void *), PU_STATIC, NULL); + return rotsprite; +} + +void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle, INT32 xpivot, INT32 ypivot, boolean flip) +{ + patch_t *rotated; + UINT16 *rawdst; + size_t size; + pictureflags_t bflip = (flip) ? PICFLAGS_XFLIP : 0; + + INT32 width = patch->width; + INT32 height = patch->height; + INT32 leftoffset = patch->leftoffset; + INT32 newwidth, newheight; + + INT32 dx, dy; + fixed_t ca = rollcosang[angle]; + fixed_t sa = rollsinang[angle]; + INT32 idx = angle; + + // Don't cache angle = 0 + if (angle < 1 || angle >= ROTANGLES) + return; + +#define ROTSPRITE_XCENTER (newwidth / 2) +#define ROTSPRITE_YCENTER (newheight / 2) + + if (flip) + idx += rotsprite->angles; + + if (rotsprite->patches[idx]) + return; + + if (bflip) + { + xpivot = width - xpivot; + leftoffset = width - leftoffset; + } + + // Find the dimensions of the rotated patch. + { + INT32 w1 = abs(FixedMul(width << FRACBITS, ca) - FixedMul(height << FRACBITS, sa)); + INT32 w2 = abs(FixedMul(-(width << FRACBITS), ca) - FixedMul(height << FRACBITS, sa)); + INT32 h1 = abs(FixedMul(width << FRACBITS, sa) + FixedMul(height << FRACBITS, ca)); + INT32 h2 = abs(FixedMul(-(width << FRACBITS), sa) + FixedMul(height << FRACBITS, ca)); + w1 = FixedInt(FixedCeil(w1 + (FRACUNIT/2))); + w2 = FixedInt(FixedCeil(w2 + (FRACUNIT/2))); + h1 = FixedInt(FixedCeil(h1 + (FRACUNIT/2))); + h2 = FixedInt(FixedCeil(h2 + (FRACUNIT/2))); + newwidth = max(width, max(w1, w2)); + newheight = max(height, max(h1, h2)); + } + + // check boundaries + { + fixed_t top[2][2]; + fixed_t bottom[2][2]; + + top[0][0] = FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, sa) + (xpivot << FRACBITS); + top[0][1] = FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, ca) + (ypivot << FRACBITS); + top[1][0] = FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, sa) + (xpivot << FRACBITS); + top[1][1] = FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, ca) + (ypivot << FRACBITS); + + bottom[0][0] = FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, sa) + (xpivot << FRACBITS); + bottom[0][1] = -FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, ca) + (ypivot << FRACBITS); + bottom[1][0] = FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, sa) + (xpivot << FRACBITS); + bottom[1][1] = -FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, ca) + (ypivot << FRACBITS); + + top[0][0] >>= FRACBITS; + top[0][1] >>= FRACBITS; + top[1][0] >>= FRACBITS; + top[1][1] >>= FRACBITS; + + bottom[0][0] >>= FRACBITS; + bottom[0][1] >>= FRACBITS; + bottom[1][0] >>= FRACBITS; + bottom[1][1] >>= FRACBITS; + +#define BOUNDARYWCHECK(b) (b[0] < 0 || b[0] >= width) +#define BOUNDARYHCHECK(b) (b[1] < 0 || b[1] >= height) +#define BOUNDARYADJUST(x) x *= 2 + // top left/right + if (BOUNDARYWCHECK(top[0]) || BOUNDARYWCHECK(top[1])) + BOUNDARYADJUST(newwidth); + // bottom left/right + else if (BOUNDARYWCHECK(bottom[0]) || BOUNDARYWCHECK(bottom[1])) + BOUNDARYADJUST(newwidth); + // top left/right + if (BOUNDARYHCHECK(top[0]) || BOUNDARYHCHECK(top[1])) + BOUNDARYADJUST(newheight); + // bottom left/right + else if (BOUNDARYHCHECK(bottom[0]) || BOUNDARYHCHECK(bottom[1])) + BOUNDARYADJUST(newheight); +#undef BOUNDARYWCHECK +#undef BOUNDARYHCHECK +#undef BOUNDARYADJUST + } + + // Draw the rotated sprite to a temporary buffer. + size = (newwidth * newheight); + if (!size) + size = (width * height); + rawdst = Z_Calloc(size * sizeof(UINT16), PU_STATIC, NULL); + + for (dy = 0; dy < newheight; dy++) + { + for (dx = 0; dx < newwidth; dx++) + { + INT32 x = (dx-ROTSPRITE_XCENTER) << FRACBITS; + INT32 y = (dy-ROTSPRITE_YCENTER) << FRACBITS; + INT32 sx = FixedMul(x, ca) + FixedMul(y, sa) + (xpivot << FRACBITS); + INT32 sy = -FixedMul(x, sa) + FixedMul(y, ca) + (ypivot << FRACBITS); + sx >>= FRACBITS; + sy >>= FRACBITS; + if (sx >= 0 && sy >= 0 && sx < width && sy < height) + { + void *input = Picture_GetPatchPixel(patch, PICFMT_PATCH, sx, sy, bflip); + if (input != NULL) + rawdst[(dy*newwidth)+dx] = (0xFF00 | (*(UINT8 *)input)); + } + } + } + + // make patch + rotated = (patch_t *)Picture_Convert(PICFMT_FLAT16, rawdst, PICFMT_PATCH, 0, &size, newwidth, newheight, 0, 0, 0); + + Z_ChangeTag(rotated, PU_PATCH_ROTATED); + Z_SetUser(rotated, (void **)(&rotsprite->patches[angle])); + + rotated->leftoffset = (rotated->width / 2) + (leftoffset - xpivot); + rotated->topoffset = (rotated->height / 2) + (patch->topoffset - ypivot); + + //BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer + rotated->topoffset += FEETADJUST>>FRACBITS; + + // free rotated image data + Z_Free(rawdst); + +#undef ROTSPRITE_XCENTER +#undef ROTSPRITE_YCENTER +} +#endif diff --git a/src/r_picformats.c b/src/r_picformats.c index 7b44d21f1..8ec78663e 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -17,11 +17,10 @@ #include "i_video.h" #include "r_data.h" #include "r_patch.h" -#include "r_textures.h" -#include "r_draw.h" -#include "r_patch.h" #include "r_picformats.h" +#include "r_textures.h" #include "r_things.h" +#include "r_draw.h" #include "v_video.h" #include "z_zone.h" #include "w_wad.h" @@ -1672,192 +1671,3 @@ void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps) R_ParseSPRTINFOLump(wadnum, i); } } - -#ifdef ROTSPRITE -// -// R_GetRollAngle -// -// Angles precalculated in R_InitSprites. -// -fixed_t rollcosang[ROTANGLES]; -fixed_t rollsinang[ROTANGLES]; -INT32 R_GetRollAngle(angle_t rollangle) -{ - INT32 ra = AngleFixed(rollangle)>>FRACBITS; -#if (ROTANGDIFF > 1) - ra += (ROTANGDIFF/2); -#endif - ra /= ROTANGDIFF; - ra %= ROTANGLES; - return ra; -} - -// -// R_CacheRotSprite -// -// Create a rotated sprite. -// -void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, INT32 angle, UINT8 flip) -{ - patch_t *patch, *newpatch; - UINT16 *rawdst; - size_t size; - pictureflags_t bflip = (flip) ? PICFLAGS_XFLIP : 0; - - // Don't cache angle = 0 - if (angle < 1 || angle >= ROTANGLES) - return; - -#define SPRITE_XCENTER (leftoffset) -#define SPRITE_YCENTER (height / 2) -#define ROTSPRITE_XCENTER (newwidth / 2) -#define ROTSPRITE_YCENTER (newheight / 2) - - if (sprframe->rotsprite.patch[rot][angle] == NULL) - { - INT32 dx, dy; - INT32 px, py; - INT32 width, height, leftoffset; - INT32 newwidth, newheight; - fixed_t ca, sa; - lumpnum_t lump = sprframe->lumppat[rot]; - - if (lump == LUMPERROR) - return; - - patch = (patch_t *)W_CachePatchNum(lump, PU_STATIC); - width = patch->width; - height = patch->height; - leftoffset = patch->leftoffset; - - // rotation pivot - px = SPRITE_XCENTER; - py = SPRITE_YCENTER; - - // get correct sprite info for sprite - if (sprinfo == NULL) - sprinfo = &spriteinfo[sprnum]; - if (sprinfo->available) - { - px = sprinfo->pivot[frame].x; - py = sprinfo->pivot[frame].y; - } - if (bflip) - { - px = width - px; - leftoffset = width - leftoffset; - } - - ca = rollcosang[angle]; - sa = rollsinang[angle]; - - // Find the dimensions of the rotated patch. - { - INT32 w1 = abs(FixedMul(width << FRACBITS, ca) - FixedMul(height << FRACBITS, sa)); - INT32 w2 = abs(FixedMul(-(width << FRACBITS), ca) - FixedMul(height << FRACBITS, sa)); - INT32 h1 = abs(FixedMul(width << FRACBITS, sa) + FixedMul(height << FRACBITS, ca)); - INT32 h2 = abs(FixedMul(-(width << FRACBITS), sa) + FixedMul(height << FRACBITS, ca)); - w1 = FixedInt(FixedCeil(w1 + (FRACUNIT/2))); - w2 = FixedInt(FixedCeil(w2 + (FRACUNIT/2))); - h1 = FixedInt(FixedCeil(h1 + (FRACUNIT/2))); - h2 = FixedInt(FixedCeil(h2 + (FRACUNIT/2))); - newwidth = max(width, max(w1, w2)); - newheight = max(height, max(h1, h2)); - } - - // check boundaries - { - fixed_t top[2][2]; - fixed_t bottom[2][2]; - - top[0][0] = FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, sa) + (px << FRACBITS); - top[0][1] = FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, ca) + (py << FRACBITS); - top[1][0] = FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, sa) + (px << FRACBITS); - top[1][1] = FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, ca) + (py << FRACBITS); - - bottom[0][0] = FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, sa) + (px << FRACBITS); - bottom[0][1] = -FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, ca) + (py << FRACBITS); - bottom[1][0] = FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, sa) + (px << FRACBITS); - bottom[1][1] = -FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, ca) + (py << FRACBITS); - - top[0][0] >>= FRACBITS; - top[0][1] >>= FRACBITS; - top[1][0] >>= FRACBITS; - top[1][1] >>= FRACBITS; - - bottom[0][0] >>= FRACBITS; - bottom[0][1] >>= FRACBITS; - bottom[1][0] >>= FRACBITS; - bottom[1][1] >>= FRACBITS; - -#define BOUNDARYWCHECK(b) (b[0] < 0 || b[0] >= width) -#define BOUNDARYHCHECK(b) (b[1] < 0 || b[1] >= height) -#define BOUNDARYADJUST(x) x *= 2 - // top left/right - if (BOUNDARYWCHECK(top[0]) || BOUNDARYWCHECK(top[1])) - BOUNDARYADJUST(newwidth); - // bottom left/right - else if (BOUNDARYWCHECK(bottom[0]) || BOUNDARYWCHECK(bottom[1])) - BOUNDARYADJUST(newwidth); - // top left/right - if (BOUNDARYHCHECK(top[0]) || BOUNDARYHCHECK(top[1])) - BOUNDARYADJUST(newheight); - // bottom left/right - else if (BOUNDARYHCHECK(bottom[0]) || BOUNDARYHCHECK(bottom[1])) - BOUNDARYADJUST(newheight); -#undef BOUNDARYWCHECK -#undef BOUNDARYHCHECK -#undef BOUNDARYADJUST - } - - // Draw the rotated sprite to a temporary buffer. - size = (newwidth * newheight); - if (!size) - size = (width * height); - rawdst = Z_Calloc(size * sizeof(UINT16), PU_STATIC, NULL); - - for (dy = 0; dy < newheight; dy++) - { - for (dx = 0; dx < newwidth; dx++) - { - INT32 x = (dx-ROTSPRITE_XCENTER) << FRACBITS; - INT32 y = (dy-ROTSPRITE_YCENTER) << FRACBITS; - INT32 sx = FixedMul(x, ca) + FixedMul(y, sa) + (px << FRACBITS); - INT32 sy = -FixedMul(x, sa) + FixedMul(y, ca) + (py << FRACBITS); - sx >>= FRACBITS; - sy >>= FRACBITS; - if (sx >= 0 && sy >= 0 && sx < width && sy < height) - { - void *input = Picture_GetPatchPixel(patch, PICFMT_PATCH, sx, sy, bflip); - if (input != NULL) - rawdst[(dy*newwidth)+dx] = (0xFF00 | (*(UINT8 *)input)); - } - } - } - - // make patch - newpatch = (patch_t *)Picture_Convert(PICFMT_FLAT16, rawdst, PICFMT_PATCH, 0, &size, newwidth, newheight, 0, 0, 0); - Z_ChangeTag(newpatch, PU_SPRITE_ROTATED); - { - newpatch->leftoffset = (newpatch->width / 2) + (leftoffset - px); - newpatch->topoffset = (newpatch->height / 2) + (patch->topoffset - py); - } - - //BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer - if (rendermode != render_none) // not for psprite - newpatch->topoffset += FEETADJUST>>FRACBITS; - - // P_PrecacheLevel - if (devparm) spritememory += size; - - Z_SetUser(newpatch, &sprframe->rotsprite.patch[rot][angle]); - - // free rotated image data - Z_Free(rawdst); - } -#undef SPRITE_XCENTER -#undef SPRITE_YCENTER -#undef ROTSPRITE_XCENTER -#undef ROTSPRITE_YCENTER -} -#endif diff --git a/src/r_picformats.h b/src/r_picformats.h index e6c4aa17a..8d3999013 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -125,12 +125,4 @@ extern spriteinfo_t spriteinfo[NUMSPRITES]; void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps); void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); -// Sprite rotation -#ifdef ROTSPRITE -INT32 R_GetRollAngle(angle_t rollangle); -void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, INT32 angle, UINT8 flip); -extern fixed_t rollcosang[ROTANGLES]; -extern fixed_t rollsinang[ROTANGLES]; -#endif - #endif // __R_PICFORMATS__ diff --git a/src/r_things.c b/src/r_things.c index a9a5c42fc..b7d7302f8 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -97,7 +97,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch { char cn = R_Frame2Char(frame), cr = R_Rotation2Char(rotation); // for debugging - INT32 r, ang; + INT32 r; lumpnum_t lumppat = wad; lumppat <<= 16; lumppat += lump; @@ -105,14 +105,10 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch if (maxframe ==(size_t)-1 || frame > maxframe) maxframe = frame; - // rotsprite #ifdef ROTSPRITE for (r = 0; r < 16; r++) - { - for (ang = 0; ang < ROTANGLES; ang++) - sprtemp[frame].rotsprite.patch[r][ang] = NULL; - } -#endif/*ROTSPRITE*/ + sprtemp[frame].rotated[r] = NULL; +#endif if (rotation == 0) { @@ -1454,7 +1450,7 @@ static void R_ProjectSprite(mobj_t *thing) thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; #ifdef ROTSPRITE - sprinfo = NULL; + sprinfo = &spriteinfo[thing->sprite]; #endif frame = thing->frame&FF_FRAMEMASK; } @@ -1463,7 +1459,7 @@ static void R_ProjectSprite(mobj_t *thing) { sprdef = &sprites[thing->sprite]; #ifdef ROTSPRITE - sprinfo = NULL; + sprinfo = &spriteinfo[thing->sprite]; #endif if (frame >= sprdef->numframes) @@ -1478,6 +1474,7 @@ static void R_ProjectSprite(mobj_t *thing) 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; } } @@ -1539,9 +1536,7 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->rollangle) { rollangle = R_GetRollAngle(thing->rollangle); - if (sprframe->rotsprite.patch[rot][rollangle] == NULL) - R_CacheRotSprite(thing->sprite, frame, sprinfo, sprframe, rot, rollangle, flip); - rotsprite = sprframe->rotsprite.patch[rot][rollangle]; + rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, sprinfo, rollangle); if (rotsprite != NULL) { spr_width = SHORT(rotsprite->width) << FRACBITS; diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index 755fa68e6..b66cea963 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -282,6 +282,8 @@ + + @@ -449,6 +451,8 @@ true + + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index 3bbcd9cb5..3291db6c9 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -474,12 +474,18 @@ Hw_Hardware - + + R_Rend + + R_Rend R_Rend + + R_Rend + R_Rend @@ -952,12 +958,18 @@ Hw_Hardware - + + R_Rend + + R_Rend R_Rend + + R_Rend + R_Rend diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj index 52617037b..3e8af3b0e 100644 --- a/src/win32/Srb2win-vc10.vcxproj +++ b/src/win32/Srb2win-vc10.vcxproj @@ -298,6 +298,8 @@ true + + @@ -454,6 +456,8 @@ + + diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters index 0689a4ac0..7279368f1 100644 --- a/src/win32/Srb2win-vc10.vcxproj.filters +++ b/src/win32/Srb2win-vc10.vcxproj.filters @@ -469,9 +469,18 @@ Hw_Hardware + + R_Rend + + + R_Rend + R_Rend + + R_Rend + R_Rend @@ -886,12 +895,18 @@ Hw_Hardware - + + R_Rend + + R_Rend R_Rend + + R_Rend + R_Rend diff --git a/src/z_zone.c b/src/z_zone.c index b704e1a30..ad64a3a07 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -795,19 +795,19 @@ static void Command_Memfree_f(void) Z_CheckHeap(-1); CONS_Printf("\x82%s", M_GetText("Memory Info\n")); - CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TotalUsage()>>10)); - CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10)); - CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10)); - CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10)); - CONS_Printf(M_GetText("Patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_PATCH)>>10)); - CONS_Printf(M_GetText("Patches (low) : %7s KB\n"), sizeu1(Z_TagUsage(PU_PATCH_LOWPRIORITY)>>10)); - CONS_Printf(M_GetText("Sprites : %7s KB\n"), sizeu1(Z_TagUsage(PU_SPRITE)>>10)); - CONS_Printf(M_GetText("Sprites (rotated) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SPRITE_ROTATED)>>10)); - CONS_Printf(M_GetText("HUD graphics : %7s KB\n"), sizeu1(Z_TagUsage(PU_HUDGFX)>>10)); - CONS_Printf(M_GetText("Locked cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_CACHE)>>10)); - CONS_Printf(M_GetText("Level : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVEL)>>10)); - CONS_Printf(M_GetText("Special thinker : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVSPEC)>>10)); - CONS_Printf(M_GetText("All purgable : %7s KB\n"), + CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TotalUsage()>>10)); + CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10)); + CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10)); + CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10)); + CONS_Printf(M_GetText("Patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_PATCH)>>10)); + CONS_Printf(M_GetText("Patches (low priority) : %7s KB\n"), sizeu1(Z_TagUsage(PU_PATCH_LOWPRIORITY)>>10)); + CONS_Printf(M_GetText("Patches (rotated) : %7s KB\n"), sizeu1(Z_TagUsage(PU_PATCH_ROTATED)>>10)); + CONS_Printf(M_GetText("Sprites : %7s KB\n"), sizeu1(Z_TagUsage(PU_SPRITE)>>10)); + CONS_Printf(M_GetText("HUD graphics : %7s KB\n"), sizeu1(Z_TagUsage(PU_HUDGFX)>>10)); + CONS_Printf(M_GetText("Locked cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_CACHE)>>10)); + CONS_Printf(M_GetText("Level : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVEL)>>10)); + CONS_Printf(M_GetText("Special thinker : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVSPEC)>>10)); + CONS_Printf(M_GetText("All purgable : %7s KB\n"), sizeu1(Z_TagsUsage(PU_PURGELEVEL, INT32_MAX)>>10)); #ifdef HWRENDER diff --git a/src/z_zone.h b/src/z_zone.h index 90a6de8eb..e80a45e7f 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -45,9 +45,10 @@ enum PU_PATCH = 14, // static entire execution time PU_PATCH_LOWPRIORITY = 15, // lower priority patch, static until level exited - PU_SPRITE = 16, // sprite patch, static until WAD added - PU_SPRITE_ROTATED = 17, // sprite patch, static until level exited or WAD added - PU_HUDGFX = 18, // HUD patch, static until WAD added + PU_PATCH_ROTATED = 16, // rotated patch, static until level exited or WAD added + PU_PATCH_DATA = 17, // patch data, lifetime depends on the patch that owns it + PU_SPRITE = 18, // sprite patch, static until WAD added + PU_HUDGFX = 19, // HUD patch, static until WAD added PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch