From 5fd87351a8468a2fe11737e9a75414d132169347 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 13 Jun 2016 22:52:20 +0100 Subject: [PATCH 01/11] Place precision of 4 on sprname string in the I_Error messages, so that you just get "PLAY" instead of "PLAYC2C8" or "PLAYA0" etc This is so custom character creators won't get confused by having two different frames shown in the same message anymore, bleh --- src/r_things.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index eaab53613..898be69af 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -280,7 +280,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, { case 0xff: // no rotations were found for that frame at all - I_Error("R_AddSingleSpriteDef: No patches found for %s frame %c", sprname, R_Frame2Char(frame)); + I_Error("R_AddSingleSpriteDef: No patches found for %.4s frame %c", sprname, R_Frame2Char(frame)); break; case 0: @@ -293,7 +293,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, // we test the patch lump, or the id lump whatever // if it was not loaded the two are LUMPERROR if (sprtemp[frame].lumppat[rotation] == 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; } From 333d8c882ec2126265bb9697fd06509ca430cd6c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 19 Jul 2016 00:04:00 +0100 Subject: [PATCH 02/11] 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: Thu, 28 Jul 2016 14:57:19 +0100 Subject: [PATCH 03/11] Make sure we detect if start >= numlines so we can deal with that properly for some apparent reason the compiler didn't like the while loop condition edit on its own (it complained about inline failures for P_MobjReadyToTrigger for some reason), so I had to add that extra bit above the while loop... and it was happy again, huh --- src/p_spec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 0bd530279..e11235d81 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1188,7 +1188,10 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) { start++; - while (lines[start].special != special) + if (start >= (INT32)numlines) + return -1; + + while (start < (INT32)numlines && lines[start].special != special) start++; if (start >= (INT32)numlines) From 4c4f124611a98c66b929403aaaad0eb1a8f63018 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 Jul 2016 16:07:26 +0100 Subject: [PATCH 04/11] Detect if -warp's parm is actually a valid map name (MAPxx or plain number), and print an "invalid map name" message if not --- src/d_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 14a8a06e1..b61ec4143 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1060,10 +1060,11 @@ void D_SRB2Main(void) if (M_CheckParm("-warp") && M_IsNextParm()) { const char *word = M_GetNextParm(); - if (fastncmp(word, "MAP", 3)) + char ch; // use this with sscanf to catch non-digits with + if (fastncmp(word, "MAP", 3)) // MAPxx name pstartmap = M_MapNumber(word[3], word[4]); - else - pstartmap = atoi(word); + else if (sscanf(word, "%d%c", &pstartmap, &ch) != 1) // a plain number + I_Error("Cannot warp to map %s (invalid map name)\n", word); // Don't check if lump exists just yet because the wads haven't been loaded! // Just do a basic range check here. if (pstartmap < 1 || pstartmap > NUMMAPS) From 76e658bf1b49322ea59ed2897cb624011e2b6afa Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 7 Aug 2016 00:21:16 +0100 Subject: [PATCH 05/11] 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 02d3382408adaa81bc68af99c5699747f345014b Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 7 Aug 2016 12:17:31 -0500 Subject: [PATCH 06/11] Leave a note to anyone foolish enough to try to fix this --- src/p_spec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index e11235d81..30b08ebb1 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1188,6 +1188,8 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) { start++; + // This redundant check stops the compiler from complaining about function expansion + // elsewhere for some reason and everything is awful if (start >= (INT32)numlines) return -1; From 6a070adf4ba1417536276a8f0a1937347d29a52b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 8 Aug 2016 14:35:18 +0100 Subject: [PATCH 07/11] 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 08/11] 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 09/11] 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 10/11] 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 11/11] 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;