From 333d8c882ec2126265bb9697fd06509ca430cd6c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 19 Jul 2016 00:04:00 +0100 Subject: [PATCH 1/7] Recreating NAMEcLcR sprite angle loading in internal, as Inu requested. --- src/hardware/hw_main.c | 27 +++++++----- src/r_defs.h | 17 +++++++- src/r_things.c | 98 +++++++++++++++++++++++++++++++----------- src/r_things.h | 9 ++++ 4 files changed, 115 insertions(+), 36 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a83960177..7afef4d51 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5096,22 +5096,29 @@ static void HWR_ProjectSprite(mobj_t *thing) I_Error("sprframes NULL for sprite %d\n", thing->sprite); #endif - if (sprframe->rotate) - { - // choose a different rotation based on player view - ang = R_PointToAngle(thing->x, thing->y); // uses viewx,viewy - rot = (ang-thing->angle+ANGLE_202h)>>29; - //Fab: lumpid is the index for spritewidth,spriteoffset... tables - lumpoff = sprframe->lumpid[rot]; - flip = sprframe->flip & (1<rotate == SRF_SINGLE) { // 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 } + else + { + // choose a different rotation based on player view + ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + + if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right + rot = 6; // F7 slot + else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left + rot = 2; // F3 slot + 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<skin && ((skin_t *)thing->skin)->flags & SF_HIRES) this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale); diff --git a/src/r_defs.h b/src/r_defs.h index 2c5860ee7..622bf4094 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -729,23 +729,36 @@ typedef struct #pragma pack() #endif +typedef enum +{ + SRF_SINGLE = 0, // 0-angle for all rotations + SRF_3D = 1, // Angles 1-8 + SRF_LEFT = 2, // Left side has single patch + SRF_RIGHT = 4, // Right side has single patch + SRF_2D = 6, // SRF_LEFT|SRF_RIGHT + SRF_NONE = 0xff // Initial value +} spriterotateflags_t; // SRF's up! + // // Sprites are patches with a special naming convention so they can be // recognized by R_InitSprites. // The base name is NNNNFx or NNNNFxFx, with x indicating the rotation, -// x = 0, 1-7. +// x = 0, 1-8, L/R // The sprite and frame specified by a thing_t is range checked at run time. // A sprite is a patch_t that is assumed to represent a three dimensional // object and may have multiple rotations predrawn. // Horizontal flipping is used to save space, thus NNNNF2F5 defines a mirrored patch. // Some sprites will only have one picture used for all views: NNNNF0 +// Some sprites will take the entirety of the left side: NNNNFL +// Or the right side: NNNNFR +// Or both, mirrored: NNNNFLFR // typedef struct { // If false use 0 for any position. // Note: as eight entries are available, we might as well insert the same // name eight times. - UINT8 rotate; + UINT8 rotate; // see spriterotateflags_t above // Lump to use for view angles 0-7. lumpnum_t lumppat[8]; // lump number 16 : 16 wad : lump diff --git a/src/r_things.c b/src/r_things.c index 25cbd15fe..a836aa88b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -100,7 +100,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch lumppat <<= 16; lumppat += lump; - if (frame >= 64 || rotation > 8) + if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) I_Error("R_InstallSpriteLump: Bad frame characters in lump %s", W_CheckNameForNum(lumppat)); if (maxframe ==(size_t)-1 || frame > maxframe) @@ -109,31 +109,67 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch if (rotation == 0) { // the lump should be used for all rotations - if (sprtemp[frame].rotate == 0) + if (sprtemp[frame].rotate == SRF_SINGLE) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn); - - if (sprtemp[frame].rotate == 1) + else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8 and L/R rotations into one debug message. CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); - sprtemp[frame].rotate = 0; + sprtemp[frame].rotate = SRF_SINGLE; for (r = 0; r < 8; r++) { sprtemp[frame].lumppat[r] = lumppat; sprtemp[frame].lumpid[r] = lumpid; } - sprtemp[frame].flip = flipped ? UINT8_MAX : 0; + sprtemp[frame].flip = flipped ? 0xFF : 0; // 11111111 in binary + return; + } + + if (rotation == ROT_L || rotation == ROT_R) + { + UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0); + + // the lump should be used for half of all rotations + if (sprtemp[frame].rotate == SRF_SINGLE) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has L/R rotations and a rot = 0 lump\n", spritename, cn); + else if (sprtemp[frame].rotate == SRF_3D) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn); + else if ((sprtemp[frame].rotate & SRF_LEFT) && (rotation == ROT_L)) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple L rotations\n", spritename, cn); + else if ((sprtemp[frame].rotate & SRF_RIGHT) && (rotation == ROT_R)) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple R rotations\n", spritename, cn); + + if (sprtemp[frame].rotate == SRF_NONE) + sprtemp[frame].rotate = SRF_SINGLE; + + sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT); + if (sprtemp[frame].rotate == (SRF_3D|SRF_2D)) + sprtemp[frame].rotate = SRF_2D; // SRF_3D|SRF_2D being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen. + + for (r = 1; r < 4; r++) // Don't set for front/back frames + { + sprtemp[frame].lumppat[r + rightfactor] = lumppat; + sprtemp[frame].lumpid[r + rightfactor] = lumpid; + } + sprtemp[frame].flip |= (flipped ? (0x0F << rightfactor) : 0); // 00001111 or 11110000 in binary, depending on rotation being ROT_L or ROT_R return; } // the lump is only used for one rotation - if (sprtemp[frame].rotate == 0) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); - - sprtemp[frame].rotate = 1; + if (sprtemp[frame].rotate == SRF_SINGLE) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has 1-8 rotations and a rot = 0 lump\n", spritename, cn); + else if ((sprtemp[frame].rotate != SRF_3D) && (sprtemp[frame].rotate != SRF_NONE)) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn); // make 0 based rotation--; + if (rotation == 0 || rotation == 4) // Front or back... + sprtemp[frame].rotate = SRF_3D; // Prevent L and R changeover + else if (rotation > 3) // Right side + sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover + else // if (rotation <= 3) // Left side + sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover + if (sprtemp[frame].lumppat[rotation] != LUMPERROR) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, '1'+rotation); @@ -195,7 +231,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, frame = R_Char2Frame(lumpinfo[l].name[4]); rotation = (UINT8)(lumpinfo[l].name[5] - '0'); - if (frame >= 64 || rotation > 8) // Give an actual NAME error -_-... + if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-... { CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); continue; @@ -278,16 +314,23 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, { switch (sprtemp[frame].rotate) { - case 0xff: + case SRF_NONE: // no rotations were found for that frame at all I_Error("R_AddSingleSpriteDef: No patches found for %s frame %c", sprname, R_Frame2Char(frame)); break; - case 0: + case SRF_SINGLE: // only the first rotation is needed break; - case 1: + case SRF_2D: // both Left and Right rotations + // we test to see whether the left and right slots are present + if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR)) + I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations", + sprname, R_Frame2Char(frame)); + break; + + default: // must have all 8 frames for (rotation = 0; rotation < 8; rotation++) // we test the patch lump, or the id lump whatever @@ -1138,22 +1181,29 @@ static void R_ProjectSprite(mobj_t *thing) I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); #endif - if (sprframe->rotate) - { - // choose a different rotation based on player view - ang = R_PointToAngle (thing->x, thing->y); - rot = (ang-thing->angle+ANGLE_202h)>>29; - //Fab: lumpid is the index for spritewidth,spriteoffset... tables - lump = sprframe->lumpid[rot]; - flip = sprframe->flip & (1<rotate == SRF_SINGLE) { // 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 0x00 or 0xFF } + else + { + // choose a different rotation based on player view + ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + + if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right + rot = 6; // F7 slot + else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left + rot = 2; // F3 slot + 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< Date: Sun, 7 Aug 2016 00:21:16 +0100 Subject: [PATCH 2/7] Minor re-ordering to optimise this branch. --- src/hardware/hw_main.c | 4 ++-- src/r_things.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7afef4d51..4c033043d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5108,9 +5108,9 @@ static void HWR_ProjectSprite(mobj_t *thing) // choose a different rotation based on player view ang = R_PointToAngle (thing->x, thing->y) - thing->angle; - if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right + if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right rot = 6; // F7 slot - else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left + else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left rot = 2; // F3 slot else // Normal behaviour rot = (ang+ANGLE_202h)>>29; diff --git a/src/r_things.c b/src/r_things.c index a836aa88b..6c26620fe 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1193,9 +1193,9 @@ static void R_ProjectSprite(mobj_t *thing) // choose a different rotation based on player view ang = R_PointToAngle (thing->x, thing->y) - thing->angle; - if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right + if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right rot = 6; // F7 slot - else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left + else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left rot = 2; // F3 slot else // Normal behaviour rot = (ang+ANGLE_202h)>>29; From 6a070adf4ba1417536276a8f0a1937347d29a52b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 8 Aug 2016 14:35:18 +0100 Subject: [PATCH 3/7] Making the flag value more obvious. --- src/r_defs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 622bf4094..9109ac7c3 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -733,9 +733,9 @@ typedef enum { SRF_SINGLE = 0, // 0-angle for all rotations SRF_3D = 1, // Angles 1-8 - SRF_LEFT = 2, // Left side has single patch - SRF_RIGHT = 4, // Right side has single patch - SRF_2D = 6, // SRF_LEFT|SRF_RIGHT + SRF_LEFT = 2, // Left side uses single patch + SRF_RIGHT = 4, // Right side uses single patch + SRF_2D = SRF_LEFT|SRF_RIGHT, // 6 SRF_NONE = 0xff // Initial value } spriterotateflags_t; // SRF's up! From c77b3aa58db93da84adde74200b2f3419d919aa3 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 8 Aug 2016 17:24:36 +0100 Subject: [PATCH 4/7] Sorted an issue MI discovered (I was basing the flip code off the C0 scenario rather than the Cn one) --- src/r_things.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index f98578e73..ff9c604ff 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -150,7 +150,12 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch sprtemp[frame].lumppat[r + rightfactor] = lumppat; sprtemp[frame].lumpid[r + rightfactor] = lumpid; } - sprtemp[frame].flip |= (flipped ? (0x0F << rightfactor) : 0); // 00001111 or 11110000 in binary, depending on rotation being ROT_L or ROT_R + + if (flipped) + sprtemp[frame].flip |= (0x0F< Date: Mon, 8 Aug 2016 21:30:20 -0400 Subject: [PATCH 5/7] I do not think you wanted to break on EVERYTHING --- src/r_things.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index ff9c604ff..5e9d93b70 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -331,10 +331,11 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, case SRF_2D: // both Left and Right rotations // we test to see whether the left and right slots are present if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR)) + { I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations", sprname, R_Frame2Char(frame)); break; - + } default: // must have all 8 frames for (rotation = 0; rotation < 8; rotation++) From 4183912c60a9e3e8380ec439899c0db9ed15f50b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 9 Aug 2016 13:01:56 +0100 Subject: [PATCH 6/7] Please don't assume indentation carries intent, especially since a break that exclusively follows an I_Error will never run --- src/r_things.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 5e9d93b70..2f19af833 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -331,11 +331,10 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, case SRF_2D: // both Left and Right rotations // we test to see whether the left and right slots are present if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR)) - { I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations", sprname, R_Frame2Char(frame)); - break; - } + break; + default: // must have all 8 frames for (rotation = 0; rotation < 8; rotation++) From 742dced437623c1491e0c068ad809789c934edab Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 9 Aug 2016 13:04:53 +0100 Subject: [PATCH 7/7] Updating I_Error to use 4 characters for the spritename only in the same way the other ones do --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 2f19af833..108589493 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -331,7 +331,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, case SRF_2D: // both Left and Right rotations // we test to see whether the left and right slots are present if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR)) - I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations", + I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations", sprname, R_Frame2Char(frame)); break;