From 52bf13367fe28cb171c7bdd391f6f1d3bdbf2346 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 16 Jun 2016 00:59:54 +0100 Subject: [PATCH 001/122] New rotation functionality. * NAMEcL refers to a frame which is seen for the entirety of an object's left side. * NAMEcR refers to a name which is seen for the entirety of an object's right side. * NAMEcLcR does both sides. * Having just a NAMEcL requires you to fill in the opposite side either with NAMEcn where n is 1 and 5 to 8 OR fill in with a NAMEcR * Switches down the centerline of the object instead of at the ANGLE_202h interval for normal sprites. * Characters were selected for 1) ease of use and 2) not getting in the way of adding support for zdoom's totally bananas 16-way sprite system at a later date if we so choose --- src/hardware/hw_main.c | 11 ++++++-- src/r_defs.h | 6 +++++ src/r_things.c | 57 ++++++++++++++++++++++++++++++++++-------- src/r_things.h | 9 +++++++ 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 35a01ffd1..aba89bdcd 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5095,8 +5095,15 @@ static void HWR_ProjectSprite(mobj_t *thing) 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; + ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + + if ((ang < ANGLE_180) && (sprframe->rotate & 4)) // See from right + rot = 6; // F7 slot + else if ((ang >= ANGLE_180) && (sprframe->rotate & 2)) // 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<= 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) @@ -111,8 +111,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch // the lump should be used for all rotations if (sprtemp[frame].rotate == 0) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn); - - if (sprtemp[frame].rotate == 1) + else // Let's complain for both 1-8 and L/R rotations. CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); sprtemp[frame].rotate = 0; @@ -121,15 +120,46 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch sprtemp[frame].lumppat[r] = lumppat; sprtemp[frame].lumpid[r] = lumpid; } - sprtemp[frame].flip = flipped ? UINT8_MAX : 0; + sprtemp[frame].flip = flipped ? UINT8_MAX : 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 == 0) + 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 == 1) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn); + // Let's not complain about multiple L/R rotations. It's not worth the effort. + + sprtemp[frame].rotate |= ((rotation == ROT_R) ? 4 : 2); + for (r = 0; r < 4; r++) + { + if ((r != 0) || (sprtemp[frame].lumppat[rotation] == LUMPERROR)) // Only set front/back angles if they don't exist + { + 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); + 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 != 1) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn); - sprtemp[frame].rotate = 1; + if (rotation == 0 || rotation == 4) // Front or back... + sprtemp[frame].rotate = 1; // Prevent L and R changeover + else if (rotation > 3) // Right side + sprtemp[frame].rotate = (1 | (sprtemp[frame].rotate & 2)); // Continue allowing L frame changeover + else // if (rotation <= 3) // Left side + sprtemp[frame].rotate = (1 | (sprtemp[frame].rotate & 4)); // Continue allowing R frame changeover // make 0 based rotation--; @@ -195,7 +225,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; @@ -287,7 +317,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, // only the first rotation is needed break; - case 1: + default: // must have all 8 frames for (rotation = 0; rotation < 8; rotation++) // we test the patch lump, or the id lump whatever @@ -1132,8 +1162,15 @@ static void R_ProjectSprite(mobj_t *thing) 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; + ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + + if ((ang < ANGLE_180) && (sprframe->rotate & 4)) // See from right + rot = 6; // F7 slot + else if ((ang >= ANGLE_180) && (sprframe->rotate & 2)) // 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, 16 Jun 2016 01:20:35 +0100 Subject: [PATCH 002/122] Forgot to stage this, woops. Adds special casing to prevent the I_Error and makes the behaviour of the cL/cR more consistent in general such that it matches my description. --- src/r_things.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 4f1faae97..6e4f780b5 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -135,14 +135,14 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn); // Let's not complain about multiple L/R rotations. It's not worth the effort. + if (sprtemp[frame].rotate == 0xff) + sprtemp[frame].rotate = 0; + sprtemp[frame].rotate |= ((rotation == ROT_R) ? 4 : 2); - for (r = 0; r < 4; r++) + for (r = 1; r < 4; r++) // Don't set for front/back frames { - if ((r != 0) || (sprtemp[frame].lumppat[rotation] == LUMPERROR)) // Only set front/back angles if they don't exist - { - sprtemp[frame].lumppat[r + rightfactor] = lumppat; - sprtemp[frame].lumpid[r + rightfactor] = lumpid; - } + 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; @@ -317,6 +317,14 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, // only the first rotation is needed break; + case 6: // (rotate & (2|4)) == (2|4) - both Left and Right rotations + case 7: + // 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 f08e996e761e169033cefca99bc64febfe3c1469 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 16 Jun 2016 01:37:48 +0100 Subject: [PATCH 003/122] MI corrections --- src/r_things.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 6e4f780b5..650b454ec 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -111,7 +111,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch // the lump should be used for all rotations if (sprtemp[frame].rotate == 0) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn); - else // Let's complain for both 1-8 and L/R rotations. + else if (sprtemp[frame].rotate != 0xff) // Let's complain for both 1-8 and L/R rotations. CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); sprtemp[frame].rotate = 0; @@ -154,6 +154,9 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch else if (sprtemp[frame].rotate != 1) 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 = 1; // Prevent L and R changeover else if (rotation > 3) // Right side @@ -161,9 +164,6 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch else // if (rotation <= 3) // Left side sprtemp[frame].rotate = (1 | (sprtemp[frame].rotate & 4)); // Continue allowing R frame changeover - // make 0 based - rotation--; - 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); From 41b35a923f64961945c7a429ea67ecc5a3171b38 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 16 Jun 2016 14:20:03 +0100 Subject: [PATCH 004/122] Gave the new flag-based system for sprite angles actual flag names instead of relying on magic numbers. Also, I did a wee smidgen of reorganisation. --- src/hardware/hw_main.c | 20 +++++++-------- src/r_defs.h | 18 ++++++++----- src/r_things.c | 57 ++++++++++++++++++++++-------------------- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index aba89bdcd..5dfb2d124 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5092,14 +5092,21 @@ static void HWR_ProjectSprite(mobj_t *thing) I_Error("sprframes NULL for sprite %d\n", thing->sprite); #endif - if (sprframe->rotate) + if (sprframe->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 & 4)) // See from right + if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right rot = 6; // F7 slot - else if ((ang >= ANGLE_180) && (sprframe->rotate & 2)) // See from left + else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left rot = 2; // F3 slot else // Normal behaviour rot = (ang+ANGLE_202h)>>29; @@ -5108,13 +5115,6 @@ static void HWR_ProjectSprite(mobj_t *thing) lumpoff = sprframe->lumpid[rot]; flip = sprframe->flip & (1<patch below - lumpoff = sprframe->lumpid[0]; //Fab: see note above - flip = sprframe->flip; // Will only be 0x00 or 0xFF - } if (thing->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 2ff2cacf9..150c3fa58 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -729,11 +729,21 @@ 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. @@ -745,13 +755,9 @@ typedef struct // typedef struct { - // If false use 0 for any position. - // If L is present, (rotate & 2) == 2. - // If R is present, (rotate & 4) == 4. - // Otherwise, use 1. // 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 650b454ec..1ea932b9a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -109,12 +109,12 @@ 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); - else if (sprtemp[frame].rotate != 0xff) // Let's complain for both 1-8 and L/R rotations. + else if (sprtemp[frame].rotate != SRF_NONE) // Let's complain for both 1-8 and L/R rotations. 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; @@ -129,16 +129,20 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0); // the lump should be used for half of all rotations - if (sprtemp[frame].rotate == 0) + 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 == 1) + 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); // Let's not complain about multiple L/R rotations. It's not worth the effort. - if (sprtemp[frame].rotate == 0xff) - sprtemp[frame].rotate = 0; + 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. - sprtemp[frame].rotate |= ((rotation == ROT_R) ? 4 : 2); for (r = 1; r < 4; r++) // Don't set for front/back frames { sprtemp[frame].lumppat[r + rightfactor] = lumppat; @@ -149,20 +153,20 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch } // the lump is only used for one rotation - if (sprtemp[frame].rotate == 0) + 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 != 1) + 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 = 1; // Prevent L and R changeover + sprtemp[frame].rotate = SRF_3D; // Prevent L and R changeover else if (rotation > 3) // Right side - sprtemp[frame].rotate = (1 | (sprtemp[frame].rotate & 2)); // Continue allowing L frame changeover + sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover else // if (rotation <= 3) // Left side - sprtemp[frame].rotate = (1 | (sprtemp[frame].rotate & 4)); // Continue allowing R frame changeover + 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); @@ -308,17 +312,16 @@ 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 6: // (rotate & (2|4)) == (2|4) - both Left and Right rotations - case 7: + 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", @@ -1167,14 +1170,21 @@ static void R_ProjectSprite(mobj_t *thing) I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); #endif - if (sprframe->rotate) + if (sprframe->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 & 4)) // See from right + if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right rot = 6; // F7 slot - else if ((ang >= ANGLE_180) && (sprframe->rotate & 2)) // See from left + else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left rot = 2; // F3 slot else // Normal behaviour rot = (ang+ANGLE_202h)>>29; @@ -1183,13 +1193,6 @@ static void R_ProjectSprite(mobj_t *thing) lump = sprframe->lumpid[rot]; flip = sprframe->flip & (1<patch below - lump = sprframe->lumpid[0]; //Fab: see note above - flip = sprframe->flip; // Will only be 0x00 or 0xFF - } I_Assert(lump < max_spritelumps); From 2a74ea07eeef1dcff6e8bd287756c6f8055d7bdb Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 22 Aug 2016 22:54:30 +0100 Subject: [PATCH 005/122] Chee wanted paper sprites' code, so here it is for the public to see. Note: Won't compile. Need to merge in the NAMEcLcR stuff first, let me do that. --- src/dehacked.c | 4 +- src/m_cheat.c | 2 +- src/p_enemy.c | 18 +++--- src/p_inter.c | 2 +- src/p_mobj.c | 30 ++++------ src/p_mobj.h | 5 +- src/p_pspr.h | 4 +- src/p_user.c | 8 +-- src/r_things.c | 158 +++++++++++++++++++++++++++++++++++++------------ src/r_things.h | 3 +- 10 files changed, 160 insertions(+), 74 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index f03dd73b4..c31c22643 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6642,7 +6642,7 @@ static const char *const MOBJFLAG_LIST[] = { "SHOOTABLE", "NOSECTOR", "NOBLOCKMAP", - "AMBUSH", + "PAPERCOLLISION", "PUSHABLE", "BOSS", "SPAWNCEILING", @@ -6700,6 +6700,7 @@ static const char *const MOBJFLAG2_LIST[] = { "BOSSNOTRAP", // No Egg Trap after boss "BOSSFLEE", // Boss is fleeing! "BOSSDEAD", // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) + "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH NULL }; @@ -6992,6 +6993,7 @@ struct { // Frame settings {"FF_FRAMEMASK",FF_FRAMEMASK}, + {"FF_PAPERSPRITE",FF_PAPERSPRITE}, {"FF_ANIMATE",FF_ANIMATE}, {"FF_FULLBRIGHT",FF_FULLBRIGHT}, {"FF_TRANSMASK",FF_TRANSMASK}, diff --git a/src/m_cheat.c b/src/m_cheat.c index 89334596e..f49930b2c 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1054,7 +1054,7 @@ void OP_NightsObjectplace(player_t *player) if (!OP_HeightOkay(player, false)) return; - if (player->mo->target->flags & MF_AMBUSH) + if (player->mo->target->flags2 & MF2_AMBUSH) angle = (UINT16)player->anotherflyangle; else { diff --git a/src/p_enemy.c b/src/p_enemy.c index 025a25973..b98412bbf 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2625,7 +2625,7 @@ for (i = cvar.value; i; --i) spawnchance[numchoices++] = type newbox = spawnchance[P_RandomKey(numchoices)]; item = mobjinfo[newbox].damage; - remains->flags &= ~MF_AMBUSH; + remains->flags2 &= ~MF2_AMBUSH; break; } default: @@ -3444,7 +3444,7 @@ void A_BubbleSpawn(mobj_t *actor) } actor->flags2 &= ~MF2_DONTDRAW; - if (!(actor->flags & MF_AMBUSH)) + if (!(actor->flags2 & MF2_AMBUSH)) { // Quick! Look through players! // Don't spawn bubbles unless a player is relatively close by (var2). @@ -3492,7 +3492,7 @@ void A_FanBubbleSpawn(mobj_t *actor) if (!(actor->eflags & MFE_UNDERWATER)) return; - if (!(actor->flags & MF_AMBUSH)) + if (!(actor->flags2 & MF2_AMBUSH)) { // Quick! Look through players! // Don't spawn bubbles unless a player is relatively close by (var2). @@ -4038,7 +4038,7 @@ void A_JetChase(mobj_t *actor) return; #endif - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) return; if (actor->z >= actor->waterbottom && actor->watertop > actor->floorz @@ -4931,7 +4931,7 @@ void A_SlingAppear(mobj_t *actor) if (firsttime) { // This is the outermost link in the chain - spawnee->flags |= MF_AMBUSH; + spawnee->flags2 |= MF2_AMBUSH; firsttime = false; } @@ -5916,7 +5916,7 @@ void A_Boss2Chase(mobj_t *actor) { actor->watertop = -actor->watertop; actor->extravalue1 = 18; - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) actor->extravalue1 -= (actor->info->spawnhealth - actor->health)*2; actor->extravalue2 = actor->extravalue1; } @@ -5942,7 +5942,7 @@ void A_Boss2Chase(mobj_t *actor) else { // Only speed up if you have the 'Deaf' flag. - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) speedvar = actor->health; else speedvar = actor->info->spawnhealth; @@ -6533,7 +6533,7 @@ void A_BuzzFly(mobj_t *actor) if (LUA_CallAction("A_BuzzFly", actor)) return; #endif - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) return; if (actor->reactiontime) @@ -6673,7 +6673,7 @@ void A_GuardChase(mobj_t *actor) return; // got a new target // chase towards player - if (--actor->movecount < 0 || !P_Move(actor, (actor->flags & MF_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) + if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) { P_NewChaseDir(actor); actor->movecount += 5; // Increase tics before change in direction allowed. diff --git a/src/p_inter.c b/src/p_inter.c index cf5512a18..aa0fce5c0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1327,7 +1327,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_SMALLMACECHAIN: case MT_BIGMACECHAIN: // Is this the last link in the chain? - if (toucher->momz > 0 || !(special->flags & MF_AMBUSH) + if (toucher->momz > 0 || !(special->flags2 & MF2_AMBUSH) || (player->pflags & PF_ITEMHANG) || (player->pflags & PF_MACESPIN)) return; diff --git a/src/p_mobj.c b/src/p_mobj.c index 62dee0a67..eed2f3c02 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2466,7 +2466,7 @@ static boolean P_ZMovement(mobj_t *mo) && abs(mom.y) < FixedMul(STOPSPEED, mo->scale) && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) { - if (mo->flags & MF_AMBUSH) + if (mo->flags2 & MF2_AMBUSH) { // If deafed, give the tumbleweed another random kick if it runs out of steam. mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); @@ -6392,7 +6392,7 @@ void P_MobjThinker(mobj_t *mobj) flame->angle = mobj->angle; - if (mobj->flags & MF_AMBUSH) // Wave up and down instead of side-to-side + if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side flame->momz = mobj->fuse << (FRACBITS-2); else flame->angle += FixedAngle(mobj->fuse*FRACUNIT); @@ -6427,7 +6427,7 @@ void P_MobjThinker(mobj_t *mobj) strength -= ((20*FRACUNIT)/16)*mobj->movedir; // If deaf'd, the object spawns on the ceiling. - if (mobj->flags & MF_AMBUSH) + if (mobj->flags2 & MF2_AMBUSH) { mobj->z = mobj->ceilingz-mobj->height; flame->momz = -strength; @@ -7283,7 +7283,7 @@ void P_MobjThinker(mobj_t *mobj) case MT_EGGMANBOX: // Eggman box case MT_GRAVITYBOX: // Gravity box case MT_QUESTIONBOX: - if ((mobj->flags & MF_AMBUSH || mobj->flags2 & MF2_STRONGBOX) && mobj->type != MT_QUESTIONBOX) + if ((mobj->flags2 & MF2_AMBUSH || mobj->flags2 & MF2_STRONGBOX) && mobj->type != MT_QUESTIONBOX) { mobjtype_t spawnchance[64]; INT32 numchoices = 0, i = 0; @@ -7311,11 +7311,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s i = P_RandomKey(numchoices); // Gotta love those random numbers! newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]); - // If the monitor respawns randomly, transfer the flag. - if (mobj->flags & MF_AMBUSH) - newmobj->flags |= MF_AMBUSH; - - // Transfer flags2 (strongbox, objectflip) + // Transfer flags2 (strongbox, objectflip, ambush) newmobj->flags2 = mobj->flags2; } else @@ -9132,7 +9128,7 @@ ML_NOCLIMB : Direction not controllable if (firsttime) { // This is the outermost link in the chain - spawnee->flags |= MF_AMBUSH; + spawnee->flags2 |= MF2_AMBUSH; firsttime = false; } @@ -9204,7 +9200,7 @@ ML_NOCLIMB : Direction not controllable { // Inverted if uppermost bit is set if (mthing->angle & 16384) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; if (mthing->angle > 0) mobj->radius = (mthing->angle & 16383)*FRACUNIT; @@ -9381,7 +9377,7 @@ ML_NOCLIMB : Direction not controllable mthing->type == mobjinfo[MT_YELLOWTV].doomednum || mthing->type == mobjinfo[MT_BLUETV].doomednum || mthing->type == mobjinfo[MT_BLACKTV].doomednum || mthing->type == mobjinfo[MT_PITYTV].doomednum || mthing->type == mobjinfo[MT_RECYCLETV].doomednum || mthing->type == mobjinfo[MT_MIXUPBOX].doomednum) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; } else if (mthing->type != mobjinfo[MT_AXIS].doomednum && @@ -9389,7 +9385,7 @@ ML_NOCLIMB : Direction not controllable mthing->type != mobjinfo[MT_AXISTRANSFERLINE].doomednum && mthing->type != mobjinfo[MT_NIGHTSBUMPER].doomednum && mthing->type != mobjinfo[MT_STARPOST].doomednum) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; } if (mthing->options & MTF_OBJECTSPECIAL) @@ -9728,7 +9724,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) P_SetMobjState(mobj, mobj->info->seestate); mobj->angle = FixedAngle(mthing->angle*FRACUNIT); - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; mthing->mobj = mobj; } // All manners of rings and coins @@ -9802,7 +9798,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) } mobj->angle = FixedAngle(mthing->angle*FRACUNIT); - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; mthing->mobj = mobj; } // *** @@ -9858,7 +9854,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) mobj->angle = FixedAngle(mthing->angle*FRACUNIT); if (mthing->options & MTF_AMBUSH) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; } } // Diagonal rings (handles both types) @@ -9916,7 +9912,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) mobj->angle = FixedAngle(mthing->angle*FRACUNIT); if (mthing->options & MTF_AMBUSH) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; } } // Rings of items (all six of them) diff --git a/src/p_mobj.h b/src/p_mobj.h index 79cffae89..c8207c564 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -107,8 +107,8 @@ typedef enum MF_NOSECTOR = 1<<3, // Don't use the blocklinks (inert but displayable) MF_NOBLOCKMAP = 1<<4, - // Not to be activated by sound, deaf monster. - MF_AMBUSH = 1<<5, + // Thin, paper-like collision bound (for visual equivalent, see FF_PAPERSPRITE) + MF_PAPERCOLLISION = 1<<5, // You can push this object. It can activate switches and things by pushing it on top. MF_PUSHABLE = 1<<6, // Object is a boss. @@ -193,6 +193,7 @@ typedef enum MF2_BOSSNOTRAP = 1<<25, // No Egg Trap after boss MF2_BOSSFLEE = 1<<26, // Boss is fleeing! MF2_BOSSDEAD = 1<<27, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) + MF2_AMBUSH = 1<<28, // Alternate behaviour typically set by MTF_AMBUSH // free: to and including 1<<31 } mobjflag2_t; diff --git a/src/p_pspr.h b/src/p_pspr.h index 2fb232e73..c0064bc3e 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -36,7 +36,9 @@ #endif /// \brief Frame flags: only the frame number -#define FF_FRAMEMASK 0x3fff +#define FF_FRAMEMASK 0x1ff +/// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION) +#define FF_PAPERSPRITE 0x800 /// \brief Frame flags: Simple stateless animation #define FF_ANIMATE 0x4000 /// \brief Frame flags: frame always appears full bright diff --git a/src/p_user.c b/src/p_user.c index 9cd6aa401..6bf8753ba 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -629,7 +629,7 @@ static void P_DeNightserizePlayer(player_t *player) if (!(mo2->type == MT_NIGHTSDRONE)) continue; - if (mo2->flags & MF_AMBUSH) + if (mo2->flags2 & MF2_AMBUSH) P_DamageMobj(player->mo, NULL, NULL, 10000); break; @@ -4931,7 +4931,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad boolean transfer1last = false; boolean transfer2last = false; vertex_t vertices[4]; - fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags & MF_AMBUSH ? -1 : 1); + fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags2 & MF2_AMBUSH ? -1 : 1); // Find next waypoint for (th = thinkercap.next; th != &thinkercap; th = th->next) @@ -5596,7 +5596,7 @@ static void P_NiGHTSMovement(player_t *player) // The 'ambush' flag says you should rotate // the other way around the axis. - if (player->mo->target->flags & MF_AMBUSH) + if (player->mo->target->flags2 & MF2_AMBUSH) backwardaxis = true; player->angle_pos = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y); @@ -7931,7 +7931,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } else if (player->mo->target) { - if (player->mo->target->flags & MF_AMBUSH) + if (player->mo->target->flags2 & MF2_AMBUSH) angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y); else angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->target->x, player->mo->target->y); diff --git a/src/r_things.c b/src/r_things.c index 22551a02d..84dff7182 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -754,11 +754,18 @@ static void R_DrawVisSprite(vissprite_t *vis) if (overflow_test < 0) overflow_test = -overflow_test; if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // fixed point mult would overflow + if (vis->scalestep) // handles right edge too + { + overflow_test = (INT64)centeryfrac - (((INT64)vis->texturemid*(vis->scale + (vis->scalestep*(vis->x2 - vis->x1))))>>FRACBITS); + if (overflow_test < 0) overflow_test = -overflow_test; + if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto + } + colfunc = basecolfunc; // hack: this isn't resetting properly somewhere. dc_colormap = vis->colormap; if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" { - // translate green skin to another color + // translate certain pixels to white colfunc = transcolfunc; if (vis->mobj->type == MT_CYBRAKDEMON) dc_translation = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE); @@ -814,13 +821,10 @@ static void R_DrawVisSprite(vissprite_t *vis) if (!dc_colormap) dc_colormap = colormaps; - dc_iscale = FixedDiv(FRACUNIT, vis->scale); dc_texturemid = vis->texturemid; dc_texheight = 0; frac = vis->startfrac; - spryscale = vis->scale; - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); windowtop = windowbottom = sprbotscreen = INT32_MAX; if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) @@ -832,28 +836,29 @@ static void R_DrawVisSprite(vissprite_t *vis) if (!vis->isScaled) { vis->scale = FixedMul(vis->scale, this_scale); - spryscale = vis->scale; - dc_iscale = FixedDiv(FRACUNIT, vis->scale); + vis->scalestep = FixedMul(vis->scalestep, this_scale); vis->xiscale = FixedDiv(vis->xiscale,this_scale); vis->isScaled = true; } dc_texturemid = FixedDiv(dc_texturemid,this_scale); + } - //Oh lordy, mercy me. Don't freak out if sprites go offscreen! - /*if (vis->xiscale > 0) - frac = FixedDiv(frac, this_scale); - else if (vis->x1 <= 0) - frac = (vis->x1 - vis->x2) * vis->xiscale;*/ + spryscale = vis->scale; + if (!(vis->scalestep)) + { sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - //dc_hires = 1; + dc_iscale = FixedDiv(FRACUNIT, vis->scale); } x1 = vis->x1; x2 = vis->x2; if (vis->x1 < 0) + { + spryscale += vis->scalestep*(-vis->x1); vis->x1 = 0; + } if (vis->x2 >= vid.width) vis->x2 = vid.width-1; @@ -869,10 +874,16 @@ static void R_DrawVisSprite(vissprite_t *vis) #else column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); #endif + if (vis->scalestep) + { + sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + dc_iscale = (0xffffffffu / (unsigned)spryscale); + } if (vis->vflip) R_DrawFlippedMaskedColumn(column, patch->height); else R_DrawMaskedColumn(column); + spryscale += vis->scalestep; } colfunc = basecolfunc; @@ -967,7 +978,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) if (testheight <= sprite->gz) return; - cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS); + cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->sortscale))>>FRACBITS); if (cutfrac < 0) continue; if (cutfrac > viewheight) @@ -1040,7 +1051,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t tr_x, tr_y; fixed_t gxt, gyt; fixed_t tx, tz; - fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! + fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! INT32 x1, x2; @@ -1057,6 +1068,9 @@ static void R_ProjectSprite(mobj_t *thing) angle_t ang; fixed_t iscale; + fixed_t scalestep; // toast '16 + fixed_t offset, offset2; + boolean papersprite = (thing->frame & FF_PAPERSPRITE); //SoM: 3/17/2000 fixed_t gz, gzt; @@ -1064,6 +1078,8 @@ static void R_ProjectSprite(mobj_t *thing) INT32 light = 0; fixed_t this_scale = thing->scale; + fixed_t ang_scale = FRACUNIT; + // transform the origin point tr_x = thing->x - viewx; tr_y = thing->y - viewy; @@ -1074,7 +1090,7 @@ static void R_ProjectSprite(mobj_t *thing) tz = gxt-gyt; // thing is behind view plane? - if (tz < FixedMul(MINZ, this_scale)) + if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; gxt = -FixedMul(tr_x, viewsin); @@ -1087,7 +1103,7 @@ static void R_ProjectSprite(mobj_t *thing) // aspect ratio stuff xscale = FixedDiv(projection, tz); - yscale = FixedDiv(projectiony, tz); + sortscale = FixedDiv(projectiony, tz); // decide which patch to use for sprite relative to player #ifdef RANGECHECK @@ -1129,10 +1145,17 @@ static void R_ProjectSprite(mobj_t *thing) I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); #endif + if (sprframe->rotate != SRF_SINGLE || papersprite) + { + ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + if (papersprite) + ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); + } + if (sprframe->rotate) { // choose a different rotation based on player view - ang = R_PointToAngle (thing->x, thing->y); + //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]; @@ -1153,22 +1176,77 @@ static void R_ProjectSprite(mobj_t *thing) // calculate edges of the shape if (flip) - tx -= FixedMul(spritecachedinfo[lump].width-spritecachedinfo[lump].offset, this_scale); + offset = spritecachedinfo[lump].offset - spritecachedinfo[lump].width; else - tx -= FixedMul(spritecachedinfo[lump].offset, this_scale); + offset = -spritecachedinfo[lump].offset; + offset = FixedMul(offset, this_scale); + tx += FixedMul(offset, ang_scale); x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; // off the right side? if (x1 > viewwidth) return; - tx += FixedMul(spritecachedinfo[lump].width, this_scale); + offset2 = FixedMul(spritecachedinfo[lump].width, this_scale); + tx += FixedMul(offset2, ang_scale); x2 = ((centerxfrac + FixedMul (tx,xscale)) >>FRACBITS) - 1; // off the left side if (x2 < 0) return; + if (papersprite) + { + fixed_t yscale2, cosmul, sinmul, tz2; + INT32 range; + + if (ang >= ANGLE_180) + { + offset *= -1; + offset2 *= -1; + } + + cosmul = FINECOSINE(thing->angle>>ANGLETOFINESHIFT); + sinmul = FINESINE(thing->angle>>ANGLETOFINESHIFT); + + tr_x += FixedMul(offset, cosmul); + tr_y += FixedMul(offset, sinmul); + gxt = FixedMul(tr_x, viewcos); + gyt = -FixedMul(tr_y, viewsin); + tz = gxt-gyt; + yscale = FixedDiv(projectiony, tz); + if (yscale < 64) return; // Fix some funky visuals + + tr_x += FixedMul(offset2, cosmul); + tr_y += FixedMul(offset2, sinmul); + gxt = FixedMul(tr_x, viewcos); + gyt = -FixedMul(tr_y, viewsin); + tz2 = gxt-gyt; + yscale2 = FixedDiv(projectiony, tz2); + if (yscale2 < 64) return; // ditto + + if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier + return; + + if (x2 > x1) + range = (x2 - x1); + else + range = 1; + + scalestep = (yscale2 - yscale)/range; + + // The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2? + // sortscale = max(yscale, yscale2); + // sortscale = min(yscale, yscale2); + } + else + { + scalestep = 0; + yscale = sortscale; + } + + xscale = FixedMul(xscale, ang_scale); + // PORTAL SPRITE CLIPPING if (portalrender) { @@ -1250,6 +1328,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->heightsec = heightsec; //SoM: 3/17/2000 vis->mobjflags = thing->flags; vis->scale = yscale; //<sortscale = sortscale; vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15 vis->gx = thing->x; vis->gy = thing->y; @@ -1259,6 +1338,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->pz = thing->z; vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; + vis->scalestep = scalestep; vis->mobj = thing; // Easy access! Tails 06-07-2002 @@ -1276,8 +1356,8 @@ static void R_ProjectSprite(mobj_t *thing) vis->xscale = xscale; //SoM: 4/17/2000 vis->sector = thing->subsector->sector; - vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, yscale))>>FRACBITS); - vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, yscale))>>FRACBITS); + vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS); + vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS); vis->cut = SC_NONE; if (thing->subsector->sector->numlights) vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap; @@ -1298,7 +1378,10 @@ static void R_ProjectSprite(mobj_t *thing) } if (vis->x1 > x1) + { vis->startfrac += FixedDiv(vis->xiscale, this_scale)*(vis->x1-x1); + vis->scale += scalestep*(vis->x1 - x1); + } //Fab: lumppat is the lump number of the patch to use, this is different // than lumpid for sprites-in-pwad : the graphics are patched @@ -1457,7 +1540,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // store information in a vissprite vis = R_NewVisSprite(); - vis->scale = yscale; //<scale = vis->sortscale = yscale; //<dispoffset = 0; // Monster Iestyn: 23/11/15 vis->gx = thing->x; vis->gy = thing->y; @@ -1467,6 +1550,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->pz = thing->z; vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; + vis->scalestep = 0; vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; @@ -1645,14 +1729,14 @@ void R_SortVisSprites(void) bestscale = bestdispoffset = INT32_MAX; for (ds = unsorted.next; ds != &unsorted; ds = ds->next) { - if (ds->scale < bestscale) + if (ds->sortscale < bestscale) { - bestscale = ds->scale; + bestscale = ds->sortscale; bestdispoffset = ds->dispoffset; best = ds; } // order visprites of same scale by dispoffset, smallest first - else if (ds->scale == bestscale && ds->dispoffset < bestdispoffset) + else if (ds->sortscale == bestscale && ds->dispoffset < bestdispoffset) { bestdispoffset = ds->dispoffset; best = ds; @@ -1814,7 +1898,7 @@ static void R_CreateDrawNodes(void) for (i = x1; i <= x2; i++) { - if (r2->seg->frontscale[i] > rover->scale) + if (r2->seg->frontscale[i] > rover->sortscale) break; } if (i > x2) @@ -1833,10 +1917,10 @@ static void R_CreateDrawNodes(void) continue; scale = r2->thickseg->scale1 > r2->thickseg->scale2 ? r2->thickseg->scale1 : r2->thickseg->scale2; - if (scale <= rover->scale) + if (scale <= rover->sortscale) continue; scale = r2->thickseg->scale1 + (r2->thickseg->scalestep * (sintersect - r2->thickseg->x1)); - if (scale <= rover->scale) + if (scale <= rover->sortscale) continue; #ifdef ESLOPE @@ -1886,11 +1970,11 @@ static void R_CreateDrawNodes(void) continue; scale = r2->seg->scale1 > r2->seg->scale2 ? r2->seg->scale1 : r2->seg->scale2; - if (scale <= rover->scale) + if (scale <= rover->sortscale) continue; scale = r2->seg->scale1 + (r2->seg->scalestep * (sintersect - r2->seg->x1)); - if (rover->scale < scale) + if (rover->sortscale < scale) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; @@ -1906,8 +1990,8 @@ static void R_CreateDrawNodes(void) if (r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt) continue; - if (r2->sprite->scale > rover->scale - || (r2->sprite->scale == rover->scale && r2->sprite->dispoffset > rover->dispoffset)) + if (r2->sprite->sortscale > rover->sortscale + || (r2->sprite->sortscale == rover->sortscale && r2->sprite->dispoffset > rover->dispoffset)) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; @@ -2060,8 +2144,8 @@ void R_ClipSprites(void) scale = ds->scale2; } - if (scale < spr->scale || - (lowscale < spr->scale && + if (scale < spr->sortscale || + (lowscale < spr->sortscale && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) { // masked mid texture? @@ -2112,7 +2196,7 @@ void R_ClipSprites(void) fixed_t mh, h; INT32 phs = viewplayer->mo->subsector->sector->heightsec; if ((mh = sectors[spr->heightsec].floorheight) > spr->gz && - (h = centeryfrac - FixedMul(mh -= viewz, spr->scale)) >= 0 && + (h = centeryfrac - FixedMul(mh -= viewz, spr->sortscale)) >= 0 && (h >>= FRACBITS) < viewheight) { if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight)) @@ -2130,7 +2214,7 @@ void R_ClipSprites(void) } if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt && - (h = centeryfrac - FixedMul(mh-viewz, spr->scale)) >= 0 && + (h = centeryfrac - FixedMul(mh-viewz, spr->sortscale)) >= 0 && (h >>= FRACBITS) < viewheight) { if (phs != -1 && viewz >= sectors[phs].ceilingheight) diff --git a/src/r_things.h b/src/r_things.h index 483db7e99..9a4ba1999 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -131,7 +131,8 @@ typedef struct vissprite_s fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors fixed_t startfrac; // horizontal position of x1 - fixed_t scale; + fixed_t scale, sortscale; // sortscale only differs from scale for flat sprites + fixed_t scalestep; // only for flat sprites, 0 otherwise fixed_t xiscale; // negative if flipped fixed_t texturemid; From e42885a23c971c4bc8e38b4a87c522fd424e55a3 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 22 Aug 2016 23:01:36 +0100 Subject: [PATCH 006/122] Forgot to do this. --- 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 a7f3fa41d..0d85a4631 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1203,7 +1203,7 @@ static void R_ProjectSprite(mobj_t *thing) else { // choose a different rotation based on player view - ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + //ang = R_PointToAngle (thing->x, thing->y) - thing->angle; if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right rot = 6; // F7 slot From e8d65f0b5481643b77a35551cd24e8c0cb821759 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 22 Aug 2016 23:39:27 +0100 Subject: [PATCH 007/122] GCC 4.6 and lower fix --- 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 0d85a4631..55866759d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1107,7 +1107,7 @@ static void R_ProjectSprite(mobj_t *thing) vissprite_t *vis; - angle_t ang; + angle_t ang = 0; // gcc 4.6 and lower fix fixed_t iscale; fixed_t scalestep; // toast '16 fixed_t offset, offset2; From 14ff3906e138aa459e73600e3be916b9d5b167b9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 23 Aug 2016 00:45:26 +0100 Subject: [PATCH 008/122] Woops, forgot to port collision as well. --- src/p_map.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/p_map.c b/src/p_map.c index 1f2d903e8..a95ed6b8d 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -469,6 +469,73 @@ static boolean PIT_CheckThing(mobj_t *thing) if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) return true; // didn't hit it + if (thing->flags & MF_PAPERCOLLISION) // CAUTION! Very easy to get stuck inside MF_SOLID objects. Giving the player MF_PAPERCOLLISION is a bad idea unless you know what you're doing. + { + fixed_t cosradius, sinradius; + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef + cosradius = FixedMul(thing->radius, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(thing->radius, FINESINE(thing->angle>>ANGLETOFINESHIFT)); + + v1.x = thing->x - cosradius; + v1.y = thing->y - sinradius; + v2.x = thing->x + cosradius; + v2.y = thing->y + sinradius; + + junk.v1 = &v1; + junk.v2 = &v2; + junk.dx = v2.x - v1.x; + junk.dy = v2.y - v1.y; + + if (tmthing->flags & MF_PAPERCOLLISION) // more strenuous checking to prevent clipping issues + { + INT32 check1, check2, check3, check4; + cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); + check1 = P_PointOnLineSide(tmx - cosradius, tmy - sinradius, &junk); + check2 = P_PointOnLineSide(tmx + cosradius, tmy + sinradius, &junk); + check3 = P_PointOnLineSide(tmx + tmthing->momx - cosradius, tmy + tmthing->momy - sinradius, &junk); + check4 = P_PointOnLineSide(tmx + tmthing->momx + cosradius, tmy + tmthing->momy + sinradius, &junk); + if ((check1 == check2) && (check2 == check3) && (check3 == check4)) + return true; // the line doesn't cross between collider's start or end + } + else + { + if ((P_PointOnLineSide(tmx - tmthing->radius, tmy - tmthing->radius, &junk) + == P_PointOnLineSide(tmx + tmthing->radius, tmy + tmthing->radius, &junk)) + && (P_PointOnLineSide(tmx + tmthing->radius, tmy - tmthing->radius, &junk) + == P_PointOnLineSide(tmx - tmthing->radius, tmy + tmthing->radius, &junk))) + return true; // the line doesn't cross between either pair of opposite corners + } + } + else if (tmthing->flags & MF_PAPERCOLLISION) + { + fixed_t cosradius, sinradius; + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef + + cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); + + v1.x = tmx - cosradius; + v1.y = tmy - sinradius; + v2.x = tmx + cosradius; + v2.y = tmy + sinradius; + + junk.v1 = &v1; + junk.v2 = &v2; + junk.dx = v2.x - v1.x; + junk.dy = v2.y - v1.y; + + // no need to check whether thing has MF_PAPERCOLLISION, since checked above + + if ((P_PointOnLineSide(thing->x - thing->radius, thing->y - thing->radius, &junk) + == P_PointOnLineSide(thing->x + thing->radius, thing->y + thing->radius, &junk)) + && (P_PointOnLineSide(thing->x + thing->radius, thing->y - thing->radius, &junk) + == P_PointOnLineSide(thing->x - thing->radius, thing->y + thing->radius, &junk))) + return true; // the line doesn't cross between either pair of opposite corners + } + #ifdef HAVE_BLUA { UINT8 shouldCollide = LUAh_MobjCollide(thing, tmthing); // checks hook for thing's type @@ -1123,6 +1190,17 @@ static boolean PIT_CheckLine(line_t *ld) if (P_BoxOnLineSide(tmbbox, ld) != -1) return true; +if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag. + { + fixed_t cosradius, sinradius; + cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); + if (P_PointOnLineSide(tmx - cosradius, tmy - sinradius, ld) + == P_PointOnLineSide(tmx + cosradius, tmy + sinradius, ld)) + return true; // the line doesn't cross between collider's start or end + + } + // A line has been hit // The moving thing's destination position will cross From a587231aa4f85dcade73fd5ccdb2dd8c5429c947 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 26 Aug 2016 22:00:53 +0100 Subject: [PATCH 009/122] Crash fix ported from internal. --- 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 55866759d..8e41fb447 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -143,7 +143,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch 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 + for (r = 0; r < 4; r++) // Thanks to R_PrecacheLevel, we can't leave sprtemp[*].lumppat[*] == LUMPERROR... so we load into the front/back angle too. { sprtemp[frame].lumppat[r + rightfactor] = lumppat; sprtemp[frame].lumpid[r + rightfactor] = lumpid; From 39d4f22660b6957e3e70a483bf7624edcbf90842 Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 13 Dec 2016 21:02:23 +0000 Subject: [PATCH 010/122] Flat sprites for OGL --- src/hardware/hw_glob.h | 1 + src/hardware/hw_main.c | 77 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 94eef1d3e..5d1a81d4f 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -78,6 +78,7 @@ typedef struct gr_vissprite_s //Hurdler: 25/04/2000: now support colormap in hardware mode UINT8 *colormap; INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing + float z1, z2; } gr_vissprite_t; // -------- diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 70520af8d..98ab6cab2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4223,6 +4223,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES); + //const boolean papersprite = (spr->mobj && (spr->mobj->frame & FF_PAPERSPRITE)); if (spr->mobj) this_scale = FIXED_TO_FLOAT(spr->mobj->scale); if (hires) @@ -4266,7 +4267,28 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // make a wall polygon (with 2 triangles), using the floor/ceiling heights, // and the 2d map coords of start/end vertices - wallVerts[0].z = wallVerts[1].z = wallVerts[2].z = wallVerts[3].z = spr->tz; + wallVerts[0].z = wallVerts[3].z = spr->z1; + wallVerts[2].z = wallVerts[1].z = spr->z2; + + // transform + wv = wallVerts; + + /*if (spr->mobj->frame & FF_PAPERSPRITE) + { + float mobjanglecos, mobjanglesin; + mobjanglesin = FIXED_TO_FLOAT(FINESINE((spr->mobj->angle-dup_viewangle+ANGLE_90)>>ANGLETOFINESHIFT)); + mobjanglecos = FIXED_TO_FLOAT(FINECOSINE((spr->mobj->angle-dup_viewangle+ANGLE_90)>>ANGLETOFINESHIFT)); + for (i = 0; i < 4; i++,wv++) + { + // x = (x * anglecos) + (z * anglesin) + // z = (x * anglesin) - (z * anglecos) + // instead of doing the z part we just add spr->tz afterwards because they are all the same + // value right now + tr_x = wv->x-spr->x2+(spr->x2-spr->x1)/2; + //wv->x = (tr_x * mobjanglecos) + (0) + (spr->x1+(spr->x2-spr->x1)/2); + wv->z = (tr_x * mobjanglesin) - (0) + (spr->tz); + } + }*/ // transform wv = wallVerts; @@ -5042,6 +5064,10 @@ static void HWR_ProjectSprite(mobj_t *thing) UINT8 flip; angle_t ang; INT32 heightsec, phs; + const boolean papersprite = (thing->frame & FF_PAPERSPRITE); + float offset; + float ang_scale = 1.0f, ang_scalez = 0.0f; + float z1, z2; if (!thing) return; @@ -5056,7 +5082,7 @@ static void HWR_ProjectSprite(mobj_t *thing) tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); // thing is behind view plane? - if (tz < ZCLIP_PLANE && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear + if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear return; tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos); @@ -5094,6 +5120,16 @@ static void HWR_ProjectSprite(mobj_t *thing) I_Error("sprframes NULL for sprite %d\n", thing->sprite); #endif + if (sprframe->rotate != SRF_SINGLE || papersprite) + { + ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + if (papersprite) + { + ang_scale = FIXED_TO_FLOAT(FINESINE(ang>>ANGLETOFINESHIFT)); + ang_scalez = FIXED_TO_FLOAT(FINECOSINE(ang>>ANGLETOFINESHIFT)); + } + } + if (sprframe->rotate == SRF_SINGLE) { // use single rotation for all views @@ -5104,8 +5140,6 @@ static void HWR_ProjectSprite(mobj_t *thing) 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 @@ -5123,9 +5157,20 @@ static void HWR_ProjectSprite(mobj_t *thing) // calculate edges of the shape if (flip) - tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale; + offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale; else - tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale; + offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale; + + if (ang_scale < 0) + { + z1 = tz + offset * ang_scalez; + tx += offset * ang_scale; + } + else + { + z1 = tz - offset * ang_scalez; + tx -= offset * ang_scale; + } // project x x1 = gr_windowcenterx + (tx * gr_centerx / tz); @@ -5136,9 +5181,25 @@ static void HWR_ProjectSprite(mobj_t *thing) x1 = tx; - tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale; + offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale; + if (ang_scale < 0) + { + z2 = z1 - offset * ang_scalez; + tx -= offset * ang_scale; + } + else + { + z2 = z1 + offset * ang_scalez; + tx += offset * ang_scale; + } + if (papersprite && max(z1, z1) < ZCLIP_PLANE) + return; + x2 = gr_windowcenterx + (tx * gr_centerx / tz); + + + if (thing->eflags & MFE_VERTICALFLIP) { gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale; @@ -5185,6 +5246,8 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->patchlumpnum = sprframe->lumppat[rot]; vis->flip = flip; vis->mobj = thing; + vis->z1 = z1; + vis->z2 = z2; //Hurdler: 25/04/2000: now support colormap in hardware mode if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" From 4fb2a188465bc9ef5fc5450b55b3cdcc8b49215d Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 13 Dec 2016 21:18:05 +0000 Subject: [PATCH 011/122] Fix a one character bug with clipping --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 98ab6cab2..d0f67b876 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5192,7 +5192,7 @@ static void HWR_ProjectSprite(mobj_t *thing) z2 = z1 + offset * ang_scalez; tx += offset * ang_scale; } - if (papersprite && max(z1, z1) < ZCLIP_PLANE) + if (papersprite && max(z1, z2) < ZCLIP_PLANE) return; x2 = gr_windowcenterx + (tx * gr_centerx / tz); From 2e72539df24e16bc7e3d0007876c445a91dd1025 Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 13 Dec 2016 21:22:40 +0000 Subject: [PATCH 012/122] Remove accidental leftovers Accidentally left a comment and stuff in there from previous attempts --- src/hardware/hw_main.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d0f67b876..d4255ba42 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4273,26 +4273,6 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // transform wv = wallVerts; - /*if (spr->mobj->frame & FF_PAPERSPRITE) - { - float mobjanglecos, mobjanglesin; - mobjanglesin = FIXED_TO_FLOAT(FINESINE((spr->mobj->angle-dup_viewangle+ANGLE_90)>>ANGLETOFINESHIFT)); - mobjanglecos = FIXED_TO_FLOAT(FINECOSINE((spr->mobj->angle-dup_viewangle+ANGLE_90)>>ANGLETOFINESHIFT)); - for (i = 0; i < 4; i++,wv++) - { - // x = (x * anglecos) + (z * anglesin) - // z = (x * anglesin) - (z * anglecos) - // instead of doing the z part we just add spr->tz afterwards because they are all the same - // value right now - tr_x = wv->x-spr->x2+(spr->x2-spr->x1)/2; - //wv->x = (tr_x * mobjanglecos) + (0) + (spr->x1+(spr->x2-spr->x1)/2); - wv->z = (tr_x * mobjanglesin) - (0) + (spr->tz); - } - }*/ - - // transform - wv = wallVerts; - for (i = 0; i < 4; i++,wv++) { //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -5197,9 +5177,6 @@ static void HWR_ProjectSprite(mobj_t *thing) x2 = gr_windowcenterx + (tx * gr_centerx / tz); - - - if (thing->eflags & MFE_VERTICALFLIP) { gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale; From 8290ae9fd4c9d86bee6de503dd5158a34fc389c4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 13 May 2017 12:49:30 +0100 Subject: [PATCH 013/122] Fix paper sprites apparently "turning" around sometimes when you turn the camera, when they're supposed to be still (sawb.wad for instance) I cleaned up some of Sryder's changes a little too I guess --- src/hardware/hw_main.c | 47 ++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 386e997de..a40a2827d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5122,15 +5122,26 @@ static void HWR_ProjectSprite(mobj_t *thing) I_Error("sprframes NULL for sprite %d\n", thing->sprite); #endif - if (sprframe->rotate != SRF_SINGLE || papersprite) + if (papersprite) { - ang = R_PointToAngle (thing->x, thing->y) - thing->angle; - if (papersprite) + // Use the actual view angle, rather than the angle formed + // between the view point and the thing + // this makes sure paper sprites always appear at the right angle! + // Note: DO NOT do this in software mode version, it actually + // makes papersprites look WORSE there (I know, I've tried) + // Monster Iestyn - 13/05/17 + ang = dup_viewangle - thing->angle; + ang_scale = FIXED_TO_FLOAT(FINESINE(ang>>ANGLETOFINESHIFT)); + ang_scalez = FIXED_TO_FLOAT(FINECOSINE(ang>>ANGLETOFINESHIFT)); + + if (ang_scale < 0) { - ang_scale = FIXED_TO_FLOAT(FINESINE(ang>>ANGLETOFINESHIFT)); - ang_scalez = FIXED_TO_FLOAT(FINECOSINE(ang>>ANGLETOFINESHIFT)); + ang_scale = -ang_scale; + ang_scalez = -ang_scalez; } } + else if (sprframe->rotate != SRF_SINGLE) + ang = R_PointToAngle (thing->x, thing->y) - thing->angle; if (sprframe->rotate == SRF_SINGLE) { @@ -5163,16 +5174,8 @@ static void HWR_ProjectSprite(mobj_t *thing) else offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale; - if (ang_scale < 0) - { - z1 = tz + offset * ang_scalez; - tx += offset * ang_scale; - } - else - { - z1 = tz - offset * ang_scalez; - tx -= offset * ang_scale; - } + z1 = tz - (offset * ang_scalez); + tx -= offset * ang_scale; // project x x1 = gr_windowcenterx + (tx * gr_centerx / tz); @@ -5184,16 +5187,10 @@ static void HWR_ProjectSprite(mobj_t *thing) x1 = tx; offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale; - if (ang_scale < 0) - { - z2 = z1 - offset * ang_scalez; - tx -= offset * ang_scale; - } - else - { - z2 = z1 + offset * ang_scalez; - tx += offset * ang_scale; - } + + z2 = z1 + (offset * ang_scalez); + tx += offset * ang_scale; + if (papersprite && max(z1, z2) < ZCLIP_PLANE) return; From 6877930ed9f1b52c76117c64a9215ea0a51d49c9 Mon Sep 17 00:00:00 2001 From: Sryder13 Date: Fri, 8 Sep 2017 00:56:58 +0100 Subject: [PATCH 014/122] Go through and draw MD2s and sprites at the same time so they are sorted from each other (mostly) correctly --- src/hardware/hw_main.c | 67 ++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 05391f4d0..f38e67ce6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4914,7 +4914,8 @@ static void HWR_CreateDrawNodes(void) // Draw all vissprites // -------------------------------------------------------------------------- #ifdef SORTING -static void HWR_DrawSprites(void) +// added the stransform so they can be switched as drawing happenes so MD2s and sprites are sorted correctly with each other +static void HWR_DrawSprites(FTransform *stransform) { if (gr_visspritecount > 0) { @@ -4933,45 +4934,33 @@ static void HWR_DrawSprites(void) if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { if (!cv_grmd2.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) + { + HWD.pfnSetTransform(stransform); HWR_DrawSprite(spr); - } - else if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) - HWR_DrawSprite(spr); - } - } -} -#endif -// -------------------------------------------------------------------------- -// Draw all MD2 -// -------------------------------------------------------------------------- -static void HWR_DrawMD2S(void) -{ - if (gr_visspritecount > 0) - { - gr_vissprite_t *spr; - - // draw all MD2 back to front - for (spr = gr_vsprsortedhead.next; - spr != &gr_vsprsortedhead; - spr = spr->next) - { -#ifdef HWPRECIP - if (!spr->precip) - { -#endif - if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - { - if (md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == false && md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale > 0.0f) + } + else + { + HWD.pfnSetTransform(&atransform); HWR_DrawMD2(spr); + } + } + else + { + if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + { + HWD.pfnSetTransform(stransform); + HWR_DrawSprite(spr); + } + else + { + HWD.pfnSetTransform(&atransform); + HWR_DrawMD2(spr); + } } - else if (md2_models[spr->mobj->sprite].notfound == false && md2_models[spr->mobj->sprite].scale > 0.0f) - HWR_DrawMD2(spr); -#ifdef HWPRECIP - } -#endif } } } +#endif // -------------------------------------------------------------------------- // HWR_AddSprites @@ -5644,12 +5633,9 @@ if (0) #ifdef SORTING HWR_SortVisSprites(); #endif - HWR_DrawMD2S(); - // Draw the sprites with trivial transform - HWD.pfnSetTransform(&stransform); #ifdef SORTING - HWR_DrawSprites(); + HWR_DrawSprites(&stransform); #endif #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? @@ -5874,12 +5860,9 @@ if (0) #ifdef SORTING HWR_SortVisSprites(); #endif - HWR_DrawMD2S(); - // Draw the sprites with trivial transform - HWD.pfnSetTransform(&stransform); #ifdef SORTING - HWR_DrawSprites(); + HWR_DrawSprites(&stransform); #endif #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? From db99537a6b67f2942c08680787a7215844770f87 Mon Sep 17 00:00:00 2001 From: Sryder13 Date: Sat, 9 Sep 2017 00:41:11 +0100 Subject: [PATCH 015/122] Various Transparent Texture Fixes Draw Textures and Flats that have holes in them like a solid polygon so they use the depth buffer and don't need to be sorted Disable all linear filtering on textures and flats that have holes in them, the linear filtering introduces translucency into the textures where the edges are. Leaving them with either a black border, or causing pixels behind the slightly translucent areas to not be drawn. Doesn't apply to sprites and the HUD as they are always already sorted properly. Make the Alpha Testing more strict on non-translucent blend modes. This makes it so any transparency below 0.5 is discarded instead. Would make anything that is blended and has holes in it look slightly better, only the HUD and MD2s where the texture has holes are effected currently. Set TF_TRANSPARENT on flat texture flags when there are holes in the texture. Minor fix to make sure MD2s always set the right blend mode --- src/hardware/hw_main.c | 30 +++++------------ src/hardware/r_opengl/r_opengl.c | 57 ++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f38e67ce6..971789122 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1072,7 +1072,6 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, /* SoM: split up and light walls according to the lightlist. This may also include leaving out parts of the wall that can't be seen */ - GLTexture_t * glTex; float realtop, realbot, top, bot; float pegt, pegb, pegmul; @@ -1238,11 +1237,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - glTex = HWR_GetTexture(texnum); + //glTex = HWR_GetTexture(texnum); if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); - else if (glTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); @@ -1298,11 +1295,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - glTex = HWR_GetTexture(texnum); + //glTex = HWR_GetTexture(texnum); if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); - else if (glTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); } @@ -2033,15 +2028,14 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } #endif - if (grTex->mipmap.flags & TF_TRANSPARENT) - blendmode = PF_Translucent; - if (gr_frontsector->numlights) { if (!(blendmode & PF_Masked)) HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_TRANSLUCENT); else + { HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTSOLIDS); + } } else if (!(blendmode & PF_Masked)) HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, blendmode, false, lightnum, colormap); @@ -2338,15 +2332,11 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { FBITFIELD blendmode = PF_Masked; - if (rover->flags & FF_TRANSLUCENT) + if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { blendmode = PF_Translucent; Surf.FlatColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; } - else if (grTex->mipmap.flags & TF_TRANSPARENT) - { - blendmode = PF_Environment; - } if (gr_frontsector->numlights) HWR_SplitWall(gr_frontsector, wallVerts, texnum, &Surf, rover->flags); @@ -2461,15 +2451,11 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { FBITFIELD blendmode = PF_Masked; - if (rover->flags & FF_TRANSLUCENT) + if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { blendmode = PF_Translucent; Surf.FlatColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; } - else if (grTex->mipmap.flags & TF_TRANSPARENT) - { - blendmode = PF_Environment; - } if (gr_backsector->numlights) HWR_SplitWall(gr_backsector, wallVerts, texnum, &Surf, rover->flags); @@ -3575,7 +3561,7 @@ static void HWR_Subsector(size_t num) alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } - else if (rover->flags & FF_TRANSLUCENT) // SoM: Flags are more efficient + else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) // SoM: Flags are more efficient { light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); #ifndef SORTING @@ -3638,7 +3624,7 @@ static void HWR_Subsector(size_t num) alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } - else if (rover->flags & FF_TRANSLUCENT) + else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); #ifndef SORTING diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index e6ff83e89..80df8afba 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1056,30 +1056,48 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) switch (PolyFlags & PF_Blending) { case PF_Translucent & PF_Blending: pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_NOTEQUAL, 0.0f); +#endif break; case PF_Masked & PF_Blending: // Hurdler: does that mean lighting is only made by alpha src? // it sounds ok, but not for polygonsmooth pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_GREATER, 0.5f); +#endif break; case PF_Additive & PF_Blending: #ifdef ATI_RAGE_PRO_COMPATIBILITY pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency #else pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest +#endif +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_NOTEQUAL, 0.0f); #endif break; case PF_Environment & PF_Blending: pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_NOTEQUAL, 0.0f); +#endif break; case PF_Substractive & PF_Blending: // good for shadow // not realy but what else ? pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_NOTEQUAL, 0.0f); +#endif break; default : // must be 0, otherwise it's an error // No blending pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_GREATER, 0.5f); +#endif break; } } @@ -1339,6 +1357,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) tex[w*j+i].s.green = 0; tex[w*j+i].s.blue = 0; tex[w*j+i].s.alpha = 0; + pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it } else { @@ -1409,8 +1428,22 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) tex_downloaded = pTexInfo->downloaded; pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues + if (pTexInfo->flags & TF_TRANSPARENT) + { +#ifdef KOS_GL_COMPATIBILITY + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NONE); +#else + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +#endif + } + else + { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + } #ifdef KOS_GL_COMPATIBILITY pglTexImage2D(GL_TEXTURE_2D, 0, GL_ARGB4444, w, h, 0, GL_ARGB4444, GL_UNSIGNED_BYTE, ptex); @@ -1865,12 +1898,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration ambient[1] = 0.75f; if (ambient[2] > 0.75f) ambient[2] = 0.75f; - - if (color[3] < 255) - { - pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - pglDepthMask(GL_FALSE); - } } pglEnable(GL_CULL_FACE); @@ -1897,10 +1924,12 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); #endif + if (color[3] < 255) + SetBlend(PF_Translucent|PF_Modulated|PF_Clip); + else + SetBlend(PF_Masked|PF_Modulated|PF_Occlude|PF_Clip); } - DrawPolygon(NULL, NULL, 0, PF_Masked|PF_Modulated|PF_Occlude|PF_Clip); - pglPushMatrix(); // should be the same as glLoadIdentity //Hurdler: now it seems to work pglTranslatef(pos->x, pos->z, pos->y); @@ -1908,14 +1937,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration scaley = -scaley; pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f); - //pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency - - // Remove depth mask when the model is transparent so it doesn't cut thorugh sprites // SRB2CBTODO: For all stuff too?! - if (color && color[3] < 255) - { - pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency - pglDepthMask(GL_FALSE); - } val = *gl_cmd_buffer++; From f3a605de6b12a947a9819561f711ee637107e46d Mon Sep 17 00:00:00 2001 From: Sryder13 Date: Fri, 15 Sep 2017 18:03:06 +0100 Subject: [PATCH 016/122] I need to stop leaving things commented out that are going --- src/hardware/hw_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 971789122..3a2b0f0ed 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1237,7 +1237,6 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - //glTex = HWR_GetTexture(texnum); if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); else @@ -1295,7 +1294,6 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - //glTex = HWR_GetTexture(texnum); if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); else From e63c1d15d87bd4fbbb583a88145bd840c9a17972 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 17 Nov 2017 23:02:34 +0000 Subject: [PATCH 017/122] * Show an emerald token box on the tally screen. * Change the horizontal spacing of the emeralds on the special stage tally screen. * (unrelated) Fix a reference to srb2.srb instead of the now-correct srb2.pk3. --- src/d_main.c | 2 +- src/hu_stuff.c | 70 ++++++++++++++++++++++++++++---------------------- src/hu_stuff.h | 3 +-- src/m_menu.c | 2 +- src/st_stuff.c | 14 +++++----- src/y_inter.c | 33 ++++++++++++++++-------- 6 files changed, 71 insertions(+), 53 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 45f9d6763..b3039ee83 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -832,7 +832,7 @@ static void IdentifyVersion(void) else if (srb2wad1 != NULL && FIL_ReadFileOK(srb2wad1)) D_AddFile(srb2wad1); else - I_Error("SRB2.SRB/SRB2.WAD not found! Expected in %s, ss files: %s and %s\n", srb2waddir, srb2wad1, srb2wad2); + I_Error("SRB2.PK3/SRB2.WAD not found! Expected in %s, ss files: %s and %s\n", srb2waddir, srb2wad1, srb2wad2); if (srb2wad1) free(srb2wad1); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 28b20f61e..ff79bd1e3 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -89,8 +89,7 @@ patch_t *tallinfin; // coop hud //------------------------------------------- -patch_t *emeraldpics[7]; -patch_t *tinyemeraldpics[7]; +patch_t *emeraldpics[3][7]; // 0 = normal, 1 = tiny, 2 = coinbox static patch_t *emblemicon; patch_t *tokenicon; static patch_t *exiticon; @@ -250,20 +249,29 @@ void HU_LoadGraphics(void) tokenicon = W_CachePatchName("TOKNICON", PU_HUDGFX); exiticon = W_CachePatchName("EXITICON", PU_HUDGFX); - emeraldpics[0] = W_CachePatchName("CHAOS1", PU_HUDGFX); - emeraldpics[1] = W_CachePatchName("CHAOS2", PU_HUDGFX); - emeraldpics[2] = W_CachePatchName("CHAOS3", PU_HUDGFX); - emeraldpics[3] = W_CachePatchName("CHAOS4", PU_HUDGFX); - emeraldpics[4] = W_CachePatchName("CHAOS5", PU_HUDGFX); - emeraldpics[5] = W_CachePatchName("CHAOS6", PU_HUDGFX); - emeraldpics[6] = W_CachePatchName("CHAOS7", PU_HUDGFX); - tinyemeraldpics[0] = W_CachePatchName("TEMER1", PU_HUDGFX); - tinyemeraldpics[1] = W_CachePatchName("TEMER2", PU_HUDGFX); - tinyemeraldpics[2] = W_CachePatchName("TEMER3", PU_HUDGFX); - tinyemeraldpics[3] = W_CachePatchName("TEMER4", PU_HUDGFX); - tinyemeraldpics[4] = W_CachePatchName("TEMER5", PU_HUDGFX); - tinyemeraldpics[5] = W_CachePatchName("TEMER6", PU_HUDGFX); - tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX); + emeraldpics[0][0] = W_CachePatchName("CHAOS1", PU_HUDGFX); + emeraldpics[0][1] = W_CachePatchName("CHAOS2", PU_HUDGFX); + emeraldpics[0][2] = W_CachePatchName("CHAOS3", PU_HUDGFX); + emeraldpics[0][3] = W_CachePatchName("CHAOS4", PU_HUDGFX); + emeraldpics[0][4] = W_CachePatchName("CHAOS5", PU_HUDGFX); + emeraldpics[0][5] = W_CachePatchName("CHAOS6", PU_HUDGFX); + emeraldpics[0][6] = W_CachePatchName("CHAOS7", PU_HUDGFX); + + emeraldpics[1][0] = W_CachePatchName("TEMER1", PU_HUDGFX); + emeraldpics[1][1] = W_CachePatchName("TEMER2", PU_HUDGFX); + emeraldpics[1][2] = W_CachePatchName("TEMER3", PU_HUDGFX); + emeraldpics[1][3] = W_CachePatchName("TEMER4", PU_HUDGFX); + emeraldpics[1][4] = W_CachePatchName("TEMER5", PU_HUDGFX); + emeraldpics[1][5] = W_CachePatchName("TEMER6", PU_HUDGFX); + emeraldpics[2][6] = W_CachePatchName("TEMER7", PU_HUDGFX); + + emeraldpics[2][0] = W_CachePatchName("EMBOX1", PU_HUDGFX); + emeraldpics[2][1] = W_CachePatchName("EMBOX2", PU_HUDGFX); + emeraldpics[2][2] = W_CachePatchName("EMBOX3", PU_HUDGFX); + emeraldpics[2][3] = W_CachePatchName("EMBOX4", PU_HUDGFX); + emeraldpics[2][4] = W_CachePatchName("EMBOX5", PU_HUDGFX); + emeraldpics[2][5] = W_CachePatchName("EMBOX6", PU_HUDGFX); + emeraldpics[2][6] = W_CachePatchName("EMBOX7", PU_HUDGFX); } // Initialise Heads up @@ -1466,25 +1474,25 @@ void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds) { //Draw the emeralds, in the CORRECT order, using tiny emerald sprites. if (pemeralds & EMERALD1) - V_DrawSmallScaledPatch(x , y-6, 0, tinyemeraldpics[0]); + V_DrawSmallScaledPatch(x , y-6, 0, emeraldpics[1][0]); if (pemeralds & EMERALD2) - V_DrawSmallScaledPatch(x+4, y-3, 0, tinyemeraldpics[1]); + V_DrawSmallScaledPatch(x+4, y-3, 0, emeraldpics[1][1]); if (pemeralds & EMERALD3) - V_DrawSmallScaledPatch(x+4, y+3, 0, tinyemeraldpics[2]); + V_DrawSmallScaledPatch(x+4, y+3, 0, emeraldpics[1][2]); if (pemeralds & EMERALD4) - V_DrawSmallScaledPatch(x , y+6, 0, tinyemeraldpics[3]); + V_DrawSmallScaledPatch(x , y+6, 0, emeraldpics[1][3]); if (pemeralds & EMERALD5) - V_DrawSmallScaledPatch(x-4, y+3, 0, tinyemeraldpics[4]); + V_DrawSmallScaledPatch(x-4, y+3, 0, emeraldpics[1][4]); if (pemeralds & EMERALD6) - V_DrawSmallScaledPatch(x-4, y-3, 0, tinyemeraldpics[5]); + V_DrawSmallScaledPatch(x-4, y-3, 0, emeraldpics[1][5]); if (pemeralds & EMERALD7) - V_DrawSmallScaledPatch(x, y, 0, tinyemeraldpics[6]); + V_DrawSmallScaledPatch(x, y, 0, emeraldpics[1][6]); } // @@ -1753,19 +1761,19 @@ static void HU_DrawCoopOverlay(void) #endif if (emeralds & EMERALD1) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)-32, 0, emeraldpics[0]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)-32, 0, emeraldpics[0][0]); if (emeralds & EMERALD2) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[1]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[0][1]); if (emeralds & EMERALD3) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[2]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[0][2]); if (emeralds & EMERALD4) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)+32, 0, emeraldpics[3]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)+32, 0, emeraldpics[0][3]); if (emeralds & EMERALD5) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[4]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[0][4]); if (emeralds & EMERALD6) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[5]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[0][5]); if (emeralds & EMERALD7) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3) , 0, emeraldpics[6]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3) , 0, emeraldpics[0][6]); } static void HU_DrawNetplayCoopOverlay(void) @@ -1780,7 +1788,7 @@ static void HU_DrawNetplayCoopOverlay(void) for (i = 0; i < 7; ++i) { if (emeralds & (1 << i)) - V_DrawScaledPatch(20 + (i * 20), 6, 0, emeraldpics[i]); + V_DrawScaledPatch(20 + (i * 20), 6, 0, emeraldpics[0][i]); } } diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 2dbeb556d..fb1fa1817 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -63,8 +63,7 @@ extern patch_t *tallnum[10]; extern patch_t *nightsnum[10]; extern patch_t *lt_font[LT_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE]; -extern patch_t *emeraldpics[7]; -extern patch_t *tinyemeraldpics[7]; +extern patch_t *emeraldpics[3][7]; extern patch_t *rflagico; extern patch_t *bflagico; extern patch_t *rmatcico; diff --git a/src/m_menu.c b/src/m_menu.c index dedbd86f0..6979c73b5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6274,7 +6274,7 @@ static void M_DrawLoadGameData(void) for (j = 0; j < 7; ++j) { if (savegameinfo[savetodraw].numemeralds & (1 << j)) - V_DrawScaledPatch(workx, y, 0, tinyemeraldpics[j]); + V_DrawScaledPatch(workx, y, 0, emeraldpics[1][j]); workx += 10; } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 437b6758a..24f4e590b 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1699,33 +1699,33 @@ static void ST_drawMatchHUD(void) offset = 136; // Used for Y now if (stplyr->powers[pw_emeralds] & EMERALD1) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[0]); + V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][0]); offset += 8; if (stplyr->powers[pw_emeralds] & EMERALD2) - V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[1]); + V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][1]); if (stplyr->powers[pw_emeralds] & EMERALD6) - V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[5]); + V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][5]); offset += 16; if (stplyr->powers[pw_emeralds] & EMERALD3) - V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[2]); + V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][2]); if (stplyr->powers[pw_emeralds] & EMERALD5) - V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[4]); + V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][4]); offset += 8; if (stplyr->powers[pw_emeralds] & EMERALD4) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[3]); + V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][3]); offset -= 16; if (stplyr->powers[pw_emeralds] & EMERALD7) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[6]); + V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][6]); #ifdef HAVE_BLUA } diff --git a/src/y_inter.c b/src/y_inter.c index 8a93b3eab..9c4d684ac 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -176,12 +176,23 @@ static INT32 SCY(INT32 z) static void Y_IntermissionTokenDrawer(void) { - INT32 y; - INT32 offs = 0; + INT32 y, offs, lowy, calc; UINT32 tokencount; - INT32 lowy = BASEVIDHEIGHT - 32; - INT16 temp = SHORT(tokenicon->height)/2; - INT32 calc; + INT16 temp; + UINT8 em; + + offs = 0; + lowy = BASEVIDHEIGHT - 32 - 8; + temp = SHORT(tokenicon->height)/2; + + if (!(emeralds & EMERALD1)) em = 0; + else if (!(emeralds & EMERALD2)) em = 1; + else if (!(emeralds & EMERALD3)) em = 2; + else if (!(emeralds & EMERALD4)) em = 3; + else if (!(emeralds & EMERALD5)) em = 4; + else if (!(emeralds & EMERALD6)) em = 5; + else if (!(emeralds & EMERALD7)) em = 6; + else return; if (tallydonetic != -1) { @@ -190,7 +201,7 @@ static void Y_IntermissionTokenDrawer(void) offs = 8; } - V_DrawFill(32, lowy-1, 16, 1, 31); // slot + V_DrawSmallScaledPatch(32, lowy-1, 0, emeraldpics[2][em]); // coinbox y = (lowy + offs + 1) - (temp + (token + 1)*8); @@ -370,14 +381,14 @@ void Y_IntermissionDrawer(void) } // draw the emeralds - if (intertic & 1) + //if (intertic & 1) { - INT32 emeraldx = 80; + INT32 emeraldx = 152 - 3*28; for (i = 0; i < 7; ++i) { - if (emeralds & (1 << i)) - V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[i]); - emeraldx += 24; + if ((emeralds & (1 << i)) && ((intertic & 1) || i != (gamemap + 1 - sstage_start))) + V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[0][i]); + emeraldx += 28; } } From 3d4adaac0908e52bc5ad39c92f78c7b1e8e9d922 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 9 Dec 2017 18:48:25 +0000 Subject: [PATCH 018/122] my mistake --- src/hu_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index ff79bd1e3..7af7aa768 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -263,7 +263,7 @@ void HU_LoadGraphics(void) emeraldpics[1][3] = W_CachePatchName("TEMER4", PU_HUDGFX); emeraldpics[1][4] = W_CachePatchName("TEMER5", PU_HUDGFX); emeraldpics[1][5] = W_CachePatchName("TEMER6", PU_HUDGFX); - emeraldpics[2][6] = W_CachePatchName("TEMER7", PU_HUDGFX); + emeraldpics[1][6] = W_CachePatchName("TEMER7", PU_HUDGFX); emeraldpics[2][0] = W_CachePatchName("EMBOX1", PU_HUDGFX); emeraldpics[2][1] = W_CachePatchName("EMBOX2", PU_HUDGFX); From ce724a61385b860f47ca0636f4eeedc1c5d88e52 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 9 Dec 2017 23:08:12 +0000 Subject: [PATCH 019/122] * Make lives pic appear in all gametypes. * Lives position now more consistent between players in splitscreen. * Ringslinger weapon bar is now at the same height as the lives pic, and also more centered horizontally. * Begin tweaking emerald icon locations for ringslinger gametypes. * Remove in-game team names from team gametypes, since this information is (mostly) conveyed by the lives pic. --- src/st_stuff.c | 129 +++++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 63 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 24f4e590b..98a4b7d95 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -688,29 +688,34 @@ static inline void ST_drawRings(void) ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); } -static void ST_drawLives(void) +static void ST_drawLivesPic(void) { - const INT32 v_splitflag = (splitscreen && stplyr == &players[displayplayer] ? V_SPLITSCREEN : 0); - INT32 livescount; - boolean notgreyedout; + const INT32 y = STRINGY(hudinfo[HUD_LIVESPIC].y+16)-16; if (!stplyr->skincolor) return; // Just joined a server, skin isn't loaded yet! // face background - V_DrawSmallScaledPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, livesback); + V_DrawSmallScaledPatch(hudinfo[HUD_LIVESPIC].x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, livesback); // face - if (stplyr->mo && stplyr->mo->color) + if (stplyr->spectator) + { + // spectator face + UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, SKINCOLOR_CLOUDY, GTC_CACHE); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); + } + else if (stplyr->mo && stplyr->mo->color) { // skincolor face/super UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->color, GTC_CACHE); patch_t *face = faceprefix[stplyr->skin]; if (stplyr->powers[pw_super]) face = superprefix[stplyr->skin]; - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag,face, colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, face, colormap); if (cv_translucenthud.value == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer) { INT32 v_supertrans = (stplyr->mo->tracer->frame & FF_TRANSMASK) >> FF_TRANSSHIFT; @@ -718,8 +723,8 @@ static void ST_drawLives(void) { v_supertrans <<= V_ALPHASHIFT; colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->tracer->color, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|v_supertrans|v_splitflag,face, colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|v_supertrans, face, colormap); } } } @@ -727,20 +732,30 @@ static void ST_drawLives(void) { // skincolor face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag,faceprefix[stplyr->skin], colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, faceprefix[stplyr->skin], colormap); } +} + +static void ST_drawLives(void) +{ + const INT32 y = STRINGY(hudinfo[HUD_LIVESNAME].y+16)-16; + INT32 livescount; + boolean notgreyedout; + + if (!stplyr->skincolor) + return; // Just joined a server, skin isn't loaded yet! // name if (strlen(skins[stplyr->skin].hudname) > 8) - V_DrawThinString(hudinfo[HUD_LIVESNAME].x, hudinfo[HUD_LIVESNAME].y + (v_splitflag ? -12 : 0), - V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP|v_splitflag, skins[stplyr->skin].hudname); + V_DrawThinString(hudinfo[HUD_LIVESNAME].x, y, + V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP, skins[stplyr->skin].hudname); else - V_DrawString(hudinfo[HUD_LIVESNAME].x, hudinfo[HUD_LIVESNAME].y + (v_splitflag ? -12 : 0), - V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP|v_splitflag, skins[stplyr->skin].hudname); + V_DrawString(hudinfo[HUD_LIVESNAME].x, y, + V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP, skins[stplyr->skin].hudname); // x - V_DrawScaledPatch(hudinfo[HUD_LIVESX].x, hudinfo[HUD_LIVESX].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, stlivex); + V_DrawScaledPatch(hudinfo[HUD_LIVESX].x, y+8, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, stlivex); // lives number if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) @@ -775,20 +790,20 @@ static void ST_drawLives(void) } if (livescount == 0x7f) - V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, false); + V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, y+8, + '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, false); else { if (livescount > 99) livescount = 99; - V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF)|v_splitflag, + V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, y+8, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), ((livescount > 99) ? "!!" : va("%d",livescount))); } } static void ST_drawInput(void) { - //const INT32 v_splitflag = (splitscreen && stplyr == &players[displayplayer] ? V_SPLITSCREEN : 0); -- no splitscreen support - record attack only for base game const UINT8 accent = (stplyr->skincolor ? Color_Index[stplyr->skincolor-1][4] : 0); UINT8 col, offs; @@ -1620,7 +1635,7 @@ static void ST_drawNiGHTSHUD(void) splitscreen = true; } -static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, INT32 xoffs, patch_t *pat) +static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, INT32 xoffs, INT32 y, patch_t *pat) { INT32 txtflags = 0, patflags = 0; @@ -1638,23 +1653,24 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I patflags = V_80TRANS; } - V_DrawScaledPatch(8 + xoffs, STRINGY(162), V_SNAPTOLEFT|patflags, pat); + V_DrawScaledPatch(8 + xoffs, y, V_SNAPTOLEFT|patflags, pat); if (stplyr->powers[weapon] > 99) - V_DrawThinString(8 + xoffs + 1, STRINGY(162), V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); + V_DrawThinString(8 + xoffs + 1, y, V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); else - V_DrawString(8 + xoffs, STRINGY(162), V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); + V_DrawString(8 + xoffs, y, V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); if (stplyr->currentweapon == wepflag) - V_DrawScaledPatch(6 + xoffs, STRINGY(162 - (splitscreen ? 4 : 2)), V_SNAPTOLEFT, curweapon); + V_DrawScaledPatch(6 + xoffs, y-2, V_SNAPTOLEFT, curweapon); } else if (stplyr->ringweapons & rwflag) - V_DrawScaledPatch(8 + xoffs, STRINGY(162), V_SNAPTOLEFT|V_TRANSLUCENT, pat); + V_DrawScaledPatch(8 + xoffs, y, V_SNAPTOLEFT|V_TRANSLUCENT, pat); } static void ST_drawMatchHUD(void) { - INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10); + const INT32 y = STRINGY(176+16)-16; // HUD_LIVESPIC + INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10) - 6; if (!G_RingSlingerGametype()) return; @@ -1667,27 +1683,27 @@ static void ST_drawMatchHUD(void) #endif if (stplyr->powers[pw_infinityring]) - ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring); + ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring); else if (stplyr->rings > 0) - V_DrawScaledPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT, normring); + V_DrawScaledPatch(8 + offset, y, V_SNAPTOLEFT, normring); else - V_DrawTranslucentPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT|V_80TRANS, normring); + V_DrawTranslucentPatch(8 + offset, y, V_SNAPTOLEFT|V_80TRANS, normring); if (!stplyr->currentweapon) - V_DrawScaledPatch(6 + offset, STRINGY(162 - (splitscreen ? 4 : 2)), V_SNAPTOLEFT, curweapon); + V_DrawScaledPatch(6 + offset, y-2, V_SNAPTOLEFT, curweapon); offset += 20; - ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, autoring); + ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring); offset += 20; - ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, bouncering); + ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, y, bouncering); offset += 20; - ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, scatterring); + ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, y, scatterring); offset += 20; - ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, grenadering); + ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, y, grenadering); offset += 20; - ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, explosionring); + ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, y, explosionring); offset += 20; - ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, railring); + ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, y, railring); #ifdef HAVE_BLUA } @@ -1696,36 +1712,36 @@ static void ST_drawMatchHUD(void) #endif // Power Stones collected - offset = 136; // Used for Y now + offset = STRINGY(128); // Used for Y now if (stplyr->powers[pw_emeralds] & EMERALD1) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][0]); + V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][0]); offset += 8; if (stplyr->powers[pw_emeralds] & EMERALD2) - V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][1]); + V_DrawScaledPatch(40, offset, V_SNAPTOLEFT, emeraldpics[1][1]); if (stplyr->powers[pw_emeralds] & EMERALD6) - V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][5]); + V_DrawScaledPatch(16, offset, V_SNAPTOLEFT, emeraldpics[1][5]); offset += 16; if (stplyr->powers[pw_emeralds] & EMERALD3) - V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][2]); + V_DrawScaledPatch(40, offset, V_SNAPTOLEFT, emeraldpics[1][2]); if (stplyr->powers[pw_emeralds] & EMERALD5) - V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][4]); + V_DrawScaledPatch(16, offset, V_SNAPTOLEFT, emeraldpics[1][4]); offset += 8; if (stplyr->powers[pw_emeralds] & EMERALD4) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][3]); + V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][3]); offset -= 16; if (stplyr->powers[pw_emeralds] & EMERALD7) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][6]); + V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][6]); #ifdef HAVE_BLUA } @@ -1880,17 +1896,6 @@ static void ST_drawCTFHUD(void) } } -// Draws "Red Team", "Blue Team", or "Spectator" for team gametypes. -static inline void ST_drawTeamName(void) -{ - if (stplyr->ctfteam == 1) - V_DrawString(256, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "RED TEAM"); - else if (stplyr->ctfteam == 2) - V_DrawString(248, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "BLUE TEAM"); - else - V_DrawString(244, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "SPECTATOR"); -} - static void ST_drawSpecialStageHUD(void) { if (totalrings > 0) @@ -2061,6 +2066,8 @@ static void ST_overlayDrawer(void) if (LUA_HudEnabled(hud_rings)) #endif ST_drawRings(); + + ST_drawLivesPic(); // always do on mystic's request - allows us to kill "RED/BLUE TEAM" text if (G_GametypeUsesLives() #ifdef HAVE_BLUA && LUA_HudEnabled(hud_lives) @@ -2142,10 +2149,6 @@ static void ST_overlayDrawer(void) else if (gametype == GT_CTF) ST_drawCTFHUD(); - // Team names for team gametypes - if (G_GametypeHasTeams()) - ST_drawTeamName(); - // Special Stage HUD if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer]) ST_drawSpecialStageHUD(); From 336a26602d0d783ff5acf9a13bf6e8dd057eabf2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 10 Dec 2017 14:35:55 +0000 Subject: [PATCH 020/122] Not strictly pretty, but fixes a bug I discovered whilst working on this. --- src/m_menu.c | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 6979c73b5..25039c596 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2045,35 +2045,7 @@ static void Newgametype_OnChange(void) P_AllocMapHeader((INT16)(cv_nextmap.value-1)); if (!M_CanShowLevelOnPlatter(cv_nextmap.value-1, cv_newgametype.value)) - { - INT32 value = 0; - - switch (cv_newgametype.value) - { - case GT_COOP: - value = TOL_COOP; - break; - case GT_COMPETITION: - value = TOL_COMPETITION; - break; - case GT_RACE: - value = TOL_RACE; - break; - case GT_MATCH: - case GT_TEAMMATCH: - value = TOL_MATCH; - break; - case GT_TAG: - case GT_HIDEANDSEEK: - value = TOL_TAG; - break; - case GT_CTF: - value = TOL_CTF; - break; - } - - CV_SetValue(&cv_nextmap, M_GetFirstLevelInList(value)); - } + CV_SetValue(&cv_nextmap, M_GetFirstLevelInList(cv_newgametype.value)); } } From 2141754e5468fc4366c3ea8870f69920254ace6d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 20 Jan 2018 22:14:24 +0000 Subject: [PATCH 021/122] V_PERPLAYER. (Hooh boy.) * Completely redid how splitscreen works, with eventual support for quads. Squish per-player stuff automatically into the right places! Works in GL, associated flag kills V_SPLITSCREEN. * Seriously update the lives-drawing function for all gametypes, with strings that replace the lives number whenever it's missing (deprecates SKINNAMEPADDING). * Improved how the nosshack works, alongside many other refactorings. --- src/dehacked.c | 16 +- src/doomdef.h | 3 - src/hardware/hw_draw.c | 47 ++- src/r_things.c | 8 - src/st_stuff.c | 782 ++++++++++++++++++----------------------- src/st_stuff.h | 12 +- src/v_video.c | 54 ++- src/v_video.h | 2 +- src/y_inter.c | 62 ++-- 9 files changed, 463 insertions(+), 523 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index cb76c663e..bd4530e00 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6799,32 +6799,22 @@ static const char *const POWERS_LIST[] = { }; static const char *const HUDITEMS_LIST[] = { - "LIVESNAME", - "LIVESPIC", - "LIVESNUM", - "LIVESX", + "LIVES", "RINGS", - "RINGSSPLIT", "RINGSNUM", - "RINGSNUMSPLIT", "SCORE", "SCORENUM", "TIME", - "TIMESPLIT", "MINUTES", - "MINUTESSPLIT", "TIMECOLON", - "TIMECOLONSPLIT", "SECONDS", - "SECONDSSPLIT", "TIMETICCOLON", "TICS", "SS_TOTALRINGS", - "SS_TOTALRINGS_SPLIT", "GETRINGS", "GETRINGSNUM", @@ -7353,7 +7343,7 @@ struct { {"V_WRAPX",V_WRAPX}, {"V_WRAPY",V_WRAPY}, {"V_NOSCALESTART",V_NOSCALESTART}, - {"V_SPLITSCREEN",V_SPLITSCREEN}, + {"V_PERPLAYER",V_PERPLAYER}, {"V_PARAMMASK",V_PARAMMASK}, {"V_SCALEPATCHMASK",V_SCALEPATCHMASK}, @@ -7503,7 +7493,7 @@ static hudnum_t get_huditem(const char *word) if (fastcmp(word, HUDITEMS_LIST[i])) return i; deh_warning("Couldn't find huditem named 'HUD_%s'",word); - return HUD_LIVESNAME; + return HUD_LIVES; } #ifndef HAVE_BLUA diff --git a/src/doomdef.h b/src/doomdef.h index a49fb0207..ee21cf308 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -560,9 +560,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls. //#define PAPER_COLLISIONCORRECTION -/// Hudname padding. -#define SKINNAMEPADDING - /// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up /// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down) /// on the bright side it fixes some weird issues with translucent walls diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index dc97f7014..f902b4802 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -33,6 +33,8 @@ #include "../z_zone.h" #include "../v_video.h" #include "../st_stuff.h" +#include "../p_local.h" // stplyr +#include "../g_game.h" // players #include #include "../i_video.h" // for rendermode != render_glide @@ -181,8 +183,49 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (option & V_NOSCALESTART) sdupx = sdupy = 2.0f; - if (option & V_SPLITSCREEN) - sdupy /= 2.0f; + if (splitscreen && (option & V_PERPLAYER)) + { + float adjusty = ((option & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; + pdupy /= 2; + cy /= 2; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; + pdupx /= 2; + cx /= 2; + if (stplyr == &players[displayplayer]) + option &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + else if (stplyr == &players[secondarydisplayplayer]) + { + cx += adjustx; + option &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + cy += adjusty; + option &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + cx += adjustx; + cy += adjusty; + option &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + option &= ~V_SNAPTOBOTTOM; + else //if (stplyr == &players[secondarydisplayplayer]) + { + cy += adjusty; + option &= ~V_SNAPTOTOP; + } + } + } if (option & V_FLIP) // Need to flip both this and sow { diff --git a/src/r_things.c b/src/r_things.c index d201786a5..fad47d26b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2497,11 +2497,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->flags = 0; strcpy(skin->realname, "Someone"); -#ifdef SKINNAMEPADDING - strcpy(skin->hudname, " ???"); -#else strcpy(skin->hudname, "???"); -#endif strncpy(skin->charsel, "CHRSONIC", 8); strncpy(skin->face, "MISSING", 8); strncpy(skin->superface, "MISSING", 8); @@ -2733,11 +2729,7 @@ static UINT16 W_CheckForSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) return INT16_MAX; // not found } -#ifdef SKINNAMEPADDING -#define HUDNAMEWRITE(value) snprintf(skin->hudname, sizeof(skin->hudname), "%5s", value) -#else #define HUDNAMEWRITE(value) STRBUFCPY(skin->hudname, value) -#endif // turn _ into spaces and . into katana dot #define SYMBOLCONVERT(name) for (value = name; *value; value++)\ diff --git a/src/st_stuff.c b/src/st_stuff.c index 98a4b7d95..1426ae405 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -125,33 +125,23 @@ static boolean facefreed[MAXPLAYERS]; hudinfo_t hudinfo[NUMHUDITEMS] = { - { 34, 176}, // HUD_LIVESNAME - { 16, 176}, // HUD_LIVESPIC - { 74, 184}, // HUD_LIVESNUM - { 38, 186}, // HUD_LIVESX + { 16, 176}, // HUD_LIVES { 16, 42}, // HUD_RINGS - { 220, 10}, // HUD_RINGSSPLIT { 96, 42}, // HUD_RINGSNUM - { 296, 10}, // HUD_RINGSNUMSPLIT { 120, 42}, // HUD_RINGSNUMTICS { 16, 10}, // HUD_SCORE { 120, 10}, // HUD_SCORENUM { 16, 26}, // HUD_TIME - { 128, 10}, // HUD_TIMESPLIT { 72, 26}, // HUD_MINUTES - { 188, 10}, // HUD_MINUTESSPLIT { 72, 26}, // HUD_TIMECOLON - { 188, 10}, // HUD_TIMECOLONSPLIT { 96, 26}, // HUD_SECONDS - { 212, 10}, // HUD_SECONDSSPLIT { 96, 26}, // HUD_TIMETICCOLON { 120, 26}, // HUD_TICS { 120, 56}, // HUD_SS_TOTALRINGS - { 296, 40}, // HUD_SS_TOTALRINGS_SPLIT { 110, 93}, // HUD_GETRINGS { 160, 93}, // HUD_GETRINGSNUM @@ -423,84 +413,26 @@ static INT32 SCZ(INT32 z) return FixedInt(FixedMul(z<>= 1; - if (stplyr != &players[displayplayer]) - y += vid.height / 2; - } - return y; -} - -static INT32 STRINGY(INT32 y) -{ - //31/10/99: fixed by Hurdler so it _works_ also in hardware mode - // do not scale to resolution for hardware accelerated - // because these modes always scale by default - if (splitscreen) - { - y >>= 1; - if (stplyr != &players[displayplayer]) - y += BASEVIDHEIGHT / 2; - } - return y; -} - -static INT32 SPLITFLAGS(INT32 f) -{ - // Pass this V_SNAPTO(TOP|BOTTOM) and it'll trim them to account for splitscreen! -Red - if (splitscreen) - { - if (stplyr != &players[displayplayer]) - f &= ~V_SNAPTOTOP; - else - f &= ~V_SNAPTOBOTTOM; - } - return f; -} - static INT32 SCX(INT32 x) { return FixedInt(FixedMul(x<>= 1; - if (stplyr != &players[displayplayer]) - y += vid.height / 2; - } - return FixedInt(FixedDiv(y, vid.fdupy)); -} -#endif - // ========================================================================= // INTERNAL DRAWING // ========================================================================= -#define ST_DrawOverlayNum(x,y,n) V_DrawTallNum(x, y, V_NOSCALESTART|V_HUDTRANS, n) -#define ST_DrawPaddedOverlayNum(x,y,n,d) V_DrawPaddedTallNum(x, y, V_NOSCALESTART|V_HUDTRANS, n, d) -#define ST_DrawOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_NOSCALESTART|V_HUDTRANS, p) -#define ST_DrawMappedOverlayPatch(x,y,p,c) V_DrawMappedScaledPatch(x, y, V_NOSCALESTART|V_HUDTRANS, p, c) -#define ST_DrawNumFromHud(h,n,f) V_DrawTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|f, n) -#define ST_DrawPadNumFromHud(h,n,q,f) V_DrawPaddedTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|f, n, q) -#define ST_DrawPatchFromHud(h,p,f) V_DrawScaledPatch(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|f, p) -#define ST_DrawNumFromHudWS(h,n,f) V_DrawTallNum(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|f, n) -#define ST_DrawPadNumFromHudWS(h,n,q,f) V_DrawPaddedTallNum(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|f, n, q) -#define ST_DrawPatchFromHudWS(h,p,f) V_DrawScaledPatch(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|f, p) +#define ST_DrawUnscaledOverlayNum(x,y,n) V_DrawTallNum(x, y, V_NOSCALESTART|V_PERPLAYER|V_HUDTRANS, n) +#define ST_DrawUnscaledPaddedOverlayNum(x,y,n,d) V_DrawPaddedTallNum(x, y, V_NOSCALESTART|V_PERPLAYER|V_HUDTRANS, n, d) +#define ST_DrawUnscaledOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_NOSCALESTART|V_PERPLAYER|V_HUDTRANS, p) +#define ST_DrawTopLeftOverlayNum(x,y,n) V_DrawTallNum(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, n) +#define ST_DrawTopLeftOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p) +#define ST_DrawMappedOverlayPatch(x,y,p,c) V_DrawMappedScaledPatch(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p, c) +#define ST_DrawNumFromHud(h,n,f) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n) +#define ST_DrawPadNumFromHud(h,n,q,f) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n, q) +#define ST_DrawPatchFromHud(h,p,f) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, p) +#define ST_DrawNumFromHudWS(h,n,f) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n) +#define ST_DrawPadNumFromHudWS(h,n,q,f) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n, q) +#define ST_DrawPatchFromHudWS(h,p,f) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, p) // Draw a number, scaled, over the view, maybe with set translucency // Always draw the number completely since it's overlay @@ -617,7 +549,7 @@ static void ST_drawScore(void) if (objectplacing) { if (op_displayflags > UINT16_MAX) - ST_DrawOverlayPatch(SCX(hudinfo[HUD_SCORENUM].x-tallminus->width), SCY(hudinfo[HUD_SCORENUM].y), tallminus); + ST_DrawTopLeftOverlayPatch((hudinfo[HUD_SCORENUM].x-tallminus->width), hudinfo[HUD_SCORENUM].y, tallminus); else ST_DrawNumFromHud(HUD_SCORENUM, op_displayflags, V_HUDTRANS); } @@ -655,7 +587,7 @@ static void ST_drawTime(void) ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon ST_DrawPadNumFromHudWS(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds - if (!splitscreen && (cv_timetic.value == 2 || cv_timetic.value == 3 || modeattacking)) // there's not enough room for tics in splitscreen, don't even bother trying! + if (cv_timetic.value == 2 || cv_timetic.value == 3 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! { ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod, V_HUDTRANS); // Period ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2, V_HUDTRANS); // Tics @@ -682,30 +614,31 @@ static inline void ST_drawRings(void) else ringnum = max(stplyr->rings, 0); - if (!splitscreen && cv_timetic.value == 3) // Yes, even in modeattacking - ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + if (cv_timetic.value == 3) // Yes, even in modeattacking + ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); else - ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); } -static void ST_drawLivesPic(void) +static void ST_drawLivesArea(void) { - const INT32 y = STRINGY(hudinfo[HUD_LIVESPIC].y+16)-16; + INT32 v_colmap = V_YELLOWMAP, livescount; + boolean notgreyedout; if (!stplyr->skincolor) return; // Just joined a server, skin isn't loaded yet! // face background - V_DrawSmallScaledPatch(hudinfo[HUD_LIVESPIC].x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, livesback); + V_DrawSmallScaledPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, livesback); // face if (stplyr->spectator) { // spectator face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, SKINCOLOR_CLOUDY, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); } else if (stplyr->mo && stplyr->mo->color) { @@ -714,8 +647,8 @@ static void ST_drawLivesPic(void) patch_t *face = faceprefix[stplyr->skin]; if (stplyr->powers[pw_super]) face = superprefix[stplyr->skin]; - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, face, colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, face, colormap); if (cv_translucenthud.value == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer) { INT32 v_supertrans = (stplyr->mo->tracer->frame & FF_TRANSMASK) >> FF_TRANSSHIFT; @@ -723,8 +656,8 @@ static void ST_drawLivesPic(void) { v_supertrans <<= V_ALPHASHIFT; colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->tracer->color, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|v_supertrans, face, colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|v_supertrans, face, colormap); } } } @@ -732,104 +665,172 @@ static void ST_drawLivesPic(void) { // skincolor face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, faceprefix[stplyr->skin], colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, faceprefix[stplyr->skin], colormap); } -} -static void ST_drawLives(void) -{ - const INT32 y = STRINGY(hudinfo[HUD_LIVESNAME].y+16)-16; - INT32 livescount; - boolean notgreyedout; - - if (!stplyr->skincolor) - return; // Just joined a server, skin isn't loaded yet! - - // name - if (strlen(skins[stplyr->skin].hudname) > 8) - V_DrawThinString(hudinfo[HUD_LIVESNAME].x, y, - V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP, skins[stplyr->skin].hudname); - else - V_DrawString(hudinfo[HUD_LIVESNAME].x, y, - V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP, skins[stplyr->skin].hudname); - // x - V_DrawScaledPatch(hudinfo[HUD_LIVESX].x, y+8, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, stlivex); - - // lives number - if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) + // Lives number + if (G_GametypeUsesLives()) { - INT32 i; - livescount = 0; - notgreyedout = (stplyr->lives > 0); - for (i = 0; i < MAXPLAYERS; i++) + // x + V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, stlivex); + + // lives number + if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) { - if (!playeringame[i]) - continue; - - if (players[i].lives < 1) - continue; - - if (players[i].lives > 1) - notgreyedout = true; - - if (players[i].lives == 0x7f) + INT32 i; + livescount = 0; + notgreyedout = (stplyr->lives > 0); + for (i = 0; i < MAXPLAYERS; i++) { - livescount = 0x7f; - break; + if (!playeringame[i]) + continue; + + if (players[i].lives < 1) + continue; + + if (players[i].lives > 1) + notgreyedout = true; + + if (players[i].lives == 0x7f) + { + livescount = 0x7f; + break; + } + else if (livescount < 99) + livescount += (players[i].lives); } - else if (livescount < 99) - livescount += (players[i].lives); + } + else + { + livescount = ((cv_cooplives.value == 0) ? 0x7f : stplyr->lives); + notgreyedout = true; + } + + if (livescount == 0x7f) + V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8, + '\x16' | 0x80 | V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, false); + else + { + if (livescount > 99) + livescount = 99; + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); } } + // Spectator + else if (stplyr->spectator) + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "SPECTATE"); + v_colmap = V_GRAYMAP; + } + // Tag + else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + { + if (stplyr->pflags & PF_TAGIT) + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, (gametype == GT_HIDEANDSEEK) ? "SEEKER" : "IT!"); + v_colmap = V_ORANGEMAP; + } + else if (stplyr->pflags & PF_GAMETYPEOVER) + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANSHALF|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "FAILED"); + v_colmap = V_GRAYMAP; + } + else + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, (gametype == GT_HIDEANDSEEK) ? "HIDER" : "RUNNER"); + v_colmap = V_GREENMAP; + } + } + // Team name + else if (G_GametypeHasTeams()) + { + if (stplyr->ctfteam == 1) + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "RED"); + v_colmap = V_REDMAP; + } + else if (stplyr->ctfteam == 2) + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "BLUE"); + v_colmap = V_BLUEMAP; + } + else + v_colmap = V_GRAYMAP; + } else { - livescount = stplyr->lives; - notgreyedout = true; + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "PLAYING"); } - if (livescount == 0x7f) - V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, y+8, - '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, false); + // name + v_colmap |= (V_HUDTRANS|V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM); + if (strlen(skins[stplyr->skin].hudname) <= 5) + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); + else if (V_ThinStringWidth(skins[stplyr->skin].hudname, v_colmap) <= 40) + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); else + V_DrawThinString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); + + // Power Stones collected + if (G_RingSlingerGametype() +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_powerstones) +#endif + ) { - if (livescount > 99) - livescount = 99; - V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, y+8, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), - ((livescount > 99) ? "!!" : va("%d",livescount))); + INT32 workx = hudinfo[HUD_LIVES].x+1, j; + if ((leveltime & 1) && stplyr->powers[pw_invulnerability] && (stplyr->powers[pw_sneakers] == stplyr->powers[pw_invulnerability])) // hack; extremely unlikely to be activated unintentionally + { + for (j = 0; j < 7; ++j) // "super" indicator + { + V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, emeraldpics[1][j]); + workx += 8; + } + } + else + { + for (j = 0; j < 7; ++j) // powerstones + { + if (stplyr->powers[pw_emeralds] & (1 << j)) + V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, emeraldpics[1][j]); + workx += 8; + } + } } } static void ST_drawInput(void) { - const UINT8 accent = (stplyr->skincolor ? Color_Index[stplyr->skincolor-1][4] : 0); - UINT8 col, offs; + const INT32 accent = V_SNAPTOLEFT|V_SNAPTOBOTTOM|(stplyr->skincolor ? Color_Index[stplyr->skincolor-1][4] : 0); + INT32 col; + UINT8 offs; - INT32 x = hudinfo[HUD_LIVESPIC].x, y = hudinfo[HUD_LIVESPIC].y; + INT32 x = hudinfo[HUD_LIVES].x, y = hudinfo[HUD_LIVES].y; if (stplyr->powers[pw_carry] == CR_NIGHTSMODE) y -= 16; // O backing - V_DrawFill(x, y-1, 16, 16, 20); - V_DrawFill(x, y+15, 16, 1, 29); + V_DrawFill(x, y-1, 16, 16, V_SNAPTOLEFT|V_SNAPTOBOTTOM|20); + V_DrawFill(x, y+15, 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); if (cv_showinputjoy.value) // joystick render! { - /*V_DrawFill(x , y , 16, 1, 16); - V_DrawFill(x , y+15, 16, 1, 16); - V_DrawFill(x , y+ 1, 1, 14, 16); - V_DrawFill(x+15, y+ 1, 1, 14, 16); -- red's outline*/ + /*V_DrawFill(x , y , 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); + V_DrawFill(x , y+15, 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); + V_DrawFill(x , y+ 1, 1, 14, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); + V_DrawFill(x+15, y+ 1, 1, 14, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); -- red's outline*/ if (stplyr->cmd.sidemove || stplyr->cmd.forwardmove) { // joystick hole - V_DrawFill(x+5, y+4, 6, 6, 29); + V_DrawFill(x+5, y+4, 6, 6, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); // joystick top V_DrawFill(x+3+stplyr->cmd.sidemove/12, y+2-stplyr->cmd.forwardmove/12, - 10, 10, 29); + 10, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); V_DrawFill(x+3+stplyr->cmd.sidemove/9, y+1-stplyr->cmd.forwardmove/9, 10, 10, accent); @@ -837,10 +838,10 @@ static void ST_drawInput(void) else { // just a limited, greyed out joystick top - V_DrawFill(x+3, y+11, 10, 1, 29); + V_DrawFill(x+3, y+11, 10, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); V_DrawFill(x+3, y+1, - 10, 10, 16); + 10, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); } } else // arrows! @@ -854,10 +855,10 @@ static void ST_drawInput(void) else { offs = 1; - col = 16; - V_DrawFill(x- 2, y+10, 6, 1, 29); - V_DrawFill(x+ 4, y+ 9, 1, 1, 29); - V_DrawFill(x+ 5, y+ 8, 1, 1, 29); + col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; + V_DrawFill(x- 2, y+10, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+ 4, y+ 9, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+ 5, y+ 8, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); } V_DrawFill(x- 2, y+ 5-offs, 6, 6, col); V_DrawFill(x+ 4, y+ 6-offs, 1, 4, col); @@ -872,12 +873,12 @@ static void ST_drawInput(void) else { offs = 1; - col = 16; - V_DrawFill(x+ 5, y+ 3, 1, 1, 29); - V_DrawFill(x+ 6, y+ 4, 1, 1, 29); - V_DrawFill(x+ 7, y+ 5, 2, 1, 29); - V_DrawFill(x+ 9, y+ 4, 1, 1, 29); - V_DrawFill(x+10, y+ 3, 1, 1, 29); + col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; + V_DrawFill(x+ 5, y+ 3, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+ 6, y+ 4, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+ 7, y+ 5, 2, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+ 9, y+ 4, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+10, y+ 3, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); } V_DrawFill(x+ 5, y- 2-offs, 6, 6, col); V_DrawFill(x+ 6, y+ 4-offs, 4, 1, col); @@ -892,10 +893,10 @@ static void ST_drawInput(void) else { offs = 1; - col = 16; - V_DrawFill(x+12, y+10, 6, 1, 29); - V_DrawFill(x+11, y+ 9, 1, 1, 29); - V_DrawFill(x+10, y+ 8, 1, 1, 29); + col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; + V_DrawFill(x+12, y+10, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+11, y+ 9, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+10, y+ 8, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); } V_DrawFill(x+12, y+ 5-offs, 6, 6, col); V_DrawFill(x+11, y+ 6-offs, 1, 4, col); @@ -910,8 +911,8 @@ static void ST_drawInput(void) else { offs = 1; - col = 16; - V_DrawFill(x+ 5, y+17, 6, 1, 29); + col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; + V_DrawFill(x+ 5, y+17, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); } V_DrawFill(x+ 5, y+12-offs, 6, 6, col); V_DrawFill(x+ 6, y+11-offs, 4, 1, col); @@ -927,16 +928,16 @@ static void ST_drawInput(void) else\ {\ offs = 1;\ - col = 16;\ - V_DrawFill(x+16+(xoffs), y+9+(yoffs), 10, 1, 29);\ + col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16;\ + V_DrawFill(x+16+(xoffs), y+9+(yoffs), 10, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29);\ }\ V_DrawFill(x+16+(xoffs), y+(yoffs)-offs, 10, 10, col);\ - V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, symb, false) + V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, V_SNAPTOLEFT|V_SNAPTOBOTTOM|symb, false) drawbutt( 4,-3, BT_JUMP, 'J'); drawbutt(15,-3, BT_USE, 'S'); - V_DrawFill(x+16+4, y+8, 21, 10, 20); // sundial backing + V_DrawFill(x+16+4, y+8, 21, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|20); // sundial backing if (stplyr->mo) { UINT8 i, precision; @@ -956,7 +957,7 @@ static void ST_drawInput(void) { V_DrawFill(x+16+14-(i*xcomp)/precision, y+12-(i*ycomp)/precision, - 1, 1, 16); + 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); } if (ycomp <= 0) @@ -973,6 +974,7 @@ static void ST_drawInput(void) if (stplyr->pflags & PF_AUTOBRAKE) { V_DrawThinString(x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM| ((!stplyr->powers[pw_carry] && (stplyr->pflags & PF_APPLYAUTOBRAKE) && !(stplyr->cmd.sidemove || stplyr->cmd.forwardmove) @@ -983,12 +985,12 @@ static void ST_drawInput(void) } if (stplyr->pflags & PF_ANALOGMODE) { - V_DrawThinString(x, y, 0, "ANALOG"); + V_DrawThinString(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM, "ANALOG"); y -= 8; } } if (!demosynced) // should always be last, so it doesn't push anything else around - V_DrawThinString(x, y, ((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); + V_DrawThinString(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); } static void ST_drawLevelTitle(void) @@ -1067,11 +1069,7 @@ static void ST_drawFirstPersonHUD(void) UINT8 i, max = (player->powers[pw_shield] & SH_FORCEHP); for (i = 0; i <= max; i++) { - INT32 flags = (V_SNAPTORIGHT|V_SNAPTOTOP)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF); - if (splitscreen) - V_DrawSmallScaledPatch(312-(3*i), STRINGY(24)+(3*i), flags, forceshield); - else - V_DrawScaledPatch(304-(3*i), 24+(3*i), flags, forceshield); + V_DrawScaledPatch(304-(3*i), 24+(3*i), (V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF), forceshield); } } else switch (player->powers[pw_shield] & SH_NOSTACK) @@ -1088,29 +1086,16 @@ static void ST_drawFirstPersonHUD(void) } if (p) - { - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24), V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - else - V_DrawScaledPatch(304, 24, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - } + V_DrawScaledPatch(304, 24, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); // pw_flashing just sets the icon to flash no matter what. invulntime = player->powers[pw_flashing] ? 1 : player->powers[pw_invulnerability]; if (invulntime > 3*TICRATE || (invulntime && leveltime & 1)) - { - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24) + 14, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); - else - V_DrawScaledPatch(304, 24 + 28, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); - } + V_DrawScaledPatch(304, 24 + 28, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); if (player->powers[pw_sneakers] > 3*TICRATE || (player->powers[pw_sneakers] && leveltime & 1)) { - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24) + 28, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); - else - V_DrawScaledPatch(304, 24 + 56, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); + V_DrawScaledPatch(304, 24 + 56, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); } p = NULL; @@ -1158,32 +1143,32 @@ static void ST_drawFirstPersonHUD(void) // Display the countdown drown numbers! if (p) - V_DrawScaledPatch(SCX((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset)), SCY(60 - SHORT(p->topoffset)), - V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, p); + V_DrawScaledPatch(SCX((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset)), SCZ(60 - SHORT(p->topoffset)), + V_PERPLAYER|V_NOSCALESTART|V_PERPLAYER|V_OFFSET|V_TRANSLUCENT, p); } static void ST_drawNightsRecords(void) { - INT32 aflag = 0; + INT32 aflag = V_PERPLAYER; if (!stplyr->texttimer) return; if (stplyr->texttimer < TICRATE/2) - aflag = (9 - 9*stplyr->texttimer/(TICRATE/2)) << V_ALPHASHIFT; + aflag |= (9 - 9*stplyr->texttimer/(TICRATE/2)) << V_ALPHASHIFT; // A "Bonus Time Start" by any other name... if (stplyr->textvar == 1) { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(52), V_GREENMAP|aflag, M_GetText("GET TO THE GOAL!")); - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), aflag, M_GetText("SCORE MULTIPLIER START!")); + V_DrawCenteredString(BASEVIDWIDTH/2, 52, V_GREENMAP|aflag, M_GetText("GET TO THE GOAL!")); + V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag, M_GetText("SCORE MULTIPLIER START!")); if (stplyr->finishedtime) { - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(140), aflag, "TIME:"); - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(148), aflag, "BONUS:"); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(140), V_ORANGEMAP|aflag, va("%d", (stplyr->startedtime - stplyr->finishedtime)/TICRATE)); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(148), V_ORANGEMAP|aflag, va("%d", (stplyr->finishedtime/TICRATE) * 100)); + V_DrawString(BASEVIDWIDTH/2 - 48, 140, aflag, "TIME:"); + V_DrawString(BASEVIDWIDTH/2 - 48, 148, aflag, "BONUS:"); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, 140, V_ORANGEMAP|aflag, va("%d", (stplyr->startedtime - stplyr->finishedtime)/TICRATE)); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, 148, V_ORANGEMAP|aflag, va("%d", (stplyr->finishedtime/TICRATE) * 100)); } } @@ -1194,7 +1179,7 @@ static void ST_drawNightsRecords(void) return; // Yes, this string is an abomination. - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), aflag, + V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag, va(M_GetText("\x80GET\x82 %d\x80 %s%s%s!"), stplyr->capsule->health, (stplyr->textvar == 3) ? M_GetText("MORE ") : "", (G_IsSpecialStage(gamemap)) ? "SPHERE" : "RING", @@ -1204,26 +1189,26 @@ static void ST_drawNightsRecords(void) // End Bonus else if (stplyr->textvar == 4) { - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(140), aflag, (G_IsSpecialStage(gamemap)) ? "ORBS:" : "RINGS:"); - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(148), aflag, "BONUS:"); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(140), V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings)); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(148), V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings * 50)); - ST_DrawNightsOverlayNum((BASEVIDWIDTH/2 + 48)<lastmarescore, nightsnum, SKINCOLOR_AZURE); + V_DrawString(BASEVIDWIDTH/2 - 56, 140, aflag, (G_IsSpecialStage(gamemap)) ? "SPHERES:" : "RINGS:"); + V_DrawString(BASEVIDWIDTH/2 - 56, 148, aflag, "BONUS:"); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings)); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings * 50)); + ST_DrawNightsOverlayNum((BASEVIDWIDTH/2 + 56)<lastmarescore, nightsnum, SKINCOLOR_AZURE); // If new record, say so! if (!(netgame || multiplayer) && G_GetBestNightsScore(gamemap, stplyr->lastmare + 1) <= stplyr->lastmarescore) { if (stplyr->texttimer & 16) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), V_YELLOWMAP|aflag, "* NEW RECORD *"); + V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_YELLOWMAP|aflag, "* NEW RECORD *"); } if (P_HasGrades(gamemap, stplyr->lastmare + 1)) { if (aflag) - V_DrawTranslucentPatch(BASEVIDWIDTH/2 + 60, STRINGY(160), aflag, + V_DrawTranslucentPatch(BASEVIDWIDTH/2 + 60, 160, aflag, ngradeletters[P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare)]); else - V_DrawScaledPatch(BASEVIDWIDTH/2 + 60, STRINGY(160), 0, + V_DrawScaledPatch(BASEVIDWIDTH/2 + 60, 160, 0, ngradeletters[P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare)]); } } @@ -1276,15 +1261,6 @@ static void ST_drawNiGHTSHUD(void) if (stplyr->texttimer && stplyr->textvar == 4) minlink = INT32_MAX; - if (G_IsSpecialStage(gamemap)) - { // Since special stages share score, time, rings, etc. - // disable splitscreen mode for its HUD. - if (stplyr != &players[displayplayer]) - return; - nosshack = splitscreen; - splitscreen = false; - } - // Drill meter if ( #ifdef HAVE_BLUA @@ -1296,7 +1272,7 @@ static void ST_drawNiGHTSHUD(void) INT32 dfill; UINT8 fillpatch; - if (splitscreen || nosshack) + if (splitscreen) { locx = 110; locy = 188; @@ -1313,46 +1289,29 @@ static void ST_drawNiGHTSHUD(void) else fillpatch = 0; - if (splitscreen) - { // 11-5-14 Replaced the old hack with a slightly better hack. -Red - V_DrawScaledPatch(locx, STRINGY(locy)-3, SPLITFLAGS(V_SNAPTOBOTTOM)|V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), SPLITFLAGS(V_SNAPTOBOTTOM)|V_HUDTRANS, drillfill[fillpatch]); - } - else if (nosshack) - { // Even dirtier hack-of-a-hack to draw seperate drill meters in splitscreen special stages but nothing else. - splitscreen = true; - V_DrawScaledPatch(locx, STRINGY(locy)-3, V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), V_HUDTRANS, drillfill[fillpatch]); - stplyr = &players[secondarydisplayplayer]; - if (stplyr->pflags & PF_DRILLING) - fillpatch = (stplyr->drillmeter & 1) + 1; - else - fillpatch = 0; - V_DrawScaledPatch(locx, STRINGY(locy-3), V_SNAPTOBOTTOM|V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]); - stplyr = &players[displayplayer]; - splitscreen = false; - } - else - { // Draw normally. <:3 - V_DrawScaledPatch(locx, locy, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, locy + 3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]); - } + V_DrawScaledPatch(locx, locy, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillbar); + for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) + V_DrawScaledPatch(locx + 2 + dfill, locy + 3, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]); // Display actual drill amount and bumper time - if (cv_debug & DBG_NIGHTSBASIC) + if (!splitscreen && (cv_debug & DBG_NIGHTSBASIC)) { if (stplyr->bumpertime) - V_DrawString(SCX(locx), SCY(locy - 8), V_NOSCALESTART|V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime))); + V_DrawString(SCX(locx), SCZ(locy - 8), V_NOSCALESTART|V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime))); else - V_DrawString(SCX(locx), SCY(locy - 8), V_NOSCALESTART|V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20))); + V_DrawString(SCX(locx), SCZ(locy - 8), V_NOSCALESTART|V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20))); } } + if (G_IsSpecialStage(gamemap)) + { // Since special stages share score, time, rings, etc. + // disable splitscreen mode for its HUD. + if (stplyr != &players[displayplayer]) + return; + nosshack = splitscreen; + splitscreen = false; + } + // Link drawing if ( #ifdef HAVE_BLUA @@ -1361,7 +1320,7 @@ static void ST_drawNiGHTSHUD(void) stplyr->linkcount > minlink) { skincolors_t colornum; - INT32 aflag; + INT32 aflag = V_PERPLAYER; fixed_t x, y, scale; if (stplyr->powers[pw_nights_linkfreeze] && (!(stplyr->powers[pw_nights_linkfreeze] & 2) || (stplyr->powers[pw_nights_linkfreeze] > flashingtics))) @@ -1369,22 +1328,20 @@ static void ST_drawNiGHTSHUD(void) else colornum = linkColor[((stplyr->linkcount-1 >= 300) ? 1 : 0)][((stplyr->linkcount-1) / 5) % NUMLINKCOLORS]; - aflag = ((stplyr->linktimer < 2*TICRATE/3) + aflag |= ((stplyr->linktimer < 2*TICRATE/3) ? (9 - 9*stplyr->linktimer/(2*TICRATE/3)) << V_ALPHASHIFT : 0); - if (splitscreen) + y = (nosshack ? 16+11+(BASEVIDHEIGHT/2) : 160+11)<linktimer) { @@ -1422,11 +1379,11 @@ static void ST_drawNiGHTSHUD(void) if (LUA_HudEnabled(hud_nightsrings)) { #endif - ST_DrawOverlayPatch(SCX(16), SCY(8), nbracket); + ST_DrawTopLeftOverlayPatch(16, 8, nbracket); if (G_IsSpecialStage(gamemap)) - ST_DrawOverlayPatch(SCX(24), SCY(8) + SCZ(8), nsshud); + ST_DrawTopLeftOverlayPatch(24, 16, nsshud); else - ST_DrawOverlayPatch(SCX(24), SCY(8) + SCZ(8), nhud[(leveltime/2)%12]); + ST_DrawTopLeftOverlayPatch(24, 16, nhud[(leveltime/2)%12]); if (G_IsSpecialStage(gamemap)) { @@ -1447,8 +1404,8 @@ static void ST_drawNiGHTSHUD(void) origamount = stplyr->capsule->spawnpoint->angle; I_Assert(origamount > 0); // should not happen now - ST_DrawOverlayPatch(SCX(72), SCY(8), nbracket); - ST_DrawOverlayPatch(SCX(74), SCY(8) + SCZ(4), minicaps); + ST_DrawTopLeftOverlayPatch(72, 8, nbracket); + ST_DrawTopLeftOverlayPatch(74, 8 + 4, minicaps); if (stplyr->capsule->reactiontime != 0) { @@ -1457,10 +1414,10 @@ static void ST_drawNiGHTSHUD(void) for (r = 0; r < 5; r++) { - ST_DrawOverlayPatch(SCX(230 - (7*r)), SCY(144), redstat); - ST_DrawOverlayPatch(SCX(188 - (7*r)), SCY(144), orngstat); - ST_DrawOverlayPatch(SCX(146 - (7*r)), SCY(144), yelstat); - ST_DrawOverlayPatch(SCX(104 - (7*r)), SCY(144), byelstat); + ST_DrawUnscaledOverlayPatch(SCX(230 - (7*r)), SCZ(144), redstat); + ST_DrawUnscaledOverlayPatch(SCX(188 - (7*r)), SCZ(144), orngstat); + ST_DrawUnscaledOverlayPatch(SCX(146 - (7*r)), SCZ(144), yelstat); + ST_DrawUnscaledOverlayPatch(SCX(104 - (7*r)), SCZ(144), byelstat); } amount = (origamount - stplyr->capsule->health); @@ -1479,7 +1436,7 @@ static void ST_drawNiGHTSHUD(void) if (r > 10) ++t; if (r > 5) ++t; - ST_DrawOverlayPatch(SCX(69 + (7*t)), SCY(144), bluestat); + ST_DrawUnscaledOverlayPatch(SCX(69 + (7*t)), SCZ(144), bluestat); } } } @@ -1488,27 +1445,27 @@ static void ST_drawNiGHTSHUD(void) INT32 cfill; // Lil' white box! - V_DrawScaledPatch(15, STRINGY(8) + 34, V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulebar); + V_DrawScaledPatch(15, 8 + 34, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulebar); amount = (origamount - stplyr->capsule->health); amount = (amount * length)/origamount; for (cfill = 0; cfill < amount && cfill < 88; ++cfill) - V_DrawScaledPatch(15 + cfill + 1, STRINGY(8) + 35, V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulefill); + V_DrawScaledPatch(15 + cfill + 1, 8 + 35, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulefill); } if (total_ringcount >= stplyr->capsule->health) - ST_DrawOverlayPatch(SCX(40), SCY(8) + SCZ(5), nredar[leveltime%8]); + ST_DrawTopLeftOverlayPatch(40, 8 + 5, nredar[leveltime%8]); else - ST_DrawOverlayPatch(SCX(40), SCY(8) + SCZ(5), narrow[(leveltime/2)%8]); + ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[(leveltime/2)%8]); } else - ST_DrawOverlayPatch(SCX(40), SCY(8) + SCZ(5), narrow[8]); + ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[8]); if (total_ringcount >= 100) - ST_DrawOverlayNum((total_ringcount >= 1000) ? SCX(76) : SCX(72), SCY(8) + SCZ(11), total_ringcount); + ST_DrawTopLeftOverlayNum((total_ringcount >= 1000) ? 76 : 72, 8 + 11, total_ringcount); else - ST_DrawOverlayNum(SCX(68), SCY(8) + SCZ(11), total_ringcount); + ST_DrawTopLeftOverlayNum(68, 8 + 11, total_ringcount); #ifdef HAVE_BLUA } #endif @@ -1519,9 +1476,7 @@ static void ST_drawNiGHTSHUD(void) && LUA_HudEnabled(hud_nightsscore) #endif ) - { - ST_DrawNightsOverlayNum(304<marescore, nightsnum, SKINCOLOR_AZURE); - } + ST_DrawNightsOverlayNum(304<marescore, nightsnum, SKINCOLOR_AZURE); if (!stplyr->exiting #ifdef HAVE_BLUA @@ -1536,16 +1491,16 @@ static void ST_drawNiGHTSHUD(void) fixed_t cornerx = vid.width, cornery = vid.height-SCZ(20); #define ASSISHHUDFIX(n) (n*vid.dupx) - ST_DrawOverlayPatch(cornerx-ASSISHHUDFIX(22), cornery, W_CachePatchName("NGRTIMER", PU_HUDGFX)); - ST_DrawPaddedOverlayNum(cornerx-ASSISHHUDFIX(22), cornery, G_TicsToCentiseconds(maretime), 2); - ST_DrawOverlayPatch(cornerx-ASSISHHUDFIX(46), cornery, sboperiod); + ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(22), cornery, W_CachePatchName("NGRTIMER", PU_HUDGFX)); + ST_DrawUnscaledPaddedOverlayNum(cornerx-ASSISHHUDFIX(22), cornery, G_TicsToCentiseconds(maretime), 2); + ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(46), cornery, sboperiod); if (maretime < 60*TICRATE) - ST_DrawOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime)); + ST_DrawUnscaledOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime)); else { - ST_DrawPaddedOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime), 2); - ST_DrawOverlayPatch(cornerx-ASSISHHUDFIX(70), cornery, sbocolon); - ST_DrawOverlayNum(cornerx-ASSISHHUDFIX(70), cornery, G_TicsToMinutes(maretime, true)); + ST_DrawUnscaledPaddedOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime), 2); + ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(70), cornery, sbocolon); + ST_DrawUnscaledOverlayNum(cornerx-ASSISHHUDFIX(70), cornery, G_TicsToMinutes(maretime, true)); } } #undef ASSISHHUDFIX @@ -1577,10 +1532,10 @@ static void ST_drawNiGHTSHUD(void) if (flashingLeft < TICRATE/2) // Start fading out { UINT32 fadingFlag = (9 - 9*flashingLeft/(TICRATE/2)) << V_ALPHASHIFT; - V_DrawTranslucentPatch(SCX(160 - (minus5sec->width/2)), SCY(28), V_NOSCALESTART|fadingFlag, minus5sec); + V_DrawTranslucentPatch(SCX(160 - (minus5sec->width/2)), SCZ(28), V_NOSCALESTART|V_PERPLAYER|fadingFlag, minus5sec); } else - V_DrawScaledPatch(SCX(160 - (minus5sec->width/2)), SCY(28), V_NOSCALESTART, minus5sec); + V_DrawScaledPatch(SCX(160 - (minus5sec->width/2)), SCZ(28), V_NOSCALESTART|V_PERPLAYER, minus5sec); } if (realnightstime < 10) @@ -1590,7 +1545,7 @@ static void ST_drawNiGHTSHUD(void) else numbersize = 48/2; - ST_DrawNightsOverlayNum((160 + numbersize)<powers[pw_nights_superloop]) { pwr = stplyr->powers[pw_nights_superloop]; - V_DrawSmallScaledPatch(SCX(110), SCY(44), V_NOSCALESTART, W_CachePatchName("NPRUA0",PU_CACHE)); - V_DrawThinString(SCX(106), SCY(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(SCX(110), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUA0",PU_CACHE)); + V_DrawThinString(SCX(106), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } if (stplyr->powers[pw_nights_helper]) { pwr = stplyr->powers[pw_nights_helper]; - V_DrawSmallScaledPatch(SCX(150), SCY(44), V_NOSCALESTART, W_CachePatchName("NPRUC0",PU_CACHE)); - V_DrawThinString(SCX(146), SCY(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(SCX(150), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUC0",PU_CACHE)); + V_DrawThinString(SCX(146), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } if (stplyr->powers[pw_nights_linkfreeze]) { pwr = stplyr->powers[pw_nights_linkfreeze]; - V_DrawSmallScaledPatch(SCX(190), SCY(44), V_NOSCALESTART, W_CachePatchName("NPRUE0",PU_CACHE)); - V_DrawThinString(SCX(186), SCY(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(SCX(190), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUE0",PU_CACHE)); + V_DrawThinString(SCX(186), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } } @@ -1653,23 +1608,23 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I patflags = V_80TRANS; } - V_DrawScaledPatch(8 + xoffs, y, V_SNAPTOLEFT|patflags, pat); + V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|patflags, pat); if (stplyr->powers[weapon] > 99) - V_DrawThinString(8 + xoffs + 1, y, V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); + V_DrawThinString(8 + xoffs + 1, y, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); else - V_DrawString(8 + xoffs, y, V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); + V_DrawString(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); if (stplyr->currentweapon == wepflag) - V_DrawScaledPatch(6 + xoffs, y-2, V_SNAPTOLEFT, curweapon); + V_DrawScaledPatch(6 + xoffs, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); } else if (stplyr->ringweapons & rwflag) - V_DrawScaledPatch(8 + xoffs, y, V_SNAPTOLEFT|V_TRANSLUCENT, pat); + V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_TRANSLUCENT, pat); } static void ST_drawMatchHUD(void) { - const INT32 y = STRINGY(176+16)-16; // HUD_LIVESPIC + const INT32 y = 176; // HUD_LIVES INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10) - 6; if (!G_RingSlingerGametype()) @@ -1678,74 +1633,30 @@ static void ST_drawMatchHUD(void) if (G_TagGametype() && !(stplyr->pflags & PF_TAGIT)) return; -#ifdef HAVE_BLUA - if (LUA_HudEnabled(hud_weaponrings)) { -#endif + { + if (stplyr->powers[pw_infinityring]) + ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring); + else if (stplyr->rings > 0) + V_DrawScaledPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM, normring); + else + V_DrawTranslucentPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_80TRANS, normring); - if (stplyr->powers[pw_infinityring]) - ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring); - else if (stplyr->rings > 0) - V_DrawScaledPatch(8 + offset, y, V_SNAPTOLEFT, normring); - else - V_DrawTranslucentPatch(8 + offset, y, V_SNAPTOLEFT|V_80TRANS, normring); + if (!stplyr->currentweapon) + V_DrawScaledPatch(6 + offset, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); - if (!stplyr->currentweapon) - V_DrawScaledPatch(6 + offset, y-2, V_SNAPTOLEFT, curweapon); - - offset += 20; - ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring); - offset += 20; - ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, y, bouncering); - offset += 20; - ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, y, scatterring); - offset += 20; - ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, y, grenadering); - offset += 20; - ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, y, explosionring); - offset += 20; - ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, y, railring); - -#ifdef HAVE_BLUA + offset += 20; + ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring); + offset += 20; + ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, y, bouncering); + offset += 20; + ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, y, scatterring); + offset += 20; + ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, y, grenadering); + offset += 20; + ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, y, explosionring); + offset += 20; + ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, y, railring); } - - if (LUA_HudEnabled(hud_powerstones)) { -#endif - - // Power Stones collected - offset = STRINGY(128); // Used for Y now - - if (stplyr->powers[pw_emeralds] & EMERALD1) - V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][0]); - - offset += 8; - - if (stplyr->powers[pw_emeralds] & EMERALD2) - V_DrawScaledPatch(40, offset, V_SNAPTOLEFT, emeraldpics[1][1]); - - if (stplyr->powers[pw_emeralds] & EMERALD6) - V_DrawScaledPatch(16, offset, V_SNAPTOLEFT, emeraldpics[1][5]); - - offset += 16; - - if (stplyr->powers[pw_emeralds] & EMERALD3) - V_DrawScaledPatch(40, offset, V_SNAPTOLEFT, emeraldpics[1][2]); - - if (stplyr->powers[pw_emeralds] & EMERALD5) - V_DrawScaledPatch(16, offset, V_SNAPTOLEFT, emeraldpics[1][4]); - - offset += 8; - - if (stplyr->powers[pw_emeralds] & EMERALD4) - V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][3]); - - offset -= 16; - - if (stplyr->powers[pw_emeralds] & EMERALD7) - V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][6]); - -#ifdef HAVE_BLUA - } -#endif } static inline void ST_drawRaceHUD(void) @@ -1776,15 +1687,15 @@ static inline void ST_drawRaceHUD(void) if (!bounce) S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); } - V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racenum->width))/2), (INT32)(SCY(height)), V_NOSCALESTART, racenum); + V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racenum->width))/2), (INT32)(SCZ(height)), V_NOSCALESTART|V_PERPLAYER, racenum); } if (circuitmap) { if (stplyr->exiting) - V_DrawString(hudinfo[HUD_LAP].x, STRINGY(hudinfo[HUD_LAP].y), V_YELLOWMAP, "FINISHED!"); + V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, V_YELLOWMAP, "FINISHED!"); else - V_DrawString(hudinfo[HUD_LAP].x, STRINGY(hudinfo[HUD_LAP].y), 0, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); + V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, 0, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); } } @@ -1832,36 +1743,27 @@ static void ST_drawTagHUD(void) // Print the stuff. if (pstext[0]) - { - if (splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(168), 0, pstext); - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), 0, pstext); - } + V_DrawCenteredString(BASEVIDWIDTH/2, 168, V_PERPLAYER|V_SNAPTOBOTTOM, pstext); + if (pstime[0]) - { - if (splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), 0, pstime); - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(192), 0, pstime); - } + V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_PERPLAYER|V_SNAPTOBOTTOM, pstime); } static void ST_drawCTFHUD(void) { - INT32 i; + INT32 i, y = 176; UINT16 whichflag = 0; // Draw the flags - V_DrawSmallScaledPatch(256, (splitscreen) ? STRINGY(160) : STRINGY(176), V_HUDTRANS, rflagico); - V_DrawSmallScaledPatch(288, (splitscreen) ? STRINGY(160) : STRINGY(176), V_HUDTRANS, bflagico); + V_DrawSmallScaledPatch(256, y, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, rflagico); + V_DrawSmallScaledPatch(280, y, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, bflagico); for (i = 0; i < MAXPLAYERS; i++) { if (players[i].gotflag & GF_REDFLAG) // Red flag isn't at base - V_DrawScaledPatch(256, (splitscreen) ? STRINGY(156) : STRINGY(174), V_HUDTRANS, nonicon); + V_DrawScaledPatch(256, y-4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, nonicon); else if (players[i].gotflag & GF_BLUEFLAG) // Blue flag isn't at base - V_DrawScaledPatch(288, (splitscreen) ? STRINGY(156) : STRINGY(174), V_HUDTRANS, nonicon); + V_DrawScaledPatch(280, y-4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, nonicon); whichflag |= players[i].gotflag; if ((whichflag & (GF_REDFLAG|GF_BLUEFLAG)) == (GF_REDFLAG|GF_BLUEFLAG)) @@ -1872,11 +1774,7 @@ static void ST_drawCTFHUD(void) if (stplyr->gotflag) { patch_t *p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; - - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24) + 42, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - else - V_DrawScaledPatch(304, 24 + 84, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); + V_DrawScaledPatch(304, 24 + 84, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); } // Display a countdown timer showing how much time left until the flag your team dropped returns to base. @@ -1885,13 +1783,13 @@ static void ST_drawCTFHUD(void) if (redflag && redflag->fuse > 1) { sprintf(timeleft, "%u", (redflag->fuse / TICRATE)); - V_DrawCenteredString(268, STRINGY(184), V_YELLOWMAP|V_HUDTRANS, timeleft); + V_DrawCenteredString(268, y+8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, timeleft); } if (blueflag && blueflag->fuse > 1) { sprintf(timeleft, "%u", (blueflag->fuse / TICRATE)); - V_DrawCenteredString(300, STRINGY(184), V_YELLOWMAP|V_HUDTRANS, timeleft); + V_DrawCenteredString(300, y+8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, timeleft); } } } @@ -1909,7 +1807,7 @@ static void ST_drawSpecialStageHUD(void) if (sstimer) { - V_DrawString(hudinfo[HUD_TIMELEFT].x, STRINGY(hudinfo[HUD_TIMELEFT].y), V_HUDTRANS, M_GetText("TIME LEFT")); + V_DrawString(hudinfo[HUD_TIMELEFT].x, hudinfo[HUD_TIMELEFT].y, V_PERPLAYER|V_HUDTRANS, M_GetText("TIME LEFT")); ST_DrawNumFromHud(HUD_TIMELEFTNUM, sstimer/TICRATE, V_HUDTRANS); } else @@ -1952,7 +1850,7 @@ static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offse interval = 0; } - V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, STRINGY(hudinfo[HUD_HUNTPICS].y), V_HUDTRANS, patches[i]); + V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, V_PERPLAYER|V_HUDTRANS, patches[i]); return interval; } @@ -2067,13 +1965,12 @@ static void ST_overlayDrawer(void) #endif ST_drawRings(); - ST_drawLivesPic(); // always do on mystic's request - allows us to kill "RED/BLUE TEAM" text - if (G_GametypeUsesLives() + if (!modeattacking #ifdef HAVE_BLUA && LUA_HudEnabled(hud_lives) #endif ) - ST_drawLives(); + ST_drawLivesArea(); } } @@ -2113,7 +2010,7 @@ static void ST_overlayDrawer(void) } if (p) - V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, STRINGY(BASEVIDHEIGHT/2 - (SHORT(p->height)/2)) - (splitscreen ? 4 : 0), (stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p); + V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, BASEVIDHEIGHT/2 - (SHORT(p->height)/2), V_PERPLAYER|(stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p); } @@ -2121,22 +2018,21 @@ static void ST_overlayDrawer(void) { // Countdown timer for Race Mode if (countdown) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(176), 0, va("%d", countdown/TICRATE)); + V_DrawCenteredString(BASEVIDWIDTH/2, 176, V_PERPLAYER, va("%d", countdown/TICRATE)); // If you are in overtime, put a big honkin' flashin' message on the screen. if (G_RingSlingerGametype() && cv_overtime.value - && (leveltime > (timelimitintics + TICRATE/2)) && cv_timelimit.value && (leveltime/TICRATE % 2 == 0)) - { - if (splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(168), 0, M_GetText("OVERTIME!")); - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), 0, M_GetText("OVERTIME!")); - } + && (leveltime > (timelimitintics + TICRATE/2)) && cv_timelimit.value && (leveltime/TICRATE % 2 == 0)) + V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_PERPLAYER, M_GetText("OVERTIME!")); // Draw Match-related stuff //\note Match HUD is drawn no matter what gametype. // ... just not if you're a spectator. - if (!stplyr->spectator) + if (!stplyr->spectator +#ifdef HAVE_BLUA + && (LUA_HudEnabled(hud_weaponrings)) +#endif + ) ST_drawMatchHUD(); // Race HUD Stuff @@ -2160,7 +2056,7 @@ static void ST_overlayDrawer(void) ST_doHuntIconsAndSound(); if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) - V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, STRINGY(hudinfo[HUD_GRAVBOOTSICO].y), V_SNAPTORIGHT, gravboots); + V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, hudinfo[HUD_GRAVBOOTSICO].y, V_PERPLAYER|V_SNAPTORIGHT, gravboots); if(!P_IsLocalPlayer(stplyr)) { @@ -2219,12 +2115,10 @@ static void ST_overlayDrawer(void) total /= 4; } - if (exiting >= total) - ; - else + if (exiting < total) { total -= exiting; - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(124), 0, va(M_GetText("%d more player%s required to exit."), total, ((total == 1) ? "" : "s"))); + V_DrawCenteredString(BASEVIDWIDTH/2, 124, V_PERPLAYER, va(M_GetText("%d more player%s required to exit."), total, ((total == 1) ? "" : "s"))); if (!splitscreen) V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); } @@ -2234,7 +2128,7 @@ static void ST_overlayDrawer(void) else if (gametype == GT_HIDEANDSEEK && (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 116, V_PERPLAYER, M_GetText("You cannot move while hiding.")); if (!splitscreen) V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); } @@ -2242,9 +2136,9 @@ static void ST_overlayDrawer(void) { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; if (respawntime > 0 && !stplyr->spectator) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s")); else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); } else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE) #ifdef HAVE_BLUA @@ -2252,14 +2146,14 @@ static void ST_overlayDrawer(void) #endif ) { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), V_HUDTRANSHALF, M_GetText("You are a spectator.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 60, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You are a spectator.")); if (G_GametypeHasTeams()) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); else if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); else if (gametype == GT_COOP && stplyr->lives <= 0) { - if (cv_cooplives.value == 1 + if (cv_cooplives.value == 2 && (netgame || multiplayer)) { INT32 i; @@ -2276,18 +2170,14 @@ static void ST_overlayDrawer(void) } if (i != MAXPLAYERS) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132)-(splitscreen ? 12 : 0), V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); } } else if (gametype != GT_COOP) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); if (!splitscreen) - { - V_DrawCenteredString(BASEVIDWIDTH/2, 148, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); - } - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(136), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 148, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); } } diff --git a/src/st_stuff.h b/src/st_stuff.h index 9be37b502..2294c35e4 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -77,33 +77,23 @@ typedef struct typedef enum { - HUD_LIVESNAME, - HUD_LIVESPIC, - HUD_LIVESNUM, - HUD_LIVESX, + HUD_LIVES, HUD_RINGS, - HUD_RINGSSPLIT, HUD_RINGSNUM, - HUD_RINGSNUMSPLIT, HUD_RINGSNUMTICS, HUD_SCORE, HUD_SCORENUM, HUD_TIME, - HUD_TIMESPLIT, HUD_MINUTES, - HUD_MINUTESSPLIT, HUD_TIMECOLON, - HUD_TIMECOLONSPLIT, HUD_SECONDS, - HUD_SECONDSSPLIT, HUD_TIMETICCOLON, HUD_TICS, HUD_SS_TOTALRINGS, - HUD_SS_TOTALRINGS_SPLIT, HUD_GETRINGS, HUD_GETRINGSNUM, diff --git a/src/v_video.c b/src/v_video.c index 20fe9229e..c9ab2933d 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -15,6 +15,8 @@ #include "doomdef.h" #include "r_local.h" +#include "p_local.h" // stplyr +#include "g_game.h" // players #include "v_video.h" #include "hu_stuff.h" #include "r_draw.h" @@ -624,8 +626,50 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t x -= FixedMul(SHORT(patch->leftoffset)<>=1; + if (splitscreen && (scrn & V_PERPLAYER)) + { + fixed_t adjusty = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1); + fdup >>= 1; + rowfrac <<= 1; + y >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + fixed_t adjustx = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1)); + colfrac <<= 1; + x >>= 1; + if (stplyr == &players[displayplayer]) + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + else if (stplyr == &players[secondarydisplayplayer]) + { + x += adjustx; + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + y += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + x += adjustx; + y += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + scrn &= ~V_SNAPTOBOTTOM; + else //if (stplyr == &players[secondarydisplayplayer]) + { + y += adjusty; + scrn &= ~V_SNAPTOTOP; + } + } + } desttop = screens[scrn&V_PARAMMASK]; @@ -670,9 +714,9 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t if (vid.height != BASEVIDHEIGHT * dupy) { // same thing here - if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) + /*if ((scrn & (V_PERPLAYER|V_SNAPTOBOTTOM)) == (V_PERPLAYER|V_SNAPTOBOTTOM)) y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); - else if (scrn & V_SNAPTOBOTTOM) + else */if (scrn & V_SNAPTOBOTTOM) y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; @@ -835,7 +879,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ if (vid.height != BASEVIDHEIGHT * dupy) { // same thing here - if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) + if ((scrn & (V_PERPLAYER|V_SNAPTOBOTTOM)) == (V_PERPLAYER|V_SNAPTOBOTTOM)) y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); else if (scrn & V_SNAPTOBOTTOM) y += (vid.height - (BASEVIDHEIGHT * dupy)); diff --git a/src/v_video.h b/src/v_video.h index f9fd475f4..66fd2f430 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -113,7 +113,7 @@ extern RGBA_t *pMasterPalette; #define V_WRAPY 0x20000000 // Don't clamp texture on Y (for HW mode) #define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords -#define V_SPLITSCREEN 0x80000000 +#define V_PERPLAYER 0x80000000 // defines for old functions #define V_DrawPatch(x,y,s,p) V_DrawFixedPatch((x)< Date: Sun, 21 Jan 2018 12:56:38 +0000 Subject: [PATCH 022/122] * Update V_DrawCroppedPatch and V_DrawFill to support V_PERPLAYER. * Fix some mistakes in the comments for v_video.h. --- src/hardware/hw_draw.c | 81 ++++++++++++++++++++++++------- src/v_video.c | 106 ++++++++++++++++++++++++++++++++++++++--- src/v_video.h | 4 +- 3 files changed, 166 insertions(+), 25 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index f902b4802..0a09a2b41 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -194,36 +194,22 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; pdupx /= 2; cx /= 2; - if (stplyr == &players[displayplayer]) - option &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; - else if (stplyr == &players[secondarydisplayplayer]) - { + if (stplyr == &players[secondarydisplayplayer]) cx += adjustx; - option &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; - } else if (stplyr == &players[thirddisplayplayer]) - { cy += adjusty; - option &= ~V_SNAPTOTOP|V_SNAPTORIGHT; - } - else //if (stplyr == &players[fourthdisplayplayer]) + else if (stplyr == &players[fourthdisplayplayer]) { cx += adjustx; cy += adjusty; - option &= ~V_SNAPTOTOP|V_SNAPTOLEFT; } } else #endif // 2 players { - if (stplyr == &players[displayplayer]) - option &= ~V_SNAPTOBOTTOM; - else //if (stplyr == &players[secondarydisplayplayer]) - { + if (stplyr == &players[secondarydisplayplayer]) cy += adjusty; - option &= ~V_SNAPTOTOP; - } } } @@ -323,6 +309,37 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal if (option & V_NOSCALESTART) sdupx = sdupy = 2.0f; + if (splitscreen && (option & V_PERPLAYER)) + { + float adjusty = ((option & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; + pdupy /= 2; + cy /= 2; + // unlike software no need to adjust texture sourcing +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; + pdupx /= 2; + cx /= 2; + if (stplyr == &players[secondarydisplayplayer]) + cx += adjustx; + else if (stplyr == &players[thirddisplayplayer]) + cy += adjusty; + if (stplyr == &players[fourthdisplayplayer]) + { + cx += adjustx; + cy += adjusty; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[secondarydisplayplayer]) + cy += adjusty; + } + } + v[0].x = v[3].x = (cx*sdupx - gpatch->leftoffset * pdupx) / vid.width - 1; v[2].x = v[1].x = (cx*sdupx + ((w) - gpatch->leftoffset) * pdupx) / vid.width - 1; v[0].y = v[1].y = 1 - (cy*sdupy - gpatch->topoffset * pdupy) / vid.height; @@ -718,6 +735,36 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) if (color & V_NOSCALESTART) sdupx = sdupy = 2.0f; + if (splitscreen && (color & V_PERPLAYER)) + { + float adjusty = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; + w >>= 1; + y >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + float adjustx = ((color & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; + w >>= 1; + x >>= 1; + if (stplyr == &players[secondarydisplayplayer]) + x += adjustx; + else if (stplyr == &players[thirddisplayplayer]) + y += adjusty; + else if (stplyr == &players[fourthdisplayplayer]) + { + x += adjustx; + y += adjusty; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[secondarydisplayplayer]) + y += adjusty; + } + } + v[0].x = v[3].x = (x*sdupx)/vid.width - 1; v[2].x = v[1].x = (x*sdupx + w*sdupx)/vid.width - 1; v[0].y = v[1].y = 1-(y*sdupy)/vid.height; diff --git a/src/v_video.c b/src/v_video.c index c9ab2933d..10d2d9af5 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -714,9 +714,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t if (vid.height != BASEVIDHEIGHT * dupy) { // same thing here - /*if ((scrn & (V_PERPLAYER|V_SNAPTOBOTTOM)) == (V_PERPLAYER|V_SNAPTOBOTTOM)) - y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); - else */if (scrn & V_SNAPTOBOTTOM) + if (scrn & V_SNAPTOBOTTOM) y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; @@ -837,6 +835,60 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ y -= FixedMul(SHORT(patch->topoffset)<leftoffset)<>= 1; + rowfrac <<= 1; + y >>= 1; + sy >>= 1; + h >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + fixed_t adjustx = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1)); + colfrac <<= 1; + x >>= 1; + sx >>= 1; + w >>= 1; + if (stplyr == &players[displayplayer]) + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + else if (stplyr == &players[secondarydisplayplayer]) + { + x += adjustx; + sx += adjustx; + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + y += adjusty; + sy += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + x += adjustx; + sx += adjustx; + y += adjusty; + sy += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + scrn &= ~V_SNAPTOBOTTOM; + else //if (stplyr == &players[secondarydisplayplayer]) + { + y += adjusty; + sy += adjusty; + scrn &= ~V_SNAPTOTOP; + } + } + } + desttop = screens[scrn&V_PARAMMASK]; if (!desttop) @@ -879,9 +931,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ if (vid.height != BASEVIDHEIGHT * dupy) { // same thing here - if ((scrn & (V_PERPLAYER|V_SNAPTOBOTTOM)) == (V_PERPLAYER|V_SNAPTOBOTTOM)) - y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); - else if (scrn & V_SNAPTOBOTTOM) + if (scrn & V_SNAPTOBOTTOM) y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; @@ -1042,6 +1092,50 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) } #endif + if (splitscreen && (c & V_PERPLAYER)) + { + fixed_t adjusty = ((c & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)>>1; + h >>= 1; + y >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + fixed_t adjustx = ((c & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)>>1; + w >>= 1; + x >>= 1; + if (stplyr == &players[displayplayer]) + c &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + else if (stplyr == &players[secondarydisplayplayer]) + { + x += adjustx; + c &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + y += adjusty; + c &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + x += adjustx; + y += adjusty; + c &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + c &= ~V_SNAPTOBOTTOM; + else //if (stplyr == &players[secondarydisplayplayer]) + { + y += adjusty; + c &= ~V_SNAPTOTOP; + } + } + } + if (!(c & V_NOSCALESTART)) { INT32 dupx = vid.dupx, dupy = vid.dupy; diff --git a/src/v_video.h b/src/v_video.h index 66fd2f430..c5dfd35a5 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -112,8 +112,8 @@ extern RGBA_t *pMasterPalette; #define V_WRAPX 0x10000000 // Don't clamp texture on X (for HW mode) #define V_WRAPY 0x20000000 // Don't clamp texture on Y (for HW mode) -#define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords -#define V_PERPLAYER 0x80000000 +#define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords +#define V_PERPLAYER 0x80000000 // automatically adjust coordinates/scaling for splitscreen mode // defines for old functions #define V_DrawPatch(x,y,s,p) V_DrawFixedPatch((x)< Date: Mon, 22 Jan 2018 23:29:57 +0000 Subject: [PATCH 023/122] * Improve the rendering of emerald coinboxes. * Make emeralds fall onto the end tally. https://cdn.discordapp.com/attachments/400761370800422922/405122775272128512/srb20003.gif --- src/y_inter.c | 52 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index eb5e742ea..ebadfd324 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -176,14 +176,10 @@ static void Y_IntermissionTokenDrawer(void) lowy = BASEVIDHEIGHT - 32 - 8; temp = SHORT(tokenicon->height)/2; - if (!(emeralds & EMERALD1)) em = 0; - else if (!(emeralds & EMERALD2)) em = 1; - else if (!(emeralds & EMERALD3)) em = 2; - else if (!(emeralds & EMERALD4)) em = 3; - else if (!(emeralds & EMERALD5)) em = 4; - else if (!(emeralds & EMERALD6)) em = 5; - else if (!(emeralds & EMERALD7)) em = 6; - else return; + em = 0; + while (emeralds & (1 << em)) + if (++em == 7) + return; if (tallydonetic != -1) { @@ -325,7 +321,7 @@ void Y_IntermissionDrawer(void) Y_IntermissionTokenDrawer(); // draw the header - if (intertic <= TICRATE) + if (intertic <= 2*TICRATE) animatetic = 0; else if (!animatetic && data.spec.bonus.points == 0 && data.spec.passed3[0] != '\0') animatetic = intertic; @@ -378,12 +374,46 @@ void Y_IntermissionDrawer(void) //if (intertic & 1) { INT32 emeraldx = 152 - 3*28; + INT32 em = (gamemap - sstage_start); + for (i = 0; i < 7; ++i) { - if ((emeralds & (1 << i)) && ((intertic & 1) || i != (gamemap + 1 - sstage_start))) + if ((i != em) && !(intertic & 1) && (emeralds & (1 << i))) V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[0][i]); emeraldx += 28; } + + if (em < 7) + { + static UINT8 emeraldbounces = 0; + static INT32 emeraldmomy = 20; + static INT32 emeraldy = -40; + + emeraldx = 152 + (em-3)*28; + + if (intertic <= 1) + { + emeraldbounces = 0; + emeraldmomy = 20; + emeraldy = -40; + } + else + { + if (emeraldbounces < 3) + { + emeraldmomy += 1; + emeraldy += emeraldmomy; + if (emeraldy > 74) + { + S_StartSound(NULL, sfx_tink); // tink + emeraldbounces++; + emeraldmomy = -(emeraldmomy/2); + emeraldy = 74; + } + } + V_DrawScaledPatch(emeraldx, emeraldy, 0, emeraldpics[0][em]); + } + } } V_DrawScaledPatch(152, 108, 0, data.spec.bonuspatch); @@ -812,7 +842,7 @@ void Y_Ticker(void) tallydonetic = -1; } - if (intertic < TICRATE) // one second pause before tally begins + if (intertic < 2*TICRATE) // one second pause before tally begins return; for (i = 0; i < MAXPLAYERS; i++) From ab0296d1c1f3380a4e5d554170826a4f23dd0ce1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 23 Jan 2018 23:13:56 +0000 Subject: [PATCH 024/122] Added a failure animation if you don't get the emerald. https://cdn.discordapp.com/attachments/402861856219463681/405477752972509185/srb20004.gif --- src/y_inter.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index ebadfd324..063268626 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -399,13 +399,29 @@ void Y_IntermissionDrawer(void) } else { - if (emeraldbounces < 3) + if (emeralds & (1 << em)) + { + if (emeraldbounces < 3) + { + emeraldmomy += 1; + emeraldy += emeraldmomy; + if (emeraldy > 74) + { + S_StartSound(NULL, sfx_tink); // tink + emeraldbounces++; + emeraldmomy = -(emeraldmomy/2); + emeraldy = 74; + } + } + } + else { emeraldmomy += 1; emeraldy += emeraldmomy; - if (emeraldy > 74) + emeraldx += intertic - 6; + if (emeraldbounces < 1 && emeraldy > 74) { - S_StartSound(NULL, sfx_tink); // tink + S_StartSound(NULL, sfx_shldls); // nope emeraldbounces++; emeraldmomy = -(emeraldmomy/2); emeraldy = 74; From eba0978a0015527c6536596420253a7452cbabdb Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 24 Jan 2018 02:07:30 +0000 Subject: [PATCH 025/122] RIP smiles --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 52cf179e7..8a8e23654 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6165,7 +6165,7 @@ static void M_DrawLoadGameData(void) { V_DrawSmallScaledPatch(x+2, y+64, 0, savselp[5]); } -#ifndef PERFECTSAVE // disabled, don't touch +#ifdef PERFECTSAVE // disabled on request else if ((savegameinfo[savetodraw].skinnum == 1) && (savegameinfo[savetodraw].lives == 99) && (savegameinfo[savetodraw].gamemap & 8192) From bf88407d00858d2523e41dda5d24cc8485a659b8 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 9 Feb 2018 17:23:35 +0000 Subject: [PATCH 026/122] Make sure both software and OpenGL ignore patches that are completely out of a multi-patch texture's bounds. This fixes OpenGL in particular crashing because of such a weird situation. --- src/hardware/hw_cache.c | 16 ++++++++++++++-- src/r_data.c | 11 +++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 78fc31afc..919bbb31c 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -62,19 +62,31 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, UINT8 texel; UINT16 texelu16; + if (!ptexturewidth) + return; + x1 = originx; x2 = x1 + SHORT(realpatch->width); + if (x1 > ptexturewidth || x2 < 0) + return; // patch not located within texture's x bounds, ignore + + if (originy > ptextureheight || (originy + SHORT(realpatch->height)) < 0) + return; // patch not located within texture's y bounds, ignore + + // patch is actually inside the texture! + // now check if texture is partly off-screen and adjust accordingly + + // left edge if (x1 < 0) x = 0; else x = x1; + // right edge if (x2 > ptexturewidth) x2 = ptexturewidth; - if (!ptexturewidth) - return; col = x * pblockwidth / ptexturewidth; ncols = ((x2 - x) * pblockwidth) / ptexturewidth; diff --git a/src/r_data.c b/src/r_data.c index c4209fad6..169b04201 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -439,11 +439,22 @@ static UINT8 *R_GenerateTexture(size_t texnum) height = SHORT(realpatch->height); x2 = x1 + width; + if (x1 > texture->width || x2 < 0) + continue; // patch not located within texture's x bounds, ignore + + if (patch->originy > texture->height || (patch->originy + height) < 0) + continue; // patch not located within texture's y bounds, ignore + + // patch is actually inside the texture! + // now check if texture is partly off-screen and adjust accordingly + + // left edge if (x1 < 0) x = 0; else x = x1; + // right edge if (x2 > texture->width) x2 = texture->width; From c1b48ea79fb53cac98b1a5d30dcbfc65973c9ce7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 12 Feb 2018 17:47:31 +0000 Subject: [PATCH 027/122] * Total overhaul of V_DrawFadeScreen(color, strength! - controllable strengths between 0-31 for COLORMAP lump like before - arbitrary colour indices in the palette via TRANSMAP lumps, with strengths 0-9 - exposed to Lua as v.fadeScreen(color, strength)! * Remove last vestiges of V_STATICPATCH. --- src/d_clisrv.c | 2 +- src/hardware/hw_draw.c | 28 ++++++++++++++-------------- src/hardware/hw_main.h | 2 +- src/lua_hudlib.c | 18 ++++++++++++++++++ src/m_menu.c | 2 +- src/v_video.c | 36 +++++++++++++++++++++++++++--------- src/v_video.h | 2 +- 7 files changed, 63 insertions(+), 27 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 72f60aa9f..6a871057e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1125,7 +1125,7 @@ static inline void CL_DrawConnectionStatus(void) INT32 ccstime = I_GetTime(); // Draw background fade - V_DrawFadeScreen(); + V_DrawFadeScreen(0xFF00, 16); // Draw the bottom box. M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 0a09a2b41..0e10c6473 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -154,9 +154,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale); float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale); - if (alphalevel == 12) - alphalevel = 0; - else if (alphalevel >= 10 && alphalevel < 13) + if (alphalevel >= 10 && alphalevel < 13) return; // make patch ready in hardware cache @@ -283,9 +281,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale); float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale); - if (alphalevel == 12) - alphalevel = 0; - else if (alphalevel >= 10 && alphalevel < 13) + if (alphalevel >= 10 && alphalevel < 13) return; // make patch ready in hardware cache @@ -494,18 +490,14 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum // | /| // |/ | // 0--1 -void HWR_FadeScreenMenuBack(UINT32 color, INT32 height) +void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) { FOutVector v[4]; FSurfaceInfo Surf; - // setup some neat-o translucency effect - if (!height) //cool hack 0 height is full height - height = vid.height; - v[0].x = v[3].x = -1.0f; v[2].x = v[1].x = 1.0f; - v[0].y = v[1].y = 1.0f-((height<<1)/(float)vid.height); + v[0].y = v[1].y = -1.0f; v[2].y = v[3].y = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; @@ -514,8 +506,16 @@ void HWR_FadeScreenMenuBack(UINT32 color, INT32 height) v[0].tow = v[1].tow = 1.0f; v[2].tow = v[3].tow = 0.0f; - Surf.FlatColor.rgba = UINT2RGBA(color); - Surf.FlatColor.s.alpha = (UINT8)((0xff/2) * ((float)height / vid.height)); //calum: varies console alpha + if (color & 0xFF00) // Do COLORMAP fade. + { + Surf.FlatColor.rgba = UINT2RGBA(0x01010160); + Surf.FlatColor.s.alpha = 0xFF - (strength*8); + } + else // Do TRANSMAP** fade. + { + Surf.FlatColor.rgba = pLocalPalette[color].rgba; + Surf.FlatColor.s.alpha = (UINT8)((float)(10-strength)*25.5f); + } HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index cb49f817c..1ae2d8fc3 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -33,7 +33,7 @@ void HWR_Shutdown(void); void HWR_clearAutomap(void); void HWR_drawAMline(const fline_t *fl, INT32 color); -void HWR_FadeScreenMenuBack(UINT32 color, INT32 height); +void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength); void HWR_DrawConsoleBack(UINT32 color, INT32 height); void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player); void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 97835d845..c592cc2f1 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -679,6 +679,23 @@ static int libd_getColormap(lua_State *L) return 1; } +static int libd_fadeScreen(lua_State *L) +{ + UINT16 color = luaL_checkinteger(L, 1); + UINT8 strength = luaL_checkinteger(L, 2); + const UINT8 maxstrength = ((color & 0xFF00) ? 31 : 9); + + HUDONLY + if (!strength) + return 0; + + if (strength > maxstrength) + return luaL_error(L, "%s fade strength %d out of range (0 - %d)", ((color & 0xFF00) ? "COLORMAP" : "TRANSMAP"), strength, maxstrength); + + V_DrawFadeScreen(color, strength); + return 0; +} + static int libd_width(lua_State *L) { HUDONLY @@ -733,6 +750,7 @@ static luaL_Reg lib_draw[] = { {"drawString", libd_drawString}, {"stringWidth", libd_stringWidth}, {"getColormap", libd_getColormap}, + {"fadeScreen", libd_fadeScreen}, {"width", libd_width}, {"height", libd_height}, {"dupx", libd_dupx}, diff --git a/src/m_menu.c b/src/m_menu.c index 8a8e23654..9f1b7efe7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2583,7 +2583,7 @@ void M_Drawer(void) { // now that's more readable with a faded background (yeah like Quake...) if (!WipeInAction) - V_DrawFadeScreen(); + V_DrawFadeScreen(0xFF00, 16); if (currentMenu->drawroutine) currentMenu->drawroutine(); // call current menu Draw routine diff --git a/src/v_video.c b/src/v_video.c index 10d2d9af5..daf0514d5 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1321,25 +1321,43 @@ void V_DrawPatchFill(patch_t *pat) // // Fade all the screen buffer, so that the menu is more readable, // especially now that we use the small hufont in the menus... +// If color is 0x00 to 0xFF, draw transtable (strength range 0-10). +// Else, use COLORMAP lump (strength range 0-31). +// IF YOU ARE NOT CAREFUL, THIS CAN AND WILL CRASH! +// I have kept the safety checks out of this function; +// the v.fadeScreen Lua interface handles those. // -void V_DrawFadeScreen(void) +void V_DrawFadeScreen(UINT16 color, UINT8 strength) { - const UINT8 *fadetable = (UINT8 *)colormaps + 16*256; - const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - UINT8 *buf = screens[0]; + if (!strength) + return; + + if (!(color & 0xFF00) && strength == 10) + { + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, color); + return; + } #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) { - HWR_FadeScreenMenuBack(0x01010160, 0); // hack, 0 means full height + HWR_FadeScreenMenuBack(color, strength); return; } #endif - // heavily simplified -- we don't need to know x or y - // position when we're doing a full screen fade - for (; buf < deststop; ++buf) - *buf = fadetable[*buf]; + { + const UINT8 *fadetable = ((color & 0xFF00) // Color is not palette index? + ? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade. + : ((UINT8 *)transtables + ((10-strength)< Date: Mon, 12 Feb 2018 18:23:57 +0000 Subject: [PATCH 028/122] * Move the non-mapping drawFill out of the source code function and into the Lua interface. * Add a drawFill fallback for COLORMAP too. * Correct a few index mishaps. --- src/lua_hudlib.c | 9 ++++++++- src/v_video.c | 10 ++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index c592cc2f1..6991f00e7 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -683,15 +683,22 @@ static int libd_fadeScreen(lua_State *L) { UINT16 color = luaL_checkinteger(L, 1); UINT8 strength = luaL_checkinteger(L, 2); - const UINT8 maxstrength = ((color & 0xFF00) ? 31 : 9); + const UINT8 maxstrength = ((color & 0xFF00) ? 32 : 10); HUDONLY + if (!strength) return 0; if (strength > maxstrength) return luaL_error(L, "%s fade strength %d out of range (0 - %d)", ((color & 0xFF00) ? "COLORMAP" : "TRANSMAP"), strength, maxstrength); + if (strength == maxstrength) // Allow as a shortcut for drawfill... + { + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color)); + return 0; + } + V_DrawFadeScreen(color, strength); return 0; } diff --git a/src/v_video.c b/src/v_video.c index daf0514d5..47142484d 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1321,7 +1321,7 @@ void V_DrawPatchFill(patch_t *pat) // // Fade all the screen buffer, so that the menu is more readable, // especially now that we use the small hufont in the menus... -// If color is 0x00 to 0xFF, draw transtable (strength range 0-10). +// If color is 0x00 to 0xFF, draw transtable (strength range 0-9). // Else, use COLORMAP lump (strength range 0-31). // IF YOU ARE NOT CAREFUL, THIS CAN AND WILL CRASH! // I have kept the safety checks out of this function; @@ -1332,12 +1332,6 @@ void V_DrawFadeScreen(UINT16 color, UINT8 strength) if (!strength) return; - if (!(color & 0xFF00) && strength == 10) - { - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, color); - return; - } - #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) { @@ -1349,7 +1343,7 @@ void V_DrawFadeScreen(UINT16 color, UINT8 strength) { const UINT8 *fadetable = ((color & 0xFF00) // Color is not palette index? ? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade. - : ((UINT8 *)transtables + ((10-strength)< Date: Mon, 12 Feb 2018 21:31:03 +0000 Subject: [PATCH 029/122] Fixed the strengths going in the wrong direction of transparency in GL! --- src/hardware/hw_draw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 0e10c6473..072380e6b 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -509,12 +509,12 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) if (color & 0xFF00) // Do COLORMAP fade. { Surf.FlatColor.rgba = UINT2RGBA(0x01010160); - Surf.FlatColor.s.alpha = 0xFF - (strength*8); + Surf.FlatColor.s.alpha = (strength*8); } else // Do TRANSMAP** fade. { Surf.FlatColor.rgba = pLocalPalette[color].rgba; - Surf.FlatColor.s.alpha = (UINT8)((float)(10-strength)*25.5f); + Surf.FlatColor.s.alpha = (UINT8)(strength*25.5f); } HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } From 836bf5e12fe58e847a6ebd5a89dfecbf59d010a3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 14 Feb 2018 22:52:25 +0000 Subject: [PATCH 030/122] Clean up z_zone.h's function protos to look more readable like m_random.h, don't name functions with "2" if not using PARANOIA or ZDEBUG also, Z_Malloc/Calloc/Realloc are now macros of the "Align" versions, regardless of ZDEBUG or not --- src/z_zone.c | 4 ++-- src/z_zone.h | 53 +++++++++++++++++++--------------------------------- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index a28ea87b0..4e9efef4b 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -541,7 +541,7 @@ void Z_CheckHeap(INT32 i) #ifdef PARANOIA void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line) #else -void Z_ChangeTag2(void *ptr, INT32 tag) +void Z_ChangeTag(void *ptr, INT32 tag) #endif { memblock_t *block; @@ -675,7 +675,7 @@ char *Z_StrDup(const char *s) #ifdef PARANOIA void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line) #else -void Z_SetUser2(void *ptr, void **newuser) +void Z_SetUser(void *ptr, void **newuser) #endif { memblock_t *block; diff --git a/src/z_zone.h b/src/z_zone.h index 552fd87ba..baadb44a6 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -62,60 +62,45 @@ void Z_Init(void); void Z_FreeTags(INT32 lowtag, INT32 hightag); void Z_CheckMemCleanup(void); void Z_CheckHeap(INT32 i); -#ifdef PARANOIA -void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); -#else -void Z_ChangeTag2(void *ptr, INT32 tag); -#endif #ifdef PARANOIA +// This is used to get the local FILE : LINE info from CPP +// prior to really call the function in question. +// +#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__) +#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) +void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); #else -void Z_SetUser2(void *ptr, void **newuser); +void Z_ChangeTag(void *ptr, INT32 tag); +void Z_SetUser(void *ptr, void **newuser); #endif #ifdef ZDEBUG -#define Z_Free(p) Z_Free2(p, __FILE__, __LINE__) -void Z_Free2(void *ptr, const char *file, INT32 line); -#define Z_Malloc(s,t,u) Z_Malloc2(s, t, u, 0, __FILE__, __LINE__) -#define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__) -void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); -#define Z_Calloc(s,t,u) Z_Calloc2(s, t, u, 0, __FILE__, __LINE__) -#define Z_CallocAlign(s,t,u,a) Z_Calloc2(s, t, u, a, __FILE__, __LINE__) -void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); -#define Z_Realloc(p,s,t,u) Z_Realloc2(p, s, t, u, 0, __FILE__, __LINE__) +#define Z_Free(p) Z_Free2(p, __FILE__, __LINE__) +#define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__) +#define Z_CallocAlign(s,t,u,a) Z_Calloc2(s, t, u, a, __FILE__, __LINE__) #define Z_ReallocAlign(p,s,t,u,a) Z_Realloc2(p,s, t, u, a, __FILE__, __LINE__) +void Z_Free2(void *ptr, const char *file, INT32 line); +void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); +void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(2); #else void Z_Free(void *ptr); void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1); -#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0) void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1); -#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) -void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2) ; -#define Z_Realloc(p, s,t,u) Z_ReallocAlign(p, s, t, u, 0) +void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2); #endif +#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0) +#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) +#define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0) + size_t Z_TagUsage(INT32 tagnum); size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); char *Z_StrDup(const char *in); -// This is used to get the local FILE : LINE info from CPP -// prior to really call the function in question. -// -#ifdef PARANOIA -#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__) -#else -#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t) -#endif - -#ifdef PARANOIA -#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) -#else -#define Z_SetUser(p,u) Z_SetUser2(p, u) -#endif - #define Z_Unlock(p) (void)p #endif From 8f834d678453fba78b5779dc44af456dee5d8718 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 14 Feb 2018 23:16:16 +0000 Subject: [PATCH 031/122] added a quick Z_FreeTag function as a shortcut to Z_FreeTags(tag, tag) where both tags are the same --- src/hardware/hw_cache.c | 8 ++++---- src/z_zone.c | 5 +++++ src/z_zone.h | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 78fc31afc..beda40391 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -581,8 +581,8 @@ void HWR_FreeTextureCache(void) // free all hardware-converted graphics cached in the heap // our gool is only the textures since user of the texture is the texture cache - Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); // Alam: free the Z_Blocks before freeing it's users @@ -629,8 +629,8 @@ void HWR_SetPalette(RGBA_t *palette) // now flush data texture cache so 32 bit texture are recomputed if (patchformat == GR_RGBA || textureformat == GR_RGBA) { - Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); } } diff --git a/src/z_zone.c b/src/z_zone.c index 4e9efef4b..37ab3d546 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -407,6 +407,11 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) } } +void Z_FreeTag(INT32 tagnum) +{ + Z_FreeTags(tagnum, tagnum); +} + // // Z_CheckMemCleanup // diff --git a/src/z_zone.h b/src/z_zone.h index baadb44a6..57ad158cf 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -59,6 +59,7 @@ #define PU_HWRPATCHINFO_UNLOCKED 103 void Z_Init(void); +void Z_FreeTag(INT32 tagnum); void Z_FreeTags(INT32 lowtag, INT32 hightag); void Z_CheckMemCleanup(void); void Z_CheckHeap(INT32 i); From 013d185d9e72b66874c638aedc70d1afccf8829a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 15 Feb 2018 16:31:05 +0000 Subject: [PATCH 032/122] Z_FreeTag and Z_TagUsage are now both macros of their respective two arg variants --- src/z_zone.c | 12 +----------- src/z_zone.h | 4 ++-- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index 37ab3d546..cf56d0baa 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -407,11 +407,6 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) } } -void Z_FreeTag(INT32 tagnum) -{ - Z_FreeTags(tagnum, tagnum); -} - // // Z_CheckMemCleanup // @@ -610,12 +605,7 @@ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) return cnt; } -size_t Z_TagUsage(INT32 tagnum) -{ - return Z_TagsUsage(tagnum, tagnum); -} - -void Command_Memfree_f(void) +static void Command_Memfree_f(void) { UINT32 freebytes, totalbytes; diff --git a/src/z_zone.h b/src/z_zone.h index 57ad158cf..b21d951d6 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -59,7 +59,7 @@ #define PU_HWRPATCHINFO_UNLOCKED 103 void Z_Init(void); -void Z_FreeTag(INT32 tagnum); +#define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum) void Z_FreeTags(INT32 lowtag, INT32 hightag); void Z_CheckMemCleanup(void); void Z_CheckHeap(INT32 i); @@ -97,7 +97,7 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb #define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) #define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0) -size_t Z_TagUsage(INT32 tagnum); +#define Z_TagUsage(tagnum) Z_TagsUsage(tagnum, tagnum) size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); char *Z_StrDup(const char *in); From 4782cc89faec9761ac577d04463842de479a92f0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 15 Feb 2018 16:53:58 +0000 Subject: [PATCH 033/122] updating comment for Z_TagsUsage in the .c file --- src/z_zone.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/z_zone.c b/src/z_zone.c index cf56d0baa..e28de13fe 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -584,11 +584,12 @@ void Z_ChangeTag(void *ptr, INT32 tag) } /** Calculates memory usage for a given set of tags. + * NOTE: Z_TagUsage is now just a macro of this function. + * * \param lowtag The lowest tag to consider. * \param hightag The highest tag to consider. * \return Number of bytes currently allocated in the heap for the * given tags. - * \sa Z_TagUsage */ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) { From 81a9b7b07013160f7894a17f6eb012f1965d529b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 15 Feb 2018 22:09:24 +0000 Subject: [PATCH 034/122] Total reorganisation of z_zone.c/h, added doxygen-compatible comments to all functions and additional regular comments where appropriate, changed purge tag macros to an enum list --- src/z_zone.c | 370 +++++++++++++++++++++++++++++++++------------------ src/z_zone.h | 130 +++++++++++------- 2 files changed, 327 insertions(+), 173 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index e28de13fe..2c7cf7c71 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -82,6 +82,59 @@ typedef struct memblock_s struct memblock_s *next, *prev; } ATTRPACK memblock_t; +// both the head and tail of the zone memory block list +static memblock_t head; + +// +// Function prototypes +// +static void Command_Memfree_f(void); +#ifdef ZDEBUG +static void Command_Memdump_f(void); +#endif + +// -------------------------- +// Zone memory initialisation +// -------------------------- + +/** Initialises zone memory. + * Used at game startup. + * + * \sa I_GetFreeMem, Command_Memfree_f, Command_Memdump_f + */ +void Z_Init(void) +{ + UINT32 total, memfree; + + memset(&head, 0x00, sizeof(head)); + + head.next = head.prev = &head; + + memfree = I_GetFreeMem(&total)>>20; + CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree); + + // Note: This allocates memory. Watch out. + COM_AddCommand("memfree", Command_Memfree_f); + +#ifdef ZDEBUG + COM_AddCommand("memdump", Command_Memdump_f); +#endif +} + + +// ---------------------- +// Zone memory allocation +// ---------------------- + +/** Returns the corresponding memblock_t for a given memory block. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \param func A string containing the name of the function that called this, + * to be printed if the function I_Errors + * \return A pointer to the memblock_t for the given memory. + * \sa Z_Free, Z_ReallocAlign + */ #ifdef ZDEBUG #define Ptr2Memblock(s, f) Ptr2Memblock2(s, f, __FILE__, __LINE__) static memblock_t *Ptr2Memblock2(void *ptr, const char* func, const char *file, INT32 line) @@ -131,32 +184,12 @@ static memblock_t *Ptr2Memblock(void *ptr, const char* func) } -static memblock_t head; - -static void Command_Memfree_f(void); -#ifdef ZDEBUG -static void Command_Memdump_f(void); -#endif - -void Z_Init(void) -{ - UINT32 total, memfree; - - memset(&head, 0x00, sizeof(head)); - - head.next = head.prev = &head; - - memfree = I_GetFreeMem(&total)>>20; - CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree); - - // Note: This allocates memory. Watch out. - COM_AddCommand("memfree", Command_Memfree_f); - -#ifdef ZDEBUG - COM_AddCommand("memdump", Command_Memdump_f); -#endif -} - +/** Frees allocated memory. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \sa Z_FreeTags + */ #ifdef ZDEBUG void Z_Free2(void *ptr, const char *file, INT32 line) #else @@ -206,7 +239,11 @@ void Z_Free(void *ptr) #endif } -// malloc() that doesn't accept failure. +/** malloc() that doesn't accept failure. + * + * \param size Amount of memory to be allocated, in bytes. + * \return A pointer to the allocated memory. + */ static void *xm(size_t size) { const size_t padedsize = size+sizeof (size_t); @@ -227,10 +264,18 @@ static void *xm(size_t size) return p; } -// Z_Malloc -// You can pass Z_Malloc() a NULL user if the tag is less than -// PU_PURGELEVEL. - +/** The Z_MallocAlign function. + * Allocates a block of memory, adds it to a linked list so we can keep track of it. + * + * \param size Amount of memory to be allocated, in bytes. + * \param tag Purge tag. + * \param user The address of a pointer to the memory to be allocated. + * When the memory is freed by Z_Free later, + * the pointer at this address will then be automatically set to NULL. + * \param alignbits The alignment of the memory to be allocated, in bits. Can be 0. + * \note You can pass Z_Malloc() a NULL user if the tag is less than PU_PURGELEVEL. + * \sa Z_CallocAlign, Z_ReallocAlign + */ #ifdef ZDEBUG void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) @@ -307,6 +352,19 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) return given; } +/** The Z_CallocAlign function. + * Allocates a block of memory, adds it to a linked list so we can keep track of it. + * Unlike Z_MallocAlign, this also initialises the bytes to zero. + * + * \param size Amount of memory to be allocated, in bytes. + * \param tag Purge tag. + * \param user The address of a pointer to the memory to be allocated. + * When the memory is freed by Z_Free later, + * the pointer at this address will then be automatically set to NULL. + * \param alignbits The alignment of the memory to be allocated, in bits. Can be 0. + * \note You can pass Z_Calloc() a NULL user if the tag is less than PU_PURGELEVEL. + * \sa Z_MallocAlign, Z_ReallocAlign + */ #ifdef ZDEBUG void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) #else @@ -323,10 +381,26 @@ void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) #endif } +/** The Z_ReallocAlign function. + * Reallocates a block of memory with a new size. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * If NULL, this function instead acts as a wrapper for Z_CallocAlign. + * \param size New size of memory block, in bytes. + * If zero, then the memory is freed and NULL is returned. + * \param tag New purge tag. + * \param user The address of a pointer to the memory to be reallocated. + * This can be a different user to the one originally assigned to the memory block. + * \param alignbits The alignment of the memory to be allocated, in bits. Can be 0. + * \return A pointer to the reallocated memory. Can be NULL if memory was freed. + * \note You can pass Z_Realloc() a NULL user if the tag is less than PU_PURGELEVEL. + * \sa Z_MallocAlign, Z_CallocAlign + */ #ifdef ZDEBUG void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) #else -void *Z_ReallocAlign(void *ptr, size_t size,INT32 tag, void *user, INT32 alignbits) +void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) #endif { void *rez; @@ -393,6 +467,11 @@ void *Z_ReallocAlign(void *ptr, size_t size,INT32 tag, void *user, INT32 alignb return rez; } +/** Frees all memory for a given set of tags. + * + * \param lowtag The lowest tag to consider. + * \param hightag The highest tag to consider. + */ void Z_FreeTags(INT32 lowtag, INT32 hightag) { memblock_t *block, *next; @@ -407,22 +486,25 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) } } -// -// Z_CheckMemCleanup -// -// TODO: Currently blocks >= PU_PURGELEVEL are freed every -// CLEANUPCOUNT. It might be better to keep track of -// the total size of all purgable memory and free it when the -// size exceeds some value. -// -// This was in Z_Malloc, but was freeing data at -// unsafe times. Now it is only called when it is safe -// to cleanup memory. +// ----------------- +// Utility functions +// ----------------- +// starting value of nextcleanup #define CLEANUPCOUNT 2000 +// number of function calls left before next cleanup static INT32 nextcleanup = CLEANUPCOUNT; +/** This was in Z_Malloc, but was freeing data at + * unsafe times. Now it is only called when it is safe + * to cleanup memory. + * + * \todo Currently blocks >= PU_PURGELEVEL are freed every + * CLEANUPCOUNT. It might be better to keep track of + * the total size of all purgable memory and free it when the + * size exceeds some value. + */ void Z_CheckMemCleanup(void) { if (nextcleanup-- == 0) @@ -538,6 +620,17 @@ void Z_CheckHeap(INT32 i) } } +// ------------------------ +// Zone memory modification +// ------------------------ + +/** Changes a memory block's purge tag. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \param tag The new tag. + * \sa Z_SetUser + */ #ifdef PARANOIA void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line) #else @@ -583,91 +676,13 @@ void Z_ChangeTag(void *ptr, INT32 tag) block->tag = tag; } -/** Calculates memory usage for a given set of tags. - * NOTE: Z_TagUsage is now just a macro of this function. +/** Changes a memory block's user. * - * \param lowtag The lowest tag to consider. - * \param hightag The highest tag to consider. - * \return Number of bytes currently allocated in the heap for the - * given tags. + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \param newuser The new user for the memory block. + * \sa Z_ChangeTag */ -size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) -{ - size_t cnt = 0; - memblock_t *rover; - - for (rover = head.next; rover != &head; rover = rover->next) - { - if (rover->tag < lowtag || rover->tag > hightag) - continue; - cnt += rover->size + sizeof *rover; - } - - return cnt; -} - -static void Command_Memfree_f(void) -{ - UINT32 freebytes, totalbytes; - - Z_CheckHeap(-1); - CONS_Printf("\x82%s", M_GetText("Memory Info\n")); - CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TagsUsage(0, INT32_MAX)>>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("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 - if (rendermode != render_soft && rendermode != render_none) - { - CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10)); - CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10)); - CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); - CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); - CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10); - } -#endif - - CONS_Printf("\x82%s", M_GetText("System Memory Info\n")); - freebytes = I_GetFreeMem(&totalbytes); - CONS_Printf(M_GetText(" Total physical memory: %7u KB\n"), totalbytes>>10); - CONS_Printf(M_GetText("Available physical memory: %7u KB\n"), freebytes>>10); -} - -#ifdef ZDEBUG -static void Command_Memdump_f(void) -{ - memblock_t *block; - INT32 mintag = 0, maxtag = INT32_MAX; - INT32 i; - - if ((i = COM_CheckParm("-min"))) - mintag = atoi(COM_Argv(i + 1)); - - if ((i = COM_CheckParm("-max"))) - maxtag = atoi(COM_Argv(i + 1)); - - for (block = head.next; block != &head; block = block->next) - if (block->tag >= mintag && block->tag <= maxtag) - { - char *filename = strrchr(block->ownerfile, PATHSEP[0]); - CONS_Printf("[%3d] %s (%s) bytes @ %s:%d\n", block->tag, sizeu1(block->size), sizeu2(block->realsize), filename ? filename + 1 : block->ownerfile, block->ownerline); - } -} -#endif - -// Creates a copy of a string. -char *Z_StrDup(const char *s) -{ - return strcpy(ZZ_Alloc(strlen(s) + 1), s); -} - - #ifdef PARANOIA void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line) #else @@ -703,3 +718,106 @@ void Z_SetUser(void *ptr, void **newuser) block->user = (void*)newuser; *newuser = ptr; } + +// ----------------- +// Zone memory usage +// ----------------- + +/** Calculates memory usage for a given set of tags. + * + * \param lowtag The lowest tag to consider. + * \param hightag The highest tag to consider. + * \return Number of bytes currently allocated in the heap for the + * given tags. + */ +size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) +{ + size_t cnt = 0; + memblock_t *rover; + + for (rover = head.next; rover != &head; rover = rover->next) + { + if (rover->tag < lowtag || rover->tag > hightag) + continue; + cnt += rover->size + sizeof *rover; + } + + return cnt; +} + +// ----------------------- +// Miscellaneous functions +// ----------------------- + +/** The function called by the "memfree" console command. + * Prints the memory being used by each part of the game to the console. + */ +static void Command_Memfree_f(void) +{ + UINT32 freebytes, totalbytes; + + Z_CheckHeap(-1); + CONS_Printf("\x82%s", M_GetText("Memory Info\n")); + CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TagsUsage(0, INT32_MAX)>>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("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 + if (rendermode != render_soft && rendermode != render_none) + { + CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10)); + CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10)); + CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); + CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); + CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10); + } +#endif + + CONS_Printf("\x82%s", M_GetText("System Memory Info\n")); + freebytes = I_GetFreeMem(&totalbytes); + CONS_Printf(M_GetText(" Total physical memory: %7u KB\n"), totalbytes>>10); + CONS_Printf(M_GetText("Available physical memory: %7u KB\n"), freebytes>>10); +} + +#ifdef ZDEBUG +/** The function called by the "memdump" console command. + * Prints zone memory debugging information (i.e. tag, size, location in code allocated). + * Can be all memory allocated in game, or between a set of tags (if -min/-max args used). + * This command is available only if ZDEBUG is enabled. + */ +static void Command_Memdump_f(void) +{ + memblock_t *block; + INT32 mintag = 0, maxtag = INT32_MAX; + INT32 i; + + if ((i = COM_CheckParm("-min"))) + mintag = atoi(COM_Argv(i + 1)); + + if ((i = COM_CheckParm("-max"))) + maxtag = atoi(COM_Argv(i + 1)); + + for (block = head.next; block != &head; block = block->next) + if (block->tag >= mintag && block->tag <= maxtag) + { + char *filename = strrchr(block->ownerfile, PATHSEP[0]); + CONS_Printf("[%3d] %s (%s) bytes @ %s:%d\n", block->tag, sizeu1(block->size), sizeu2(block->realsize), filename ? filename + 1 : block->ownerfile, block->ownerline); + } +} +#endif + +/** Creates a copy of a string. + * + * \param s The string to be copied. + * \return A copy of the string, allocated in zone memory. + */ +char *Z_StrDup(const char *s) +{ + return strcpy(ZZ_Alloc(strlen(s) + 1), s); +} diff --git a/src/z_zone.h b/src/z_zone.h index b21d951d6..d74639be9 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -30,53 +30,53 @@ //#define ZDEBUG // -// ZONE MEMORY -// PU - purge tags. -// Tags < PU_LEVEL are not purged until freed explicitly. -#define PU_STATIC 1 // static entire execution time -#define PU_LUA 2 // static entire execution time -- used by lua so it doesn't get caught in loops forever - -#define PU_SOUND 11 // static while playing -#define PU_MUSIC 12 // static while playing -#define PU_HUDGFX 13 // static until WAD added - -#define PU_HWRPATCHINFO 21 // Hardware GLPatch_t struct for OpenGL texture cache -#define PU_HWRPATCHCOLMIPMAP 22 // Hardware GLMipmap_t struct colromap variation of patch - -#define PU_HWRCACHE 48 // static until unlocked -#define PU_CACHE 49 // static until unlocked - -// Tags s.t. PU_LEVEL <= tag < PU_PURGELEVEL are purged at level start -#define PU_LEVEL 50 // static until level exited -#define PU_LEVSPEC 51 // a special thinker in a level -#define PU_HWRPLANE 52 - -// Tags >= PU_PURGELEVEL are purgable whenever needed -#define PU_PURGELEVEL 100 -#define PU_CACHE_UNLOCKED 101 -#define PU_HWRCACHE_UNLOCKED 102 // 'second-level' cache for graphics - // stored in hardware format and downloaded as needed -#define PU_HWRPATCHINFO_UNLOCKED 103 - -void Z_Init(void); -#define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum) -void Z_FreeTags(INT32 lowtag, INT32 hightag); -void Z_CheckMemCleanup(void); -void Z_CheckHeap(INT32 i); - -#ifdef PARANOIA -// This is used to get the local FILE : LINE info from CPP -// prior to really call the function in question. +// Purge tags // -#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__) -#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) -void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); -void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); -#else -void Z_ChangeTag(void *ptr, INT32 tag); -void Z_SetUser(void *ptr, void **newuser); -#endif +// Now they are an enum! -- Monster Iestyn 15/02/18 +// +enum +{ + // Tags < PU_LEVEL are not purged until freed explicitly. + PU_STATIC = 1, // static entire execution time + PU_LUA = 2, // static entire execution time -- used by lua so it doesn't get caught in loops forever + PU_SOUND = 11, // static while playing + PU_MUSIC = 12, // static while playing + PU_HUDGFX = 13, // 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 + + PU_HWRCACHE = 48, // static until unlocked + PU_CACHE = 49, // static until unlocked + + // Tags s.t. PU_LEVEL <= tag < PU_PURGELEVEL are purged at level start + PU_LEVEL = 50, // static until level exited + PU_LEVSPEC = 51, // a special thinker in a level + PU_HWRPLANE = 52, // if ZPLANALLOC is enabled in hw_bsp.c, this is used to alloc polygons for OpenGL + + // Tags >= PU_PURGELEVEL are purgable whenever needed + PU_PURGELEVEL = 100, // Note: this is never actually used as a tag + PU_CACHE_UNLOCKED = 101, // Note: unused + PU_HWRCACHE_UNLOCKED = 102, // 'unlocked' PU_HWRCACHE memory: + // 'second-level' cache for graphics + // stored in hardware format and downloaded as needed + PU_HWRPATCHINFO_UNLOCKED = 103, // 'unlocked' PU_HWRPATCHINFO memory +}; + +// +// Zone memory initialisation +// +void Z_Init(void); + +// +// Zone memory allocation +// +// enable ZDEBUG to get the file + line the functions were called from +// for ZZ_Alloc, see doomdef.h +// + +// Z_Free and alloc with alignment #ifdef ZDEBUG #define Z_Free(p) Z_Free2(p, __FILE__, __LINE__) #define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__) @@ -93,15 +93,51 @@ void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALL void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2); #endif +// Alloc with no alignment #define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0) #define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) #define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0) +// Free all memory by tag +// these don't give line numbers for ZDEBUG currently though +// (perhaps this should be changed in future?) +#define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum) +void Z_FreeTags(INT32 lowtag, INT32 hightag); + +// +// Utility functions +// +void Z_CheckMemCleanup(void); +void Z_CheckHeap(INT32 i); + +// +// Zone memory modification +// +// enable PARANOIA to get the file + line the functions were called from +// +#ifdef PARANOIA +#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__) +#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) +void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); +void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); +#else +void Z_ChangeTag(void *ptr, INT32 tag); +void Z_SetUser(void *ptr, void **newuser); +#endif + +// +// Zone memory usage +// +// Note: These give the memory used in bytes, +// shift down by 10 to convert to KB +// #define Z_TagUsage(tagnum) Z_TagsUsage(tagnum, tagnum) size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); +// +// Miscellaneous functions +// char *Z_StrDup(const char *in); - -#define Z_Unlock(p) (void)p +#define Z_Unlock(p) (void)p // TODO: remove this now that NDS code has been removed #endif From 1bc98da70b7b4a64f1c44639f92fbbbf8cbb858e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 16 Feb 2018 20:32:43 +0000 Subject: [PATCH 035/122] Added Z_TotalUsage as a shortcut for Z_TagsUsage(0, INT32_MAX) --- src/st_stuff.c | 2 +- src/z_zone.c | 2 +- src/z_zone.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 437b6758a..887925666 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -606,7 +606,7 @@ static void ST_drawDebugInfo(void) if (cv_debug & DBG_MEMORY) { - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10))); + V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap: %7sKB", sizeu1(Z_TotalUsage()>>10))); } } diff --git a/src/z_zone.c b/src/z_zone.c index 2c7cf7c71..b5799b583 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -758,7 +758,7 @@ 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_TagsUsage(0, INT32_MAX)>>10)); + 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)); diff --git a/src/z_zone.h b/src/z_zone.h index d74639be9..205c9ed79 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -133,6 +133,7 @@ void Z_SetUser(void *ptr, void **newuser); // #define Z_TagUsage(tagnum) Z_TagsUsage(tagnum, tagnum) size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); +#define Z_TotalUsage() Z_TagsUsage(0, INT32_MAX) // // Miscellaneous functions From d921f26e54c1f9234a6eca2a31225ffe5372de32 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 17 Feb 2018 00:01:42 -0500 Subject: [PATCH 036/122] Don't init the sound system on dedicated servers --- src/d_main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 063d28453..ea24430ec 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1223,7 +1223,13 @@ void D_SRB2Main(void) CONS_Printf("R_Init(): Init SRB2 refresh daemon.\n"); R_Init(); - // setting up sound + // setting up sound + if (dedicated) + { + nosound = true; + nomidimusic = nodigimusic = true; + } + else CONS_Printf("S_Init(): Setting up sound.\n"); if (M_CheckParm("-nosound")) nosound = true; @@ -1239,7 +1245,7 @@ void D_SRB2Main(void) I_StartupSound(); I_InitMusic(); S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); - + CONS_Printf("ST_Init(): Init status bar.\n"); ST_Init(); From 36d1259cebcfb7f3ecf7be7469724379e87e3d31 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 17 Feb 2018 00:37:17 -0500 Subject: [PATCH 037/122] Removed some redundant checks --- src/sdl/sdl_sound.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 1a2cabd23..6c70c163b 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1180,12 +1180,6 @@ void I_StartupSound(void) audio.callback = I_UpdateStream; audio.userdata = &localdata; - if (dedicated) - { - nosound = nomidimusic = nodigimusic = true; - return; - } - // Configure sound device CONS_Printf("I_StartupSound:\n"); @@ -1481,9 +1475,6 @@ void I_InitMusic(void) I_AddExitFunc(I_ShutdownGMEMusic); #endif - if ((nomidimusic && nodigimusic) || dedicated) - return; - #ifdef HAVE_MIXER MIX_VERSION(&MIXcompiled) MIXlinked = Mix_Linked_Version(); From fb3e78c0205057de87222d9004cfafe0f74bc8f6 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 20 Feb 2018 17:06:03 +0000 Subject: [PATCH 038/122] Make CON_Responder eat Ctrl+key combos that have no effect, instead of passing the key on to G_Responder --- src/console.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/console.c b/src/console.c index 70f8ab6f8..267a91744 100644 --- a/src/console.c +++ b/src/console.c @@ -842,8 +842,9 @@ boolean CON_Responder(event_t *ev) return true; } - // don't eat the key - return false; + // ...why shouldn't it eat the key? if it doesn't, it just means you + // can control Sonic from the console, which is silly + return true; //return false; } // command completion forward (tab) and backward (shift-tab) From ad8c51ab8f9dd7117b303c137e46d93ee754ec09 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 21 Feb 2018 22:45:51 +0000 Subject: [PATCH 039/122] removing stupid dumb useless code fish --- src/dehacked.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b7e874b16..365241084 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1860,7 +1860,6 @@ static void readframe(MYFILE *f, INT32 num) char *word1; char *word2 = NULL; char *tmp; - INT32 j; do { @@ -1875,16 +1874,6 @@ static void readframe(MYFILE *f, INT32 num) if (s == tmp) continue; // Skip comment lines, but don't break. - for (j = 0; s[j] != '\n'; j++) - { - if (s[j] == '=') - { - j += 2; - j = atoi(&s[j]); - break; - } - } - word1 = strtok(s, " "); if (word1) strupr(word1); From 6e21059713d7012bdd4244e0a21f36f764e25581 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 23 Feb 2018 20:08:02 +0000 Subject: [PATCH 040/122] Eat unprintable keys too, since there's no reason to feed them to G_Responder anyway when the console is open --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index 267a91744..3c06561ce 100644 --- a/src/console.c +++ b/src/console.c @@ -1043,7 +1043,7 @@ boolean CON_Responder(event_t *ev) // enter a char into the command prompt if (key < 32 || key > 127) - return false; + return true; // even if key can't be printed, eat it anyway // add key to cmd line here if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers From 1216c9da18b1d3c7e22d7a13c1d7f98040d82e27 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 23 Feb 2018 20:21:16 +0000 Subject: [PATCH 041/122] Use __linux__ instead of LINUX/LINUX64 Turns out compiling for Linux 32-bit using the Makefiles never actually defines LINUX! Apart from that, most of the existing Linux-specific code in SRB2's source code (except for tmap.s) actually uses __linux__ instead anyway --- src/sdl/i_system.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 3ad57559d..4675ac142 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2709,7 +2709,7 @@ const char *I_LocateWad(void) return waddir; } -#if defined(LINUX) || defined(LINUX64) +#ifdef __linux__ #define MEMINFO_FILE "/proc/meminfo" #define MEMTOTAL "MemTotal:" #define MEMFREE "MemFree:" @@ -2773,7 +2773,7 @@ UINT32 I_GetFreeMem(UINT32 *total) (PVOID) &pr_arena, sizeof (UINT32)); return pr_arena; -#elif defined (LINUX) || defined (LINUX64) +#elif defined (__linux__) /* Linux */ char buf[1024]; char *memTag; @@ -2822,7 +2822,7 @@ UINT32 I_GetFreeMem(UINT32 *total) if (total) *total = 48<<20; return 48<<20; -#endif /* LINUX */ +#endif } const CPUInfoFlags *I_CPUInfo(void) From 4a0305eec8e4646d171ccc527cb706175609a3ba Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 23 Feb 2018 20:40:19 +0000 Subject: [PATCH 042/122] more I_GetFreeMem fixes: don't attempt to set *total to 0L if total itself is NULL --- src/sdl/i_system.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 4675ac142..e86a39cab 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2729,20 +2729,23 @@ UINT32 I_GetFreeMem(UINT32 *total) }; if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) { - *total = 0L; + if (total) + *total = 0L; return 0; } if (kvm_nlist(kd, namelist) != 0) { kvm_close (kd); - *total = 0L; + if (total) + *total = 0L; return 0; } if (kvm_read(kd, namelist[X_SUM].n_value, &sum, sizeof (sum)) != sizeof (sum)) { kvm_close(kd); - *total = 0L; + if (total) + *total = 0L; return 0; } kvm_close(kd); @@ -2789,25 +2792,28 @@ UINT32 I_GetFreeMem(UINT32 *total) if (n < 0) { // Error - *total = 0L; + if (total) + *total = 0L; return 0; } buf[n] = '\0'; - if (NULL == (memTag = strstr(buf, MEMTOTAL))) + if ((memTag = strstr(buf, MEMTOTAL)) == NULL) { // Error - *total = 0L; + if (total) + *total = 0L; return 0; } memTag += sizeof (MEMTOTAL); totalKBytes = atoi(memTag); - if (NULL == (memTag = strstr(buf, MEMFREE))) + if ((memTag = strstr(buf, MEMFREE)) == NULL) { // Error - *total = 0L; + if (total) + *total = 0L; return 0; } From 33d5baa2aad5eb6f27f19eb15900c3883c8cc8ba Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 2 Mar 2018 13:32:55 +0000 Subject: [PATCH 043/122] * Add new console text colours - sky, purple, aqua, peridot, azure, brown, rosy, and invert. * Remove redundant check from V_DrawFadeScreen(). * Clean up potential endless sound source in Race HUD. --- src/console.c | 82 +++++++++++++++++++++++++++----------------------- src/console.h | 2 +- src/dehacked.c | 10 +++++- src/st_stuff.c | 2 +- src/v_video.c | 35 ++++++++++++++------- src/v_video.h | 10 +++++- 6 files changed, 88 insertions(+), 53 deletions(-) diff --git a/src/console.c b/src/console.c index a504af06d..842d8766d 100644 --- a/src/console.c +++ b/src/console.c @@ -226,13 +226,9 @@ static void CONS_Bind_f(void) // Font colormap colors // TODO: This could probably be improved somehow... // These colormaps are 99% identical, with just a few changed bytes -UINT8 *yellowmap; -UINT8 *purplemap; -UINT8 *lgreenmap; -UINT8 *bluemap; -UINT8 *graymap; -UINT8 *redmap; -UINT8 *orangemap; +// This could EASILY be handled by modifying a centralised colormap +// for software depending on the prior state - but yknow, OpenGL... +UINT8 *yellowmap, *magentamap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap, *skymap, *purplemap, *aquamap, *peridotmap, *azuremap, *brownmap, *rosymap, *invertmap; // Console BG color UINT8 *consolebgmap = NULL; @@ -280,45 +276,55 @@ static void CONS_backcolor_Change(void) static void CON_SetupColormaps(void) { INT32 i; + UINT8 *memorysrc = (UINT8 *)Z_Malloc((256*15), PU_STATIC, NULL); - yellowmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - graymap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - purplemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - lgreenmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - bluemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - redmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - orangemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + magentamap = memorysrc; + yellowmap = (magentamap+256); + lgreenmap = (yellowmap+256); + bluemap = (lgreenmap+256); + redmap = (bluemap+256); + graymap = (redmap+256); + orangemap = (graymap+256); + skymap = (orangemap+256); + purplemap = (skymap+256); + aquamap = (purplemap+256); + peridotmap = (aquamap+256); + azuremap = (peridotmap+256); + brownmap = (azuremap+256); + rosymap = (brownmap+256); + invertmap = (rosymap+256); // setup the other colormaps, for console text // these don't need to be aligned, unless you convert the // V_DrawMappedPatch() into optimised asm. - for (i = 0; i < 256; i++) - { - yellowmap[i] = (UINT8)i; // remap each color to itself... - graymap[i] = (UINT8)i; - purplemap[i] = (UINT8)i; - lgreenmap[i] = (UINT8)i; - bluemap[i] = (UINT8)i; - redmap[i] = (UINT8)i; - orangemap[i] = (UINT8)i; - } + for (i = 0; i < (256*15); i++, ++memorysrc) + *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... - yellowmap[3] = (UINT8)73; - yellowmap[9] = (UINT8)66; - purplemap[3] = (UINT8)184; - purplemap[9] = (UINT8)186; - lgreenmap[3] = (UINT8)98; - lgreenmap[9] = (UINT8)106; - bluemap[3] = (UINT8)147; - bluemap[9] = (UINT8)158; - graymap[3] = (UINT8)10; - graymap[9] = (UINT8)15; - redmap[3] = (UINT8)210; - redmap[9] = (UINT8)32; - orangemap[3] = (UINT8)52; - orangemap[9] = (UINT8)57; +#define colset(map, a, b, c) \ + map[1] = (UINT8)a;\ + map[3] = (UINT8)b;\ + map[9] = (UINT8)c + + colset(magentamap, 177, 178, 184); + colset(yellowmap, 82, 73, 66); + colset(lgreenmap, 97, 98, 106); + colset(bluemap, 146, 147, 155); + colset(redmap, 210, 32, 39); + colset(graymap, 8, 10, 15); + colset(orangemap, 51, 52, 57); + colset(skymap, 129, 130, 133); + colset(purplemap, 160, 161, 163); + colset(aquamap, 120, 121, 123); + colset(peridotmap, 88, 188, 190); + colset(azuremap, 144, 145, 170); + colset(brownmap, 219, 221, 224); + colset(rosymap, 200, 201, 203); + colset(invertmap, 27, 26, 22); + invertmap[26] = (UINT8)3; + +#undef colset // Init back colormap CON_SetupBackColormap(); diff --git a/src/console.h b/src/console.h index 1e510e89a..970f841d0 100644 --- a/src/console.h +++ b/src/console.h @@ -34,7 +34,7 @@ extern UINT32 con_scalefactor; // console text scale factor extern consvar_t cons_backcolor; -extern UINT8 *yellowmap, *purplemap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap; +extern UINT8 *yellowmap, *magentamap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap, *skymap, *purplemap, *aquamap, *peridotmap, *azuremap, *brownmap, *rosymap, *invertmap; // Console bg color (auto updated to match) extern UINT8 *consolebgmap; diff --git a/src/dehacked.c b/src/dehacked.c index bd4530e00..7202ba31b 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7311,13 +7311,21 @@ struct { {"V_6WIDTHSPACE",V_6WIDTHSPACE}, {"V_OLDSPACING",V_OLDSPACING}, {"V_MONOSPACE",V_MONOSPACE}, - {"V_PURPLEMAP",V_PURPLEMAP}, + {"V_MAGENTAMAP",V_MAGENTAMAP}, {"V_YELLOWMAP",V_YELLOWMAP}, {"V_GREENMAP",V_GREENMAP}, {"V_BLUEMAP",V_BLUEMAP}, {"V_REDMAP",V_REDMAP}, {"V_GRAYMAP",V_GRAYMAP}, {"V_ORANGEMAP",V_ORANGEMAP}, + {"V_SKYMAP",V_SKYMAP}, + {"V_PURPLEMAP",V_PURPLEMAP}, + {"V_AQUAMAP",V_AQUAMAP}, + {"V_PERIDOTMAP",V_PERIDOTMAP}, + {"V_AZUREMAP",V_AZUREMAP}, + {"V_BROWNMAP",V_BROWNMAP}, + {"V_ROSYMAP",V_ROSYMAP}, + {"V_INVERTMAP",V_INVERTMAP}, {"V_TRANSLUCENT",V_TRANSLUCENT}, {"V_10TRANS",V_10TRANS}, {"V_20TRANS",V_20TRANS}, diff --git a/src/st_stuff.c b/src/st_stuff.c index 1426ae405..6d6c2d017 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1684,7 +1684,7 @@ static inline void ST_drawRaceHUD(void) if (bounce < 3) { height -= (2 - bounce); - if (!bounce) + if (!(P_AutoPause() || paused) && !bounce) S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); } V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racenum->width))/2), (INT32)(SCZ(height)), V_NOSCALESTART|V_PERPLAYER, racenum); diff --git a/src/v_video.c b/src/v_video.c index 47142484d..d23e5f4f5 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1329,9 +1329,6 @@ void V_DrawPatchFill(patch_t *pat) // void V_DrawFadeScreen(UINT16 color, UINT8 strength) { - if (!strength) - return; - #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) { @@ -1395,20 +1392,36 @@ static const UINT8 *V_GetStringColormap(INT32 colorflags) { switch ((colorflags & V_CHARCOLORMASK) >> V_CHARCOLORSHIFT) { - case 1: // 0x81, purple - return purplemap; - case 2: // 0x82, yellow + case 1: // 0x81, magenta + return magentamap; + case 2: // 0x82, yellow return yellowmap; - case 3: // 0x83, lgreen + case 3: // 0x83, lgreen return lgreenmap; - case 4: // 0x84, blue + case 4: // 0x84, blue return bluemap; - case 5: // 0x85, red + case 5: // 0x85, red return redmap; - case 6: // 0x86, gray + case 6: // 0x86, gray return graymap; - case 7: // 0x87, orange + case 7: // 0x87, orange return orangemap; + case 8: // 0x88, sky + return skymap; + case 9: // 0x89, purple + return purplemap; + case 10: // 0x8A, aqua + return aquamap; + case 11: // 0x8B, peridot + return peridotmap; + case 12: // 0x8C, azure + return azuremap; + case 13: // 0x8D, brown + return brownmap; + case 14: // 0x8E, rosy + return rosymap; + case 15: // 0x8F, invert + return invertmap; default: // reset return NULL; } diff --git a/src/v_video.h b/src/v_video.h index ee244c671..5645ed2ce 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -73,13 +73,21 @@ extern RGBA_t *pMasterPalette; #define V_CHARCOLORSHIFT 12 #define V_CHARCOLORMASK 0x0000F000 // for simplicity's sake, shortcuts to specific colors -#define V_PURPLEMAP 0x00001000 +#define V_MAGENTAMAP 0x00001000 #define V_YELLOWMAP 0x00002000 #define V_GREENMAP 0x00003000 #define V_BLUEMAP 0x00004000 #define V_REDMAP 0x00005000 #define V_GRAYMAP 0x00006000 #define V_ORANGEMAP 0x00007000 +#define V_SKYMAP 0x00008000 +#define V_PURPLEMAP 0x00009000 +#define V_AQUAMAP 0x0000A000 +#define V_PERIDOTMAP 0x0000B000 +#define V_AZUREMAP 0x0000C000 +#define V_BROWNMAP 0x0000D000 +#define V_ROSYMAP 0x0000E000 +#define V_INVERTMAP 0x0000F000 // use bits 17-20 for alpha transparency #define V_ALPHASHIFT 16 From 1fe79a0d718bece374aa17b32c55c9a842137f6a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Mar 2018 19:08:53 +0000 Subject: [PATCH 044/122] Fix movies not recording the "extension" to special stage intro fades --- src/p_setup.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 8e746457b..52cd6ddbb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2565,6 +2565,7 @@ boolean P_SetupLevel(boolean skipprecip) { tic_t starttime = I_GetTime(); tic_t endtime = starttime + (3*TICRATE)/2; + tic_t nowtime; S_StartSound(NULL, sfx_s3kaf); @@ -2574,9 +2575,17 @@ boolean P_SetupLevel(boolean skipprecip) F_WipeEndScreen(); F_RunWipe(wipedefs[wipe_speclevel_towhite], false); + nowtime = lastwipetic; // Hold on white for extra effect. - while (I_GetTime() < endtime) - I_Sleep(); + while (nowtime < endtime) + { + // wait loop + while (!((nowtime = I_GetTime()) - lastwipetic)) + I_Sleep(); + lastwipetic = nowtime; + if (moviemode) // make sure we save frames for the white hold too + M_SaveFrame(); + } ranspecialwipe = 1; } From e3151f26dc901fb9762ba28a5558b0704e6113a9 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Mar 2018 22:24:03 +0000 Subject: [PATCH 045/122] rewrite download file screen code: * fix screen to properly truncate the filename to just the real name only * if the real name itself is too long, use ellipsis and paste in parts of the start and end of the actual name note: I haven't actually tested if this works or compiles yet, I haven't the time right now --- src/d_clisrv.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 004eed86f..8783fb365 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1158,21 +1158,38 @@ static inline void CL_DrawConnectionStatus(void) { INT32 dldlength; static char tempname[32]; + fileneeded_t *file = &fileneeded[lastfilenum]; + char *filename = file->filename; Net_GetNetStat(); - dldlength = (INT32)((fileneeded[lastfilenum].currentsize/(double)fileneeded[lastfilenum].totalsize) * 256); + dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256); if (dldlength > 256) dldlength = 256; V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175); V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 160); memset(tempname, 0, sizeof(tempname)); - nameonly(strncpy(tempname, fileneeded[lastfilenum].filename, 31)); + // offset filename to just the name only part + filename += strlen(filename) - nameonlylength(filename); + + if (strlen(filename) > 31) // too long to display fully + { + size_t endhalfpos = strlen(filename)-12; + // display as first 16 chars + ... + last 12 chars + // which should add up to 31 if our math(s) is correct + strncpy(tempname, filename, 16); + strncpy(tempname+16, "...", 3); + strncpy(tempname+16+3, filename+endhalfpos, 12); + } + else // we can copy the whole thing in safely + { + strncpy(tempname, filename, 31); + } V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP, va(M_GetText("Downloading \"%s\""), tempname)); V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, - va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,fileneeded[lastfilenum].totalsize>>10)); + va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,file->totalsize>>10)); V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, va("%3.1fK/s ", ((double)getbps)/1024)); } From a66824d63f5ed6eaeaca8afc518d5579247f0abb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 6 Mar 2018 20:20:27 +0000 Subject: [PATCH 046/122] replace the 3 strncpys with a snprintf --- src/d_clisrv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 8783fb365..46f8a9a10 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1177,9 +1177,7 @@ static inline void CL_DrawConnectionStatus(void) size_t endhalfpos = strlen(filename)-12; // display as first 16 chars + ... + last 12 chars // which should add up to 31 if our math(s) is correct - strncpy(tempname, filename, 16); - strncpy(tempname+16, "...", 3); - strncpy(tempname+16+3, filename+endhalfpos, 12); + snprintf(tempname, 31, "%.16s...%.12s", filename, filename+endhalfpos); } else // we can copy the whole thing in safely { From aba4adfabca9adb9c3aa85b680c78bc685cea02b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 6 Mar 2018 20:52:55 +0000 Subject: [PATCH 047/122] shrunk buffer from 32 to 28 so that all of "Downloading "extremely...longname.wad"" can fit on screen at once. --- src/d_clisrv.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 46f8a9a10..7d0e44b45 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1157,7 +1157,7 @@ static inline void CL_DrawConnectionStatus(void) if (lastfilenum != -1) { INT32 dldlength; - static char tempname[32]; + static char tempname[28]; fileneeded_t *file = &fileneeded[lastfilenum]; char *filename = file->filename; @@ -1172,16 +1172,16 @@ static inline void CL_DrawConnectionStatus(void) // offset filename to just the name only part filename += strlen(filename) - nameonlylength(filename); - if (strlen(filename) > 31) // too long to display fully + if (strlen(filename) > sizeof(tempname)-1) // too long to display fully { - size_t endhalfpos = strlen(filename)-12; - // display as first 16 chars + ... + last 12 chars - // which should add up to 31 if our math(s) is correct - snprintf(tempname, 31, "%.16s...%.12s", filename, filename+endhalfpos); + size_t endhalfpos = strlen(filename)-10; + // display as first 14 chars + ... + last 10 chars + // which should add up to 27 if our math(s) is correct + snprintf(tempname, sizeof(tempname), "%.14s...%.10s", filename, filename+endhalfpos); } else // we can copy the whole thing in safely { - strncpy(tempname, filename, 31); + strncpy(tempname, filename, sizeof(tempname)-1); } V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP, From 67ee1637c98688f5d9cae6ad781373b27e372c48 Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 6 Mar 2018 03:48:15 +0000 Subject: [PATCH 048/122] Decrease far clipping plane The Far clipping plane did not need to be nearly as high as it was, the new value is 32768, which I suspect is about how far software can render before it completely falls apart. It is desirable to increase the near clipping plane to between 6-10, but it can introduce more issues with close geometry not being drawn when the player or camera is scaled or viewheight is set to MIN in first person view. It would also stop sprites from being drawn ever so slightly too early, but this isn't too much of an issue and isn't too noticeable with those values. Might look into scaling near clipping plane in accordance to camera scale in the future. The reason for wanting to increase the near clipping plane is because the small value can cause very noticeable Z-fighting where there shouldn't be on older GPU's, usually Intel ones, that don't support 24-bits for the depth buffer. --- src/hardware/hw_defs.h | 4 ++-- src/hardware/hw_main.c | 13 +++++++------ src/hardware/r_opengl/r_opengl.c | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 70d776d9e..04802122e 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -20,8 +20,8 @@ #define _HWR_DEFS_ #include "../doomtype.h" -#define ZCLIP_PLANE 4.0f -#define NZCLIP_PLANE 0.9f +#define ZCLIP_PLANE 4.0f // Used for the actual game drawing +#define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures // ========================================================================== // SIMPLE TYPES diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3a2b0f0ed..3a1cf3d9b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5330,12 +5330,13 @@ static void HWR_DrawSkyBackground(player_t *player) //Hurdler: the sky is the only texture who need 4.0f instead of 1.0 // because it's called just after clearing the screen // and thus, the near clipping plane is set to 3.99 - v[0].x = v[3].x = -4.0f; - v[1].x = v[2].x = 4.0f; - v[0].y = v[1].y = -4.0f; - v[2].y = v[3].y = 4.0f; + // Sryder: Just use the near clipping plane value then + v[0].x = v[3].x = -ZCLIP_PLANE-1; + v[1].x = v[2].x = ZCLIP_PLANE+1; + v[0].y = v[1].y = -ZCLIP_PLANE-1; + v[2].y = v[3].y = ZCLIP_PLANE+1; - v[0].z = v[1].z = v[2].z = v[3].z = 4.0f; + v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1; // X @@ -5403,7 +5404,7 @@ static inline void HWR_ClearView(void) (INT32)gr_viewwindowy, (INT32)(gr_viewwindowx + gr_viewwidth), (INT32)(gr_viewwindowy + gr_viewheight), - 3.99f); + ZCLIP_PLANE); HWD.pfnClearBuffer(false, true, 0); //disable clip window - set to full size diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 2ee5c8a80..0ab2bdae8 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -59,7 +59,7 @@ typedef struct GLRGBAFloat GLRGBAFloat; #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) #define ASPECT_RATIO (1.0f) //(320.0f/200.0f) -#define FAR_CLIPPING_PLANE 150000.0f // Draw further! Tails 01-21-2001 +#define FAR_CLIPPING_PLANE 32768.0f // Draw further! Tails 01-21-2001 static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; // ************************************************************************** From 77af3a8f95c453cfd013cf37c97cfe03f5554e7f Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 7 Mar 2018 05:19:06 +0000 Subject: [PATCH 049/122] Optimise the screen texture setup for SDL2, Post-processor, and wipes. Only use glCopyTexImage2D when first creating the screen texture, use glCopyTexSubImage2D anytime after that as it does not define a new texture each time. Flushing of the screen textures has been implemented for when the screen size changes (so that the screen textures don't stay at a wrong size) and the game is closed, I believe they would leave a memory leak before. --- src/hardware/hw_drv.h | 2 + src/hardware/hw_main.c | 3 + src/hardware/r_opengl/r_opengl.c | 145 +++++++++++++++++++++++-------- src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + src/sdl12/hwsym_sdl.c | 1 + src/sdl12/i_video.c | 1 + src/win32/win_dll.c | 2 + 8 files changed, 122 insertions(+), 34 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 7672f47c2..a5ac82001 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -79,6 +79,7 @@ EXPORT char *HWRAPI(GetRenderer) (void); #define SCREENVERTS 10 EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); #endif +EXPORT void HWRAPI(FlushScreenTextures) (void); EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(EndScreenWipe) (void); EXPORT void HWRAPI(DoScreenWipe) (float alpha); @@ -124,6 +125,7 @@ struct hwdriver_s #ifdef SHUFFLE PostImgRedraw pfnPostImgRedraw; #endif + FlushScreenTextures pfnFlushScreenTextures; StartScreenWipe pfnStartScreenWipe; EndScreenWipe pfnEndScreenWipe; DoScreenWipe pfnDoScreenWipe; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3a1cf3d9b..d401bc374 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5443,6 +5443,8 @@ void HWR_SetViewSize(void) gr_pspritexscale = gr_viewwidth / BASEVIDWIDTH; gr_pspriteyscale = ((vid.height*gr_pspritexscale*BASEVIDWIDTH)/BASEVIDHEIGHT)/vid.width; + + HWD.pfnFlushScreenTextures(); } // ========================================================================== @@ -6036,6 +6038,7 @@ void HWR_Shutdown(void) HWR_FreeExtraSubsectors(); HWR_FreePolyPool(); HWR_FreeTextureCache(); + HWD.pfnFlushScreenTextures(); } void transform(float *cx, float *cy, float *cz) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 0ab2bdae8..9eb013a13 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -107,10 +107,19 @@ static GLint viewport[4]; #endif // Yay for arbitrary numbers! NextTexAvail is buggy for some reason. -static GLuint screentexture = 60000; -static GLuint startScreenWipe = 60001; -static GLuint endScreenWipe = 60002; -static GLuint finalScreenTexture = 60003; +// Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing +// flush all of the stored textures, leaving them unavailable at times such as between levels +// These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs +// can know when the textures aren't there, as textures are always considered resident in their virtual memory +// TODO: Store them in a more normal way +#define SCRTEX_SCREENTEXTURE 65535 +#define SCRTEX_STARTSCREENWIPE 65534 +#define SCRTEX_ENDSCREENWIPE 65533 +#define SCRTEX_FINALSCREENTEXTURE 65532 +static GLuint screentexture = 0; +static GLuint startScreenWipe = 0; +static GLuint endScreenWipe = 0; +static GLuint finalScreenTexture = 0; #if 0 GLuint screentexture = FIRST_TEX_AVAIL; #endif @@ -263,6 +272,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) /* texture mapping */ //GL_EXT_copy_texture #ifndef KOS_GL_COMPATIBILITY #define pglCopyTexImage2D glCopyTexImage2D +#define pglCopyTexSubImage2D glCopyTexSubImage2D #endif #else //!STATIC_OPENGL @@ -387,6 +397,8 @@ static PFNglBindTexture pglBindTexture; /* texture mapping */ //GL_EXT_copy_texture typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); static PFNglCopyTexImage2D pglCopyTexImage2D; +typedef void (APIENTRY * PFNglCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +static PFNglCopyTexSubImage2D pglCopyTexSubImage2D; #endif /* GLU functions */ typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data); @@ -503,6 +515,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglBindTexture , glBindTexture) GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D) + GETOPENGLFUNC(pglCopyTexSubImage2D , glCopyTexSubImage2D) #undef GETOPENGLFUNC @@ -654,6 +667,10 @@ void SetModelView(GLint w, GLint h) { // DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); + // The screen textures need to be flushed if the width or height change so that they be remade for the correct size + if (screen_width != w || screen_height != h) + FlushScreenTextures(); + screen_width = w; screen_height = h; @@ -801,6 +818,7 @@ void Flush(void) screentexture = FIRST_TEX_AVAIL; } #endif + tex_downloaded = 0; } @@ -2156,10 +2174,25 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) } #endif //SHUFFLE +// Sryder: This needs to be called whenever the screen changes resolution in order to reset the screen textures to use +// a new size +EXPORT void HWRAPI(FlushScreenTextures) (void) +{ + pglDeleteTextures(1, &screentexture); + pglDeleteTextures(1, &startScreenWipe); + pglDeleteTextures(1, &endScreenWipe); + pglDeleteTextures(1, &finalScreenTexture); + screentexture = 0; + startScreenWipe = 0; + endScreenWipe = 0; + finalScreenTexture = 0; +} + // Create Screen to fade from EXPORT void HWRAPI(StartScreenWipe) (void) { INT32 texsize = 2048; + boolean firstTime = (startScreenWipe == 0); // Use a power of two texture, dammit if(screen_width <= 512) @@ -2168,27 +2201,38 @@ EXPORT void HWRAPI(StartScreenWipe) (void) texsize = 1024; // Create screen texture + if (firstTime) + startScreenWipe = SCRTEX_STARTSCREENWIPE; pglBindTexture(GL_TEXTURE_2D, startScreenWipe); + + if (firstTime) + { #ifdef KOS_GL_COMPATIBILITY - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); #else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #endif - Clamp2D(GL_TEXTURE_WRAP_S); - Clamp2D(GL_TEXTURE_WRAP_T); + Clamp2D(GL_TEXTURE_WRAP_S); + Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); +#endif + } + else +#ifndef KOS_GL_COMPATIBILITY + pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); #endif - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + tex_downloaded = startScreenWipe; } // Create Screen to fade to EXPORT void HWRAPI(EndScreenWipe)(void) { INT32 texsize = 2048; + boolean firstTime = (endScreenWipe == 0); // Use a power of two texture, dammit if(screen_width <= 512) @@ -2197,21 +2241,32 @@ EXPORT void HWRAPI(EndScreenWipe)(void) texsize = 1024; // Create screen texture + if (firstTime) + endScreenWipe = SCRTEX_ENDSCREENWIPE; pglBindTexture(GL_TEXTURE_2D, endScreenWipe); + + if (firstTime) + { #ifdef KOS_GL_COMPATIBILITY - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); #else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #endif - Clamp2D(GL_TEXTURE_WRAP_S); - Clamp2D(GL_TEXTURE_WRAP_T); + Clamp2D(GL_TEXTURE_WRAP_S); + Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); +#endif + } + else +#ifndef KOS_GL_COMPATIBILITY + pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); #endif - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + + tex_downloaded = endScreenWipe; } @@ -2253,7 +2308,7 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void) pglEnd(); - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + tex_downloaded = screentexture; } // Do screen fades! @@ -2344,6 +2399,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha) pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit pglActiveTexture(GL_TEXTURE0); + tex_downloaded = endScreenWipe; } else { @@ -2369,11 +2425,10 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha) pglTexCoord2f(xfix, 0.0f); pglVertex3f(1.0f, -1.0f, 1.0f); pglEnd(); + tex_downloaded = endScreenWipe; #ifndef MINI_GL_COMPATIBILITY } #endif - - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now } @@ -2381,6 +2436,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha) EXPORT void HWRAPI(MakeScreenTexture) (void) { INT32 texsize = 2048; + boolean firstTime = (screentexture == 0); // Use a power of two texture, dammit if(screen_width <= 512) @@ -2389,7 +2445,12 @@ EXPORT void HWRAPI(MakeScreenTexture) (void) texsize = 1024; // Create screen texture + if (firstTime) + screentexture = SCRTEX_SCREENTEXTURE; pglBindTexture(GL_TEXTURE_2D, screentexture); + + if (firstTime) + { #ifdef KOS_GL_COMPATIBILITY pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); @@ -2400,15 +2461,21 @@ EXPORT void HWRAPI(MakeScreenTexture) (void) Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); +#endif + } + else +#ifndef KOS_GL_COMPATIBILITY + pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); #endif - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + tex_downloaded = screentexture; } EXPORT void HWRAPI(MakeScreenFinalTexture) (void) { INT32 texsize = 2048; + boolean firstTime = (finalScreenTexture == 0); // Use a power of two texture, dammit if(screen_width <= 512) @@ -2417,21 +2484,31 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void) texsize = 1024; // Create screen texture + if (firstTime) + finalScreenTexture = SCRTEX_FINALSCREENTEXTURE; pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); + + if (firstTime) + { #ifdef KOS_GL_COMPATIBILITY - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); #else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #endif - Clamp2D(GL_TEXTURE_WRAP_S); - Clamp2D(GL_TEXTURE_WRAP_T); + Clamp2D(GL_TEXTURE_WRAP_S); + Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); +#endif + } + else +#ifndef KOS_GL_COMPATIBILITY + pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); #endif - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + tex_downloaded = finalScreenTexture; } @@ -2476,7 +2553,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) SetModelView(screen_width, screen_height); SetStates(); - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + tex_downloaded = finalScreenTexture; } #endif //HWRENDER diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index f4686d2bf..05ac6450e 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -94,6 +94,7 @@ void *hwSym(const char *funcName,void *handle) #ifdef SHUFFLE GETFUNC(PostImgRedraw); #endif //SHUFFLE + GETFUNC(FlushScreenTextures); GETFUNC(StartScreenWipe); GETFUNC(EndScreenWipe); GETFUNC(DoScreenWipe); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 1bda0e180..87ce84158 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1442,6 +1442,7 @@ void I_StartupGraphics(void) #ifdef SHUFFLE HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); #endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); diff --git a/src/sdl12/hwsym_sdl.c b/src/sdl12/hwsym_sdl.c index 54f5da3a0..49340138f 100644 --- a/src/sdl12/hwsym_sdl.c +++ b/src/sdl12/hwsym_sdl.c @@ -100,6 +100,7 @@ void *hwSym(const char *funcName,void *handle) #ifdef SHUFFLE GETFUNC(PostImgRedraw); #endif //SHUFFLE + GETFUNC(FlushScreenTextures); GETFUNC(StartScreenWipe); GETFUNC(EndScreenWipe); GETFUNC(DoScreenWipe); diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index 197924eda..349e06cba 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -1972,6 +1972,7 @@ void I_StartupGraphics(void) #ifdef SHUFFLE HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); #endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index 8fa4d17f7..c9b3fba4e 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -117,6 +117,7 @@ static loadfunc_t hwdFuncTable[] = { #ifdef SHUFFLE {"PostImgRedraw@4", &hwdriver.pfnPostImgRedraw}, #endif + {"FlushScreenTextures@0",&hwdriver.pfnFlushScreenTextures}, {"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe}, {"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe}, {"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe}, @@ -147,6 +148,7 @@ static loadfunc_t hwdFuncTable[] = { #ifdef SHUFFLE {"PostImgRedraw", &hwdriver.pfnPostImgRedraw}, #endif + {"FlushScreenTextures"},&hwdriver.pfnFlushScreenTextures}, {"StartScreenWipe", &hwdriver.pfnStartScreenWipe}, {"EndScreenWipe", &hwdriver.pfnEndScreenWipe}, {"DoScreenWipe", &hwdriver.pfnDoScreenWipe}, From 121fcd83692d2e3946678bc270a80fe679247110 Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 8 Mar 2018 22:28:38 +0000 Subject: [PATCH 050/122] Fix screenshot functionality in fullscreen in SDL2 --- src/hardware/hw_draw.c | 14 ++++++ src/hardware/hw_drv.h | 6 +++ src/hardware/r_opengl/r_opengl.c | 79 ++++++++++++++++++++++++++++++++ src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + src/sdl12/hwsym_sdl.c | 1 + src/sdl12/i_video.c | 1 + 7 files changed, 103 insertions(+) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index f23753ee5..867a86a15 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -769,6 +769,9 @@ UINT8 *HWR_GetScreenshot(void) if (!buf) return NULL; // returns 24bit 888 RGB +#ifdef HAVE_SDL + if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf)) +#endif HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); return buf; } @@ -782,8 +785,19 @@ boolean HWR_Screenshot(const char *lbmname) return false; // returns 24bit 888 RGB +#ifdef HAVE_SDL + // Sryder: SDL2 uses borderless fullscreen mode, and creates a screen texture to upscale to the screen size. + // This breaks screenshots because the code here takes a screenshot of just the resolution from the bottom + // left corner, while the "true" resolution is the monitor resolution. We can either take a screenshot of + // the true resolution or just use the already made screen texture + // NOTE: The SDL1.2 version should get a return of false from ReadScreenTexture as no screen texture will have + // been made, this will also mean that if the screen texture doesn't exist for some reason it will fall + // back to the old version + if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf)) +#endif HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); + #ifdef USE_PNG ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL); #else diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index a5ac82001..ab4025697 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -58,6 +58,9 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data); +#ifdef HAVE_SDL +EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 * dst_data); +#endif EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); EXPORT void HWRAPI(ClearMipMapCache) (void); @@ -104,6 +107,9 @@ struct hwdriver_s ClearBuffer pfnClearBuffer; SetTexture pfnSetTexture; ReadRect pfnReadRect; +#ifdef HAVE_SDL + ReadScreenTexture pfnReadScreenTexture; +#endif GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 9eb013a13..fb8555aa9 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -260,6 +260,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglTexEnvi glTexEnvi #define pglTexParameteri glTexParameteri #define pglTexImage2D glTexImage2D +#define pglGetTexImage glGetTexImage /* Fog */ #define pglFogf glFogf @@ -381,6 +382,8 @@ typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint static PFNglTexParameteri pglTexParameteri; typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static PFNglTexImage2D pglTexImage2D; +typedef void (APIENTRY * PFNglGetTexImage) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +static PFNglGetTexImage pglGetTexImage; /* Fog */ typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param); @@ -507,6 +510,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglTexEnvi , glTexEnvi) GETOPENGLFUNC(pglTexParameteri , glTexParameteri) GETOPENGLFUNC(pglTexImage2D , glTexImage2D) + GETOPENGLFUNC(pglGetTexImage , glGetTexImage) GETOPENGLFUNC(pglFogf , glFogf) GETOPENGLFUNC(pglFogfv , glFogfv) @@ -933,6 +937,81 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, #endif } +#ifdef HAVE_SDL +EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width, + INT32 height, INT32 dst_stride, + UINT16 * dst_data) +{ +#ifdef KOS_GL_COMPATIBILITY + (void)x; + (void)y; + (void)width; + (void)height; + (void)dst_stride; + (void)dst_data; +#else + INT32 i, j; + INT32 texsize = 2048; + GLubyte *image; + // DBG_Printf ("ReadScreenTexture()\n"); + if (screentexture == 0) + return false; // No screen texture + + if(screen_width <= 1024) + texsize = 1024; + if(screen_width <= 512) + texsize = 512; + + if (x < 0) + x = 0; + if (x + width > screen_width) + width = screen_width - x; + if (y < 0) + y = 0; + if (y + height > screen_height) + height = screen_height - y; + + image = malloc(texsize*texsize*3*sizeof (*image)); + if (!image) + return false; + pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); + tex_downloaded = finalScreenTexture; + pglGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image); + + if (dst_stride == width*3) + { + UINT8 *dest = (void *)dst_data; + for (i = y + height-1; i >= y; i--) + { + for (j = x; j < width + x; j++) + { + dest[((height-1-i-y)*width+j-x)*3] = image[(i*texsize+j)*3]; + dest[((height-1-i-y)*width+j-x)*3+1] = image[(i*texsize+j)*3+1]; + dest[((height-1-i-y)*width+j-x)*3+2] = image[(i*texsize+j)*3+2]; + } + } + } + else + { + // Sryder: NOTE: I'm not entirely sure this works, as far as I know nothing in the game uses it. + for (i = y + height-1; i >= y; i--) + { + for (j = x; j < width + x; j++) + { + dst_data[(height-1-i-y)*width+j-x] = + (UINT16)( + ((image[(i*texsize+j)*3]>>3)<<11) | + ((image[(i*texsize+j)*3+1]>>2)<<5) | + ((image[(i*texsize+j)*3+2]>>3))); + } + } + } + free(image); + return true; +#endif +} +#endif + // -----------------+ // GClipRect : Defines the 2D hardware clipping window diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 05ac6450e..33bcfd6f3 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -83,6 +83,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearBuffer); GETFUNC(SetTexture); GETFUNC(ReadRect); + GETFUNC(ReadScreenTexture); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); GETFUNC(SetSpecialState); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 87ce84158..2df8a6ff5 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1430,6 +1430,7 @@ void I_StartupGraphics(void) HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); diff --git a/src/sdl12/hwsym_sdl.c b/src/sdl12/hwsym_sdl.c index 49340138f..3a10d8253 100644 --- a/src/sdl12/hwsym_sdl.c +++ b/src/sdl12/hwsym_sdl.c @@ -89,6 +89,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearBuffer); GETFUNC(SetTexture); GETFUNC(ReadRect); + GETFUNC(ReadScreenTexture); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); GETFUNC(SetSpecialState); diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index 349e06cba..076ce4fd2 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -1960,6 +1960,7 @@ void I_StartupGraphics(void) HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); From e4ed3a793b7ad37db1ecb8cc600f300af6b20c91 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 9 Mar 2018 09:58:10 +0000 Subject: [PATCH 051/122] Small hacky fix for MD2s and sprites until sorting for walls, floors, and sprites is done Sorts all translucent sprites and MD2s so they're drawn after all the opaque ones. Fixes most of the observable issues between translucent MD2s and opaque sprites/MD2s. --- src/hardware/hw_main.c | 30 ++++++++++++++++++++++++++++++ src/hardware/r_opengl/r_opengl.c | 1 - 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d401bc374..33cf54a38 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4565,6 +4565,33 @@ static void HWR_SortVisSprites(void) gr_vsprsortedhead.prev->next = best; gr_vsprsortedhead.prev = best; } + + // Sryder: Oh boy, while it's nice having ALL the sprites sorted properly, it fails when we bring MD2's into the + // mix and they want to be translucent. So let's place all the translucent sprites and MD2's AFTER + // everything else, but still ordered of course, the depth buffer can handle the opaque ones plenty fine. + // We just need to move all translucent ones to the end in order + // TODO: Fully sort all sprites and MD2s with walls and floors, this part will be unnecessary after that + best = gr_vsprsortedhead.next; + for (i = 0; i < gr_visspritecount; i++) + { + if ((best->mobj->flags2 & MF2_SHADOW) || (best->mobj->frame & FF_TRANSMASK)) + { + if (best == gr_vsprsortedhead.next) + { + gr_vsprsortedhead.next = best->next; + } + best->prev->next = best->next; + best->next->prev = best->prev; + best->prev = gr_vsprsortedhead.prev; + gr_vsprsortedhead.prev->next = best; + gr_vsprsortedhead.prev = best; + ds = best; + best = best->next; + ds->next = &gr_vsprsortedhead; + } + else + best = best->next; + } } // A drawnode is something that points to a 3D floor, 3D side, or masked @@ -4912,7 +4939,10 @@ static void HWR_DrawSprites(FTransform *stransform) { #ifdef HWPRECIP if (spr->precip) + { + HWD.pfnSetTransform(stransform); HWR_DrawPrecipitationSprite(spr); + } else #endif if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index fb8555aa9..14cff5995 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2100,7 +2100,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, if (color) pglDisable(GL_LIGHTING); pglShadeModel(GL_FLAT); - pglDepthMask(GL_TRUE); pglDisable(GL_CULL_FACE); } From aefe06e2ef61681a5c34b803e6cce739c12c7c52 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 9 Mar 2018 16:34:09 +0100 Subject: [PATCH 052/122] Fix Lua panic when archiving a table element with an userdata key --- src/lua_script.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index 167e4a0b4..ce96878bf 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -478,10 +478,10 @@ static const struct { {NULL, ARCH_NULL} }; -static UINT8 GetUserdataArchType(void) +static UINT8 GetUserdataArchType(int index) { UINT8 i; - lua_getmetatable(gL, -1); + lua_getmetatable(gL, index); for (i = 0; meta2arch[i].meta; i++) { @@ -560,7 +560,7 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) break; } case LUA_TUSERDATA: - switch (GetUserdataArchType()) + switch (GetUserdataArchType(myindex)) { case ARCH_MOBJINFO: { @@ -777,6 +777,7 @@ static void ArchiveTables(void) CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -1), luaL_typename(gL, -1)); lua_pop(gL, 1); } + lua_pop(gL, 1); } lua_pop(gL, 1); From 68cb91920508ada5962640a46afe041873933e31 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 14 Mar 2018 16:47:19 +0000 Subject: [PATCH 053/122] down with cis --- src/f_finale.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 692abb35f..17110df4f 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -969,7 +969,7 @@ static const char *credits[] = { "\1Programming", "Alam \"GBC\" Arias", "Logan \"GBA\" Arias", - "Tim \"RedEnchilada\" Bordelon", + "Colette \"fickle\" Bordelon", "Callum Dickinson", "Scott \"Graue\" Feeney", "Nathan \"Jazz\" Giroux", @@ -979,11 +979,11 @@ static const char *credits[] = { "John \"JTE\" Muniz", "Ehab \"Wolfy\" Saeed", "\"SSNTails\"", - "Matthew \"Inuyasha\" Walsh", + "\"Kaito Sinclaire\"", "", "\1Programming", "\1Assistance", - "\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom) + "\"chi.miru\"", // helped port slope drawing code from ZDoom "Andrew \"orospakr\" Clunis", "Gregor \"Oogaland\" Dick", "Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol) @@ -1047,7 +1047,7 @@ static const char *credits[] = { "Rob Tisdell", "Jarrett \"JEV3\" Voight", "Johnny \"Sonikku\" Wallbank", - "Matthew \"Inuyasha\" Walsh", + "\"Kaito Sinclaire\"", "Marco \"Digiku\" Zafra", "", "\1Boss Design", From a5ab9f01bbb9114af91b3073e845136a848192a9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 14 Mar 2018 16:49:10 +0000 Subject: [PATCH 054/122] oh yeah this guy's name needs changing too --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 17110df4f..36258664a 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1017,7 +1017,7 @@ static const char *credits[] = { "\1Music and Sound", "\1Production", "Malcolm \"RedXVI\" Brown", - "David \"Bulmybag\" Bulmer", + "Dave \"DemonTomatoDave\" Bulmer", "Paul \"Boinciel\" Clempson", "Cyan Helkaraxe", "Kepa \"Nev3r\" Iceta", From fee87141096949b139cd052f9f0e7a13861180e8 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 14 Mar 2018 16:55:33 +0000 Subject: [PATCH 055/122] i suck at the alphabet! --- src/f_finale.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 36258664a..0bcf24ed5 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -978,8 +978,8 @@ static const char *credits[] = { "Ronald \"Furyhunter\" Kinard", // The SDL2 port "John \"JTE\" Muniz", "Ehab \"Wolfy\" Saeed", - "\"SSNTails\"", "\"Kaito Sinclaire\"", + "\"SSNTails\"", "", "\1Programming", "\1Assistance", @@ -1041,13 +1041,13 @@ static const char *credits[] = { "Kepa \"Nev3r\" Iceta", "Thomas \"Shadow Hog\" Igoe", "Erik \"Torgo\" Nielsen", + "\"Kaito Sinclaire\"", "Wessel \"Spherallic\" Smit", "\"Spazzo\"", "\"SSNTails\"", "Rob Tisdell", "Jarrett \"JEV3\" Voight", "Johnny \"Sonikku\" Wallbank", - "\"Kaito Sinclaire\"", "Marco \"Digiku\" Zafra", "", "\1Boss Design", From 5a4ea9fab3d447abc5374ab24a361c43e6784ddf Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 15 Mar 2018 23:58:37 +0000 Subject: [PATCH 056/122] Better fog block colouring They still aren't perfect, but now they are at least not quite so obviously just translucent polygons over the level. A mixture between partially modulating the background colours and adding the fog colour. Notably white fog blocks look like they're brightening what's behind them. Additive was also setting noalphatest before, can probably decide that depending on what it needs anyway. I don't think it's currently used anyway. --- src/hardware/hw_defs.h | 5 ++-- src/hardware/hw_main.c | 40 +++++++++++++++----------------- src/hardware/r_opengl/r_opengl.c | 8 +++++++ 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 04802122e..c05ff3e79 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -133,12 +133,13 @@ enum EPolyFlags PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture) PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency - PF_Additive = 0x00000024, // Poly is added to the frame buffer + PF_Additive = 0x00000004, // Poly is added to the frame buffer PF_Environment = 0x00000008, // Poly should be drawn environment mapped. // Hurdler: used for text drawing PF_Substractive = 0x00000010, // for splat PF_NoAlphaTest = 0x00000020, // hiden param - PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive)&~PF_NoAlphaTest, + PF_Fog = 0x00000040, // Fog blocks + PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest, // other flag bits diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 33cf54a38..284c2c555 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -489,10 +489,10 @@ UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogbloc } -static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color, UINT32 fadecolor) // Let's see if this can work +static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this can work { - RGBA_t realcolor, fogcolor, surfcolor; - INT32 alpha, fogalpha; + RGBA_t realcolor, surfcolor; + INT32 alpha; // Don't go out of bounds if (light < 0) @@ -501,13 +501,11 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color, UINT32 fadecolor) // L light = 255; realcolor.rgba = color; - fogcolor.rgba = fadecolor; alpha = (realcolor.s.alpha*255)/25; - fogalpha = (fogcolor.s.alpha*255)/25; - // Fog blocks seem to get slightly more opaque with more opaque colourmap opacity, and much more opaque with darker brightness - surfcolor.s.alpha = (UINT8)(CALCLIGHT(light, ((0xFF-light)+alpha)/2)+CALCLIGHT(0xFF-light, ((light)+fogalpha)/2)); + // at 255 brightness, alpha is between 0 and 127, at 0 brightness alpha will always be 255 + surfcolor.s.alpha = (alpha*light)/(2*256)+255-light; return surfcolor.s.alpha; } @@ -773,7 +771,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, true); } - if (PolyFlags & PF_Translucent) + if (PolyFlags & (PF_Translucent|PF_Fog)) { Surf.FlatColor.s.alpha = (UINT8)alpha; PolyFlags |= PF_Modulated|PF_Occlude|PF_Clip; @@ -1380,7 +1378,7 @@ static void HWR_SplitFog(sector_t *sector, wallVert3D *wallVerts, FSurfaceInfo* wallVerts[0].y = wallVerts[1].y = bot; if (!solid) // Don't draw it if there's more fog behind it - HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Translucent|PF_NoTexture, true, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Fog|PF_NoTexture, true, lightnum, colormap); top = height; } @@ -2306,7 +2304,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { FBITFIELD blendmode; - blendmode = PF_Translucent|PF_NoTexture; + blendmode = PF_Fog|PF_NoTexture; lightnum = rover->master->frontsector->lightlevel; colormap = rover->master->frontsector->extra_colormap; @@ -2314,11 +2312,11 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (rover->master->frontsector->extra_colormap) { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba,rover->master->frontsector->extra_colormap->fadergba); + Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba); } else { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG,FADEFOG); + Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG); } if (gr_frontsector->numlights) @@ -2426,18 +2424,18 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { FBITFIELD blendmode; - blendmode = PF_Translucent|PF_NoTexture; + blendmode = PF_Fog|PF_NoTexture; lightnum = rover->master->frontsector->lightlevel; colormap = rover->master->frontsector->extra_colormap; if (rover->master->frontsector->extra_colormap) { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba,rover->master->frontsector->extra_colormap->fadergba); + Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba); } else { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG,FADEFOG); + Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG); } if (gr_backsector->numlights) @@ -3547,16 +3545,16 @@ static void HWR_Subsector(size_t num) light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); if (rover->master->frontsector->extra_colormap) - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba, rover->master->frontsector->extra_colormap->fadergba); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba); else - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG, FADEFOG); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); HWR_AddTransparentFloor(0, &extrasubsectors[num], false, *rover->bottomheight, *gr_frontsector->lightlist[light].lightlevel, - alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture, + alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) // SoM: Flags are more efficient @@ -3610,16 +3608,16 @@ static void HWR_Subsector(size_t num) light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); if (rover->master->frontsector->extra_colormap) - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba, rover->master->frontsector->extra_colormap->fadergba); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba); else - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG, FADEFOG); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); HWR_AddTransparentFloor(0, &extrasubsectors[num], true, *rover->topheight, *gr_frontsector->lightlist[light].lightlevel, - alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture, + alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 14cff5995..cf87c101e 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1187,6 +1187,14 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); #ifndef KOS_GL_COMPATIBILITY pglAlphaFunc(GL_NOTEQUAL, 0.0f); +#endif + break; + case PF_Fog & PF_Fog: + // Sryder: Fog + // multiplies input colour by input alpha, and destination colour by input colour, then adds them + pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR); +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_NOTEQUAL, 0.0f); #endif break; default : // must be 0, otherwise it's an error From 1b3e1f78af6d58519a011eb84b55f3edf22e3cd0 Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 15 Mar 2018 23:59:01 +0000 Subject: [PATCH 057/122] Translucent floors shouldn't write into the depth buffer --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 284c2c555..83783072f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -774,7 +774,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (PolyFlags & (PF_Translucent|PF_Fog)) { Surf.FlatColor.s.alpha = (UINT8)alpha; - PolyFlags |= PF_Modulated|PF_Occlude|PF_Clip; + PolyFlags |= PF_Modulated|PF_Clip; } else PolyFlags |= PF_Masked|PF_Modulated|PF_Clip; From 7764a1bb5dcc8c91929c5c9a475e1f61633dce0c Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 16 Mar 2018 18:08:24 +0000 Subject: [PATCH 058/122] Match HWR_DrawFixedPatch to V_DrawFixedPatch --- src/hardware/hw_draw.c | 103 ++++++++++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 21 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 867a86a15..30b0518cb 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -147,10 +147,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, // | /| // |/ | // 0--1 - float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; - float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; - float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale); - float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale); + float dupx, dupy, fscale, fwidth, fheight; if (alphalevel >= 10 && alphalevel < 13) return; @@ -161,40 +158,104 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, else HWR_GetMappedPatch(gpatch, colormap); + dupx = (float)vid.dupx; + dupy = (float)vid.dupy; + switch (option & V_SCALEPATCHMASK) { case V_NOSCALEPATCH: - pdupx = pdupy = 2.0f; + dupx = dupy = 1.0f; break; case V_SMALLSCALEPATCH: - pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); - pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); + dupx = (float)vid.smalldupx; + dupy = (float)vid.smalldupy; break; case V_MEDSCALEPATCH: - pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); - pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); + dupx = (float)vid.meddupx; + dupy = (float)vid.meddupy; break; } - if (option & V_NOSCALESTART) - sdupx = sdupy = 2.0f; + dupx = dupy = (dupx < dupy ? dupx : dupy); + fscale = FIXED_TO_FLOAT(pscale); - if (option & V_SPLITSCREEN) - sdupy /= 2.0f; - - if (option & V_FLIP) // Need to flip both this and sow + if (option & V_OFFSET) { - v[0].x = v[3].x = (cx*sdupx-(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; - v[2].x = v[1].x = (cx*sdupx+gpatch->leftoffset*pdupx)/vid.width - 1; + cx -= (float)gpatch->leftoffset * dupx * fscale; + cy -= (float)gpatch->topoffset * dupy * fscale; } else { - v[0].x = v[3].x = (cx*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1; - v[2].x = v[1].x = (cx*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; + cy -= (float)gpatch->topoffset * fscale; + if (option & V_FLIP) + cx -= ((float)gpatch->width - (float)gpatch->leftoffset) * fscale; + else + cx -= (float)gpatch->leftoffset * fscale; } - v[0].y = v[1].y = 1-(cy*sdupy-gpatch->topoffset*pdupy)/vid.height; - v[2].y = v[3].y = 1-(cy*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height; + if (option & V_SPLITSCREEN) + cy /= 2; + + if (!(option & V_NOSCALESTART)) + { + cx = cx * dupx; + cy = cy * dupy; + + if (!(option & V_SCALEPATCHMASK)) + { + // centre screen + if (vid.width != BASEVIDWIDTH * vid.dupx) + { + if (option & V_SNAPTORIGHT) + cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(option & V_SNAPTOLEFT)) + cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2; + } + if (vid.height != BASEVIDHEIGHT * vid.dupy) + { + if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) + cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy)); + else if (option & V_SNAPTOBOTTOM) + cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(option & V_SNAPTOTOP)) + cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2; + } + // if it's meant to cover the whole screen, black out the rest + // TODO + /*if (x == 0 && SHORT(gpatch->width) == BASEVIDWIDTH && y == 0 && SHORT(gpatch->height) == BASEVIDHEIGHT) + { + const column_t *column = (const column_t *)((const UINT8 *)((patch_t *)gpatch) + LONG(((patch_t *)gpatch)->columnofs[0])); + const UINT8 *source = (const UINT8 *)(column) + 3; + HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); + }*/ + } + } + + if (pscale != FRACUNIT) + { + fwidth = (float)gpatch->width * fscale * dupx; + fheight = (float)gpatch->height * fscale * dupy; + } + else + { + fwidth = (float)gpatch->width * dupx; + fheight = (float)gpatch->height * dupy; + } + + // positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1 + cx = -1 + (cx / (vid.width/2)); + cy = 1 - (cy / (vid.height/2)); + + // fwidth and fheight are similar + fwidth /= vid.width / 2; + fheight /= vid.height / 2; + + // set the polygon vertices to the right positions + v[0].x = v[3].x = cx; + v[2].x = v[1].x = cx + fwidth; + + v[0].y = v[1].y = cy; + v[2].y = v[3].y = cy - fheight; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; From 7830c031f786e8820c7b29b9da7d2b5f094f75be Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 16 Mar 2018 19:46:45 +0000 Subject: [PATCH 059/122] Make HWR_DrawFill match V_DrawFill --- src/hardware/hw_draw.c | 81 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 30b0518cb..c9ba87786 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -717,7 +717,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) { FOutVector v[4]; FSurfaceInfo Surf; - float sdupx, sdupy; + float fx, fy, fw, fh; if (w < 0 || h < 0) return; // consistency w/ software @@ -726,16 +726,79 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) // | /| // |/ | // 0--1 - sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; - sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; - if (color & V_NOSCALESTART) - sdupx = sdupy = 2.0f; + fx = (float)x; + fy = (float)y; + fw = (float)w; + fh = (float)h; - v[0].x = v[3].x = (x*sdupx)/vid.width - 1; - v[2].x = v[1].x = (x*sdupx + w*sdupx)/vid.width - 1; - v[0].y = v[1].y = 1-(y*sdupy)/vid.height; - v[2].y = v[3].y = 1-(y*sdupy + h*sdupy)/vid.height; + if (!(color & V_NOSCALESTART)) + { + float dupx = (float)vid.dupx, dupy = (float)vid.dupy; + + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) + { + RGBA_t rgbaColour = V_GetColor(color); + FRGBAFloat clearColour; + clearColour.red = (float)rgbaColour.s.red / 255; + clearColour.green = (float)rgbaColour.s.green / 255; + clearColour.blue = (float)rgbaColour.s.blue / 255; + clearColour.alpha = 1; + HWD.pfnClearBuffer(true, false, &clearColour); + return; + } + + fx *= dupx; + fy *= dupy; + fw *= dupx; + fh *= dupy; + + if (vid.width != BASEVIDWIDTH * vid.dupx) + { + if (color & V_SNAPTORIGHT) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(color & V_SNAPTOLEFT)) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (color & V_SNAPTOBOTTOM) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(color & V_SNAPTOTOP)) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2; + } + } + + if (fx >= vid.width || fy >= vid.height) + return; + if (fx < 0) + { + fw += fx; + fx = 0; + } + if (fy < 0) + { + fh += fy; + fy = 0; + } + + if (fw <= 0 || fh <= 0) + return; + if (fx + fw > vid.width) + fw = (float)vid.width - fx; + if (fy + fh > vid.height) + fh = (float)vid.height - fy; + + fx = -1 + fx / (vid.width / 2); + fy = 1 - fy / (vid.height / 2); + fw = fw / (vid.width / 2); + fh = fh / (vid.height / 2); + + v[0].x = v[3].x = fx; + v[2].x = v[1].x = fx + fw; + v[0].y = v[1].y = fy; + v[2].y = v[3].y = fy - fh; //Hurdler: do we still use this argb color? if not, we should remove it v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; From 801f7547d3893a338fa40fe86afeeab46a60f87d Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 17 Mar 2018 13:26:43 +0000 Subject: [PATCH 060/122] Add the full-screen drawfill functionality to HWR_DrawFixedPatch --- src/hardware/hw_draw.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index c9ba87786..8b5c2f76c 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -203,6 +203,18 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (!(option & V_SCALEPATCHMASK)) { + // if it's meant to cover the whole screen, black out the rest + // cx and cy are possibly *slightly* off from float maths + // This is done before here compared to software because we directly alter cx and cy to centre + if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) + { + // Need to temporarily cache the real patch to get the colour of the top left pixel + patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); + const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); + const UINT8 *source = (const UINT8 *)(column) + 3; + HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); + Z_Free(realpatch); + } // centre screen if (vid.width != BASEVIDWIDTH * vid.dupx) { @@ -220,14 +232,6 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, else if (!(option & V_SNAPTOTOP)) cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2; } - // if it's meant to cover the whole screen, black out the rest - // TODO - /*if (x == 0 && SHORT(gpatch->width) == BASEVIDWIDTH && y == 0 && SHORT(gpatch->height) == BASEVIDHEIGHT) - { - const column_t *column = (const column_t *)((const UINT8 *)((patch_t *)gpatch) + LONG(((patch_t *)gpatch)->columnofs[0])); - const UINT8 *source = (const UINT8 *)(column) + 3; - HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); - }*/ } } From a9214ebd378414401d67c3beb720bcd7b8b1ecf3 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 17 Mar 2018 13:58:44 +0000 Subject: [PATCH 061/122] Match HWR_DrawCroppedPatch to V_DrawCroppedPatch --- src/hardware/hw_draw.c | 108 +++++++++++++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 15 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 8b5c2f76c..14e9b6f54 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -312,10 +312,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal // | /| // |/ | // 0--1 - float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; - float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; - float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale); - float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale); + float dupx, dupy, fscale, fwidth, fheight; if (alphalevel >= 10 && alphalevel < 13) return; @@ -323,28 +320,109 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal // make patch ready in hardware cache HWR_GetPatch(gpatch); + dupx = (float)vid.dupx; + dupy = (float)vid.dupy; + switch (option & V_SCALEPATCHMASK) { case V_NOSCALEPATCH: - pdupx = pdupy = 2.0f; + dupx = dupy = 1.0f; break; case V_SMALLSCALEPATCH: - pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); - pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); + dupx = (float)vid.smalldupx; + dupy = (float)vid.smalldupy; break; case V_MEDSCALEPATCH: - pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); - pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); + dupx = (float)vid.meddupx; + dupy = (float)vid.meddupy; break; } - if (option & V_NOSCALESTART) - sdupx = sdupy = 2.0f; + dupx = dupy = (dupx < dupy ? dupx : dupy); + fscale = FIXED_TO_FLOAT(pscale); - v[0].x = v[3].x = (cx*sdupx - gpatch->leftoffset * pdupx) / vid.width - 1; - v[2].x = v[1].x = (cx*sdupx + ((w-sx) - gpatch->leftoffset) * pdupx) / vid.width - 1; - v[0].y = v[1].y = 1 - (cy*sdupy - gpatch->topoffset * pdupy) / vid.height; - v[2].y = v[3].y = 1 - (cy*sdupy + ((h-sy) - gpatch->topoffset) * pdupy) / vid.height; + cy -= (float)gpatch->topoffset * fscale; + cx -= (float)gpatch->leftoffset * fscale; + + if (!(option & V_NOSCALESTART)) + { + cx = cx * dupx; + cy = cy * dupy; + + if (!(option & V_SCALEPATCHMASK)) + { + // if it's meant to cover the whole screen, black out the rest + // cx and cy are possibly *slightly* off from float maths + // This is done before here compared to software because we directly alter cx and cy to centre + if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) + { + // Need to temporarily cache the real patch to get the colour of the top left pixel + patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); + const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); + const UINT8 *source = (const UINT8 *)(column) + 3; + HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); + Z_Free(realpatch); + } + // centre screen + if (vid.width != BASEVIDWIDTH * vid.dupx) + { + if (option & V_SNAPTORIGHT) + cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(option & V_SNAPTOLEFT)) + cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2; + } + if (vid.height != BASEVIDHEIGHT * vid.dupy) + { + if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) + cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy)); + else if (option & V_SNAPTOBOTTOM) + cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(option & V_SNAPTOTOP)) + cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2; + } + } + } + + fwidth = w; + fheight = h; + + if (fwidth > w - sx) + fwidth = w - sx; + + if (fheight > h - sy) + fheight = h - sy; + + if (fwidth > gpatch->width) + fwidth = gpatch->width; + + if (fheight > gpatch->height) + fheight = gpatch->height; + + if (pscale != FRACUNIT) + { + fwidth *= fscale * dupx; + fheight *= fscale * dupy; + } + else + { + fwidth *= dupx; + fheight *= dupy; + } + + // positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1 + cx = -1 + (cx / (vid.width/2)); + cy = 1 - (cy / (vid.height/2)); + + // fwidth and fheight are similar + fwidth /= vid.width / 2; + fheight /= vid.height / 2; + + // set the polygon vertices to the right positions + v[0].x = v[3].x = cx; + v[2].x = v[1].x = cx + fwidth; + + v[0].y = v[1].y = cy; + v[2].y = v[3].y = cy - fheight; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; From 6de0cc6bccb02529107cc2c7a093969784214d6f Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 17 Mar 2018 14:47:06 +0000 Subject: [PATCH 062/122] Remove the OpenGL only code from V_DrawPatchFill That's all of the HUD drawing functions that are currently used updated in GL. --- src/v_video.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index cc81cedbc..161c03d0b 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -937,14 +937,6 @@ void V_DrawPatchFill(patch_t *pat) INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; -#ifdef HWRENDER - if (rendermode == render_opengl) - { - pw = FixedMul(SHORT(pat->width)*FRACUNIT, vid.fdupx)>>FRACBITS; - ph = FixedMul(SHORT(pat->height)*FRACUNIT, vid.fdupy)>>FRACBITS; - } -#endif - for (x = 0; x < vid.width; x += pw) { for (y = 0; y < vid.height; y += ph) From 527df5c248cbb9e453355cdd9a14aa8698dea00e Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 17 Mar 2018 15:11:32 +0000 Subject: [PATCH 063/122] Fix OpenGL Title Screen Sky My IDE doesn't seem to like Vada's name. --- src/f_finale.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 692abb35f..f2a9f4038 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -233,11 +233,19 @@ static void F_SkyScroll(INT32 scrollspeed) #ifdef HWRENDER else if (rendermode != render_none) { // if only software rendering could be this simple and retarded - scrolled = animtimer; - if (scrolled > 0) - V_DrawScaledPatch(scrolled - SHORT(pat->width), 0, 0, pat); - for (x = 0; x < fakedwidth; x += SHORT(pat->width)) - V_DrawScaledPatch(x + scrolled, 0, 0, pat); + INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); + INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; + scrolled = animtimer * dupz; + for (x = 0; x < vid.width; x += pw) + { + for (y = 0; y < vid.height; y += ph) + { + if (scrolled > 0) + V_DrawScaledPatch(scrolled - pw, y, V_NOSCALESTART, pat); + + V_DrawScaledPatch(x + scrolled, y, V_NOSCALESTART, pat); + } + } } #endif @@ -999,7 +1007,7 @@ static const char *credits[] = { "", "\1Sprite Artists", "Odi \"Iceman404\" Atunzu", - "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: + "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: "Jim \"MotorRoach\" DeMello", "Desmond \"Blade\" DesJardins", "Sherman \"CoatRack\" DesJardins", From 31d1ef8db05c77a755d243c6b612fd32886cbc45 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 17 Mar 2018 19:22:14 +0000 Subject: [PATCH 064/122] Draw the final screen texture in the centre with black bars Only applies when the monitor aspect ratio is different to the game's aspect ratio. --- src/hardware/r_opengl/r_opengl.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index cf87c101e..026d0126b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2601,6 +2601,9 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void) EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) { float xfix, yfix; + float origaspect, newaspect; + float xoff = 1, yoff = 1; // xoffset and yoffset for the polygon to have black bars around the screen + FRGBAFloat clearColour; INT32 texsize = 2048; if(screen_width <= 1024) @@ -2611,28 +2614,43 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) xfix = 1/((float)(texsize)/((float)((screen_width)))); yfix = 1/((float)(texsize)/((float)((screen_height)))); - //pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + origaspect = (float)screen_width / screen_height; + newaspect = (float)width / height; + if (origaspect < newaspect) + { + xoff = origaspect / newaspect; + yoff = 1; + } + else if (origaspect > newaspect) + { + xoff = 1; + yoff = newaspect / origaspect; + } + pglViewport(0, 0, width, height); + clearColour.red = clearColour.green = clearColour.blue = 0; + clearColour.alpha = 1; + ClearBuffer(true, false, &clearColour); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglBegin(GL_QUADS); pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); // Bottom left pglTexCoord2f(0.0f, 0.0f); - pglVertex3f(-1, -1, 1.0f); + pglVertex3f(-xoff, -yoff, 1.0f); // Top left pglTexCoord2f(0.0f, yfix); - pglVertex3f(-1, 1, 1.0f); + pglVertex3f(-xoff, yoff, 1.0f); // Top right pglTexCoord2f(xfix, yfix); - pglVertex3f(1, 1, 1.0f); + pglVertex3f(xoff, yoff, 1.0f); // Bottom right pglTexCoord2f(xfix, 0.0f); - pglVertex3f(1, -1, 1.0f); + pglVertex3f(xoff, -yoff, 1.0f); pglEnd(); From a984d979d113e119ca64ca4e53693064470c22f9 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 18 Mar 2018 17:12:12 +0000 Subject: [PATCH 065/122] Fix wipes in low resolutions --- src/hardware/r_opengl/r_opengl.c | 15 ++++++--------- src/sdl/ogl_sdl.c | 7 +++++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 026d0126b..5d861e618 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2538,14 +2538,14 @@ EXPORT void HWRAPI(MakeScreenTexture) (void) if (firstTime) { #ifdef KOS_GL_COMPATIBILITY - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); #else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #endif - Clamp2D(GL_TEXTURE_WRAP_S); - Clamp2D(GL_TEXTURE_WRAP_T); + Clamp2D(GL_TEXTURE_WRAP_S); + Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); #endif @@ -2654,9 +2654,6 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) pglEnd(); - SetModelView(screen_width, screen_height); - SetStates(); - tex_downloaded = finalScreenTexture; } diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index cd7ced7ca..4347b35b2 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -214,8 +214,11 @@ void OglSdlFinishUpdate(boolean waitvbl) HWR_DrawScreenFinalTexture(sdlw, sdlh); SDL_GL_SwapWindow(window); - SetModelView(realwidth, realheight); - SetStates(); + GClipRect(0, 0, realwidth, realheight, NZCLIP_PLANE); + + // Sryder: We need to draw the final screen texture again into the other buffer in the original position so that + // effects that want to take the old screen can do so after this + HWR_DrawScreenFinalTexture(realwidth, realheight); } EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) From f3d63b82cedd57b668d334607d4d22f935c3381d Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 18 Mar 2018 18:31:51 +0000 Subject: [PATCH 066/122] Revert "Fix screenshot functionality in fullscreen in SDL2" This reverts commit 121fcd83692d2e3946678bc270a80fe679247110. The reason I am reverting this is because the last commit actually fixes the *old* screenshot functionality, as the screen is being drawn back onto the buffer after they're swapped in the "real" size. Meaning the old function actually works perfectly fine now. --- src/hardware/hw_draw.c | 14 ------ src/hardware/hw_drv.h | 6 --- src/hardware/r_opengl/r_opengl.c | 79 -------------------------------- src/sdl/hwsym_sdl.c | 1 - src/sdl/i_video.c | 1 - src/sdl12/hwsym_sdl.c | 1 - src/sdl12/i_video.c | 1 - 7 files changed, 103 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 14e9b6f54..84081dd25 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -975,9 +975,6 @@ UINT8 *HWR_GetScreenshot(void) if (!buf) return NULL; // returns 24bit 888 RGB -#ifdef HAVE_SDL - if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf)) -#endif HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); return buf; } @@ -991,19 +988,8 @@ boolean HWR_Screenshot(const char *lbmname) return false; // returns 24bit 888 RGB -#ifdef HAVE_SDL - // Sryder: SDL2 uses borderless fullscreen mode, and creates a screen texture to upscale to the screen size. - // This breaks screenshots because the code here takes a screenshot of just the resolution from the bottom - // left corner, while the "true" resolution is the monitor resolution. We can either take a screenshot of - // the true resolution or just use the already made screen texture - // NOTE: The SDL1.2 version should get a return of false from ReadScreenTexture as no screen texture will have - // been made, this will also mean that if the screen texture doesn't exist for some reason it will fall - // back to the old version - if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf)) -#endif HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); - #ifdef USE_PNG ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL); #else diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index ab4025697..a5ac82001 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -58,9 +58,6 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data); -#ifdef HAVE_SDL -EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 * dst_data); -#endif EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); EXPORT void HWRAPI(ClearMipMapCache) (void); @@ -107,9 +104,6 @@ struct hwdriver_s ClearBuffer pfnClearBuffer; SetTexture pfnSetTexture; ReadRect pfnReadRect; -#ifdef HAVE_SDL - ReadScreenTexture pfnReadScreenTexture; -#endif GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 5d861e618..8e3ae3e21 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -260,7 +260,6 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglTexEnvi glTexEnvi #define pglTexParameteri glTexParameteri #define pglTexImage2D glTexImage2D -#define pglGetTexImage glGetTexImage /* Fog */ #define pglFogf glFogf @@ -382,8 +381,6 @@ typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint static PFNglTexParameteri pglTexParameteri; typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static PFNglTexImage2D pglTexImage2D; -typedef void (APIENTRY * PFNglGetTexImage) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); -static PFNglGetTexImage pglGetTexImage; /* Fog */ typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param); @@ -510,7 +507,6 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglTexEnvi , glTexEnvi) GETOPENGLFUNC(pglTexParameteri , glTexParameteri) GETOPENGLFUNC(pglTexImage2D , glTexImage2D) - GETOPENGLFUNC(pglGetTexImage , glGetTexImage) GETOPENGLFUNC(pglFogf , glFogf) GETOPENGLFUNC(pglFogfv , glFogfv) @@ -937,81 +933,6 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, #endif } -#ifdef HAVE_SDL -EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width, - INT32 height, INT32 dst_stride, - UINT16 * dst_data) -{ -#ifdef KOS_GL_COMPATIBILITY - (void)x; - (void)y; - (void)width; - (void)height; - (void)dst_stride; - (void)dst_data; -#else - INT32 i, j; - INT32 texsize = 2048; - GLubyte *image; - // DBG_Printf ("ReadScreenTexture()\n"); - if (screentexture == 0) - return false; // No screen texture - - if(screen_width <= 1024) - texsize = 1024; - if(screen_width <= 512) - texsize = 512; - - if (x < 0) - x = 0; - if (x + width > screen_width) - width = screen_width - x; - if (y < 0) - y = 0; - if (y + height > screen_height) - height = screen_height - y; - - image = malloc(texsize*texsize*3*sizeof (*image)); - if (!image) - return false; - pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); - tex_downloaded = finalScreenTexture; - pglGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image); - - if (dst_stride == width*3) - { - UINT8 *dest = (void *)dst_data; - for (i = y + height-1; i >= y; i--) - { - for (j = x; j < width + x; j++) - { - dest[((height-1-i-y)*width+j-x)*3] = image[(i*texsize+j)*3]; - dest[((height-1-i-y)*width+j-x)*3+1] = image[(i*texsize+j)*3+1]; - dest[((height-1-i-y)*width+j-x)*3+2] = image[(i*texsize+j)*3+2]; - } - } - } - else - { - // Sryder: NOTE: I'm not entirely sure this works, as far as I know nothing in the game uses it. - for (i = y + height-1; i >= y; i--) - { - for (j = x; j < width + x; j++) - { - dst_data[(height-1-i-y)*width+j-x] = - (UINT16)( - ((image[(i*texsize+j)*3]>>3)<<11) | - ((image[(i*texsize+j)*3+1]>>2)<<5) | - ((image[(i*texsize+j)*3+2]>>3))); - } - } - } - free(image); - return true; -#endif -} -#endif - // -----------------+ // GClipRect : Defines the 2D hardware clipping window diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 33bcfd6f3..05ac6450e 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -83,7 +83,6 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearBuffer); GETFUNC(SetTexture); GETFUNC(ReadRect); - GETFUNC(ReadScreenTexture); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); GETFUNC(SetSpecialState); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 2df8a6ff5..87ce84158 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1430,7 +1430,6 @@ void I_StartupGraphics(void) HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); diff --git a/src/sdl12/hwsym_sdl.c b/src/sdl12/hwsym_sdl.c index 3a10d8253..49340138f 100644 --- a/src/sdl12/hwsym_sdl.c +++ b/src/sdl12/hwsym_sdl.c @@ -89,7 +89,6 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearBuffer); GETFUNC(SetTexture); GETFUNC(ReadRect); - GETFUNC(ReadScreenTexture); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); GETFUNC(SetSpecialState); diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index 076ce4fd2..349e06cba 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -1960,7 +1960,6 @@ void I_StartupGraphics(void) HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); From 7d1885917ac8a06713b33f7cf68b79d630d2c2b5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 18 Mar 2018 18:26:41 +0000 Subject: [PATCH 067/122] Some minor intro tweaks. --- src/f_finale.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 05c3d5fc0..a85655e53 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -322,7 +322,7 @@ void F_StartIntro(void) "hovers around the planet.\xBF It suddenly\n" "appears from nowhere, circles around, and\n" "\xB6- just as mysteriously as it arrives -\xB6\n" - "vanishes after about two months.\xBF\n" + "vanishes after about one week.\xBF\n" "No one knows why it appears, or how.\n#"); introtext[5] = M_GetText( @@ -334,11 +334,11 @@ void F_StartIntro(void) "the screen, and just shrugged it off.\n#"); introtext[6] = M_GetText( - "It was only later\n" + "It was hours later\n" "that he had an\n" "idea. \xBF\xA7\"The Black\n" - "Rock usually has a\n" - "lot of energy\n" + "Rock has a large\n" + "amount of energy\n" "within it\xAC...\xA7\xBF\n" "If I can somehow\n" "harness this,\xB8 I\n" @@ -356,37 +356,37 @@ void F_StartIntro(void) "a reunion party...\n#"); introtext[8] = M_GetText( - "\xA5\"We're\xB6 ready\xB6 to\xB4 fire\xB6 in\xB6 15\xB6 seconds!\"\xA8\xB8\n" - "The robot said, his voice crackling a\n" - "little down the com-link. \xBF\xA7\"Good!\"\xA8\xB8\n" - "Eggman sat back in his Egg-Mobile and\n" + "\xA5\"PRE-""\xB6""PARING-""\xB6""TO-""\xB4""FIRE-\xB6IN-""\xB6""15-""\xB6""SECONDS!\"\xA8\xB8\n" + "his targeting system crackled\n" + "robotically down the com-link. \xBF\xA7\"Good!\"\xA8\xB8\n" + "Eggman sat back in his eggmobile and\n" "began to count down as he saw the\n" - "GreenFlower city on the main monitor.\n#"); + "Greenflower mountain on the monitor.\n#"); introtext[9] = M_GetText( "\xA5\"10...\xD2""9...\xD2""8...\"\xA8\xD2\n" "Meanwhile, Sonic was tearing across the\n" "zones. Everything became a blur as he\n" - "ran around loops, skimmed over water,\n" + "ran up slopes, skimmed over water,\n" "and catapulted himself off rocks with\n" "his phenomenal speed.\n#"); introtext[10] = M_GetText( "\xA5\"6...\xD2""5...\xD2""4...\"\xA8\xD2\n" "Sonic knew he was getting closer to the\n" - "City, and pushed himself harder.\xB4 Finally,\n" - "the city appeared in the horizon.\xD2\xD2\n" + "zone, and pushed himself harder.\xB4 Finally,\n" + "the mountain appeared in the horizon.\xD2\xD2\n" "\xA5\"3...\xD2""2...\xD2""1...\xD2""Zero.\"\n#"); introtext[11] = M_GetText( - "GreenFlower City was gone.\xC4\n" + "Greenflower Mountain was no more.\xC4\n" "Sonic arrived just in time to see what\n" "little of the 'ruins' were left.\n" - "Everyone and everything in the city\n" + "The natural beauty of the zone\n" "had been obliterated.\n#"); introtext[12] = M_GetText( - "\xA7\"You're not quite as dead as we thought,\n" + "\xA7\"You're not quite as gone as we thought,\n" "huh?\xBF Are you going to tell us your plan as\n" "usual or will I \xA8\xB4'have to work it out'\xA7 or\n" "something?\"\xD2\xD2\n" @@ -400,8 +400,8 @@ void F_StartIntro(void) "leaving Sonic\n" "and Tails behind.\xB6\n" "Tails looked at\n" - "the ruins of the\n" - "Greenflower City\n" + "the once-perfect\n" + "mountainside\n" "with a grim face\n" "and sighed.\xC6\n" "\xA7\"Now\xB6 what do we\n" From c0cc1471e5b0842a0138be0df7842f6a8aea620e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 19 Mar 2018 16:39:37 +0000 Subject: [PATCH 068/122] Make some tweaks to devmode offsets. --- src/st_stuff.c | 67 ++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 6d6c2d017..5601a85ee 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -470,55 +470,55 @@ static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fix static void ST_drawDebugInfo(void) { INT32 height = 192; - INT32 dist = 8; if (!(stplyr->mo && cv_debug)) return; if (cv_ticrate.value) - { height -= 12; - dist >>= 1; - } + +#define dist 4 +#define VFLAGS V_MONOSPACE|V_SNAPTOBOTTOM|V_SNAPTORIGHT if (cv_debug & DBG_BASIC) { const fixed_t d = AngleFixed(stplyr->mo->angle); - V_DrawRightAlignedString(320, height - 24, V_MONOSPACE, va("X: %6d", stplyr->mo->x>>FRACBITS)); - V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Y: %6d", stplyr->mo->y>>FRACBITS)); - V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Z: %6d", stplyr->mo->z>>FRACBITS)); - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("A: %6d", FixedInt(d))); + V_DrawRightAlignedString(320, height - 24, VFLAGS, va("X: %6d", stplyr->mo->x>>FRACBITS)); + V_DrawRightAlignedString(320, height - 16, VFLAGS, va("Y: %6d", stplyr->mo->y>>FRACBITS)); + V_DrawRightAlignedString(320, height - 8, VFLAGS, va("Z: %6d", stplyr->mo->z>>FRACBITS)); + V_DrawRightAlignedString(320, height, VFLAGS, va("A: %6d", FixedInt(d))); height -= (32+dist); } if (cv_debug & DBG_DETAILED) { - V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield])); - V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT)); - V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("CARRY: %5x", stplyr->powers[pw_carry])); - V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); + V_DrawRightAlignedString(320, height - 104, VFLAGS, va("SHIELD: %5x", stplyr->powers[pw_shield])); + V_DrawRightAlignedString(320, height - 96, VFLAGS, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT)); + V_DrawRightAlignedString(320, height - 88, VFLAGS, va("CARRY: %5x", stplyr->powers[pw_carry])); + V_DrawRightAlignedString(320, height - 80, VFLAGS, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); // Flags - V_DrawRightAlignedString(304-92, height - 72, V_MONOSPACE, "PF:"); - V_DrawString(304-90, height - 72, (stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP, "SJ"); - V_DrawString(304-72, height - 72, (stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP, "JD"); - V_DrawString(304-54, height - 72, (stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP, "SP"); - V_DrawString(304-36, height - 72, (stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP, "ST"); - V_DrawString(304-18, height - 72, (stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP, "TH"); - V_DrawString(304, height - 72, (stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP, "SH"); + V_DrawRightAlignedString(304-92, height - 72, VFLAGS, "PF:"); + V_DrawString(304-90, height - 72, VFLAGS|((stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP), "SJ"); + V_DrawString(304-72, height - 72, VFLAGS|((stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP), "JD"); + V_DrawString(304-54, height - 72, VFLAGS|((stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP), "SP"); + V_DrawString(304-36, height - 72, VFLAGS|((stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP), "ST"); + V_DrawString(304-18, height - 72, VFLAGS|((stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP), "TH"); + V_DrawString(304, height - 72, VFLAGS|((stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP), "SH"); - V_DrawRightAlignedString(320, height - 64, V_MONOSPACE, va("CEILZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); - V_DrawRightAlignedString(320, height - 56, V_MONOSPACE, va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); + V_DrawRightAlignedString(320, height - 64, VFLAGS, va("CEILZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); + V_DrawRightAlignedString(320, height - 56, VFLAGS, va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); - V_DrawRightAlignedString(320, height - 48, V_MONOSPACE, va("CNVX: %6d", stplyr->cmomx>>FRACBITS)); - V_DrawRightAlignedString(320, height - 40, V_MONOSPACE, va("CNVY: %6d", stplyr->cmomy>>FRACBITS)); - V_DrawRightAlignedString(320, height - 32, V_MONOSPACE, va("PLTZ: %6d", stplyr->mo->pmomz>>FRACBITS)); + V_DrawRightAlignedString(320, height - 48, VFLAGS, va("CNVX: %6d", stplyr->cmomx>>FRACBITS)); + V_DrawRightAlignedString(320, height - 40, VFLAGS, va("CNVY: %6d", stplyr->cmomy>>FRACBITS)); + V_DrawRightAlignedString(320, height - 32, VFLAGS, va("PLTZ: %6d", stplyr->mo->pmomz>>FRACBITS)); - V_DrawRightAlignedString(320, height - 24, V_MONOSPACE, va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); - V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); - V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("SPEED: %6d", stplyr->speed>>FRACBITS)); + V_DrawRightAlignedString(320, height - 24, VFLAGS, va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); + V_DrawRightAlignedString(320, height - 16, VFLAGS, va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); + V_DrawRightAlignedString(320, height - 8, VFLAGS, va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); + + V_DrawRightAlignedString(320, height, VFLAGS, va("SPEED: %6d", stplyr->speed>>FRACBITS)); height -= (112+dist); } @@ -529,17 +529,20 @@ static void ST_drawDebugInfo(void) peekres *= 10000; // Change from fixed point peekres >>= FRACBITS; // to displayable decimal - V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Init: %08x", P_GetInitSeed())); - V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Seed: %08x", P_GetRandSeed())); - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("== : .%04d", peekres)); + V_DrawRightAlignedString(320, height - 16, VFLAGS, va("Init: %08x", P_GetInitSeed())); + V_DrawRightAlignedString(320, height - 8, VFLAGS, va("Seed: %08x", P_GetRandSeed())); + V_DrawRightAlignedString(320, height, VFLAGS, va("== : .%04d", peekres)); height -= (24+dist); } if (cv_debug & DBG_MEMORY) { - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10))); + V_DrawRightAlignedString(320, height, VFLAGS, va("Heap: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10))); } + +#undef VFLAGS +#undef dist } static void ST_drawScore(void) From 4798f853826820d12fc81b4cbe9b0617898d6908 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 19 Mar 2018 16:40:15 +0000 Subject: [PATCH 069/122] Fix issues with the level platter in nonstandard resolutions. --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 9f1b7efe7..24beff317 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4425,14 +4425,14 @@ static void M_DrawLevelPlatterMenu(void) V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); // finds row at top of the screen - while (y > 0) + while (y > -8) { iter = ((iter == 0) ? levelselect.numrows-1 : iter-1); y -= lsvseperation(iter); } // draw from top to bottom - while (y < 200) + while (y < (vid.height/vid.dupy)) { M_DrawLevelPlatterRow(iter, y); y += lsvseperation(iter); From 7885ae57e2e33af4e62025bea18c749ca62168d1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 19 Mar 2018 23:08:51 +0000 Subject: [PATCH 070/122] * Allow for V_ flag control for hudinfo SOC/Lua stuff through hudinfo[n].f (for flags). * Fix Old Special Stage offsets. * Fix drowning number offsets. * Remove useless "WS" macros. --- src/dehacked.c | 4 + src/lua_hudlib.c | 10 ++- src/st_stuff.c | 194 ++++++++++++++++++++++++----------------------- src/st_stuff.h | 2 +- src/y_inter.c | 6 +- 5 files changed, 117 insertions(+), 99 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 7202ba31b..0804999a8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1584,6 +1584,10 @@ static void readhuditem(MYFILE *f, INT32 num) { hudinfo[num].y = i; } + else if (fastcmp(word, "F")) + { + hudinfo[num].f = i; + } else deh_warning("Level header %d: unknown word '%s'", num, word); } diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 6991f00e7..a709ba9f4 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -63,12 +63,14 @@ static const char *const hud_disable_options[] = { enum hudinfo { hudinfo_x = 0, - hudinfo_y + hudinfo_y, + hudinfo_f }; static const char *const hudinfo_opt[] = { "x", "y", + "f", NULL}; enum patch { @@ -198,6 +200,9 @@ static int hudinfo_get(lua_State *L) case hudinfo_y: lua_pushinteger(L, info->y); break; + case hudinfo_f: + lua_pushinteger(L, info->f); + break; } return 1; } @@ -216,6 +221,9 @@ static int hudinfo_set(lua_State *L) case hudinfo_y: info->y = (INT32)luaL_checkinteger(L, 3); break; + case hudinfo_f: + info->f = (INT32)luaL_checkinteger(L, 3); + break; } return 0; } diff --git a/src/st_stuff.c b/src/st_stuff.c index 5601a85ee..4f7c8fc28 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -125,32 +125,34 @@ static boolean facefreed[MAXPLAYERS]; hudinfo_t hudinfo[NUMHUDITEMS] = { - { 16, 176}, // HUD_LIVES + { 16, 176, V_SNAPTOLEFT|V_SNAPTOBOTTOM}, // HUD_LIVES - { 16, 42}, // HUD_RINGS - { 96, 42}, // HUD_RINGSNUM - { 120, 42}, // HUD_RINGSNUMTICS + { 16, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGS + { 96, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGSNUM + { 120, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGSNUMTICS - { 16, 10}, // HUD_SCORE - { 120, 10}, // HUD_SCORENUM + { 16, 10, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SCORE + { 120, 10, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SCORENUM - { 16, 26}, // HUD_TIME - { 72, 26}, // HUD_MINUTES - { 72, 26}, // HUD_TIMECOLON - { 96, 26}, // HUD_SECONDS - { 96, 26}, // HUD_TIMETICCOLON - { 120, 26}, // HUD_TICS + { 16, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIME + { 72, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_MINUTES + { 72, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIMECOLON + { 96, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SECONDS + { 96, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIMETICCOLON + { 120, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TICS - { 120, 56}, // HUD_SS_TOTALRINGS + { 0, 56, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SS_TOTALRINGS - { 110, 93}, // HUD_GETRINGS - { 160, 93}, // HUD_GETRINGSNUM - { 124, 160}, // HUD_TIMELEFT - { 168, 176}, // HUD_TIMELEFTNUM - { 130, 93}, // HUD_TIMEUP - { 152, 168}, // HUD_HUNTPICS - { 152, 24}, // HUD_GRAVBOOTSICO - { 240, 160}, // HUD_LAP + { 110, 93, 0}, // HUD_GETRINGS + { 160, 93, 0}, // HUD_GETRINGSNUM + { 124, 160, 0}, // HUD_TIMELEFT + { 168, 176, 0}, // HUD_TIMELEFTNUM + { 130, 93, 0}, // HUD_TIMEUP + { 152, 168, 0}, // HUD_HUNTPICS + + { 152, 24, V_SNAPTORIGHT}, // HUD_GRAVBOOTSICO + + { 240, 160, V_SNAPTOBOTTOM|V_SNAPTORIGHT}, // HUD_LAP }; // @@ -427,12 +429,9 @@ static INT32 SCX(INT32 x) #define ST_DrawTopLeftOverlayNum(x,y,n) V_DrawTallNum(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, n) #define ST_DrawTopLeftOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p) #define ST_DrawMappedOverlayPatch(x,y,p,c) V_DrawMappedScaledPatch(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p, c) -#define ST_DrawNumFromHud(h,n,f) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n) -#define ST_DrawPadNumFromHud(h,n,q,f) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n, q) -#define ST_DrawPatchFromHud(h,p,f) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, p) -#define ST_DrawNumFromHudWS(h,n,f) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n) -#define ST_DrawPadNumFromHudWS(h,n,q,f) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n, q) -#define ST_DrawPatchFromHudWS(h,p,f) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, p) +#define ST_DrawNumFromHud(h,n,flags) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, n) +#define ST_DrawPadNumFromHud(h,n,q,flags) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, n, q) +#define ST_DrawPatchFromHud(h,p,flags) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, p) // Draw a number, scaled, over the view, maybe with set translucency // Always draw the number completely since it's overlay @@ -565,7 +564,7 @@ static void ST_drawTime(void) INT32 seconds, minutes, tictrn, tics; // TIME: - ST_DrawPatchFromHudWS(HUD_TIME, ((mapheaderinfo[gamemap-1]->countdown && countdowntimer < 11*TICRATE && leveltime/5 & 1) ? sboredtime : sbotime), V_HUDTRANS); + ST_DrawPatchFromHud(HUD_TIME, ((mapheaderinfo[gamemap-1]->countdown && countdowntimer < 11*TICRATE && leveltime/5 & 1) ? sboredtime : sbotime), V_HUDTRANS); if (objectplacing) { @@ -583,12 +582,12 @@ static void ST_drawTime(void) } if (cv_timetic.value == 1) // Tics only -- how simple is this? - ST_DrawNumFromHudWS(HUD_SECONDS, tics, V_HUDTRANS); + ST_DrawNumFromHud(HUD_SECONDS, tics, V_HUDTRANS); else { - ST_DrawNumFromHudWS(HUD_MINUTES, minutes, V_HUDTRANS); // Minutes - ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon - ST_DrawPadNumFromHudWS(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds + ST_DrawNumFromHud(HUD_MINUTES, minutes, V_HUDTRANS); // Minutes + ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon + ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds if (cv_timetic.value == 2 || cv_timetic.value == 3 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! { @@ -602,7 +601,7 @@ static inline void ST_drawRings(void) { INT32 ringnum; - ST_DrawPatchFromHudWS(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + ST_DrawPatchFromHud(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); if (objectplacing) ringnum = op_currentdoomednum; @@ -620,7 +619,7 @@ static inline void ST_drawRings(void) if (cv_timetic.value == 3) // Yes, even in modeattacking ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); else - ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + ST_DrawNumFromHud(HUD_RINGSNUM, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); } static void ST_drawLivesArea(void) @@ -633,7 +632,7 @@ static void ST_drawLivesArea(void) // face background V_DrawSmallScaledPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, livesback); + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, livesback); // face if (stplyr->spectator) @@ -641,7 +640,7 @@ static void ST_drawLivesArea(void) // spectator face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, SKINCOLOR_CLOUDY, GTC_CACHE); V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); } else if (stplyr->mo && stplyr->mo->color) { @@ -651,7 +650,7 @@ static void ST_drawLivesArea(void) if (stplyr->powers[pw_super]) face = superprefix[stplyr->skin]; V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, face, colormap); + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, face, colormap); if (cv_translucenthud.value == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer) { INT32 v_supertrans = (stplyr->mo->tracer->frame & FF_TRANSMASK) >> FF_TRANSSHIFT; @@ -660,7 +659,7 @@ static void ST_drawLivesArea(void) v_supertrans <<= V_ALPHASHIFT; colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->tracer->color, GTC_CACHE); V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|v_supertrans, face, colormap); + hudinfo[HUD_LIVES].f|V_PERPLAYER|v_supertrans, face, colormap); } } } @@ -669,7 +668,7 @@ static void ST_drawLivesArea(void) // skincolor face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE); V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, faceprefix[stplyr->skin], colormap); + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, faceprefix[stplyr->skin], colormap); } // Lives number @@ -677,7 +676,7 @@ static void ST_drawLivesArea(void) { // x V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, stlivex); + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); // lives number if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) @@ -713,19 +712,19 @@ static void ST_drawLivesArea(void) if (livescount == 0x7f) V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8, - '\x16' | 0x80 | V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, false); + '\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false); else { if (livescount > 99) livescount = 99; V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); + hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); } } // Spectator else if (stplyr->spectator) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "SPECTATE"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "SPECTATE"); v_colmap = V_GRAYMAP; } // Tag @@ -733,17 +732,17 @@ static void ST_drawLivesArea(void) { if (stplyr->pflags & PF_TAGIT) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, (gametype == GT_HIDEANDSEEK) ? "SEEKER" : "IT!"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, (gametype == GT_HIDEANDSEEK) ? "SEEKER" : "IT!"); v_colmap = V_ORANGEMAP; } else if (stplyr->pflags & PF_GAMETYPEOVER) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANSHALF|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "FAILED"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANSHALF|hudinfo[HUD_LIVES].f|V_PERPLAYER, "FAILED"); v_colmap = V_GRAYMAP; } else { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, (gametype == GT_HIDEANDSEEK) ? "HIDER" : "RUNNER"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, (gametype == GT_HIDEANDSEEK) ? "HIDER" : "RUNNER"); v_colmap = V_GREENMAP; } } @@ -752,12 +751,12 @@ static void ST_drawLivesArea(void) { if (stplyr->ctfteam == 1) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "RED"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED"); v_colmap = V_REDMAP; } else if (stplyr->ctfteam == 2) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "BLUE"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE"); v_colmap = V_BLUEMAP; } else @@ -765,11 +764,11 @@ static void ST_drawLivesArea(void) } else { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "PLAYING"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "PLAYING"); } // name - v_colmap |= (V_HUDTRANS|V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM); + v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); if (strlen(skins[stplyr->skin].hudname) <= 5) V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); else if (V_ThinStringWidth(skins[stplyr->skin].hudname, v_colmap) <= 40) @@ -789,7 +788,7 @@ static void ST_drawLivesArea(void) { for (j = 0; j < 7; ++j) // "super" indicator { - V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, emeraldpics[1][j]); + V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, emeraldpics[1][j]); workx += 8; } } @@ -798,7 +797,7 @@ static void ST_drawLivesArea(void) for (j = 0; j < 7; ++j) // powerstones { if (stplyr->powers[pw_emeralds] & (1 << j)) - V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, emeraldpics[1][j]); + V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, emeraldpics[1][j]); workx += 8; } } @@ -817,23 +816,23 @@ static void ST_drawInput(void) y -= 16; // O backing - V_DrawFill(x, y-1, 16, 16, V_SNAPTOLEFT|V_SNAPTOBOTTOM|20); - V_DrawFill(x, y+15, 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x, y-1, 16, 16, hudinfo[HUD_LIVES].f|20); + V_DrawFill(x, y+15, 16, 1, hudinfo[HUD_LIVES].f|29); if (cv_showinputjoy.value) // joystick render! { - /*V_DrawFill(x , y , 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); - V_DrawFill(x , y+15, 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); - V_DrawFill(x , y+ 1, 1, 14, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); - V_DrawFill(x+15, y+ 1, 1, 14, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); -- red's outline*/ + /*V_DrawFill(x , y , 16, 1, hudinfo[HUD_LIVES].f|16); + V_DrawFill(x , y+15, 16, 1, hudinfo[HUD_LIVES].f|16); + V_DrawFill(x , y+ 1, 1, 14, hudinfo[HUD_LIVES].f|16); + V_DrawFill(x+15, y+ 1, 1, 14, hudinfo[HUD_LIVES].f|16); -- red's outline*/ if (stplyr->cmd.sidemove || stplyr->cmd.forwardmove) { // joystick hole - V_DrawFill(x+5, y+4, 6, 6, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+5, y+4, 6, 6, hudinfo[HUD_LIVES].f|29); // joystick top V_DrawFill(x+3+stplyr->cmd.sidemove/12, y+2-stplyr->cmd.forwardmove/12, - 10, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + 10, 10, hudinfo[HUD_LIVES].f|29); V_DrawFill(x+3+stplyr->cmd.sidemove/9, y+1-stplyr->cmd.forwardmove/9, 10, 10, accent); @@ -841,10 +840,10 @@ static void ST_drawInput(void) else { // just a limited, greyed out joystick top - V_DrawFill(x+3, y+11, 10, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+3, y+11, 10, 1, hudinfo[HUD_LIVES].f|29); V_DrawFill(x+3, y+1, - 10, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); + 10, 10, hudinfo[HUD_LIVES].f|16); } } else // arrows! @@ -858,10 +857,10 @@ static void ST_drawInput(void) else { offs = 1; - col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; - V_DrawFill(x- 2, y+10, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+ 4, y+ 9, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+ 5, y+ 8, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x- 2, y+10, 6, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 4, y+ 9, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 5, y+ 8, 1, 1, hudinfo[HUD_LIVES].f|29); } V_DrawFill(x- 2, y+ 5-offs, 6, 6, col); V_DrawFill(x+ 4, y+ 6-offs, 1, 4, col); @@ -876,12 +875,12 @@ static void ST_drawInput(void) else { offs = 1; - col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; - V_DrawFill(x+ 5, y+ 3, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+ 6, y+ 4, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+ 7, y+ 5, 2, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+ 9, y+ 4, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+10, y+ 3, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x+ 5, y+ 3, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 6, y+ 4, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 7, y+ 5, 2, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 9, y+ 4, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+10, y+ 3, 1, 1, hudinfo[HUD_LIVES].f|29); } V_DrawFill(x+ 5, y- 2-offs, 6, 6, col); V_DrawFill(x+ 6, y+ 4-offs, 4, 1, col); @@ -896,10 +895,10 @@ static void ST_drawInput(void) else { offs = 1; - col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; - V_DrawFill(x+12, y+10, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+11, y+ 9, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+10, y+ 8, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x+12, y+10, 6, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+11, y+ 9, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+10, y+ 8, 1, 1, hudinfo[HUD_LIVES].f|29); } V_DrawFill(x+12, y+ 5-offs, 6, 6, col); V_DrawFill(x+11, y+ 6-offs, 1, 4, col); @@ -914,8 +913,8 @@ static void ST_drawInput(void) else { offs = 1; - col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; - V_DrawFill(x+ 5, y+17, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x+ 5, y+17, 6, 1, hudinfo[HUD_LIVES].f|29); } V_DrawFill(x+ 5, y+12-offs, 6, 6, col); V_DrawFill(x+ 6, y+11-offs, 4, 1, col); @@ -931,16 +930,16 @@ static void ST_drawInput(void) else\ {\ offs = 1;\ - col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16;\ - V_DrawFill(x+16+(xoffs), y+9+(yoffs), 10, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29);\ + col = hudinfo[HUD_LIVES].f|16;\ + V_DrawFill(x+16+(xoffs), y+9+(yoffs), 10, 1, hudinfo[HUD_LIVES].f|29);\ }\ V_DrawFill(x+16+(xoffs), y+(yoffs)-offs, 10, 10, col);\ - V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, V_SNAPTOLEFT|V_SNAPTOBOTTOM|symb, false) + V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, hudinfo[HUD_LIVES].f|symb, false) drawbutt( 4,-3, BT_JUMP, 'J'); drawbutt(15,-3, BT_USE, 'S'); - V_DrawFill(x+16+4, y+8, 21, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|20); // sundial backing + V_DrawFill(x+16+4, y+8, 21, 10, hudinfo[HUD_LIVES].f|20); // sundial backing if (stplyr->mo) { UINT8 i, precision; @@ -960,7 +959,7 @@ static void ST_drawInput(void) { V_DrawFill(x+16+14-(i*xcomp)/precision, y+12-(i*ycomp)/precision, - 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); + 1, 1, hudinfo[HUD_LIVES].f|16); } if (ycomp <= 0) @@ -977,7 +976,7 @@ static void ST_drawInput(void) if (stplyr->pflags & PF_AUTOBRAKE) { V_DrawThinString(x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM| + hudinfo[HUD_LIVES].f| ((!stplyr->powers[pw_carry] && (stplyr->pflags & PF_APPLYAUTOBRAKE) && !(stplyr->cmd.sidemove || stplyr->cmd.forwardmove) @@ -988,12 +987,12 @@ static void ST_drawInput(void) } if (stplyr->pflags & PF_ANALOGMODE) { - V_DrawThinString(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM, "ANALOG"); + V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "ANALOG"); y -= 8; } } if (!demosynced) // should always be last, so it doesn't push anything else around - V_DrawThinString(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); + V_DrawThinString(x, y, hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); } static void ST_drawLevelTitle(void) @@ -1146,8 +1145,8 @@ static void ST_drawFirstPersonHUD(void) // Display the countdown drown numbers! if (p) - V_DrawScaledPatch(SCX((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset)), SCZ(60 - SHORT(p->topoffset)), - V_PERPLAYER|V_NOSCALESTART|V_PERPLAYER|V_OFFSET|V_TRANSLUCENT, p); + V_DrawScaledPatch((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset), 60 - SHORT(p->topoffset), + V_PERPLAYER|V_PERPLAYER|V_TRANSLUCENT, p); } static void ST_drawNightsRecords(void) @@ -1696,9 +1695,9 @@ static inline void ST_drawRaceHUD(void) if (circuitmap) { if (stplyr->exiting) - V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, V_YELLOWMAP, "FINISHED!"); + V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f|V_YELLOWMAP, "FINISHED!"); else - V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, 0, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); + V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); } } @@ -1800,7 +1799,14 @@ static void ST_drawCTFHUD(void) static void ST_drawSpecialStageHUD(void) { if (totalrings > 0) - ST_DrawNumFromHudWS(HUD_SS_TOTALRINGS, totalrings, V_HUDTRANS); + { + if (hudinfo[HUD_SS_TOTALRINGS].x) + ST_DrawNumFromHud(HUD_SS_TOTALRINGS, totalrings, V_HUDTRANS); + else if (cv_timetic.value == 3) + V_DrawTallNum(hudinfo[HUD_RINGSNUMTICS].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUMTICS].f|V_PERPLAYER|V_HUDTRANS, totalrings); + else + V_DrawTallNum(hudinfo[HUD_RINGSNUM].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUM].f|V_PERPLAYER|V_HUDTRANS, totalrings); + } if (leveltime < 5*TICRATE && totalrings > 0) { @@ -1810,7 +1816,7 @@ static void ST_drawSpecialStageHUD(void) if (sstimer) { - V_DrawString(hudinfo[HUD_TIMELEFT].x, hudinfo[HUD_TIMELEFT].y, V_PERPLAYER|V_HUDTRANS, M_GetText("TIME LEFT")); + V_DrawString(hudinfo[HUD_TIMELEFT].x, hudinfo[HUD_TIMELEFT].y, hudinfo[HUD_TIMELEFT].f|V_PERPLAYER|V_HUDTRANS, M_GetText("TIME LEFT")); ST_DrawNumFromHud(HUD_TIMELEFTNUM, sstimer/TICRATE, V_HUDTRANS); } else @@ -1853,7 +1859,7 @@ static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offse interval = 0; } - V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, V_PERPLAYER|V_HUDTRANS, patches[i]); + V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, hudinfo[HUD_HUNTPICS].f|V_PERPLAYER|V_HUDTRANS, patches[i]); return interval; } @@ -2059,7 +2065,7 @@ static void ST_overlayDrawer(void) ST_doHuntIconsAndSound(); if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) - V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, hudinfo[HUD_GRAVBOOTSICO].y, V_PERPLAYER|V_SNAPTORIGHT, gravboots); + V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, hudinfo[HUD_GRAVBOOTSICO].y, hudinfo[HUD_GRAVBOOTSICO].f|V_PERPLAYER, gravboots); if(!P_IsLocalPlayer(stplyr)) { diff --git a/src/st_stuff.h b/src/st_stuff.h index 2294c35e4..50937907f 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -72,7 +72,7 @@ extern patch_t *ngradeletters[7]; */ typedef struct { - INT32 x, y; + INT32 x, y, f; } hudinfo_t; typedef enum diff --git a/src/y_inter.c b/src/y_inter.c index 063268626..7ac28018b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -161,9 +161,9 @@ static void Y_FollowIntermission(void); static void Y_UnloadData(void); // Stuff copy+pasted from st_stuff.c -#define ST_DrawNumFromHud(h,n) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, V_SNAPTOTOP|V_SNAPTOLEFT, n) -#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, V_SNAPTOTOP|V_SNAPTOLEFT, n, q) -#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, V_SNAPTOTOP|V_SNAPTOLEFT, p) +#define ST_DrawNumFromHud(h,n) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, n) +#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, n, q) +#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, p) static void Y_IntermissionTokenDrawer(void) { From ae033a940911e15bd1c3bdae759f8b485550bb3a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 20 Mar 2018 00:19:20 +0000 Subject: [PATCH 071/122] * Clean up a lot of NiGHTS stuff still using the old, shitty NOSCALESTART offsetting in nonstandard resolutions. * Clean up the ST_ drawing macro list. --- src/st_stuff.c | 70 +++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 4f7c8fc28..168c98724 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -410,25 +410,10 @@ void ST_changeDemoView(void) boolean st_overlay; -static INT32 SCZ(INT32 z) -{ - return FixedInt(FixedMul(z<bumpertime) - V_DrawString(SCX(locx), SCZ(locy - 8), V_NOSCALESTART|V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime))); + V_DrawString(locx, locy - 8, V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime))); else - V_DrawString(SCX(locx), SCZ(locy - 8), V_NOSCALESTART|V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20))); + V_DrawString(locx, locy - 8, V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20))); } } @@ -1416,10 +1401,10 @@ static void ST_drawNiGHTSHUD(void) for (r = 0; r < 5; r++) { - ST_DrawUnscaledOverlayPatch(SCX(230 - (7*r)), SCZ(144), redstat); - ST_DrawUnscaledOverlayPatch(SCX(188 - (7*r)), SCZ(144), orngstat); - ST_DrawUnscaledOverlayPatch(SCX(146 - (7*r)), SCZ(144), yelstat); - ST_DrawUnscaledOverlayPatch(SCX(104 - (7*r)), SCZ(144), byelstat); + V_DrawScaledPatch(230 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, redstat); + V_DrawScaledPatch(188 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, orngstat); + V_DrawScaledPatch(146 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, yelstat); + V_DrawScaledPatch(104 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, byelstat); } amount = (origamount - stplyr->capsule->health); @@ -1438,7 +1423,7 @@ static void ST_drawNiGHTSHUD(void) if (r > 10) ++t; if (r > 5) ++t; - ST_DrawUnscaledOverlayPatch(SCX(69 + (7*t)), SCZ(144), bluestat); + V_DrawScaledPatch(69 + (7*t), 144, V_PERPLAYER|V_HUDTRANS, bluestat); } } } @@ -1465,9 +1450,9 @@ static void ST_drawNiGHTSHUD(void) ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[8]); if (total_ringcount >= 100) - ST_DrawTopLeftOverlayNum((total_ringcount >= 1000) ? 76 : 72, 8 + 11, total_ringcount); + V_DrawTallNum((total_ringcount >= 1000) ? 76 : 72, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_ringcount); else - ST_DrawTopLeftOverlayNum(68, 8 + 11, total_ringcount); + V_DrawTallNum(68, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_ringcount); #ifdef HAVE_BLUA } #endif @@ -1490,22 +1475,21 @@ static void ST_drawNiGHTSHUD(void) if (modeattacking == ATTACKING_NIGHTS) { INT32 maretime = max(stplyr->realtime - stplyr->marebegunat, 0); - fixed_t cornerx = vid.width, cornery = vid.height-SCZ(20); -#define ASSISHHUDFIX(n) (n*vid.dupx) - ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(22), cornery, W_CachePatchName("NGRTIMER", PU_HUDGFX)); - ST_DrawUnscaledPaddedOverlayNum(cornerx-ASSISHHUDFIX(22), cornery, G_TicsToCentiseconds(maretime), 2); - ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(46), cornery, sboperiod); +#define VFLAGS V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER|V_HUDTRANS + V_DrawScaledPatch(BASEVIDWIDTH-22, BASEVIDHEIGHT-20, VFLAGS, W_CachePatchName("NGRTIMER", PU_HUDGFX)); + V_DrawPaddedTallNum(BASEVIDWIDTH-22, BASEVIDHEIGHT-20, VFLAGS, G_TicsToCentiseconds(maretime), 2); + V_DrawScaledPatch(BASEVIDWIDTH-46, BASEVIDHEIGHT-20, VFLAGS, sboperiod); if (maretime < 60*TICRATE) - ST_DrawUnscaledOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime)); + V_DrawTallNum(BASEVIDWIDTH-46, BASEVIDHEIGHT-20, VFLAGS, G_TicsToSeconds(maretime)); else { - ST_DrawUnscaledPaddedOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime), 2); - ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(70), cornery, sbocolon); - ST_DrawUnscaledOverlayNum(cornerx-ASSISHHUDFIX(70), cornery, G_TicsToMinutes(maretime, true)); + V_DrawPaddedTallNum(BASEVIDWIDTH-46, BASEVIDHEIGHT-20, VFLAGS, G_TicsToSeconds(maretime), 2); + V_DrawScaledPatch(BASEVIDWIDTH-70, BASEVIDHEIGHT-20, VFLAGS, sbocolon); + V_DrawTallNum(BASEVIDWIDTH-70, BASEVIDHEIGHT-20, VFLAGS, G_TicsToMinutes(maretime, true)); } +#undef VFLAGS } -#undef ASSISHHUDFIX } // Ideya time remaining @@ -1534,10 +1518,10 @@ static void ST_drawNiGHTSHUD(void) if (flashingLeft < TICRATE/2) // Start fading out { UINT32 fadingFlag = (9 - 9*flashingLeft/(TICRATE/2)) << V_ALPHASHIFT; - V_DrawTranslucentPatch(SCX(160 - (minus5sec->width/2)), SCZ(28), V_NOSCALESTART|V_PERPLAYER|fadingFlag, minus5sec); + V_DrawTranslucentPatch(160 - (minus5sec->width/2), 28, V_PERPLAYER|fadingFlag, minus5sec); } else - V_DrawScaledPatch(SCX(160 - (minus5sec->width/2)), SCZ(28), V_NOSCALESTART|V_PERPLAYER, minus5sec); + V_DrawScaledPatch(160 - (minus5sec->width/2), 28, V_PERPLAYER, minus5sec); } if (realnightstime < 10) @@ -1563,22 +1547,22 @@ static void ST_drawNiGHTSHUD(void) if (stplyr->powers[pw_nights_superloop]) { pwr = stplyr->powers[pw_nights_superloop]; - V_DrawSmallScaledPatch(SCX(110), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUA0",PU_CACHE)); - V_DrawThinString(SCX(106), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(110, 44, 0, W_CachePatchName("NPRUA0",PU_CACHE)); + V_DrawThinString(106, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } if (stplyr->powers[pw_nights_helper]) { pwr = stplyr->powers[pw_nights_helper]; - V_DrawSmallScaledPatch(SCX(150), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUC0",PU_CACHE)); - V_DrawThinString(SCX(146), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(150, 44, 0, W_CachePatchName("NPRUC0",PU_CACHE)); + V_DrawThinString(146, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } if (stplyr->powers[pw_nights_linkfreeze]) { pwr = stplyr->powers[pw_nights_linkfreeze]; - V_DrawSmallScaledPatch(SCX(190), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUE0",PU_CACHE)); - V_DrawThinString(SCX(186), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(190, 44, 0, W_CachePatchName("NPRUE0",PU_CACHE)); + V_DrawThinString(186, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } } @@ -1689,7 +1673,7 @@ static inline void ST_drawRaceHUD(void) if (!(P_AutoPause() || paused) && !bounce) S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); } - V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racenum->width))/2), (INT32)(SCZ(height)), V_NOSCALESTART|V_PERPLAYER, racenum); + V_DrawScaledPatch(((BASEVIDWIDTH - SHORT(racenum->width))/2), height, V_PERPLAYER, racenum); } if (circuitmap) From 4e95066f5ac700bd868c140c90394bd94a9c2fad Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 20 Mar 2018 14:20:02 +0000 Subject: [PATCH 072/122] Some fixes and updates for HWR_SplitWall Solid walls *can* be cut Fix issues with water and fog FOFs not cutting each other out correctly Fix Fog colourmap and lighting setting that is done here. Remove HWR_SplitFog There is currently a bug with FF_DOUBLESHADOW (that also exists in software) but has a larger impact here. When 2 FF_DOUBLESHADOW lights are directly stacked on each other the bottom one has its height set incorrectly. This causes all the Fog in the timed gravity flipping section of ERZ2 to be drawn and it looks really bad. --- src/hardware/hw_main.c | 246 +++++++++++++---------------------------- 1 file changed, 76 insertions(+), 170 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 83783072f..c4e3d879e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1065,7 +1065,7 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) // // HWR_SplitWall // -static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, FSurfaceInfo* Surf, UINT32 cutflag) +static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, FSurfaceInfo* Surf, UINT32 cutflag, ffloor_t *pfloor) { /* SoM: split up and light walls according to the lightlist. This may also include leaving out parts @@ -1093,7 +1093,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, lightlist_t * list = sector->lightlist; const UINT8 alpha = Surf->FlatColor.s.alpha; FUINT lightnum; - extracolormap_t *colormap; + extracolormap_t *colormap = NULL; realtop = top = wallVerts[3].y; realbot = bot = wallVerts[0].y; @@ -1109,7 +1109,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, endpegmul = (endpegb - endpegt) / (endtop - endbot); #endif - for (i = 1; i < sector->numlights; i++) + for (i = 0; i < sector->numlights; i++) { #ifdef ESLOPE if (endtop < endrealbot) @@ -1117,35 +1117,38 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (top < realbot) return; - //Hurdler: fix a crashing bug, but is it correct? -// if (!list[i].caster) -// continue; + // There's a compiler warning here if this comment isn't here because of indentation + if (!(list[i].flags & FF_NOSHADE)) + { + if (pfloor && (pfloor->flags & FF_FOG)) + { + lightnum = pfloor->master->frontsector->lightlevel; + colormap = pfloor->master->frontsector->extra_colormap; + } + else + { + lightnum = *list[i].lightlevel; + colormap = list[i].extra_colormap; + } + } solid = false; - if (list[i].caster) + if ((sector->lightlist[i].flags & FF_CUTSOLIDS) && !(cutflag & FF_EXTRA)) + solid = true; + else if ((sector->lightlist[i].flags & FF_CUTEXTRA) && (cutflag & FF_EXTRA)) { - if (sector->lightlist[i].caster->flags & FF_CUTSOLIDS && !(cutflag & FF_EXTRA)) - solid = true; - else if (sector->lightlist[i].caster->flags & FF_CUTEXTRA && cutflag & FF_EXTRA) + if (sector->lightlist[i].flags & FF_EXTRA) { - if (sector->lightlist[i].caster->flags & FF_EXTRA) - { - if (sector->lightlist[i].caster->flags == cutflag) // Only merge with your own types - solid = true; - } - else + if ((sector->lightlist[i].flags & (FF_FOG|FF_SWIMMABLE)) == (cutflag & (FF_FOG|FF_SWIMMABLE))) // Only merge with your own types solid = true; } else - solid = false; + solid = true; } else solid = false; - if (cutflag == FF_CUTSOLIDS) // These are regular walls sent in from StoreWallRange, they shouldn't be cut from this - solid = false; - #ifdef ESLOPE if (list[i].slope) { @@ -1185,34 +1188,53 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (solid && endtop > endbheight) endtop = endbheight; #endif - continue; } +#ifdef ESLOPE + if (i + 1 < sector->numlights) + { + if (list[i+1].slope) + { + temp = P_GetZAt(list[i+1].slope, v1x, v1y); + bheight = FIXED_TO_FLOAT(temp); + temp = P_GetZAt(list[i+1].slope, v2x, v2y); + endbheight = FIXED_TO_FLOAT(temp); + } + else + bheight = endbheight = FIXED_TO_FLOAT(list[i+1].height); + } + else + { + bheight = realbot; + endbheight = endrealbot; + } +#else + if (i + 1 < sector->numlights) + { + bheight = FIXED_TO_FLOAT(list[i+1].height); + } + else + { + bheight = realbot; + } +#endif + + if (endbheight >= endtop) + if (bheight >= top) + continue; + //Found a break; - bot = height; + bot = bheight; if (bot < realbot) bot = realbot; #ifdef ESLOPE - endbot = endheight; + endbot = endbheight; if (endbot < endrealbot) endbot = endrealbot; #endif - - // colormap test - if (list[i-1].caster) - { - lightnum = *list[i-1].lightlevel; - colormap = list[i-1].extra_colormap; - } - else - { - lightnum = sector->lightlevel; - colormap = sector->extra_colormap; - } - Surf->FlatColor.s.alpha = alpha; #ifdef ESLOPE @@ -1235,20 +1257,16 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - if (cutflag & FF_TRANSLUCENT) + if (cutflag & FF_FOG) + HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture, true, lightnum, colormap); + else if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); - if (solid) - top = bheight; - else - top = height; + top = bot; #ifdef ESLOPE - if (solid) - endtop = endbheight; - else - endtop = endheight; + endtop = endbot; #endif } @@ -1260,17 +1278,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (top <= realbot) return; - if (list[i-1].caster) - { - lightnum = *list[i-1].lightlevel; - colormap = list[i-1].extra_colormap; - } - else - { - lightnum = sector->lightlevel; - colormap = sector->extra_colormap; - } - Surf->FlatColor.s.alpha = alpha; + Surf->FlatColor.s.alpha = alpha; #ifdef ESLOPE wallVerts[3].t = pegt + ((realtop - top) * pegmul); @@ -1292,116 +1300,14 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - if (cutflag & FF_TRANSLUCENT) + if (cutflag & FF_FOG) + HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture, true, lightnum, colormap); + else if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); } -// -// HWR_SplitFog -// Exclusively for fog -// -static void HWR_SplitFog(sector_t *sector, wallVert3D *wallVerts, FSurfaceInfo* Surf, UINT32 cutflag, FUINT lightnum, extracolormap_t *colormap) -{ - /* SoM: split up and light walls according to the - lightlist. This may also include leaving out parts - of the wall that can't be seen */ - float realtop, realbot, top, bot; - float pegt, pegb, pegmul; - float height = 0.0f, bheight = 0.0f; - INT32 solid, i; - lightlist_t * list = sector->lightlist; - const UINT8 alpha = Surf->FlatColor.s.alpha; - - realtop = top = wallVerts[2].y; - realbot = bot = wallVerts[0].y; - pegt = wallVerts[2].t; - pegb = wallVerts[0].t; - pegmul = (pegb - pegt) / (top - bot); - - for (i = 1; i < sector->numlights; i++) - { - if (top < realbot) - return; - - //Hurdler: fix a crashing bug, but is it correct? -// if (!list[i].caster) -// continue; - - solid = false; - - if (list[i].caster) - { - if (sector->lightlist[i].caster->flags & FF_FOG && cutflag & FF_FOG) // Only fog cuts fog - { - if (sector->lightlist[i].caster->flags & FF_EXTRA) - { - if (sector->lightlist[i].caster->flags == cutflag) // only cut by the same - solid = true; - } - else - solid = true; - } - } - - height = FIXED_TO_FLOAT(list[i].height); - - if (solid) - bheight = FIXED_TO_FLOAT(*list[i].caster->bottomheight); - - if (height >= top) - { - if (solid && top > bheight) - top = bheight; - continue; - } - - //Found a break; - bot = height; - - if (bot < realbot) - bot = realbot; - - { - - - - Surf->FlatColor.s.alpha = alpha; - } - - wallVerts[3].t = wallVerts[2].t = pegt + ((realtop - top) * pegmul); - wallVerts[0].t = wallVerts[1].t = pegt + ((realtop - bot) * pegmul); - - // set top/bottom coords - wallVerts[2].y = wallVerts[3].y = top; - wallVerts[0].y = wallVerts[1].y = bot; - - if (!solid) // Don't draw it if there's more fog behind it - HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Fog|PF_NoTexture, true, lightnum, colormap); - - top = height; - } - - bot = realbot; - if (top <= realbot) - return; - - { - - Surf->FlatColor.s.alpha = alpha; - } - - wallVerts[3].t = wallVerts[2].t = pegt + ((realtop - top) * pegmul); - wallVerts[0].t = wallVerts[1].t = pegt + ((realtop - bot) * pegmul); - - // set top/bottom coords - wallVerts[2].y = wallVerts[3].y = top; - wallVerts[0].y = wallVerts[1].y = bot; - - HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Translucent|PF_NoTexture, true, lightnum, colormap); -} - // HWR_DrawSkyWalls // Draw walls into the depth buffer so that anything behind is culled properly static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top) @@ -1678,7 +1584,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, gr_toptexture, &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_toptexture, &Surf, FF_CUTLEVEL, NULL); else if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, gr_toptexture, PF_Environment, false, lightnum, colormap); else @@ -1761,7 +1667,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, gr_bottomtexture, &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_bottomtexture, &Surf, FF_CUTLEVEL, NULL); else if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, gr_bottomtexture, PF_Environment, false, lightnum, colormap); else @@ -2027,10 +1933,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (gr_frontsector->numlights) { if (!(blendmode & PF_Masked)) - HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_TRANSLUCENT); + HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_TRANSLUCENT, NULL); else { - HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTLEVEL, NULL); } } else if (!(blendmode & PF_Masked)) @@ -2182,7 +2088,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif // I don't think that solid walls can use translucent linedef types... if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTLEVEL, NULL); else { if (grTex->mipmap.flags & TF_TRANSPARENT) @@ -2320,7 +2226,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } if (gr_frontsector->numlights) - HWR_SplitFog(gr_frontsector, wallVerts, &Surf, rover->flags, lightnum, colormap); + HWR_SplitWall(gr_frontsector, wallVerts, 0, &Surf, rover->flags, rover); else HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap); } @@ -2335,7 +2241,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, texnum, &Surf, rover->flags); + HWR_SplitWall(gr_frontsector, wallVerts, texnum, &Surf, rover->flags, rover); else { if (blendmode != PF_Masked) @@ -2439,7 +2345,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } if (gr_backsector->numlights) - HWR_SplitFog(gr_backsector, wallVerts, &Surf, rover->flags, lightnum, colormap); + HWR_SplitWall(gr_backsector, wallVerts, 0, &Surf, rover->flags, rover); else HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap); } @@ -2454,7 +2360,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } if (gr_backsector->numlights) - HWR_SplitWall(gr_backsector, wallVerts, texnum, &Surf, rover->flags); + HWR_SplitWall(gr_backsector, wallVerts, texnum, &Surf, rover->flags, rover); else { if (blendmode != PF_Masked) From 05bf3674d3a34b868b215e78bb6c1b709d10ff45 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 20 Mar 2018 15:00:27 +0000 Subject: [PATCH 073/122] * M_Random function access to v! (so v.RandomFixed(), etc...) * Remove deprecated P_Random() from Lua. --- src/lua_baselib.c | 11 +------ src/lua_hudlib.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9d65a5832..ed29acc33 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -214,15 +214,7 @@ static int lib_pRandomRange(lua_State *L) return 1; } -// Deprecated, macros, etc. -static int lib_pRandom(lua_State *L) -{ - NOHUD - LUA_Deprecated(L, "P_Random", "P_RandomByte"); - lua_pushinteger(L, P_RandomByte()); - return 1; -} - +// Macros. static int lib_pSignedRandom(lua_State *L) { NOHUD @@ -2481,7 +2473,6 @@ static luaL_Reg lib[] = { {"P_RandomByte",lib_pRandomByte}, {"P_RandomKey",lib_pRandomKey}, {"P_RandomRange",lib_pRandomRange}, - {"P_Random",lib_pRandom}, // DEPRECATED {"P_SignedRandom",lib_pSignedRandom}, // MACRO {"P_RandomChance",lib_pRandomChance}, // MACRO diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index a709ba9f4..afc81c37d 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -20,6 +20,7 @@ #include "i_video.h" // rendermode #include "p_local.h" // camera_t #include "screen.h" // screen width/height +#include "m_random.h" // m_random #include "v_video.h" #include "w_wad.h" #include "z_zone.h" @@ -752,20 +753,92 @@ static int libd_renderer(lua_State *L) return 1; } +// M_RANDOM +////////////// + +static int libd_RandomFixed(lua_State *L) +{ + HUDONLY + lua_pushfixed(L, M_RandomFixed()); + return 1; +} + +static int libd_RandomByte(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, M_RandomByte()); + return 1; +} + +static int libd_RandomKey(lua_State *L) +{ + INT32 a = (INT32)luaL_checkinteger(L, 1); + + HUDONLY + if (a > 65536) + LUA_UsageWarning(L, "v.RandomKey: range > 65536 is undefined behavior"); + lua_pushinteger(L, M_RandomKey(a)); + return 1; +} + +static int libd_RandomRange(lua_State *L) +{ + INT32 a = (INT32)luaL_checkinteger(L, 1); + INT32 b = (INT32)luaL_checkinteger(L, 2); + + HUDONLY + if (b < a) { + INT32 c = a; + a = b; + b = c; + } + if ((b-a+1) > 65536) + LUA_UsageWarning(L, "v.RandomRange: range > 65536 is undefined behavior"); + lua_pushinteger(L, M_RandomRange(a, b)); + return 1; +} + +// Macros. +static int libd_SignedRandom(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, M_SignedRandom()); + return 1; +} + +static int libd_RandomChance(lua_State *L) +{ + fixed_t p = luaL_checkfixed(L, 1); + HUDONLY + lua_pushboolean(L, M_RandomChance(p)); + return 1; +} + static luaL_Reg lib_draw[] = { + // cache {"patchExists", libd_patchExists}, {"cachePatch", libd_cachePatch}, {"getSpritePatch", libd_getSpritePatch}, {"getSprite2Patch", libd_getSprite2Patch}, + {"getColormap", libd_getColormap}, + // drawing {"draw", libd_draw}, {"drawScaled", libd_drawScaled}, {"drawNum", libd_drawNum}, {"drawPaddedNum", libd_drawPaddedNum}, {"drawFill", libd_drawFill}, {"drawString", libd_drawString}, - {"stringWidth", libd_stringWidth}, - {"getColormap", libd_getColormap}, {"fadeScreen", libd_fadeScreen}, + // misc + {"stringWidth", libd_stringWidth}, + // m_random + {"RandomFixed",libd_RandomFixed}, + {"RandomByte",libd_RandomByte}, + {"RandomKey",libd_RandomKey}, + {"RandomRange",libd_RandomRange}, + {"SignedRandom",libd_SignedRandom}, // MACRO + {"RandomChance",libd_RandomChance}, // MACRO + // properties {"width", libd_width}, {"height", libd_height}, {"dupx", libd_dupx}, From 24c017564e603575cf8dc59923df45d7390a848d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 21 Mar 2018 18:18:45 +0000 Subject: [PATCH 074/122] Mammoth commit! * Make TIME part of HUD count down in a bunch of circumstances where it was otherwise some other seperate thing. * Make race countdown happen in a bunch of appropriate circumstances. * Refactor race countdown. * Remove a lot of useless stuff from H&S/Tag UI. * Make co-op/competition/race end-of-act countdown use the race countdown and bigger HUD font. * Remove useless PLAYING/SPECTATE text from lives element. * Merge lap counter into lives element. * Move some other text around. --- src/hu_stuff.c | 16 +--- src/m_menu.c | 8 +- src/p_user.c | 4 +- src/screen.c | 11 +-- src/st_stuff.c | 238 ++++++++++++++++++++++++++++--------------------- src/st_stuff.h | 1 - 6 files changed, 152 insertions(+), 126 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 7af7aa768..58db7961b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1591,20 +1591,8 @@ static void HU_DrawRankings(void) { if (cv_timelimit.value && timelimitintics > 0) { - INT32 timeval = (timelimitintics+1-leveltime)/TICRATE; - - if (leveltime <= timelimitintics) - { - V_DrawCenteredString(64, 8, 0, "TIME LEFT"); - V_DrawCenteredString(64, 16, 0, va("%u", timeval)); - } - - // overtime - if ((leveltime > (timelimitintics + TICRATE/2)) && cv_overtime.value) - { - V_DrawCenteredString(64, 8, 0, "TIME LEFT"); - V_DrawCenteredString(64, 16, 0, "OVERTIME"); - } + V_DrawCenteredString(64, 8, 0, "TIME"); + V_DrawCenteredString(64, 16, 0, va("%i:%02i", G_TicsToMinutes(stplyr->realtime, true), G_TicsToSeconds(stplyr->realtime))); } if (cv_pointlimit.value > 0) diff --git a/src/m_menu.c b/src/m_menu.c index 24beff317..e53d9012f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5682,7 +5682,7 @@ static void M_DrawChecklist(void) beat = va("Get %d points in %s", cond[condnum].requirement, level); break; case UC_MAPTIME: - beat = va("Beat %s in %d:%d.%d", level, + beat = va("Beat %s in %d:%02d.%02d", level, G_TicsToMinutes(cond[condnum].requirement, true), G_TicsToSeconds(cond[condnum].requirement), G_TicsToCentiseconds(cond[condnum].requirement)); @@ -5707,7 +5707,7 @@ static void M_DrawChecklist(void) beat = va("Get %d points over all maps", cond[condnum].requirement); break; case UC_OVERALLTIME: - beat = va("Get a total time of less than %d:%d.%d", + beat = va("Get a total time of less than %d:%02d.%02d", G_TicsToMinutes(cond[condnum].requirement, true), G_TicsToSeconds(cond[condnum].requirement), G_TicsToCentiseconds(cond[condnum].requirement)); @@ -5755,12 +5755,12 @@ static void M_DrawChecklist(void) break; case UC_NIGHTSTIME: if (cond[condnum].extrainfo2) - beat = va("Beat %s, mare %d in %d:%d.%d", level, cond[condnum].extrainfo2, + beat = va("Beat %s, mare %d in %d:%02d.%02d", level, cond[condnum].extrainfo2, G_TicsToMinutes(cond[condnum].requirement, true), G_TicsToSeconds(cond[condnum].requirement), G_TicsToCentiseconds(cond[condnum].requirement)); else - beat = va("Beat %s in %d:%d.%d", + beat = va("Beat %s in %d:%02d.%02d", level, G_TicsToMinutes(cond[condnum].requirement, true), G_TicsToSeconds(cond[condnum].requirement), diff --git a/src/p_user.c b/src/p_user.c index f422e9b65..d127e7139 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1725,7 +1725,7 @@ void P_DoPlayerExit(player_t *player) else if (gametype == GT_RACE || gametype == GT_COMPETITION) // If in Race Mode, allow { if (!countdown) // a 60-second wait ala Sonic 2. - countdown = cv_countdowntime.value*TICRATE + 1; // Use cv_countdowntime + countdown = (cv_countdowntime.value - 1)*TICRATE + 1; // Use cv_countdowntime player->exiting = 3*TICRATE; @@ -9538,7 +9538,7 @@ void P_PlayerThink(player_t *player) if (i == MAXPLAYERS && player->exiting == 3*TICRATE) // finished player->exiting = (14*TICRATE)/5 + 1; - // If 10 seconds are left on the timer, + // If 11 seconds are left on the timer, // begin the drown music for countdown! if (countdown == 11*TICRATE - 1) { diff --git a/src/screen.c b/src/screen.c index 28765785b..5120aa581 100644 --- a/src/screen.c +++ b/src/screen.c @@ -455,9 +455,8 @@ void SCR_ClosedCaptions(void) if (music && !gamestopped && (closedcaptions[i].t < flashingtics) && (closedcaptions[i].t & 1)) continue; - flags = V_NOSCALESTART|V_ALLOWLOWERCASE; - y = vid.height-((i + 2)*10*vid.dupy); - dot = ' '; + flags = V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_ALLOWLOWERCASE; + y = BASEVIDHEIGHT-((i + 2)*10); if (closedcaptions[i].b) y -= (closedcaptions[i].b--)*vid.dupy; @@ -469,8 +468,10 @@ void SCR_ClosedCaptions(void) dot = '\x19'; else if (closedcaptions[i].c && closedcaptions[i].c->origin) dot = '\x1E'; + else + dot = ' '; - V_DrawRightAlignedString(vid.width-(20*vid.dupx), y, - flags, va("%c [%s]", dot, (closedcaptions[i].s->caption[0] ? closedcaptions[i].s->caption : closedcaptions[i].s->name))); + V_DrawRightAlignedString(BASEVIDWIDTH - 20, y, flags, + va("%c [%s]", dot, (closedcaptions[i].s->caption[0] ? closedcaptions[i].s->caption : closedcaptions[i].s->name))); } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 168c98724..b9005ab68 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -151,8 +151,6 @@ hudinfo_t hudinfo[NUMHUDITEMS] = { 152, 168, 0}, // HUD_HUNTPICS { 152, 24, V_SNAPTORIGHT}, // HUD_GRAVBOOTSICO - - { 240, 160, V_SNAPTOBOTTOM|V_SNAPTORIGHT}, // HUD_LAP }; // @@ -541,15 +539,46 @@ static void ST_drawScore(void) ST_DrawNumFromHud(HUD_SCORENUM, op_displayflags, V_HUDTRANS); } else - ST_DrawNumFromHud(HUD_SCORENUM, stplyr->score,V_HUDTRANS); + ST_DrawNumFromHud(HUD_SCORENUM, stplyr->score, V_HUDTRANS); +} + +static void ST_drawRaceNum(INT32 time) +{ + INT32 height, bounce; + patch_t *racenum; + + time += TICRATE; + height = ((3*BASEVIDHEIGHT)>>2) - 8; + bounce = TICRATE - (1 + (time % TICRATE)); + + switch (time/TICRATE) + { + case 3: + racenum = race3; + break; + case 2: + racenum = race2; + break; + case 1: + racenum = race1; + break; + default: + racenum = racego; + break; + } + if (bounce < 3) + { + height -= (2 - bounce); + if (!(P_AutoPause() || paused) && !bounce) + S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); + } + V_DrawScaledPatch(((BASEVIDWIDTH - SHORT(racenum->width))/2), height, V_PERPLAYER, racenum); } static void ST_drawTime(void) { INT32 seconds, minutes, tictrn, tics; - - // TIME: - ST_DrawPatchFromHud(HUD_TIME, ((mapheaderinfo[gamemap-1]->countdown && countdowntimer < 11*TICRATE && leveltime/5 & 1) ? sboredtime : sbotime), V_HUDTRANS); + boolean downwards = false; if (objectplacing) { @@ -560,12 +589,61 @@ static void ST_drawTime(void) } else { - tics = (mapheaderinfo[gamemap-1]->countdown ? countdowntimer : stplyr->realtime); - seconds = G_TicsToSeconds(tics); + // Counting down the hidetime? + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (leveltime <= (hidetime*TICRATE))) + { + tics = (hidetime*TICRATE - leveltime); + if (tics < 3*TICRATE) + ST_drawRaceNum(tics); + downwards = true; + } + else + { + // Hidetime finish! + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (leveltime < ((hidetime+1)*TICRATE))) + ST_drawRaceNum(hidetime*TICRATE - leveltime); + + // Time limit? + if (gametype != GT_RACE && gametype != GT_COMPETITION && gametype != GT_COOP && cv_timelimit.value && timelimitintics > 0) + { + if (timelimitintics >= leveltime) + { + tics = (timelimitintics - leveltime); + if (tics < 3*TICRATE) + ST_drawRaceNum(tics); + } + else // Overtime! + tics = 0; + downwards = true; + } + // Post-hidetime normal. + else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + tics = stplyr->realtime - hidetime*TICRATE; + // "Shadow! What are you doing? Hurry and get back here + // right now before the island blows up with you on it!" + // "Blows up??" *awkward silence* "I've got to get outta + // here and find Amy and Tails right away!" + else if (mapheaderinfo[gamemap-1]->countdown) + { + tics = countdowntimer; + downwards = true; + } + // Normal. + else + tics = stplyr->realtime; + } + minutes = G_TicsToMinutes(tics, true); + seconds = G_TicsToSeconds(tics); tictrn = G_TicsToCentiseconds(tics); } + // TIME: + ST_DrawPatchFromHud(HUD_TIME, ((downwards && (tics < 30*TICRATE) && (leveltime/5 & 1)) ? sboredtime : sbotime), V_HUDTRANS); + + if (!tics && downwards && (leveltime/5 & 1)) // overtime! + return; + if (cv_timetic.value == 1) // Tics only -- how simple is this? ST_DrawNumFromHud(HUD_SECONDS, tics, V_HUDTRANS); else @@ -709,7 +787,7 @@ static void ST_drawLivesArea(void) // Spectator else if (stplyr->spectator) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "SPECTATE"); + //V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "SPECTATOR"); v_colmap = V_GRAYMAP; } // Tag @@ -747,10 +825,19 @@ static void ST_drawLivesArea(void) else v_colmap = V_GRAYMAP; } - else + else if (circuitmap) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "PLAYING"); + if (stplyr->exiting) + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "FINISHED"); + //V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f|V_YELLOWMAP, "FINISHED!"); + else + { + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, va("%u/%d", stplyr->laps+1, cv_numlaps.value)); + //V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); + } } + /*else + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "PLAYING");*/ // name v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); @@ -1647,92 +1734,34 @@ static void ST_drawMatchHUD(void) static inline void ST_drawRaceHUD(void) { - if (leveltime >= TICRATE && leveltime < 5*TICRATE) - { - INT32 height = ((3*BASEVIDHEIGHT)>>2) - 8; - INT32 bounce = (leveltime % TICRATE); - patch_t *racenum; - switch (leveltime/TICRATE) - { - case 1: - racenum = race3; - break; - case 2: - racenum = race2; - break; - case 3: - racenum = race1; - break; - default: - racenum = racego; - break; - } - if (bounce < 3) - { - height -= (2 - bounce); - if (!(P_AutoPause() || paused) && !bounce) - S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); - } - V_DrawScaledPatch(((BASEVIDWIDTH - SHORT(racenum->width))/2), height, V_PERPLAYER, racenum); - } - - if (circuitmap) - { - if (stplyr->exiting) - V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f|V_YELLOWMAP, "FINISHED!"); - else - V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); - } + if (leveltime > TICRATE && leveltime <= 5*TICRATE) + ST_drawRaceNum(4*TICRATE - leveltime); } static void ST_drawTagHUD(void) { - char pstime[33] = ""; char pstext[33] = ""; // Figure out what we're going to print. if (leveltime < hidetime * TICRATE) //during the hide time, the seeker and hiders have different messages on their HUD. { - if (hidetime) - sprintf(pstime, "%d", (hidetime - leveltime/TICRATE)); //hide time is in seconds, not tics. - - if (stplyr->pflags & PF_TAGIT && !stplyr->spectator) - sprintf(pstext, "%s", M_GetText("WAITING FOR PLAYERS TO HIDE...")); - else - { - if (!stplyr->spectator) //spectators get a generic HUD message rather than a gametype specific one. - { - if (gametype == GT_HIDEANDSEEK) //hide and seek. - sprintf(pstext, "%s", M_GetText("HIDE BEFORE TIME RUNS OUT!")); - else //default - sprintf(pstext, "%s", M_GetText("FLEE BEFORE YOU ARE HUNTED!")); - } - else - sprintf(pstext, "%s", M_GetText("HIDE TIME REMAINING:")); - } - } - else - { - if (cv_timelimit.value && timelimitintics >= leveltime) - sprintf(pstime, "%d", (timelimitintics-leveltime)/TICRATE); - if (stplyr->pflags & PF_TAGIT) - sprintf(pstext, "%s", M_GetText("YOU'RE IT!")); - else - { - if (cv_timelimit.value) - sprintf(pstext, "%s", M_GetText("TIME REMAINING:")); - else //Since having no hud message in tag is not characteristic: - sprintf(pstext, "%s", M_GetText("NO TIME LIMIT")); - } + sprintf(pstext, "%s", M_GetText("Waiting for players to hide...")); + else if (gametype == GT_HIDEANDSEEK) //hide and seek. + sprintf(pstext, "%s", M_GetText("Hide before time runs out!")); + else //default + sprintf(pstext, "%s", M_GetText("Flee before you are hunted!")); } + else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) + { + sprintf(pstext, "%s", M_GetText("You cannot move while hiding.")); + if (!splitscreen) + V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); + } // Print the stuff. if (pstext[0]) - V_DrawCenteredString(BASEVIDWIDTH/2, 168, V_PERPLAYER|V_SNAPTOBOTTOM, pstext); - - if (pstime[0]) - V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_PERPLAYER|V_SNAPTOBOTTOM, pstime); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER, pstext); } static void ST_drawCTFHUD(void) @@ -2010,8 +2039,24 @@ static void ST_overlayDrawer(void) if (!hu_showscores) // hide the following if TAB is held { // Countdown timer for Race Mode - if (countdown) - V_DrawCenteredString(BASEVIDWIDTH/2, 176, V_PERPLAYER, va("%d", countdown/TICRATE)); + if (countdown > 1) + { + tic_t time = countdown/TICRATE + 1; + if (time < 4) + ST_drawRaceNum(countdown); + else + { + tic_t num = time; + INT32 sz = SHORT(tallnum[0]->width)/2, width = 0; + do + { + width += sz; + num /= 10; + } while (num); + V_DrawTallNum((BASEVIDWIDTH/2) + width, ((3*BASEVIDHEIGHT)>>2) - 7, V_PERPLAYER, time); + //V_DrawCenteredString(BASEVIDWIDTH/2, 176, V_PERPLAYER, va("%d", countdown/TICRATE + 1)); + } + } // If you are in overtime, put a big honkin' flashin' message on the screen. if (G_RingSlingerGametype() && cv_overtime.value @@ -2032,7 +2077,7 @@ static void ST_overlayDrawer(void) if (gametype == GT_RACE || gametype == GT_COMPETITION) ST_drawRaceHUD(); // Tag HUD Stuff - else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) ST_drawTagHUD(); // CTF HUD Stuff else if (gametype == GT_CTF) @@ -2118,20 +2163,13 @@ static void ST_overlayDrawer(void) } else if (!splitscreen && gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); - else if (gametype == GT_HIDEANDSEEK && - (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) - { - V_DrawCenteredString(BASEVIDWIDTH/2, 116, V_PERPLAYER, M_GetText("You cannot move while hiding.")); - if (!splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); - } else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; if (respawntime > 0 && !stplyr->spectator) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, va(M_GetText("Respawn in %d..."), respawntime)); else - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); } else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE) #ifdef HAVE_BLUA @@ -2141,9 +2179,9 @@ static void ST_overlayDrawer(void) { V_DrawCenteredString(BASEVIDWIDTH/2, 60, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You are a spectator.")); if (G_GametypeHasTeams()) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); else if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); else if (gametype == GT_COOP && stplyr->lives <= 0) { if (cv_cooplives.value == 2 @@ -2163,13 +2201,13 @@ static void ST_overlayDrawer(void) } if (i != MAXPLAYERS) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); } } else if (gametype != GT_COOP) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); if (!splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); V_DrawCenteredString(BASEVIDWIDTH/2, 148, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); } } diff --git a/src/st_stuff.h b/src/st_stuff.h index 50937907f..df1ac6433 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -102,7 +102,6 @@ typedef enum HUD_TIMEUP, HUD_HUNTPICS, HUD_GRAVBOOTSICO, - HUD_LAP, NUMHUDITEMS } hudnum_t; From 0885d271711155e02d389c04f12bf2c234d1a7f1 Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 21 Mar 2018 19:45:37 +0000 Subject: [PATCH 075/122] Transform sprites in world space rather than screen space Transformation based on screen space would make sense if we didn't want anything in the world to effect the sprites. This should allow sprite splitting and sorting of sprites with level geometry easier. stransform is no longer needed. --- src/hardware/hw_glob.h | 1 + src/hardware/hw_main.c | 249 +++++++++++++---------------------------- 2 files changed, 79 insertions(+), 171 deletions(-) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 94eef1d3e..fea06caff 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -68,6 +68,7 @@ typedef struct gr_vissprite_s struct gr_vissprite_s *prev; struct gr_vissprite_s *next; float x1, x2; + float z1, z2; float tz, ty; lumpnum_t patchlumpnum; boolean flip; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c4e3d879e..7b9628b3d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3928,12 +3928,10 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale) { - UINT8 i; - float tr_x, tr_y; - FOutVector *wv; FOutVector swallVerts[4]; FSurfaceInfo sSurf; fixed_t floorheight, mobjfloor; + float offset = 0; mobjfloor = HWR_OpaqueFloorAtPos( spr->mobj->x, spr->mobj->y, @@ -3972,6 +3970,8 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t } floorheight = FixedInt(spr->mobj->z - floorheight); + + offset = floorheight; } else floorheight = FixedInt(spr->mobj->z - mobjfloor); @@ -3984,47 +3984,42 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t // 0--1 // x1/x2 were already scaled in HWR_ProjectSprite + // First match the normal sprite swallVerts[0].x = swallVerts[3].x = spr->x1; swallVerts[2].x = swallVerts[1].x = spr->x2; + swallVerts[0].z = swallVerts[3].z = spr->z1; + swallVerts[2].z = swallVerts[1].z = spr->z2; if (spr->mobj && this_scale != 1.0f) { // Always a pixel above the floor, perfectly flat. swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3); - swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset) * this_scale; - swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset * this_scale; + // Now transform the TOP vertices along the floor in the direction of the camera + swallVerts[3].x = spr->x1 + ((gpatch->height * this_scale) + offset) * gr_viewcos; + swallVerts[2].x = spr->x2 + ((gpatch->height * this_scale) + offset) * gr_viewcos; + swallVerts[3].z = spr->z1 + ((gpatch->height * this_scale) + offset) * gr_viewsin; + swallVerts[2].z = spr->z2 + ((gpatch->height * this_scale) + offset) * gr_viewsin; } else { // Always a pixel above the floor, perfectly flat. swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3); - // Spread out top away from the camera. (Fixme: Make it always move out in the same direction!... somehow.) - swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset); - swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset; + // Now transform the TOP vertices along the floor in the direction of the camera + swallVerts[3].x = spr->x1 + (gpatch->height + offset) * gr_viewcos; + swallVerts[2].x = spr->x2 + (gpatch->height + offset) * gr_viewcos; + swallVerts[3].z = spr->z1 + (gpatch->height + offset) * gr_viewsin; + swallVerts[2].z = spr->z2 + (gpatch->height + offset) * gr_viewsin; } - // transform - wv = swallVerts; - - for (i = 0; i < 4; i++,wv++) + // We also need to move the bottom ones away when shadowoffs is on + if (cv_shadowoffs.value) { - // Offset away from the camera based on height from floor. - if (cv_shadowoffs.value) - wv->z += floorheight; - wv->z += 3; - - //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - tr_x = wv->z; - tr_y = wv->y; - wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin); - wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos); - // ---------------------- mega lame test ---------------------------------- - - //scale y before frustum so that frustum can be scaled to screen height - wv->y *= ORIGINAL_ASPECT * gr_fovlud; - wv->x *= gr_fovlud; + swallVerts[0].x = spr->x1 + offset * gr_viewcos; + swallVerts[1].x = spr->x2 + offset * gr_viewcos; + swallVerts[0].z = spr->z1 + offset * gr_viewsin; + swallVerts[1].z = spr->z2 + offset * gr_viewsin; } if (spr->flip) @@ -4111,10 +4106,8 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t // -----------------+ static void HWR_DrawSprite(gr_vissprite_t *spr) { - UINT8 i; - float tr_x, tr_y, this_scale = 1.0f; + float this_scale = 1.0f; FOutVector wallVerts[4]; - FOutVector *wv; GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES); @@ -4161,24 +4154,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // make a wall polygon (with 2 triangles), using the floor/ceiling heights, // and the 2d map coords of start/end vertices - wallVerts[0].z = wallVerts[1].z = wallVerts[2].z = wallVerts[3].z = spr->tz; - - // transform - wv = wallVerts; - - for (i = 0; i < 4; i++,wv++) - { - //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - tr_x = wv->z; - tr_y = wv->y; - wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin); - wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos); - // ---------------------- mega lame test ---------------------------------- - - //scale y before frustum so that frustum can be scaled to screen height - wv->y *= ORIGINAL_ASPECT * gr_fovlud; - wv->x *= gr_fovlud; - } + wallVerts[0].z = wallVerts[3].z = spr->z1; + wallVerts[1].z = wallVerts[2].z = spr->z2; if (spr->flip) { @@ -4289,11 +4266,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // Sprite drawer for precipitation static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) { - UINT8 i; FBITFIELD blend = 0; - float tr_x, tr_y; FOutVector wallVerts[4]; - FOutVector *wv; GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; @@ -4319,24 +4293,8 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) // make a wall polygon (with 2 triangles), using the floor/ceiling heights, // and the 2d map coords of start/end vertices - wallVerts[0].z = wallVerts[1].z = wallVerts[2].z = wallVerts[3].z = spr->tz; - - // transform - wv = wallVerts; - - for (i = 0; i < 4; i++, wv++) - { - //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - tr_x = wv->z; - tr_y = wv->y; - wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin); - wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos); - // ---------------------- mega lame test ---------------------------------- - - //scale y before frustum so that frustum can be scaled to screen height - wv->y *= ORIGINAL_ASPECT * gr_fovlud; - wv->x *= gr_fovlud; - } + wallVerts[0].z = wallVerts[3].z = spr->z1; + wallVerts[1].z = wallVerts[2].z = spr->z2; wallVerts[0].sow = wallVerts[3].sow = 0; wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; @@ -4830,7 +4788,7 @@ static void HWR_CreateDrawNodes(void) // -------------------------------------------------------------------------- #ifdef SORTING // added the stransform so they can be switched as drawing happenes so MD2s and sprites are sorted correctly with each other -static void HWR_DrawSprites(FTransform *stransform) +static void HWR_DrawSprites() { if (gr_visspritecount > 0) { @@ -4843,37 +4801,22 @@ static void HWR_DrawSprites(FTransform *stransform) { #ifdef HWPRECIP if (spr->precip) - { - HWD.pfnSetTransform(stransform); HWR_DrawPrecipitationSprite(spr); - } else #endif if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { if (!cv_grmd2.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) - { - HWD.pfnSetTransform(stransform); HWR_DrawSprite(spr); - } else - { - HWD.pfnSetTransform(&atransform); HWR_DrawMD2(spr); - } } else { if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) - { - HWD.pfnSetTransform(stransform); HWR_DrawSprite(spr); - } else - { - HWD.pfnSetTransform(&atransform); HWR_DrawMD2(spr); - } } } } @@ -4963,8 +4906,10 @@ static void HWR_ProjectSprite(mobj_t *thing) { gr_vissprite_t *vis; float tr_x, tr_y; - float tx, tz; + float tz; float x1, x2; + float z1, z2; + float rightsin, rightcos; float this_scale; float gz, gzt; spritedef_t *sprdef; @@ -4991,7 +4936,9 @@ static void HWR_ProjectSprite(mobj_t *thing) if (tz < ZCLIP_PLANE && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear return; - tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos); + // The above can stay as it works for cutting sprites that are too close + tr_x = FIXED_TO_FLOAT(thing->x); + tr_y = FIXED_TO_FLOAT(thing->y); // decide which patch to use for sprite relative to player #ifdef RANGECHECK @@ -5046,23 +4993,23 @@ static void HWR_ProjectSprite(mobj_t *thing) if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale); - // calculate edges of the shape + rightsin = FIXED_TO_FLOAT(FINESINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); + rightcos = FIXED_TO_FLOAT(FINECOSINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); if (flip) - tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale; + { + x1 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale); + x2 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale); + } else - tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale; + { + x1 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale); + x2 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale); + } - // project x - x1 = gr_windowcenterx + (tx * gr_centerx / tz); - - //faB : tr_x doesnt matter - // hurdler: it's used in cliptosolidsegs - tr_x = x1; - - x1 = tx; - - tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale; - x2 = gr_windowcenterx + (tx * gr_centerx / tz); + z1 = tr_y + x1 * rightsin; + z2 = tr_y - x2 * rightsin; + x1 = tr_x + x1 * rightcos; + x2 = tr_x - x2 * rightcos; if (thing->eflags & MFE_VERTICALFLIP) { @@ -5099,13 +5046,10 @@ static void HWR_ProjectSprite(mobj_t *thing) // store information in a vissprite vis = HWR_NewVisSprite(); vis->x1 = x1; -#if 0 vis->x2 = x2; -#else - (void)x2; -#endif - vis->x2 = tx; - vis->tz = tz; + vis->z1 = z1; + vis->z2 = z2; + vis->tz = tz; // Keep tz for the simple sprite sorting that happens vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST vis->patchlumpnum = sprframe->lumppat[rot]; vis->flip = flip; @@ -5136,7 +5080,7 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->colormap = colormaps; // set top/bottom coords - vis->ty = gzt - gr_viewz; + vis->ty = gzt; //CONS_Debug(DBG_RENDER, "------------------\nH: sprite : %d\nH: frame : %x\nH: type : %d\nH: sname : %s\n\n", // thing->sprite, thing->frame, thing->type, sprnames[thing->sprite]); @@ -5155,8 +5099,10 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) { gr_vissprite_t *vis; float tr_x, tr_y; - float tx, tz; + float tz; float x1, x2; + float z1, z2; + float rightsin, rightcos; spritedef_t *sprdef; spriteframe_t *sprframe; size_t lumpoff; @@ -5174,7 +5120,8 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) if (tz < ZCLIP_PLANE) return; - tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos); + tr_x = FIXED_TO_FLOAT(thing->x); + tr_y = FIXED_TO_FLOAT(thing->y); // decide which patch to use for sprite relative to player if ((unsigned)thing->sprite >= numsprites) @@ -5201,32 +5148,32 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) lumpoff = sprframe->lumpid[0]; flip = sprframe->flip; // Will only be 0x00 or 0xFF - // calculate edges of the shape - tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset); + rightsin = FIXED_TO_FLOAT(FINESINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); + rightcos = FIXED_TO_FLOAT(FINECOSINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); + if (flip) + { + x1 = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset); + x2 = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset); + } + else + { + x1 = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset); + x2 = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset); + } - // project x - x1 = gr_windowcenterx + (tx * gr_centerx / tz); - - //faB : tr_x doesnt matter - // hurdler: it's used in cliptosolidsegs - tr_x = x1; - - x1 = tx; - - tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width); - x2 = gr_windowcenterx + (tx * gr_centerx / tz); + z1 = tr_y + x1 * rightsin; + z2 = tr_y - x2 * rightsin; + x1 = tr_x + x1 * rightcos; + x2 = tr_x - x2 * rightcos; // // store information in a vissprite // vis = HWR_NewVisSprite(); vis->x1 = x1; -#if 0 vis->x2 = x2; -#else - (void)x2; -#endif - vis->x2 = tx; + vis->z1 = z1; + vis->z2 = z2; vis->tz = tz; vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST vis->patchlumpnum = sprframe->lumppat[rot]; @@ -5236,7 +5183,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->colormap = colormaps; // set top/bottom coords - vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset) - gr_viewz; + vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset); vis->precip = true; } @@ -5387,7 +5334,6 @@ void HWR_SetViewSize(void) void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) { const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); - FTransform stransform; postimg_t *type; if (splitscreen && player == &players[secondarydisplayplayer]) @@ -5457,25 +5403,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) atransform.fovyangle = fpov; // Tails atransform.splitscreen = splitscreen; - // Transform for sprites - stransform.anglex = 0.0f; - stransform.angley = -270.0f; - - if (*type == postimg_flip) - stransform.flip = true; - else - stransform.flip = false; - - stransform.x = 0.0f; - stransform.y = 0.0f; - stransform.z = 0.0f; - stransform.scalex = 1; - stransform.scaley = 1; - stransform.scalez = 1; - stransform.fovxangle = 90.0f; - stransform.fovyangle = 90.0f; - stransform.splitscreen = splitscreen; - gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); //------------------------------------------------------------------------ @@ -5556,7 +5483,7 @@ if (0) #endif #ifdef SORTING - HWR_DrawSprites(&stransform); + HWR_DrawSprites(); #endif #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? @@ -5599,7 +5526,6 @@ if (0) void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) { const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); - FTransform stransform; postimg_t *type; const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on @@ -5684,25 +5610,6 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) atransform.fovyangle = fpov; // Tails atransform.splitscreen = splitscreen; - // Transform for sprites - stransform.anglex = 0.0f; - stransform.angley = -270.0f; - - if (*type == postimg_flip) - stransform.flip = true; - else - stransform.flip = false; - - stransform.x = 0.0f; - stransform.y = 0.0f; - stransform.z = 0.0f; - stransform.scalex = 1; - stransform.scaley = 1; - stransform.scalez = 1; - stransform.fovxangle = 90.0f; - stransform.fovyangle = 90.0f; - stransform.splitscreen = splitscreen; - gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); //------------------------------------------------------------------------ @@ -5783,7 +5690,7 @@ if (0) #endif #ifdef SORTING - HWR_DrawSprites(&stransform); + HWR_DrawSprites(); #endif #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? From 839ee0ab852c0ccfe8b974b93dccbb0a38fdba6d Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 22 Mar 2018 00:52:14 +0000 Subject: [PATCH 076/122] OpenGL Sprite Splitting --- src/hardware/hw_main.c | 309 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 289 insertions(+), 20 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7b9628b3d..b17ead955 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1219,7 +1219,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, } #endif +#ifdef ESLOPE if (endbheight >= endtop) +#endif if (bheight >= top) continue; @@ -4099,6 +4101,285 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t } } +static void HWR_SplitSprite(gr_vissprite_t *spr) +{ + float this_scale = 1.0f; + FOutVector wallVerts[4]; + GLPatch_t *gpatch; + FSurfaceInfo Surf; + const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES); + extracolormap_t *colormap; + FUINT lightlevel; + FBITFIELD blend = 0; + UINT8 alpha; + + INT32 i; + float realtop, realbot, top, bot; + float towtop, towbot, towmult; + float bheight; + const sector_t *sector = spr->mobj->subsector->sector; + const lightlist_t *list = sector->lightlist; +#ifdef ESLOPE + float endrealtop, endrealbot, endtop, endbot; + float endbheight; + fixed_t temp; + fixed_t v1x, v1y, v2x, v2y; +#endif + + this_scale = FIXED_TO_FLOAT(spr->mobj->scale); + + if (hires) + this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)spr->mobj->skin)->highresscale); + + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + + // cache the patch in the graphics card memory + //12/12/99: Hurdler: same comment as above (for md2) + //Hurdler: 25/04/2000: now support colormap in hardware mode + HWR_GetMappedPatch(gpatch, spr->colormap); + + // Draw shadow BEFORE sprite + if (cv_shadow.value // Shadows enabled + && (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow. + && !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow. +#ifdef ALAM_LIGHTING + && !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow. + && (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players. +#endif + && (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground. + { + //////////////////// + // SHADOW SPRITE! // + //////////////////// + HWR_DrawSpriteShadow(spr, gpatch, this_scale); + } + + wallVerts[0].x = wallVerts[3].x = spr->x1; + wallVerts[2].x = wallVerts[1].x = spr->x2; + wallVerts[0].z = wallVerts[3].z = spr->z1; + wallVerts[1].z = wallVerts[2].z = spr->z2; + + wallVerts[2].y = wallVerts[3].y = spr->ty; + if (spr->mobj && this_scale != 1.0f) + wallVerts[0].y = wallVerts[1].y = spr->ty - gpatch->height * this_scale; + else + wallVerts[0].y = wallVerts[1].y = spr->ty - gpatch->height; + + v1x = FLOAT_TO_FIXED(spr->x1); + v1y = FLOAT_TO_FIXED(spr->z1); + v2x = FLOAT_TO_FIXED(spr->x2); + v2y = FLOAT_TO_FIXED(spr->z2); + + if (spr->flip) + { + wallVerts[0].sow = wallVerts[3].sow = gpatch->max_s; + wallVerts[2].sow = wallVerts[1].sow = 0; + }else{ + wallVerts[0].sow = wallVerts[3].sow = 0; + wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; + } + + // flip the texture coords (look familiar?) + if (spr->vflip) + { + wallVerts[3].tow = wallVerts[2].tow = gpatch->max_t; + wallVerts[0].tow = wallVerts[1].tow = 0; + }else{ + wallVerts[3].tow = wallVerts[2].tow = 0; + wallVerts[0].tow = wallVerts[1].tow = gpatch->max_t; + } + + realtop = top = wallVerts[3].y; + realbot = bot = wallVerts[0].y; + towtop = wallVerts[3].tow; + towbot = wallVerts[0].tow; + towmult = (towbot - towtop) / (top - bot); + +#ifdef ESLOPE + endrealtop = endtop = wallVerts[2].y; + endrealbot = endbot = wallVerts[1].y; +#endif + + if (!cv_translucency.value) // translucency disabled + { + Surf.FlatColor.s.alpha = 0xFF; + blend = PF_Translucent|PF_Occlude; + } + else if (spr->mobj->flags2 & MF2_SHADOW) + { + Surf.FlatColor.s.alpha = 0x40; + blend = PF_Translucent; + } + else if (spr->mobj->frame & FF_TRANSMASK) + blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); + else + { + // BP: i agree that is little better in environement but it don't + // work properly under glide nor with fogcolor to ffffff :( + // Hurdler: PF_Environement would be cool, but we need to fix + // the issue with the fog before + Surf.FlatColor.s.alpha = 0xFF; + blend = PF_Translucent|PF_Occlude; + } + + alpha = Surf.FlatColor.s.alpha; + + // Start with the lightlevel and colormap from the top of the sprite + lightlevel = *list[sector->numlights - 1].lightlevel; + colormap = list[sector->numlights - 1].extra_colormap; + i = 0; + temp = FLOAT_TO_FIXED(realtop); + +#ifdef ESLOPE + for (i = 1; i < sector->numlights; i++) + { + fixed_t h = sector->lightlist[i].slope ? P_GetZAt(sector->lightlist[i].slope, spr->mobj->x, spr->mobj->y) + : sector->lightlist[i].height; + if (h <= temp) + { + lightlevel = *list[i-1].lightlevel; + colormap = list[i-1].extra_colormap; + break; + } + } +#else + i = R_GetPlaneLight(sector, temp, false); + lightlevel = *list[i].lightlevel; + colormap = list[i].extra_colormap; +#endif + + for (i = 0; i < sector->numlights; i++) + { +#ifdef ESLOPE + if (endtop < endrealbot) +#endif + if (top < realbot) + return; + + // even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite + if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES)) + { + lightlevel = *list[i].lightlevel; + colormap = list[i].extra_colormap; + } + +#ifdef ESLOPE + if (i + 1 < sector->numlights) + { + if (list[i+1].slope) + { + temp = P_GetZAt(list[i+1].slope, v1x, v1y); + bheight = FIXED_TO_FLOAT(temp); + temp = P_GetZAt(list[i+1].slope, v2x, v2y); + endbheight = FIXED_TO_FLOAT(temp); + } + else + bheight = endbheight = FIXED_TO_FLOAT(list[i+1].height); + } + else + { + bheight = realbot; + endbheight = endrealbot; + } +#else + if (i + 1 < sector->numlights) + { + bheight = FIXED_TO_FLOAT(list[i+1].height); + } + else + { + bheight = realbot; + } +#endif + +#ifdef ESLOPE + if (endbheight >= endtop) +#endif + if (bheight >= top) + continue; + + bot = bheight; + + if (bot < realbot) + bot = realbot; + +#ifdef ESLOPE + endbot = endbheight; + + if (endbot < endrealbot) + endbot = endrealbot; +#endif + +#ifdef ESLOPE + wallVerts[3].tow = towtop + ((realtop - top) * towmult); + wallVerts[2].tow = towtop + ((endrealtop - endtop) * towmult); + wallVerts[0].tow = towtop + ((realtop - bot) * towmult); + wallVerts[1].tow = towtop + ((endrealtop - endbot) * towmult); + + wallVerts[3].y = top; + wallVerts[2].y = endtop; + wallVerts[0].y = bot; + wallVerts[1].y = endbot; +#else + wallVerts[3].tow = wallVerts[2].tow = towtop + ((realtop - top) * towmult); + wallVerts[0].tow = wallVerts[1].tow = towtop + ((realtop - bot) * towmult); + + wallVerts[2].y = wallVerts[3].y = top; + wallVerts[0].y = wallVerts[1].y = bot; +#endif + + if (colormap) + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); + else + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + + Surf.FlatColor.s.alpha = alpha; + + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + + top = bot; +#ifdef ESLOPE + endtop = endbot; +#endif + } + + bot = realbot; +#ifdef ESLOPE + endbot = endrealbot; + if (endtop <= endrealbot) +#endif + if (top <= realbot) + return; + + // If we're ever down here, somehow the above loop hasn't draw all the light levels of sprite +#ifdef ESLOPE + wallVerts[3].tow = towtop + ((realtop - top) * towmult); + wallVerts[2].tow = towtop + ((endrealtop - endtop) * towmult); + wallVerts[0].tow = towtop + ((realtop - bot) * towmult); + wallVerts[1].tow = towtop + ((endrealtop - endbot) * towmult); + + wallVerts[3].y = top; + wallVerts[2].y = endtop; + wallVerts[0].y = bot; + wallVerts[1].y = endbot; +#else + wallVerts[3].tow = wallVerts[2].tow = towtop + ((realtop - top) * towmult); + wallVerts[0].tow = wallVerts[1].tow = towtop + ((realtop - bot) * towmult); + + wallVerts[2].y = wallVerts[3].y = top; + wallVerts[0].y = wallVerts[1].y = bot; +#endif + + if (colormap) + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); + else + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + + Surf.FlatColor.s.alpha = alpha; + + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); +} + // -----------------+ // HWR_DrawSprite : Draw flat sprites // : (monsters, bonuses, weapons, lights, ...) @@ -4122,6 +4403,12 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) if (!spr->mobj->subsector) return; + if (spr->mobj->subsector->sector->numlights) + { + HWR_SplitSprite(spr); + return; + } + // cache sprite graphics //12/12/99: Hurdler: // OK, I don't change anything for MD2 support because I want to be @@ -4207,26 +4494,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) UINT8 lightlevel = 255; extracolormap_t *colormap = sector->extra_colormap; - if (sector->numlights) - { - INT32 light; - - light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before - - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *sector->lightlist[light].lightlevel; - - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; - } - else - { - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = sector->lightlevel; - - if (sector->extra_colormap) - colormap = sector->extra_colormap; - } + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = sector->lightlevel; if (colormap) Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); From fab4b7f5eab7509a6c2a3a6bc1b05ce7d3452ebd Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 22 Mar 2018 01:10:53 +0000 Subject: [PATCH 077/122] Stop squashing the screen vertically in non-green resolutions --- src/hardware/hw_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b17ead955..86b80904f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5666,7 +5666,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy) atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz) atransform.scalex = 1; - atransform.scaley = ORIGINAL_ASPECT; + atransform.scaley = (float)vid.width/vid.height; atransform.scalez = 1; atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails @@ -5873,7 +5873,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy) atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz) atransform.scalex = 1; - atransform.scaley = ORIGINAL_ASPECT; + atransform.scaley = (float)vid.width/vid.height; atransform.scalez = 1; atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails From a431197921a847cf387da362dc2cbfebb0299ef8 Mon Sep 17 00:00:00 2001 From: jameds Date: Thu, 11 Jan 2018 17:35:39 -0800 Subject: [PATCH 078/122] Fixed "invalid pointer" error when passing "" to Command_connect(). --- src/d_clisrv.c | 2 +- src/m_menu.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7d0e44b45..36d13fc14 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2244,7 +2244,7 @@ static void Command_connect(void) // Assume we connect directly. boolean viams = false; - if (COM_Argc() < 2) + if (COM_Argc() < 2 || *COM_Argv(1) == 0) { CONS_Printf(M_GetText( "Connect (port): connect to a server\n" diff --git a/src/m_menu.c b/src/m_menu.c index ea93d1e2d..0ab771579 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6295,6 +6295,13 @@ static void M_DrawConnectIPMenu(void) static void M_ConnectIP(INT32 choice) { (void)choice; + + if (*setupm_ip == 0) + { + M_StartMessage("You must specify an IP address.\n", NULL, MM_NOTHING); + return; + } + COM_BufAddText(va("connect \"%s\"\n", setupm_ip)); // A little "please wait" message. From f62cb3a30a7bd36d52a5c6a7853baf9aaf887aa9 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 23 Mar 2018 22:27:29 +0000 Subject: [PATCH 079/122] I've commented out the call to HWR_CorrectSWTricks. I don't think it does anything for us anymore, and might even break things with slopes. Someone let me know if I'm wrong and am breaking things horribly here. --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 8e746457b..e93cbed51 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2718,7 +2718,7 @@ boolean P_SetupLevel(boolean skipprecip) HWR_ResetLights(); #endif // Correct missing sidedefs & deep water trick - HWR_CorrectSWTricks(); + //HWR_CorrectSWTricks(); HWR_CreatePlanePolygons((INT32)numnodes - 1); } #endif From 876d0fa58b3ba39d86cfd4b46a488c711211d706 Mon Sep 17 00:00:00 2001 From: jameds Date: Fri, 23 Mar 2018 18:06:32 -0700 Subject: [PATCH 080/122] Removed contradictory `-connect` check --- src/d_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 063d28453..7368383b5 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1068,7 +1068,7 @@ void D_SRB2Main(void) // add any files specified on the command line with -file wadfile // to the wad list - if (!(M_CheckParm("-connect"))) + if (!(M_CheckParm("-connect") && !M_CheckParm("-server"))) { if (M_CheckParm("-file")) { @@ -1323,7 +1323,7 @@ void D_SRB2Main(void) ultimatemode = true; } - if (autostart || netgame || M_CheckParm("+connect") || M_CheckParm("-connect")) + if (autostart || netgame) { gameaction = ga_nothing; @@ -1361,8 +1361,7 @@ void D_SRB2Main(void) } } - if (server && !M_CheckParm("+map") && !M_CheckParm("+connect") - && !M_CheckParm("-connect")) + if (server && !M_CheckParm("+map")) { // Prevent warping to nonexistent levels if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR) From dc9fd6f02ed4b681ed4982d119672f07cc91e585 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 25 Mar 2018 19:07:21 -0400 Subject: [PATCH 081/122] MT_NIGHTSBUMPER Spawn: Don't reset mthing->options --- src/p_mobj.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 8695d57e4..157092dea 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10060,9 +10060,6 @@ domaceagain: // the bumper in 30 degree increments. mobj->threshold = (mthing->options & 15) % 12; // It loops over, etc P_SetMobjState(mobj, mobj->info->spawnstate+mobj->threshold); - - // you can shut up now, OBJECTFLIP. And all of the other options, for that matter. - mthing->options &= ~0xF; break; case MT_EGGCAPSULE: if (mthing->angle <= 0) From d85f108997bfeca3e0b1731c1aad70617456400b Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 25 Mar 2018 19:42:46 -0400 Subject: [PATCH 082/122] P_SpawnMapThing: Ignore MTF_ flags if MT_NIGHTSBUMPER --- src/p_mobj.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 157092dea..4c0ebb657 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10261,6 +10261,14 @@ domaceagain: } } + // ignore MTF_ flags and return early + if (i == MT_NIGHTSBUMPER) + { + mobj->angle = FixedAngle(mthing->angle*FRACUNIT); + mthing->mobj = mobj; + return; + } + mobj->angle = FixedAngle(mthing->angle*FRACUNIT); if ((mthing->options & MTF_AMBUSH) From 98601dc757cb2c06fe8402bbb76f92475b7bd0c5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 26 Mar 2018 23:53:09 +0100 Subject: [PATCH 083/122] A lot! * cv_powerupdisplay. Never, First-person only (default), Always. * New monitor stuff. * Fixed hitmessages. * Some CTF stuff. * Aaaaugh it's a lot I hate myself I need to work on my coursework. * I'll figure out what I did here in the merge request when that's done. --- src/d_netcmd.c | 6 +- src/dehacked.c | 9 +- src/doomstat.h | 1 + src/hu_stuff.c | 22 +-- src/info.c | 163 +++++++++---------- src/info.h | 7 +- src/m_cheat.c | 2 +- src/m_menu.c | 27 ++-- src/p_inter.c | 5 +- src/p_spec.c | 9 +- src/p_user.c | 12 +- src/screen.c | 14 +- src/sounds.c | 16 +- src/st_stuff.c | 417 +++++++++++++++++++++++++++++++------------------ src/st_stuff.h | 2 +- 15 files changed, 415 insertions(+), 297 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 94eada152..cc641b8b0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -309,9 +309,12 @@ consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Tics"}, {2, "Centiseconds"}, {3, "Mania"}, {0, NULL}}; +static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Centiseconds"}, {2, "Mania"}, {3, "Tics"}, {0, NULL}}; consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display +static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}}; +consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display + consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}}; @@ -670,6 +673,7 @@ void D_RegisterClientCommands(void) // HUD CV_RegisterVar(&cv_timetic); + CV_RegisterVar(&cv_powerupdisplay); CV_RegisterVar(&cv_itemfinder); CV_RegisterVar(&cv_showinputjoy); diff --git a/src/dehacked.c b/src/dehacked.c index 704786879..3726cb381 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4521,6 +4521,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BOXSPARKLE1", "S_BOXSPARKLE2", "S_BOXSPARKLE3", + "S_BOXSPARKLE4", "S_BOX_FLICKER", "S_BOX_POP1", @@ -5511,8 +5512,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Got Flag Sign "S_GOTFLAG", - "S_GOTREDFLAG", - "S_GOTBLUEFLAG", "S_CORK", @@ -5852,6 +5851,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_XPLD_FLICKY", "S_XPLD1", "S_XPLD2", + "S_XPLD3", + "S_XPLD4", + "S_XPLD5", + "S_XPLD6", "S_XPLD_EGGTRAP", // Underwater Explosion @@ -6815,7 +6818,7 @@ static const char *const HUDITEMS_LIST[] = { "TIMELEFTNUM", "TIMEUP", "HUNTPICS", - "GRAVBOOTSICO", + "POWERUPS", "LAP" }; diff --git a/src/doomstat.h b/src/doomstat.h index de260ef06..d4735f6b2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -498,6 +498,7 @@ extern boolean singletics; #include "d_clisrv.h" extern consvar_t cv_timetic; // display high resolution timer +extern consvar_t cv_powerupdisplay; // display powerups extern consvar_t cv_showinputjoy; // display joystick in time attack extern consvar_t cv_forceskin; // force clients to use the server's skin extern consvar_t cv_downloading; // allow clients to downloading WADs. diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 58db7961b..c955a490d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1547,7 +1547,7 @@ static inline void HU_DrawSpectatorTicker(void) templength = length; } - V_DrawString(templength, height + 8, V_TRANSLUCENT, current); + V_DrawString(templength, height + 8, V_TRANSLUCENT|V_ALLOWLOWERCASE, current); } length += (signed)strlen(player_names[i]) * 8 + 16; @@ -1559,7 +1559,6 @@ static inline void HU_DrawSpectatorTicker(void) // static void HU_DrawRankings(void) { - patch_t *p; playersort_t tab[MAXPLAYERS]; INT32 i, j, scorelines; boolean completed[MAXPLAYERS]; @@ -1568,25 +1567,6 @@ static void HU_DrawRankings(void) // draw the current gametype in the lower right HU_drawGametype(); - if (G_GametypeHasTeams()) - { - if (gametype == GT_CTF) - p = bflagico; - else - p = bmatcico; - - V_DrawSmallScaledPatch(128 - SHORT(p->width)/4, 4, 0, p); - V_DrawCenteredString(128, 16, 0, va("%u", bluescore)); - - if (gametype == GT_CTF) - p = rflagico; - else - p = rmatcico; - - V_DrawSmallScaledPatch(192 - SHORT(p->width)/4, 4, 0, p); - V_DrawCenteredString(192, 16, 0, va("%u", redscore)); - } - if (gametype != GT_RACE && gametype != GT_COMPETITION && gametype != GT_COOP) { if (cv_timelimit.value && timelimitintics > 0) diff --git a/src/info.c b/src/info.c index acb12379a..58a2ba8f4 100644 --- a/src/info.c +++ b/src/info.c @@ -680,7 +680,7 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY // 1-Up box sprites (uses player sprite) - {SPR_PLAY, SPR2_LIFE, 2, {NULL}, 0, 16, S_PLAY_BOX2}, // S_PLAY_BOX1 + {SPR_PLAY, SPR2_LIFE, 2, {NULL}, 0, 18, S_PLAY_BOX2}, // S_PLAY_BOX1 {SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2 {SPR_PLAY, SPR2_LIFE, 4, {NULL}, 0, 4, S_PLAY_ICON2}, // S_PLAY_ICON1 {SPR_NULL, 0, 12, {NULL}, 0, 0, S_PLAY_ICON3}, // S_PLAY_ICON2 @@ -1727,9 +1727,10 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 2, {A_SetRandomTics}, TICRATE/2, 3*TICRATE, S_CANNONLAUNCHER1}, // S_CANNONLAUNCHER3 // Monitor Miscellany - {SPR_NSPK, FF_TRANS40, 20, {NULL}, 0, 0, S_BOXSPARKLE2}, // S_BOXSPARKLE1 - {SPR_NSPK, FF_TRANS60, 10, {NULL}, 0, 0, S_BOXSPARKLE3}, // S_BOXSPARKLE2 - {SPR_NSPK, FF_TRANS80, 5, {NULL}, 0, 0, S_NULL}, // S_BOXSPARKLE3 + {SPR_NSPK, 0, 16, {NULL}, 0, 0, S_BOXSPARKLE2}, // S_BOXSPARKLE1 + {SPR_NSPK, 1, 12, {NULL}, 0, 0, S_BOXSPARKLE3}, // S_BOXSPARKLE2 + {SPR_NSPK, 2, 8, {NULL}, 0, 0, S_BOXSPARKLE4}, // S_BOXSPARKLE3 + {SPR_NSPK, 3, 4, {NULL}, 0, 0, S_NULL}, // S_BOXSPARKLE4 {SPR_MSTV, 0, 1, {NULL}, 0, 0, S_SPAWNSTATE}, // S_BOX_FLICKER {SPR_MSTV, 0, 4, {A_MonitorPop}, 0, 0, S_BOX_POP2}, // S_BOX_POP1 @@ -2735,8 +2736,6 @@ state_t states[NUMSTATES] = // CTF Sign {SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG - {SPR_GFLG, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTREDFLAG - {SPR_GFLG, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTBLUEFLAG {SPR_CORK, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORK @@ -3121,11 +3120,15 @@ state_t states[NUMSTATES] = {SPR_SPRK, FF_TRANS90|3, 1, {NULL}, 0, 0, S_NULL}, // S_SPRK16 // Robot Explosion - {SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY - {SPR_BOM1, 0, 1, {A_Scream}, 0, 0, S_XPLD2}, // S_XPLD1 - {SPR_BOM1, FF_ANIMATE|1, 15, {NULL}, 2, 5, S_NULL}, // S_XPLD2 + {SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY + {SPR_BOM1, 0, 2, {A_Scream}, 0, 0, S_XPLD2}, // S_XPLD1 + {SPR_BOM1, 1, 2, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2 + {SPR_BOM1, 2, 3, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3 + {SPR_BOM1, 3, 3, {NULL}, 0, 0, S_XPLD5}, // S_XPLD4 + {SPR_BOM1, 4, 4, {NULL}, 0, 0, S_XPLD6}, // S_XPLD5 + {SPR_BOM1, 5, 4, {NULL}, 0, 0, S_NULL}, // S_XPLD6 - {SPR_BOM1, FF_ANIMATE, 20, {NULL}, 3, 5, S_INVISIBLE}, // S_XPLD_EGGTRAP + {SPR_BOM1, FF_ANIMATE, 21, {NULL}, 5, 4, S_INVISIBLE}, // S_XPLD_EGGTRAP // Underwater Explosion {SPR_BOM4, 0, 3, {A_Scream}, 0, 0, S_WPLD2}, // S_WPLD1 @@ -6386,8 +6389,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_RING_ICON, // damage @@ -6413,8 +6416,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_PITY_ICON, // damage @@ -6440,8 +6443,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_ATTRACT_ICON,// damage @@ -6467,8 +6470,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_FORCE_ICON, // damage @@ -6494,8 +6497,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_ARMAGEDDON_ICON, // damage @@ -6521,8 +6524,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_WHIRLWIND_ICON, // damage @@ -6548,8 +6551,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_ELEMENTAL_ICON, // damage @@ -6575,8 +6578,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_SNEAKERS_ICON, // damage @@ -6602,8 +6605,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_INVULN_ICON, // damage @@ -6629,8 +6632,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_1UP_ICON, // damage @@ -6656,8 +6659,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_EGGMAN_ICON, // damage @@ -6683,8 +6686,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_MIXUP_ICON, // damage @@ -6710,8 +6713,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_UNKNOWN, // damage @@ -6737,8 +6740,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_GRAVITY_ICON, // damage @@ -6764,8 +6767,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_RECYCLER_ICON, // damage @@ -6791,8 +6794,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_SCORE1K_ICON, // damage @@ -6818,8 +6821,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_SCORE10K_ICON, // damage @@ -6845,8 +6848,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_FLAMEAURA_ICON, // damage @@ -6872,8 +6875,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_BUBBLEWRAP_ICON, // damage @@ -6899,8 +6902,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_THUNDERCOIN_ICON, // damage @@ -6926,8 +6929,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_PITY_ICON, // damage @@ -6953,8 +6956,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_ATTRACT_ICON,// damage @@ -6980,8 +6983,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_FORCE_ICON, // damage @@ -7007,8 +7010,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_ARMAGEDDON_ICON, // damage @@ -7034,8 +7037,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_WHIRLWIND_ICON, // damage @@ -7061,8 +7064,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_ELEMENTAL_ICON, // damage @@ -7088,8 +7091,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_SNEAKERS_ICON, // damage @@ -7115,8 +7118,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_INVULN_ICON, // damage @@ -7142,8 +7145,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_EGGMAN_ICON, // damage @@ -7169,8 +7172,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_GRAVITY_ICON, // damage @@ -7196,8 +7199,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_FLAMEAURA_ICON, // damage @@ -7223,8 +7226,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_BUBBLEWRAP_ICON, // damage @@ -7250,8 +7253,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_THUNDERCOIN_ICON, // damage @@ -7277,8 +7280,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_RING_ICON, // damage @@ -7304,8 +7307,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_RING_ICON, // damage diff --git a/src/info.h b/src/info.h index 35a3f5f15..f9052b5da 100644 --- a/src/info.h +++ b/src/info.h @@ -1834,6 +1834,7 @@ typedef enum state S_BOXSPARKLE1, S_BOXSPARKLE2, S_BOXSPARKLE3, + S_BOXSPARKLE4, S_BOX_FLICKER, S_BOX_POP1, @@ -2826,8 +2827,6 @@ typedef enum state // Got Flag Sign S_GOTFLAG, - S_GOTREDFLAG, - S_GOTBLUEFLAG, S_CORK, @@ -3167,6 +3166,10 @@ typedef enum state S_XPLD_FLICKY, S_XPLD1, S_XPLD2, + S_XPLD3, + S_XPLD4, + S_XPLD5, + S_XPLD6, S_XPLD_EGGTRAP, // Underwater Explosion diff --git a/src/m_cheat.c b/src/m_cheat.c index a4eaede3a..174e2780d 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1266,7 +1266,7 @@ void Command_ObjectPlace_f(void) if (!COM_CheckParm("-silent")) { - HU_SetCEchoFlags(V_RETURN8|V_MONOSPACE); + HU_SetCEchoFlags(V_RETURN8|V_MONOSPACE|V_AUTOFADEOUT); HU_SetCEchoDuration(10); HU_DoCEcho(va(M_GetText( "\\\\\\\\\\\\\\\\\\\\\\\\\x82" diff --git a/src/m_menu.c b/src/m_menu.c index e53d9012f..4857df104 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1196,24 +1196,25 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Show HUD", &cv_showhud, 61}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "HUD Transparency", &cv_translucenthud, 66}, - {IT_STRING | IT_CVAR, NULL, "Time Display", &cv_timetic, 71}, + {IT_STRING | IT_CVAR, NULL, "Score/Time/Rings", &cv_timetic, 71}, + {IT_STRING | IT_CVAR, NULL, "Show Powerups", &cv_powerupdisplay, 76}, #ifdef SEENAMES - {IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 76}, + {IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 81}, #endif - {IT_HEADER, NULL, "Console", NULL, 85}, - {IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 91}, - {IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 96}, + {IT_HEADER, NULL, "Console", NULL, 90}, + {IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 96}, + {IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 101}, - {IT_HEADER, NULL, "Level", NULL, 105}, - {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 111}, - {IT_STRING | IT_CVAR, NULL, "NiGHTS Draw Dist.", &cv_drawdist_nights, 116}, - {IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 121}, - {IT_STRING | IT_CVAR, NULL, "Weather Density", &cv_precipdensity, 126}, + {IT_HEADER, NULL, "Level", NULL, 110}, + {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 116}, + {IT_STRING | IT_CVAR, NULL, "NiGHTS Draw Dist.", &cv_drawdist_nights, 121}, + {IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 126}, + {IT_STRING | IT_CVAR, NULL, "Weather Density", &cv_precipdensity, 131}, - {IT_HEADER, NULL, "Diagnostic", NULL, 135}, - {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 141}, - {IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 146}, + {IT_HEADER, NULL, "Diagnostic", NULL, 140}, + {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 146}, + {IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 151}, }; static menuitem_t OP_VideoModeMenu[] = diff --git a/src/p_inter.c b/src/p_inter.c index 4c9e231fe..833a9ba52 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3365,8 +3365,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_KillPlayer(player, source, damage); } - P_HitDeathMessages(player, inflictor, source, damagetype); - P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); } @@ -3381,6 +3379,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da else target->health -= damage; + if (player) + P_HitDeathMessages(player, inflictor, source, damagetype); + if (source && source->player && target) G_GhostAddHit(target); diff --git a/src/p_spec.c b/src/p_spec.c index 0b005baff..595473a5c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -31,6 +31,7 @@ #include "p_polyobj.h" #include "p_slopes.h" #include "hu_stuff.h" +#include "v_video.h" // V_AUTOFADEOUT|V_ALLOWLOWERCASE #include "m_misc.h" #include "m_cond.h" //unlock triggers #include "lua_hook.h" // LUAh_LinedefExecute @@ -3815,9 +3816,9 @@ DoneSection2: if (!P_IsFlagAtBase(MT_REDFLAG)) break; - HU_SetCEchoFlags(0); + HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); HU_SetCEchoDuration(5); - HU_DoCEcho(va(M_GetText("%s\\captured the blue flag.\\\\\\\\"), player_names[player-players])); + HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sBLUE FLAG%s.\\\\\\\\"), "\x85", player_names[player-players], "\x80", "\x84", "\x80")); if (splitscreen || players[consoleplayer].ctfteam == 1) S_StartSound(NULL, sfx_flgcap); @@ -3848,9 +3849,9 @@ DoneSection2: if (!P_IsFlagAtBase(MT_BLUEFLAG)) break; - HU_SetCEchoFlags(0); + HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); HU_SetCEchoDuration(5); - HU_DoCEcho(va(M_GetText("%s\\captured the red flag.\\\\\\\\"), player_names[player-players])); + HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sRED FLAG%s.\\\\\\\\"), "\x84", player_names[player-players], "\x80", "\x85", "\x80")); if (splitscreen || players[consoleplayer].ctfteam == 2) S_StartSound(NULL, sfx_flgcap); diff --git a/src/p_user.c b/src/p_user.c index d127e7139..86eb1bef4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2585,13 +2585,11 @@ static void P_DoPlayerHeadSigns(player_t *player) } else sign->z += P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale); - if (leveltime & 4) - { - if (player->gotflag & GF_REDFLAG) - P_SetMobjStateNF(sign, S_GOTREDFLAG); - } - else if (player->gotflag & GF_BLUEFLAG) - P_SetMobjStateNF(sign, S_GOTBLUEFLAG); + + if (player->gotflag & GF_REDFLAG) + sign->frame = 1|FF_FULLBRIGHT; + else //if (player->gotflag & GF_BLUEFLAG) + sign->frame = 2|FF_FULLBRIGHT; } } } diff --git a/src/screen.c b/src/screen.c index 5120aa581..5b16992c7 100644 --- a/src/screen.c +++ b/src/screen.c @@ -440,6 +440,18 @@ void SCR_ClosedCaptions(void) { UINT8 i; boolean gamestopped = (paused || P_AutoPause()); + INT32 basey = BASEVIDHEIGHT; + + if (gamestate == GS_LEVEL) + { + if (splitscreen) + basey -= 8; + else if (((maptol & TOL_NIGHTS) && (modeattacking == ATTACKING_NIGHTS)) + || (cv_powerupdisplay.value == 2) + || (cv_powerupdisplay.value == 1 && ((stplyr == &players[displayplayer] && !camera.chase) + || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)))) + basey -= 16; + } for (i = 0; i < NUMCAPTIONS; i++) { @@ -456,7 +468,7 @@ void SCR_ClosedCaptions(void) continue; flags = V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_ALLOWLOWERCASE; - y = BASEVIDHEIGHT-((i + 2)*10); + y = basey-((i + 2)*10); if (closedcaptions[i].b) y -= (closedcaptions[i].b--)*vid.dupy; diff --git a/src/sounds.c b/src/sounds.c index 475d65cd1..293ce381d 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -85,14 +85,14 @@ sfxinfo_t S_sfx[NUMSFX] = {"athun1", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Thunder"}, {"athun2", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Thunder"}, - {"amwtr1", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr2", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr3", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr4", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr5", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr6", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr7", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr8", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, + {"amwtr1", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr2", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr3", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr4", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr5", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr6", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr7", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr8", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, {"bubbl1", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, {"bubbl2", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, {"bubbl3", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, diff --git a/src/st_stuff.c b/src/st_stuff.c index 93709e453..25a61fa3a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -101,6 +101,7 @@ static patch_t *invincibility; static patch_t *sneakers; static patch_t *gravboots; static patch_t *nonicon; +static patch_t *nonicon2; static patch_t *bluestat; static patch_t *byelstat; static patch_t *orngstat; @@ -150,7 +151,7 @@ hudinfo_t hudinfo[NUMHUDITEMS] = { 130, 93, 0}, // HUD_TIMEUP { 152, 168, 0}, // HUD_HUNTPICS - { 152, 24, V_SNAPTORIGHT}, // HUD_GRAVBOOTSICO + { 288, 176, V_SNAPTORIGHT|V_SNAPTOBOTTOM}, // HUD_POWERUPS }; // @@ -275,18 +276,18 @@ void ST_LoadGraphics(void) scatterring = W_CachePatchName("SCATIND", PU_HUDGFX); grenadering = W_CachePatchName("GRENIND", PU_HUDGFX); railring = W_CachePatchName("RAILIND", PU_HUDGFX); - jumpshield = W_CachePatchName("TVWWC0", PU_HUDGFX); - forceshield = W_CachePatchName("TVFOC0", PU_HUDGFX); - ringshield = W_CachePatchName("TVATC0", PU_HUDGFX); - watershield = W_CachePatchName("TVELC0", PU_HUDGFX); - bombshield = W_CachePatchName("TVARC0", PU_HUDGFX); - pityshield = W_CachePatchName("TVPIC0", PU_HUDGFX); - flameshield = W_CachePatchName("TVFLC0", PU_HUDGFX); - bubbleshield = W_CachePatchName("TVBBC0", PU_HUDGFX); - thundershield = W_CachePatchName("TVZPC0", PU_HUDGFX); - invincibility = W_CachePatchName("TVIVC0", PU_HUDGFX); - sneakers = W_CachePatchName("TVSSC0", PU_HUDGFX); - gravboots = W_CachePatchName("TVGVC0", PU_HUDGFX); + jumpshield = W_CachePatchName("TVWWICON", PU_HUDGFX); + forceshield = W_CachePatchName("TVFOICON", PU_HUDGFX); + ringshield = W_CachePatchName("TVATICON", PU_HUDGFX); + watershield = W_CachePatchName("TVELICON", PU_HUDGFX); + bombshield = W_CachePatchName("TVARICON", PU_HUDGFX); + pityshield = W_CachePatchName("TVPIICON", PU_HUDGFX); + flameshield = W_CachePatchName("TVFLICON", PU_HUDGFX); + bubbleshield = W_CachePatchName("TVBBICON", PU_HUDGFX); + thundershield = W_CachePatchName("TVZPICON", PU_HUDGFX); + invincibility = W_CachePatchName("TVIVICON", PU_HUDGFX); + sneakers = W_CachePatchName("TVSSICON", PU_HUDGFX); + gravboots = W_CachePatchName("TVGVICON", PU_HUDGFX); tagico = W_CachePatchName("TAGICO", PU_HUDGFX); rflagico = W_CachePatchName("RFLAGICO", PU_HUDGFX); @@ -296,6 +297,7 @@ void ST_LoadGraphics(void) gotrflag = W_CachePatchName("GOTRFLAG", PU_HUDGFX); gotbflag = W_CachePatchName("GOTBFLAG", PU_HUDGFX); nonicon = W_CachePatchName("NONICON", PU_HUDGFX); + nonicon2 = W_CachePatchName("NONICON2", PU_HUDGFX); // NiGHTS HUD things bluestat = W_CachePatchName("BLUESTAT", PU_HUDGFX); @@ -644,7 +646,7 @@ static void ST_drawTime(void) if (!tics && downwards && (leveltime/5 & 1)) // overtime! return; - if (cv_timetic.value == 1) // Tics only -- how simple is this? + if (cv_timetic.value == 3) // Tics only -- how simple is this? ST_DrawNumFromHud(HUD_SECONDS, tics, V_HUDTRANS); else { @@ -652,7 +654,7 @@ static void ST_drawTime(void) ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds - if (cv_timetic.value == 2 || cv_timetic.value == 3 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! + if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! { ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod, V_HUDTRANS); // Period ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2, V_HUDTRANS); // Tics @@ -679,7 +681,7 @@ static inline void ST_drawRings(void) else ringnum = max(stplyr->rings, 0); - if (cv_timetic.value == 3) // Yes, even in modeattacking + if (cv_timetic.value == 2) // Yes, even in modeattacking ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); else ST_DrawNumFromHud(HUD_RINGSNUM, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); @@ -1128,93 +1130,160 @@ static void ST_drawLevelTitle(void) V_DrawCenteredString(subttlxpos, lvlttly+48, V_ALLOWLOWERCASE, subttl); } -static void ST_drawFirstPersonHUD(void) +static void ST_drawPowerupHUD(void) { - player_t *player = stplyr; patch_t *p = NULL; UINT16 invulntime = 0; + INT32 offs = hudinfo[HUD_POWERUPS].x; + static INT32 flagoffs = 0, shieldoffs = 0; +#define ICONSEP (16+4) // matches weapon rings HUD - if (player->playerstate != PST_LIVE) + if (stplyr->spectator || stplyr->playerstate != PST_LIVE) return; // Graue 06-18-2004: no V_NOSCALESTART, no SCX, no SCY, snap to right - if ((player->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE) + if (stplyr->powers[pw_shield] & SH_NOSTACK) { - UINT8 i, max = (player->powers[pw_shield] & SH_FORCEHP); - for (i = 0; i <= max; i++) + shieldoffs = ICONSEP; + + if ((stplyr->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE) { - V_DrawScaledPatch(304-(3*i), 24+(3*i), (V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF), forceshield); + UINT8 i, max = (stplyr->powers[pw_shield] & SH_FORCEHP); + for (i = 0; i <= max; i++) + { + V_DrawSmallScaledPatch(offs-(i<<1), hudinfo[HUD_POWERUPS].y-(i<<1), (V_PERPLAYER|hudinfo[HUD_POWERUPS].f)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF), forceshield); + } + } + else + { + switch (stplyr->powers[pw_shield] & SH_NOSTACK) + { + case SH_WHIRLWIND: p = jumpshield; break; + case SH_ELEMENTAL: p = watershield; break; + case SH_ARMAGEDDON: p = bombshield; break; + case SH_ATTRACT: p = ringshield; break; + case SH_PITY: p = pityshield; break; + case SH_FLAMEAURA: p = flameshield; break; + case SH_BUBBLEWRAP: p = bubbleshield; break; + case SH_THUNDERCOIN: p = thundershield; break; + default: break; + } + + if (p) + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); } } - else switch (player->powers[pw_shield] & SH_NOSTACK) + else if (shieldoffs) { - case SH_WHIRLWIND: p = jumpshield; break; - case SH_ELEMENTAL: p = watershield; break; - case SH_ARMAGEDDON: p = bombshield; break; - case SH_ATTRACT: p = ringshield; break; - case SH_PITY: p = pityshield; break; - case SH_FLAMEAURA: p = flameshield; break; - case SH_BUBBLEWRAP: p = bubbleshield; break; - case SH_THUNDERCOIN: p = thundershield; break; - default: break; - } - - if (p) - V_DrawScaledPatch(304, 24, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - - // pw_flashing just sets the icon to flash no matter what. - invulntime = player->powers[pw_flashing] ? 1 : player->powers[pw_invulnerability]; - if (invulntime > 3*TICRATE || (invulntime && leveltime & 1)) - V_DrawScaledPatch(304, 24 + 28, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); - - if (player->powers[pw_sneakers] > 3*TICRATE || (player->powers[pw_sneakers] && leveltime & 1)) - { - V_DrawScaledPatch(304, 24 + 56, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); - } - - p = NULL; - - { - UINT32 airtime; - UINT32 frame = 0; - spriteframe_t *sprframe; - // If both air timers are active, use the air timer with the least time left - if (player->powers[pw_underwater] && player->powers[pw_spacetime]) - airtime = min(player->powers[pw_underwater], player->powers[pw_spacetime]); - else // Use whichever one is active otherwise - airtime = (player->powers[pw_spacetime]) ? player->powers[pw_spacetime] : player->powers[pw_underwater]; - - if (!airtime) - return; // No air timers are active, nothing would be drawn anyway - - airtime--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity - - if (airtime > 11*TICRATE) - return; // Not time to draw any drown numbers yet - // Choose which frame to use based on time left - if (airtime <= 11*TICRATE && airtime >= 10*TICRATE) - frame = 5; - else if (airtime <= 9*TICRATE && airtime >= 8*TICRATE) - frame = 4; - else if (airtime <= 7*TICRATE && airtime >= 6*TICRATE) - frame = 3; - else if (airtime <= 5*TICRATE && airtime >= 4*TICRATE) - frame = 2; - else if (airtime <= 3*TICRATE && airtime >= 2*TICRATE) - frame = 1; - else if (airtime <= 1*TICRATE && airtime > 0) - frame = 0; + if (shieldoffs > 1) + shieldoffs = 2*shieldoffs/3; else - return; // Don't draw anything between numbers - - if (player->charflags & SF_MACHINE) - frame += 6; // Robots use different drown numbers - - // Get the front angle patch for the frame - sprframe = &sprites[SPR_DRWN].spriteframes[frame]; - p = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + shieldoffs = 0; } + offs -= shieldoffs; + + // YOU have a flag. Display a monitor-like icon for it. + if (stplyr->gotflag) + { + flagoffs = ICONSEP; + p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); + } + else if (flagoffs) + { + if (flagoffs > 1) + flagoffs = 2*flagoffs/3; + else + flagoffs = 0; + } + + offs -= flagoffs; + + invulntime = stplyr->powers[pw_flashing] ? stplyr->powers[pw_flashing] : stplyr->powers[pw_invulnerability]; + if (stplyr->powers[pw_invulnerability] > 3*TICRATE || (invulntime && leveltime & 1)) + { + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, invincibility); + V_DrawRightAlignedThinString(offs + 16, hudinfo[HUD_POWERUPS].y + 8, V_PERPLAYER|hudinfo[HUD_POWERUPS].f, va("%d", invulntime/TICRATE)); + } + + if (invulntime > 7) + offs -= ICONSEP; + else + { + UINT8 a = ICONSEP, b = 7-invulntime; + while (b--) + a = 2*a/3; + offs -= a; + } + + if (stplyr->powers[pw_sneakers] > 3*TICRATE || (stplyr->powers[pw_sneakers] && leveltime & 1)) + { + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, sneakers); + V_DrawRightAlignedThinString(offs + 16, hudinfo[HUD_POWERUPS].y + 8, V_PERPLAYER|hudinfo[HUD_POWERUPS].f, va("%d", stplyr->powers[pw_sneakers]/TICRATE)); + } + + if (stplyr->powers[pw_sneakers] > 7) + offs -= ICONSEP; + else + { + UINT8 a = ICONSEP, b = 7-stplyr->powers[pw_sneakers]; + while (b--) + a = 2*a/3; + offs -= a; + } + + if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) + { + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, gravboots); + V_DrawRightAlignedThinString(offs + 16, hudinfo[HUD_POWERUPS].y + 8, V_PERPLAYER|hudinfo[HUD_POWERUPS].f, va("%d", stplyr->powers[pw_gravityboots]/TICRATE)); + } + +#undef ICONSEP +} + +static void ST_drawFirstPersonHUD(void) +{ + patch_t *p = NULL; + UINT32 airtime; + UINT32 frame = 0; + spriteframe_t *sprframe; + // If both air timers are active, use the air timer with the least time left + if (stplyr->powers[pw_underwater] && stplyr->powers[pw_spacetime]) + airtime = min(stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime]); + else // Use whichever one is active otherwise + airtime = (stplyr->powers[pw_spacetime]) ? stplyr->powers[pw_spacetime] : stplyr->powers[pw_underwater]; + + if (!airtime) + return; // No air timers are active, nothing would be drawn anyway + + airtime--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity + + if (airtime > 11*TICRATE) + return; // Not time to draw any drown numbers yet + // Choose which frame to use based on time left + if (airtime <= 11*TICRATE && airtime >= 10*TICRATE) + frame = 5; + else if (airtime <= 9*TICRATE && airtime >= 8*TICRATE) + frame = 4; + else if (airtime <= 7*TICRATE && airtime >= 6*TICRATE) + frame = 3; + else if (airtime <= 5*TICRATE && airtime >= 4*TICRATE) + frame = 2; + else if (airtime <= 3*TICRATE && airtime >= 2*TICRATE) + frame = 1; + else if (airtime <= 1*TICRATE && airtime > 0) + frame = 0; + else + return; // Don't draw anything between numbers + + if (stplyr->charflags & SF_MACHINE) + frame += 6; // Robots use different drown numbers + + // Get the front angle patch for the frame + sprframe = &sprites[SPR_DRWN].spriteframes[frame]; + p = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + // Display the countdown drown numbers! if (p) V_DrawScaledPatch((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset), 60 - SHORT(p->topoffset), @@ -1674,7 +1743,7 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I if (weapon == pw_infinityring || (stplyr->ringweapons & rwflag)) - txtflags |= V_20TRANS; + ; //txtflags |= V_20TRANS; else { txtflags |= V_TRANSLUCENT; @@ -1683,10 +1752,10 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|patflags, pat); - if (stplyr->powers[weapon] > 99) - V_DrawThinString(8 + xoffs + 1, y, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); - else - V_DrawString(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); + //if (stplyr->powers[weapon] > 9) + V_DrawRightAlignedThinString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); + /*else + V_DrawRightAlignedString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon]));*/ if (stplyr->currentweapon == wepflag) V_DrawScaledPatch(6 + xoffs, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); @@ -1756,57 +1825,67 @@ static void ST_drawTagHUD(void) { sprintf(pstext, "%s", M_GetText("You cannot move while hiding.")); if (!splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); + V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); } // Print the stuff. if (pstext[0]) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER, pstext); + V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, pstext); } -static void ST_drawCTFHUD(void) +static void ST_drawTeamHUD(void) { - INT32 i, y = 176; - UINT16 whichflag = 0; + patch_t *p; +#define SEP 20 - // Draw the flags - V_DrawSmallScaledPatch(256, y, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, rflagico); - V_DrawSmallScaledPatch(280, y, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, bflagico); + if (gametype == GT_CTF) + p = bflagico; + else + p = bmatcico; - for (i = 0; i < MAXPLAYERS; i++) + V_DrawSmallScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); + + if (gametype == GT_CTF) + p = rflagico; + else + p = rmatcico; + + V_DrawSmallScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); + + if (gametype != GT_CTF) + goto num; { - if (players[i].gotflag & GF_REDFLAG) // Red flag isn't at base - V_DrawScaledPatch(256, y-4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, nonicon); - else if (players[i].gotflag & GF_BLUEFLAG) // Blue flag isn't at base - V_DrawScaledPatch(280, y-4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, nonicon); + INT32 i; + UINT16 whichflag = 0; - whichflag |= players[i].gotflag; - if ((whichflag & (GF_REDFLAG|GF_BLUEFLAG)) == (GF_REDFLAG|GF_BLUEFLAG)) - break; // both flags were found, let's stop early - } - - // YOU have a flag. Display a monitor-like icon for it. - if (stplyr->gotflag) - { - patch_t *p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; - V_DrawScaledPatch(304, 24 + 84, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - } - - // Display a countdown timer showing how much time left until the flag your team dropped returns to base. - { - char timeleft[33]; - if (redflag && redflag->fuse > 1) + // Show which flags aren't at base. + for (i = 0; i < MAXPLAYERS; i++) { - sprintf(timeleft, "%u", (redflag->fuse / TICRATE)); - V_DrawCenteredString(268, y+8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, timeleft); + if (players[i].gotflag & GF_BLUEFLAG) // Blue flag isn't at base + V_DrawScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(nonicon->width)/2, 0, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, nonicon); + if (players[i].gotflag & GF_REDFLAG) // Red flag isn't at base + V_DrawScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(nonicon2->width)/2, 0, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, nonicon2); + + whichflag |= players[i].gotflag; + if ((whichflag & (GF_REDFLAG|GF_BLUEFLAG)) == (GF_REDFLAG|GF_BLUEFLAG)) + break; // both flags were found, let's stop early } - if (blueflag && blueflag->fuse > 1) + // Display a countdown timer showing how much time left until the flag returns to base. { - sprintf(timeleft, "%u", (blueflag->fuse / TICRATE)); - V_DrawCenteredString(300, y+8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, timeleft); + if (blueflag && blueflag->fuse > 1) + V_DrawCenteredString(BASEVIDWIDTH/2 - SEP, 8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", (blueflag->fuse / TICRATE))); + + if (redflag && redflag->fuse > 1) + V_DrawCenteredString(BASEVIDWIDTH/2 + SEP, 8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", (redflag->fuse / TICRATE))); } } + +num: + V_DrawCenteredString(BASEVIDWIDTH/2 - SEP, 16, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", bluescore)); + V_DrawCenteredString(BASEVIDWIDTH/2 + SEP, 16, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", redscore)); + +#undef SEP } static void ST_drawSpecialStageHUD(void) @@ -1815,7 +1894,7 @@ static void ST_drawSpecialStageHUD(void) { if (hudinfo[HUD_SS_TOTALRINGS].x) ST_DrawNumFromHud(HUD_SS_TOTALRINGS, totalrings, V_HUDTRANS); - else if (cv_timetic.value == 3) + else if (cv_timetic.value == 2) V_DrawTallNum(hudinfo[HUD_RINGSNUMTICS].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUMTICS].f|V_PERPLAYER|V_HUDTRANS, totalrings); else V_DrawTallNum(hudinfo[HUD_RINGSNUM].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUM].f|V_PERPLAYER|V_HUDTRANS, totalrings); @@ -2035,6 +2114,8 @@ static void ST_overlayDrawer(void) V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, BASEVIDHEIGHT/2 - (SHORT(p->height)/2), V_PERPLAYER|(stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p); } + if (G_GametypeHasTeams()) + ST_drawTeamHUD(); if (!hu_showscores) // hide the following if TAB is held { @@ -2079,9 +2160,6 @@ static void ST_overlayDrawer(void) // Tag HUD Stuff else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) ST_drawTagHUD(); - // CTF HUD Stuff - else if (gametype == GT_CTF) - ST_drawCTFHUD(); // Special Stage HUD if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer]) @@ -2093,9 +2171,6 @@ static void ST_overlayDrawer(void) else ST_doHuntIconsAndSound(); - if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) - V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, hudinfo[HUD_GRAVBOOTSICO].y, hudinfo[HUD_GRAVBOOTSICO].f|V_PERPLAYER, gravboots); - if(!P_IsLocalPlayer(stplyr)) { char name[MAXPLAYERNAME+1]; @@ -2109,10 +2184,14 @@ static void ST_overlayDrawer(void) // This is where we draw all the fun cheese if you have the chasecam off! if ((stplyr == &players[displayplayer] && !camera.chase) - || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)) + || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)) { ST_drawFirstPersonHUD(); + if (cv_powerupdisplay.value) + ST_drawPowerupHUD(); } + else if (cv_powerupdisplay.value == 2) + ST_drawPowerupHUD(); } #ifdef HAVE_BLUA @@ -2149,27 +2228,30 @@ static void ST_overlayDrawer(void) if (cv_playersforexit.value != 4) { total *= cv_playersforexit.value; - if (total % 4) total += 4; // round up + if (total & 3) + total += 4; // round up total /= 4; } if (exiting < total) { total -= exiting; - V_DrawCenteredString(BASEVIDWIDTH/2, 124, V_PERPLAYER, va(M_GetText("%d more player%s required to exit."), total, ((total == 1) ? "" : "s"))); + V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s"))); if (!splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); + { + V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); + } } } else if (!splitscreen && gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); + V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; if (respawntime > 0 && !stplyr->spectator) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, va(M_GetText("Respawn in %d..."), respawntime)); + V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, va(M_GetText("Respawn in %d..."), respawntime)); else - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); + V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""JUMP:""\x80 Respawn")); } else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE) #ifdef HAVE_BLUA @@ -2177,14 +2259,13 @@ static void ST_overlayDrawer(void) #endif ) { - V_DrawCenteredString(BASEVIDWIDTH/2, 60, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You are a spectator.")); - if (G_GametypeHasTeams()) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); - else if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); - else if (gametype == GT_COOP && stplyr->lives <= 0) + INT32 y = 176 - 16; // HUD_LIVES + if (G_IsSpecialStage(gamemap) && useNightsSS) + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("Wait for the stage to end...")); + else if (gametype == GT_COOP) { - if (cv_cooplives.value == 2 + if (stplyr->lives <= 0 + && cv_cooplives.value == 2 && (netgame || multiplayer)) { INT32 i; @@ -2201,14 +2282,26 @@ static void ST_overlayDrawer(void) } if (i != MAXPLAYERS) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("You'll steal a life on respawn...")); + else + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Wait to respawn...")); } + else + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Wait to respawn...")); } - else if (gametype != GT_COOP) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); + else + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""FIRE:""\x80 Enter game")); + y -= 8; + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""SPIN:""\x80 Sink")); + y -= 8; + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""JUMP:""\x80 Float")); + y -= 8; if (!splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); - V_DrawCenteredString(BASEVIDWIDTH/2, 148, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); + { + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); + y -= 8; + } + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_GRAYMAP, M_GetText("Spectator mode:")); } } @@ -2252,6 +2345,24 @@ void ST_Drawer(void) #endif if (rendermode != render_none) ST_doPaletteStuff(); + // Blindfold! + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + && (leveltime < hidetime * TICRATE)) + { + if (players[displayplayer].pflags & PF_TAGIT) + { + stplyr = &players[displayplayer]; + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); + V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("You are blindfolded!")); + } + else if (splitscreen && players[secondarydisplayplayer].pflags & PF_TAGIT) + { + stplyr = &players[secondarydisplayplayer]; + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); + V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("You are blindfolded!")); + } + } + if (st_overlay) { // No deadview! diff --git a/src/st_stuff.h b/src/st_stuff.h index df1ac6433..df0adace3 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -101,7 +101,7 @@ typedef enum HUD_TIMELEFTNUM, HUD_TIMEUP, HUD_HUNTPICS, - HUD_GRAVBOOTSICO, + HUD_POWERUPS, NUMHUDITEMS } hudnum_t; From fc3e863fd3a371df6c21fcc222a656780df5bab0 Mon Sep 17 00:00:00 2001 From: Nevur Date: Thu, 29 Mar 2018 20:12:19 +0200 Subject: [PATCH 084/122] asdf Signed-off-by: Nevur --- src/p_slopes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index f480b6e4f..7c84a2db5 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -251,7 +251,7 @@ void P_SpawnSlope_Line(int linenum) UINT8 flags = 0; // Slope flags if (line->flags & ML_NOSONIC) flags |= SL_NOPHYSICS; - if (line->flags & ML_NOTAILS) + if (!(line->flags & ML_NOTAILS)) flags |= SL_NODYNAMIC; if (line->flags & ML_NOKNUX) flags |= SL_ANCHORVERTEX; From 65c893da86e23bc3c75aeb16a4d4ec1cdebdc79d Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 29 Mar 2018 23:28:54 +0100 Subject: [PATCH 085/122] static tempsec for R_FakeFlat I don't fully understand this, but it's what software does and it fixes the issue of the lighting in DSZ3. Also don't need the extra call to R_Prep3DFloors. --- src/hardware/hw_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 86b80904f..a0ea9b47a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2676,7 +2676,7 @@ static void HWR_AddLine(seg_t * line) angle_t span, tspan; // SoM: Backsector needs to be run through R_FakeFlat - sector_t tempsec; + static sector_t tempsec; if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; @@ -3235,7 +3235,7 @@ static void HWR_Subsector(size_t num) INT16 count; seg_t *line; subsector_t *sub; - sector_t tempsec; //SoM: 4/7/2000 + static sector_t tempsec; //SoM: 4/7/2000 INT32 floorlightlevel; INT32 ceilinglightlevel; INT32 locFloorHeight, locCeilingHeight; @@ -3418,8 +3418,6 @@ static void HWR_Subsector(size_t num) { /// \todo fix light, xoffs, yoffs, extracolormap ? ffloor_t * rover; - - R_Prep3DFloors(gr_frontsector); for (rover = gr_frontsector->ffloors; rover; rover = rover->next) { From de8f1fa407beede452ad5d391f92a288c4b70cc3 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 30 Mar 2018 16:39:59 +0100 Subject: [PATCH 086/122] * Incorporate (almost) all of Mystic's feedback. * Prevent ANY input when blindfolded. * Make CECHOs always perplayer'd. (A little hacky; quads will need work here.) * Make NiGHTS link timer bounces not a mess, and only when the colour changes. --- src/g_game.c | 4 +- src/hu_stuff.c | 8 +- src/p_user.c | 2 +- src/st_stuff.c | 484 ++++++++++++++++++++++++++----------------------- 4 files changed, 264 insertions(+), 234 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 9db9c413b..984b1ec40 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -888,7 +888,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // why build a ticcmd if we're paused? // Or, for that matter, if we're being reborn. - if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN)) + // ...OR if we're blindfolded. No looking into the floor. + if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + && (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT))))) { cmd->angleturn = (INT16)(localangle >> 16); cmd->aiming = G_ClipAimingPitch(&localaiming); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index c955a490d..a13801388 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -947,7 +947,7 @@ static void HU_DrawCEcho(void) INT32 y = (BASEVIDHEIGHT/2)-4; INT32 pnumlines = 0; - UINT32 realflags = cechoflags; + UINT32 realflags = cechoflags|V_PERPLAYER; // requested as part of splitscreen's stuff INT32 realalpha = (INT32)((cechoflags & V_ALPHAMASK) >> V_ALPHASHIFT); char *line; @@ -990,6 +990,12 @@ static void HU_DrawCEcho(void) *line = '\0'; V_DrawCenteredString(BASEVIDWIDTH/2, y, realflags, echoptr); + if (splitscreen) + { + stplyr = ((stplyr == &players[displayplayer]) ? &players[secondarydisplayplayer] : &players[displayplayer]); + V_DrawCenteredString(BASEVIDWIDTH/2, y, realflags, echoptr); + stplyr = ((stplyr == &players[displayplayer]) ? &players[secondarydisplayplayer] : &players[displayplayer]); + } y += ((realflags & V_RETURN8) ? 8 : 12); echoptr = line; diff --git a/src/p_user.c b/src/p_user.c index 86eb1bef4..b8634afa8 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9709,7 +9709,7 @@ void P_PlayerThink(player_t *player) } } - if (player->linktimer && (player->linktimer >= (2*TICRATE - 1) || !player->powers[pw_nights_linkfreeze])) + if (player->linktimer && !player->powers[pw_nights_linkfreeze]) { if (--player->linktimer <= 0) // Link timer player->linkcount = 0; diff --git a/src/st_stuff.c b/src/st_stuff.c index 25a61fa3a..3ae212bc1 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -737,14 +737,19 @@ static void ST_drawLivesArea(void) } // Lives number - if (G_GametypeUsesLives()) + if (G_GametypeUsesLives() || gametype == GT_RACE) { // x V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); // lives number - if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) + if (gametype == GT_RACE) + { + livescount = 0x7f; + notgreyedout = true; + } + else if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) { INT32 i; livescount = 0; @@ -788,58 +793,30 @@ static void ST_drawLivesArea(void) } // Spectator else if (stplyr->spectator) - { - //V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "SPECTATOR"); v_colmap = V_GRAYMAP; - } // Tag else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) { if (stplyr->pflags & PF_TAGIT) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, (gametype == GT_HIDEANDSEEK) ? "SEEKER" : "IT!"); + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "IT!"); v_colmap = V_ORANGEMAP; } - else if (stplyr->pflags & PF_GAMETYPEOVER) - { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANSHALF|hudinfo[HUD_LIVES].f|V_PERPLAYER, "FAILED"); - v_colmap = V_GRAYMAP; - } - else - { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, (gametype == GT_HIDEANDSEEK) ? "HIDER" : "RUNNER"); - v_colmap = V_GREENMAP; - } } // Team name else if (G_GametypeHasTeams()) { if (stplyr->ctfteam == 1) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED"); + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED"); v_colmap = V_REDMAP; } else if (stplyr->ctfteam == 2) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE"); + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE"); v_colmap = V_BLUEMAP; } - else - v_colmap = V_GRAYMAP; } - else if (circuitmap) - { - if (stplyr->exiting) - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "FINISHED"); - //V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f|V_YELLOWMAP, "FINISHED!"); - else - { - V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, va("%u/%d", stplyr->laps+1, cv_numlaps.value)); - //V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); - } - } - /*else - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "PLAYING");*/ // name v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); @@ -1074,13 +1051,8 @@ static void ST_drawLevelTitle(void) char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *subttl = mapheaderinfo[gamemap-1]->subttl; INT32 actnum = mapheaderinfo[gamemap-1]->actnum; - INT32 lvlttlxpos; + INT32 lvlttly, zoney, lvlttlxpos, ttlnumxpos, zonexpos; INT32 subttlxpos = BASEVIDWIDTH/2; - INT32 ttlnumxpos; - INT32 zonexpos; - - INT32 lvlttly; - INT32 zoney; if (!(timeinmap > 2 && timeinmap-3 < 110)) return; @@ -1095,10 +1067,41 @@ static void ST_drawLevelTitle(void) ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl); zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("ZONE")); + ttlnumxpos++; if (lvlttlxpos < 0) lvlttlxpos = 0; +#if 0 // toaster's experiment. srb2&toast.exe one day, maybe? Requires stuff below to be converted to fixed point. +#define MIDTTLY 79 +#define MIDZONEY 105 +#define MIDDIFF 4 + + if (timeinmap < 10) + { + fixed_t z = ((timeinmap - 3)<levelflags & LF_NOZONE)) - V_DrawLevelTitle(zonexpos, zoney, 0, M_GetText("ZONE")); + V_DrawLevelTitle(zonexpos, zoney, V_PERPLAYER, M_GetText("ZONE")); if (lvlttly+48 < 200) - V_DrawCenteredString(subttlxpos, lvlttly+48, V_ALLOWLOWERCASE, subttl); + V_DrawCenteredString(subttlxpos, lvlttly+48, V_PERPLAYER|V_ALLOWLOWERCASE, subttl); } static void ST_drawPowerupHUD(void) @@ -1135,7 +1139,8 @@ static void ST_drawPowerupHUD(void) patch_t *p = NULL; UINT16 invulntime = 0; INT32 offs = hudinfo[HUD_POWERUPS].x; - static INT32 flagoffs = 0, shieldoffs = 0; + const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); + static INT32 flagoffs[2] = {0, 0}, shieldoffs[2] = {0, 0}; #define ICONSEP (16+4) // matches weapon rings HUD if (stplyr->spectator || stplyr->playerstate != PST_LIVE) @@ -1144,7 +1149,7 @@ static void ST_drawPowerupHUD(void) // Graue 06-18-2004: no V_NOSCALESTART, no SCX, no SCY, snap to right if (stplyr->powers[pw_shield] & SH_NOSTACK) { - shieldoffs = ICONSEP; + shieldoffs[q] = ICONSEP; if ((stplyr->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE) { @@ -1173,32 +1178,32 @@ static void ST_drawPowerupHUD(void) V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); } } - else if (shieldoffs) + else if (shieldoffs[q]) { - if (shieldoffs > 1) - shieldoffs = 2*shieldoffs/3; + if (shieldoffs[q] > 1) + shieldoffs[q] = 2*shieldoffs[q]/3; else - shieldoffs = 0; + shieldoffs[q] = 0; } - offs -= shieldoffs; + offs -= shieldoffs[q]; // YOU have a flag. Display a monitor-like icon for it. if (stplyr->gotflag) { - flagoffs = ICONSEP; + flagoffs[q] = ICONSEP; p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); } - else if (flagoffs) + else if (flagoffs[q]) { - if (flagoffs > 1) - flagoffs = 2*flagoffs/3; + if (flagoffs[q] > 1) + flagoffs[q] = 2*flagoffs[q]/3; else - flagoffs = 0; + flagoffs[q] = 0; } - offs -= flagoffs; + offs -= flagoffs[q]; invulntime = stplyr->powers[pw_flashing] ? stplyr->powers[pw_flashing] : stplyr->powers[pw_invulnerability]; if (stplyr->powers[pw_invulnerability] > 3*TICRATE || (invulntime && leveltime & 1)) @@ -1394,7 +1399,6 @@ static void ST_drawNiGHTSHUD(void) INT32 origamount; INT32 minlink = 1; INT32 total_ringcount; - boolean nosshack = false; // When debugging, show "0 Link". if (cv_debug & DBG_NIGHTSBASIC) @@ -1411,21 +1415,10 @@ static void ST_drawNiGHTSHUD(void) #endif stplyr->powers[pw_carry] == CR_NIGHTSMODE) { - INT32 locx, locy; + INT32 locx = 16, locy = 180; INT32 dfill; UINT8 fillpatch; - if (splitscreen) - { - locx = 110; - locy = 188; - } - else - { - locx = 16; - locy = 180; - } - // Use which patch? if (stplyr->pflags & PF_DRILLING) fillpatch = (stplyr->drillmeter & 1) + 1; @@ -1446,14 +1439,17 @@ static void ST_drawNiGHTSHUD(void) } } - if (G_IsSpecialStage(gamemap)) + /*if (G_IsSpecialStage(gamemap)) { // Since special stages share score, time, rings, etc. // disable splitscreen mode for its HUD. + // -------------------------------------- + // NOPE! Consistency between different splitscreen stuffs + // now we've got the screen squashing instead. ~toast if (stplyr != &players[displayplayer]) return; nosshack = splitscreen; splitscreen = false; - } + }*/ // Link drawing if ( @@ -1462,42 +1458,39 @@ static void ST_drawNiGHTSHUD(void) #endif stplyr->linkcount > minlink) { + static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0}; + const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); + INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? 1 : 0); skincolors_t colornum; - INT32 aflag = V_PERPLAYER; fixed_t x, y, scale; + if (sel != prevsel[q]) + { + prevsel[q] = sel; + prevtime[q] = 2 + mag; + } + if (stplyr->powers[pw_nights_linkfreeze] && (!(stplyr->powers[pw_nights_linkfreeze] & 2) || (stplyr->powers[pw_nights_linkfreeze] > flashingtics))) colornum = SKINCOLOR_ICY; else - colornum = linkColor[((stplyr->linkcount-1 >= 300) ? 1 : 0)][((stplyr->linkcount-1) / 5) % NUMLINKCOLORS]; + colornum = linkColor[mag][sel]; aflag |= ((stplyr->linktimer < 2*TICRATE/3) ? (9 - 9*stplyr->linktimer/(2*TICRATE/3)) << V_ALPHASHIFT : 0); - y = (nosshack ? 16+11+(BASEVIDHEIGHT/2) : 160+11)<linktimer) - { - case (2*TICRATE): - scale = (36*FRACUNIT)/32; - break; - case (2*TICRATE - 1): - scale = (34*FRACUNIT)/32; - break; - default: - scale = FRACUNIT; - break; - } + scale = FRACUNIT; y -= (11*scale); @@ -1619,7 +1612,7 @@ static void ST_drawNiGHTSHUD(void) && LUA_HudEnabled(hud_nightsscore) #endif ) - ST_DrawNightsOverlayNum(304<marescore, nightsnum, SKINCOLOR_AZURE); + ST_DrawNightsOverlayNum(304<marescore, nightsnum, SKINCOLOR_AZURE); if (!stplyr->exiting #ifdef HAVE_BLUA @@ -1687,7 +1680,7 @@ static void ST_drawNiGHTSHUD(void) else numbersize = 48/2; - ST_DrawNightsOverlayNum((160 + numbersize)<weapondelay, del = 0, p = 16; + while (q) + { + if (q > p) + { + del += p; + q -= p; + q /= 2; + if (p > 1) + p /= 2; + } + else + { + del += q; + break; + } + } + V_DrawScaledPatch(6 + xoffs, y-2 - del/2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); } static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, INT32 xoffs, INT32 y, patch_t *pat) @@ -1751,14 +1763,10 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I } V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|patflags, pat); - - //if (stplyr->powers[weapon] > 9) - V_DrawRightAlignedThinString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); - /*else - V_DrawRightAlignedString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon]));*/ + V_DrawRightAlignedThinString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); if (stplyr->currentweapon == wepflag) - V_DrawScaledPatch(6 + xoffs, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); + ST_drawWeaponSelect(xoffs, y); } else if (stplyr->ringweapons & rwflag) V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_TRANSLUCENT, pat); @@ -1778,13 +1786,16 @@ static void ST_drawMatchHUD(void) { if (stplyr->powers[pw_infinityring]) ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring); - else if (stplyr->rings > 0) - V_DrawScaledPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM, normring); else - V_DrawTranslucentPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_80TRANS, normring); + { + if (stplyr->rings > 0) + V_DrawScaledPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM, normring); + else + V_DrawTranslucentPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_80TRANS, normring); - if (!stplyr->currentweapon) - V_DrawScaledPatch(6 + offset, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); + if (!stplyr->currentweapon) + ST_drawWeaponSelect(offset, y); + } offset += 20; ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring); @@ -1801,38 +1812,145 @@ static void ST_drawMatchHUD(void) } } +static void ST_drawTextHUD(void) +{ + INT32 y = 176 - 16; // HUD_LIVES + boolean dof12 = false, dospecheader = false; + +#define textHUDdraw(str) \ +{\ + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, str);\ + y -= 8;\ +} + + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) + { + if (leveltime < hidetime * TICRATE) + { + if (stplyr->pflags & PF_TAGIT) + { + textHUDdraw(M_GetText("Waiting for players to hide...")) + textHUDdraw(M_GetText("\x82""You are blindfolded!")) + } + else if (gametype == GT_HIDEANDSEEK) + textHUDdraw(M_GetText("Hide before time runs out!")) + else + textHUDdraw(M_GetText("Flee before you are hunted!")) + } + else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) + { + textHUDdraw(M_GetText("You cannot move while hiding.")) + dof12 = true; + } + } + + if (!stplyr->spectator && stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP) + { + INT32 i, total = 0, exiting = 0; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + if (players[i].lives <= 0) + continue; + + total++; + if (players[i].exiting) + exiting++; + } + + if (cv_playersforexit.value != 4) + { + total *= cv_playersforexit.value; + if (total & 3) + total += 4; // round up + total /= 4; + } + + if (exiting < total) + { + total -= exiting; + textHUDdraw(va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s"))) + dof12 = true; + } + } + else if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) + dof12 = true; + else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. + { + INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; + + if (respawntime > 0 && !stplyr->spectator) + textHUDdraw(va(M_GetText("Respawn in %d..."), respawntime)) + else + textHUDdraw(M_GetText("\x82""JUMP:""\x80 Respawn")) + } + else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE)) + { + if (G_IsSpecialStage(gamemap) && useNightsSS) + textHUDdraw(M_GetText("\x82""Wait for the stage to end...")) + else if (gametype == GT_COOP) + { + if (stplyr->lives <= 0 + && cv_cooplives.value == 2 + && (netgame || multiplayer)) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (&players[i] == stplyr) + continue; + + if (players[i].lives > 1) + break; + } + + if (i != MAXPLAYERS) + textHUDdraw(M_GetText("You'll steal a life on respawn...")) + else + textHUDdraw(M_GetText("Wait to respawn...")) + } + else + textHUDdraw(M_GetText("Wait to respawn...")) + } + else + textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game")) + + textHUDdraw(M_GetText("\x82""SPIN:""\x80 Sink")) + textHUDdraw(M_GetText("\x82""JUMP:""\x80 Float")) + + dof12 = true; + dospecheader = true; + } + + if (!splitscreen && dof12) + textHUDdraw(M_GetText("\x82""F12:""\x80 Switch view")) + + if (circuitmap) + { + if (stplyr->exiting) + textHUDdraw(M_GetText("\x82""FINISHED!")) + else + textHUDdraw(va("Lap:""\x82 %u/%d", stplyr->laps+1, cv_numlaps.value)) + } + + if (dospecheader) + textHUDdraw(M_GetText("\x86""Spectator mode:")) + +#undef textHUDdraw + +} + static inline void ST_drawRaceHUD(void) { if (leveltime > TICRATE && leveltime <= 5*TICRATE) ST_drawRaceNum(4*TICRATE - leveltime); } -static void ST_drawTagHUD(void) -{ - char pstext[33] = ""; - - // Figure out what we're going to print. - if (leveltime < hidetime * TICRATE) //during the hide time, the seeker and hiders have different messages on their HUD. - { - if (stplyr->pflags & PF_TAGIT) - sprintf(pstext, "%s", M_GetText("Waiting for players to hide...")); - else if (gametype == GT_HIDEANDSEEK) //hide and seek. - sprintf(pstext, "%s", M_GetText("Hide before time runs out!")); - else //default - sprintf(pstext, "%s", M_GetText("Flee before you are hunted!")); - } - else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) - { - sprintf(pstext, "%s", M_GetText("You cannot move while hiding.")); - if (!splitscreen) - V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); - } - - // Print the stuff. - if (pstext[0]) - V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, pstext); -} - static void ST_drawTeamHUD(void) { patch_t *p; @@ -2157,9 +2275,6 @@ static void ST_overlayDrawer(void) // Race HUD Stuff if (gametype == GT_RACE || gametype == GT_COMPETITION) ST_drawRaceHUD(); - // Tag HUD Stuff - else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) - ST_drawTagHUD(); // Special Stage HUD if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer]) @@ -2207,103 +2322,12 @@ static void ST_overlayDrawer(void) ) ST_drawLevelTitle(); - if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer) - { - if (!stplyr->spectator && stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP) - { - INT32 i, total = 0, exiting = 0; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - if (players[i].lives <= 0) - continue; - - total++; - if (players[i].exiting) - exiting++; - } - - if (cv_playersforexit.value != 4) - { - total *= cv_playersforexit.value; - if (total & 3) - total += 4; // round up - total /= 4; - } - - if (exiting < total) - { - total -= exiting; - V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s"))); - if (!splitscreen) - { - V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); - } - } - } - else if (!splitscreen && gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) - V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); - else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. - { - INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; - if (respawntime > 0 && !stplyr->spectator) - V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, va(M_GetText("Respawn in %d..."), respawntime)); - else - V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""JUMP:""\x80 Respawn")); - } - else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE) + if (!hu_showscores && (netgame || multiplayer) #ifdef HAVE_BLUA && LUA_HudEnabled(hud_textspectator) #endif - ) - { - INT32 y = 176 - 16; // HUD_LIVES - if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("Wait for the stage to end...")); - else if (gametype == GT_COOP) - { - if (stplyr->lives <= 0 - && cv_cooplives.value == 2 - && (netgame || multiplayer)) - { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - if (&players[i] == stplyr) - continue; - - if (players[i].lives > 1) - break; - } - - if (i != MAXPLAYERS) - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("You'll steal a life on respawn...")); - else - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Wait to respawn...")); - } - else - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Wait to respawn...")); - } - else - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""FIRE:""\x80 Enter game")); - y -= 8; - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""SPIN:""\x80 Sink")); - y -= 8; - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""JUMP:""\x80 Float")); - y -= 8; - if (!splitscreen) - { - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); - y -= 8; - } - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_GRAYMAP, M_GetText("Spectator mode:")); - } - } + ) + ST_drawTextHUD(); if (modeattacking) ST_drawInput(); @@ -2353,13 +2377,11 @@ void ST_Drawer(void) { stplyr = &players[displayplayer]; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); - V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("You are blindfolded!")); } else if (splitscreen && players[secondarydisplayplayer].pflags & PF_TAGIT) { stplyr = &players[secondarydisplayplayer]; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); - V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("You are blindfolded!")); } } From f3aa02e26dad0ce1178925284f65cc8eb7b6e4f3 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 30 Mar 2018 18:13:52 +0100 Subject: [PATCH 087/122] Start with lightnum on sector lightlevel --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a0ea9b47a..16587e5db 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1092,7 +1092,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, INT32 solid, i; lightlist_t * list = sector->lightlist; const UINT8 alpha = Surf->FlatColor.s.alpha; - FUINT lightnum; + FUINT lightnum = sector->lightlevel; extracolormap_t *colormap = NULL; realtop = top = wallVerts[3].y; From 0aaae501d379ee8526d190634e8af02ce4e8d1e8 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 30 Mar 2018 18:53:23 +0100 Subject: [PATCH 088/122] Warnings must die --- src/f_finale.c | 2 +- src/hardware/hw_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index cd699b6cb..958bef0f6 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -234,7 +234,7 @@ static void F_SkyScroll(INT32 scrollspeed) else if (rendermode != render_none) { // if only software rendering could be this simple and retarded INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); - INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; + INT32 y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; scrolled = animtimer * dupz; for (x = 0; x < vid.width; x += pw) { diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 16587e5db..becd1b1c2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5055,7 +5055,7 @@ static void HWR_CreateDrawNodes(void) // -------------------------------------------------------------------------- #ifdef SORTING // added the stransform so they can be switched as drawing happenes so MD2s and sprites are sorted correctly with each other -static void HWR_DrawSprites() +static void HWR_DrawSprites(void) { if (gr_visspritecount > 0) { From d9b5155e6ea4110199a440415cf9f41234b7b07c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 30 Mar 2018 21:49:15 +0100 Subject: [PATCH 089/122] * Make Tokens appear in competition. * Tweak thrown ring colours. * Make Armageddon shield loop properly. * Tweak drowning numbers to be consistent between third and first person. --- src/dehacked.c | 32 +++++++++++++++++ src/g_game.c | 4 +-- src/info.c | 96 +++++++++++++++++++++++++++++++++----------------- src/info.h | 32 +++++++++++++++++ src/p_inter.c | 26 +++++++------- src/p_mobj.c | 2 +- src/p_user.c | 27 +++++++------- src/st_stuff.c | 33 ++++++++--------- 8 files changed, 172 insertions(+), 80 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 3726cb381..a7ba72a6c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5015,6 +5015,22 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARMF14", "S_ARMF15", "S_ARMF16", + "S_ARMF17", + "S_ARMF18", + "S_ARMF19", + "S_ARMF20", + "S_ARMF21", + "S_ARMF22", + "S_ARMF23", + "S_ARMF24", + "S_ARMF25", + "S_ARMF26", + "S_ARMF27", + "S_ARMF28", + "S_ARMF29", + "S_ARMF30", + "S_ARMF31", + "S_ARMF32", "S_ARMB1", "S_ARMB2", @@ -5032,6 +5048,22 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARMB14", "S_ARMB15", "S_ARMB16", + "S_ARMB17", + "S_ARMB18", + "S_ARMB19", + "S_ARMB20", + "S_ARMB21", + "S_ARMB22", + "S_ARMB23", + "S_ARMB24", + "S_ARMB25", + "S_ARMB26", + "S_ARMB27", + "S_ARMB28", + "S_ARMB29", + "S_ARMB30", + "S_ARMB31", + "S_ARMB32", "S_WIND1", "S_WIND2", diff --git a/src/g_game.c b/src/g_game.c index 984b1ec40..509ccf0ab 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -133,8 +133,8 @@ boolean useNightsSS = false; UINT8 skincolor_redteam = SKINCOLOR_RED; UINT8 skincolor_blueteam = SKINCOLOR_BLUE; -UINT8 skincolor_redring = SKINCOLOR_RED; -UINT8 skincolor_bluering = SKINCOLOR_AZURE; +UINT8 skincolor_redring = SKINCOLOR_SALMON; +UINT8 skincolor_bluering = SKINCOLOR_CORNFLOWER; tic_t countdowntimer = 0; boolean countdowntimeup = false; diff --git a/src/info.c b/src/info.c index 58a2ba8f4..5f46744bd 100644 --- a/src/info.c +++ b/src/info.c @@ -2215,39 +2215,71 @@ state_t states[NUMSTATES] = {SPR_ARMA, FF_TRANS40|14, 2, {NULL}, 0, 0, S_ARMA16}, // S_ARMA15 {SPR_ARMA, FF_TRANS40|15, 2, {NULL}, 0, 0, S_ARMA1 }, // S_ARMA16 - {SPR_ARMF, FF_FULLBRIGHT , 3, {NULL}, 0, 0, S_ARMF2 }, // S_ARMF1 - {SPR_ARMF, FF_FULLBRIGHT| 1, 3, {NULL}, 0, 0, S_ARMF3 }, // S_ARMF2 - {SPR_ARMF, FF_FULLBRIGHT| 2, 3, {NULL}, 0, 0, S_ARMF4 }, // S_ARMF3 - {SPR_ARMF, FF_FULLBRIGHT| 3, 3, {NULL}, 0, 0, S_ARMF5 }, // S_ARMF4 - {SPR_ARMF, FF_FULLBRIGHT| 4, 3, {NULL}, 0, 0, S_ARMF6 }, // S_ARMF5 - {SPR_ARMF, FF_FULLBRIGHT| 5, 3, {NULL}, 0, 0, S_ARMF7 }, // S_ARMF6 - {SPR_ARMF, FF_FULLBRIGHT| 6, 3, {NULL}, 0, 0, S_ARMF8 }, // S_ARMF7 - {SPR_ARMF, FF_FULLBRIGHT| 7, 3, {NULL}, 0, 0, S_ARMF9 }, // S_ARMF8 - {SPR_ARMF, FF_FULLBRIGHT| 8, 3, {NULL}, 0, 0, S_ARMF10}, // S_ARMF9 - {SPR_ARMF, FF_FULLBRIGHT| 9, 3, {NULL}, 0, 0, S_ARMF11}, // S_ARMF10 - {SPR_ARMF, FF_FULLBRIGHT|10, 3, {NULL}, 0, 0, S_ARMF12}, // S_ARMF11 - {SPR_ARMF, FF_FULLBRIGHT|11, 3, {NULL}, 0, 0, S_ARMF13}, // S_ARMF12 - {SPR_ARMF, FF_FULLBRIGHT|12, 3, {NULL}, 0, 0, S_ARMF14}, // S_ARMF13 - {SPR_ARMF, FF_FULLBRIGHT|13, 3, {NULL}, 0, 0, S_ARMF15}, // S_ARMF14 - {SPR_ARMF, FF_FULLBRIGHT|14, 3, {NULL}, 0, 0, S_ARMF16}, // S_ARMF15 - {SPR_ARMF, FF_FULLBRIGHT|15, 3, {NULL}, 0, 0, S_ARMF1 }, // S_ARMF16 + {SPR_ARMF, FF_FULLBRIGHT , 2, {NULL}, 0, 0, S_ARMF2 }, // S_ARMF1 + {SPR_ARMF, FF_FULLBRIGHT| 1, 2, {NULL}, 0, 0, S_ARMF3 }, // S_ARMF2 + {SPR_ARMF, FF_FULLBRIGHT| 2, 2, {NULL}, 0, 0, S_ARMF4 }, // S_ARMF3 + {SPR_ARMF, FF_FULLBRIGHT| 3, 2, {NULL}, 0, 0, S_ARMF5 }, // S_ARMF4 + {SPR_ARMF, FF_FULLBRIGHT| 4, 2, {NULL}, 0, 0, S_ARMF6 }, // S_ARMF5 + {SPR_ARMF, FF_FULLBRIGHT| 5, 2, {NULL}, 0, 0, S_ARMF7 }, // S_ARMF6 + {SPR_ARMF, FF_FULLBRIGHT| 6, 2, {NULL}, 0, 0, S_ARMF8 }, // S_ARMF7 + {SPR_ARMF, FF_FULLBRIGHT| 7, 2, {NULL}, 0, 0, S_ARMF9 }, // S_ARMF8 + {SPR_ARMF, FF_FULLBRIGHT| 8, 2, {NULL}, 0, 0, S_ARMF10}, // S_ARMF9 + {SPR_ARMF, FF_FULLBRIGHT| 9, 2, {NULL}, 0, 0, S_ARMF11}, // S_ARMF10 + {SPR_ARMF, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_ARMF12}, // S_ARMF11 + {SPR_ARMF, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_ARMF13}, // S_ARMF12 + {SPR_ARMF, FF_FULLBRIGHT|12, 2, {NULL}, 0, 0, S_ARMF14}, // S_ARMF13 + {SPR_ARMF, FF_FULLBRIGHT|13, 2, {NULL}, 0, 0, S_ARMF15}, // S_ARMF14 + {SPR_ARMF, FF_FULLBRIGHT|14, 2, {NULL}, 0, 0, S_ARMF16}, // S_ARMF15 + {SPR_ARMF, FF_FULLBRIGHT|15, 2, {NULL}, 0, 0, S_ARMF17}, // S_ARMF16 + {SPR_ARMB, FF_FULLBRIGHT , 2, {NULL}, 0, 0, S_ARMF18}, // S_ARMF17 + {SPR_ARMB, FF_FULLBRIGHT| 1, 2, {NULL}, 0, 0, S_ARMF19}, // S_ARMF18 + {SPR_ARMB, FF_FULLBRIGHT| 2, 2, {NULL}, 0, 0, S_ARMF20}, // S_ARMF19 + {SPR_ARMB, FF_FULLBRIGHT| 3, 2, {NULL}, 0, 0, S_ARMF21}, // S_ARMF20 + {SPR_ARMB, FF_FULLBRIGHT| 4, 2, {NULL}, 0, 0, S_ARMF22}, // S_ARMF21 + {SPR_ARMB, FF_FULLBRIGHT| 5, 2, {NULL}, 0, 0, S_ARMF23}, // S_ARMF22 + {SPR_ARMB, FF_FULLBRIGHT| 6, 2, {NULL}, 0, 0, S_ARMF24}, // S_ARMF23 + {SPR_ARMB, FF_FULLBRIGHT| 7, 2, {NULL}, 0, 0, S_ARMF25}, // S_ARMF24 + {SPR_ARMB, FF_FULLBRIGHT| 8, 2, {NULL}, 0, 0, S_ARMF26}, // S_ARMF25 + {SPR_ARMB, FF_FULLBRIGHT| 9, 2, {NULL}, 0, 0, S_ARMF27}, // S_ARMF26 + {SPR_ARMB, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_ARMF28}, // S_ARMF27 + {SPR_ARMB, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_ARMF29}, // S_ARMF28 + {SPR_ARMB, FF_FULLBRIGHT|12, 2, {NULL}, 0, 0, S_ARMF30}, // S_ARMF29 + {SPR_ARMB, FF_FULLBRIGHT|13, 2, {NULL}, 0, 0, S_ARMF31}, // S_ARMF30 + {SPR_ARMB, FF_FULLBRIGHT|14, 2, {NULL}, 0, 0, S_ARMF32}, // S_ARMF31 + {SPR_ARMB, FF_FULLBRIGHT|15, 2, {NULL}, 0, 0, S_ARMF1 }, // S_ARMF32 - {SPR_ARMB, FF_FULLBRIGHT| 0, 3, {NULL}, 1, 0, S_ARMB2 }, // S_ARMB1 - {SPR_ARMB, FF_FULLBRIGHT| 1, 3, {NULL}, 1, 0, S_ARMB3 }, // S_ARMB2 - {SPR_ARMB, FF_FULLBRIGHT| 2, 3, {NULL}, 1, 0, S_ARMB4 }, // S_ARMB3 - {SPR_ARMB, FF_FULLBRIGHT| 3, 3, {NULL}, 1, 0, S_ARMB5 }, // S_ARMB4 - {SPR_ARMB, FF_FULLBRIGHT| 4, 3, {NULL}, 1, 0, S_ARMB6 }, // S_ARMB5 - {SPR_ARMB, FF_FULLBRIGHT| 5, 3, {NULL}, 1, 0, S_ARMB7 }, // S_ARMB6 - {SPR_ARMB, FF_FULLBRIGHT| 6, 3, {NULL}, 1, 0, S_ARMB8 }, // S_ARMB7 - {SPR_ARMB, FF_FULLBRIGHT| 7, 3, {NULL}, 1, 0, S_ARMB9 }, // S_ARMB8 - {SPR_ARMB, FF_FULLBRIGHT| 8, 3, {NULL}, 1, 0, S_ARMB10}, // S_ARMB9 - {SPR_ARMB, FF_FULLBRIGHT| 9, 3, {NULL}, 1, 0, S_ARMB11}, // S_ARMB10 - {SPR_ARMB, FF_FULLBRIGHT|10, 3, {NULL}, 1, 0, S_ARMB12}, // S_ARMB11 - {SPR_ARMB, FF_FULLBRIGHT|11, 3, {NULL}, 1, 0, S_ARMB13}, // S_ARMB12 - {SPR_ARMB, FF_FULLBRIGHT|12, 3, {NULL}, 1, 0, S_ARMB14}, // S_ARMB13 - {SPR_ARMB, FF_FULLBRIGHT|13, 3, {NULL}, 1, 0, S_ARMB15}, // S_ARMB14 - {SPR_ARMB, FF_FULLBRIGHT|14, 3, {NULL}, 1, 0, S_ARMB16}, // S_ARMB15 - {SPR_ARMB, FF_FULLBRIGHT|15, 3, {NULL}, 1, 0, S_ARMB1 }, // S_ARMB16 + {SPR_ARMB, FF_FULLBRIGHT , 2, {NULL}, 1, 0, S_ARMB2 }, // S_ARMB1 + {SPR_ARMB, FF_FULLBRIGHT| 1, 2, {NULL}, 1, 0, S_ARMB3 }, // S_ARMB2 + {SPR_ARMB, FF_FULLBRIGHT| 2, 2, {NULL}, 1, 0, S_ARMB4 }, // S_ARMB3 + {SPR_ARMB, FF_FULLBRIGHT| 3, 2, {NULL}, 1, 0, S_ARMB5 }, // S_ARMB4 + {SPR_ARMB, FF_FULLBRIGHT| 4, 2, {NULL}, 1, 0, S_ARMB6 }, // S_ARMB5 + {SPR_ARMB, FF_FULLBRIGHT| 5, 2, {NULL}, 1, 0, S_ARMB7 }, // S_ARMB6 + {SPR_ARMB, FF_FULLBRIGHT| 6, 2, {NULL}, 1, 0, S_ARMB8 }, // S_ARMB7 + {SPR_ARMB, FF_FULLBRIGHT| 7, 2, {NULL}, 1, 0, S_ARMB9 }, // S_ARMB8 + {SPR_ARMB, FF_FULLBRIGHT| 8, 2, {NULL}, 1, 0, S_ARMB10}, // S_ARMB9 + {SPR_ARMB, FF_FULLBRIGHT| 9, 2, {NULL}, 1, 0, S_ARMB11}, // S_ARMB10 + {SPR_ARMB, FF_FULLBRIGHT|10, 2, {NULL}, 1, 0, S_ARMB12}, // S_ARMB11 + {SPR_ARMB, FF_FULLBRIGHT|11, 2, {NULL}, 1, 0, S_ARMB13}, // S_ARMB12 + {SPR_ARMB, FF_FULLBRIGHT|12, 2, {NULL}, 1, 0, S_ARMB14}, // S_ARMB13 + {SPR_ARMB, FF_FULLBRIGHT|13, 2, {NULL}, 1, 0, S_ARMB15}, // S_ARMB14 + {SPR_ARMB, FF_FULLBRIGHT|14, 2, {NULL}, 1, 0, S_ARMB16}, // S_ARMB15 + {SPR_ARMB, FF_FULLBRIGHT|15, 2, {NULL}, 1, 0, S_ARMB17}, // S_ARMB16 + {SPR_ARMF, FF_FULLBRIGHT , 2, {NULL}, 1, 0, S_ARMB18}, // S_ARMB17 + {SPR_ARMF, FF_FULLBRIGHT| 1, 2, {NULL}, 1, 0, S_ARMB19}, // S_ARMB18 + {SPR_ARMF, FF_FULLBRIGHT| 2, 2, {NULL}, 1, 0, S_ARMB20}, // S_ARMB19 + {SPR_ARMF, FF_FULLBRIGHT| 3, 2, {NULL}, 1, 0, S_ARMB21}, // S_ARMB20 + {SPR_ARMF, FF_FULLBRIGHT| 4, 2, {NULL}, 1, 0, S_ARMB22}, // S_ARMB21 + {SPR_ARMF, FF_FULLBRIGHT| 5, 2, {NULL}, 1, 0, S_ARMB23}, // S_ARMB22 + {SPR_ARMF, FF_FULLBRIGHT| 6, 2, {NULL}, 1, 0, S_ARMB24}, // S_ARMB23 + {SPR_ARMF, FF_FULLBRIGHT| 7, 2, {NULL}, 1, 0, S_ARMB25}, // S_ARMB24 + {SPR_ARMF, FF_FULLBRIGHT| 8, 2, {NULL}, 1, 0, S_ARMB26}, // S_ARMB25 + {SPR_ARMF, FF_FULLBRIGHT| 9, 2, {NULL}, 1, 0, S_ARMB27}, // S_ARMB26 + {SPR_ARMF, FF_FULLBRIGHT|10, 2, {NULL}, 1, 0, S_ARMB28}, // S_ARMB27 + {SPR_ARMF, FF_FULLBRIGHT|11, 2, {NULL}, 1, 0, S_ARMB29}, // S_ARMB28 + {SPR_ARMF, FF_FULLBRIGHT|12, 2, {NULL}, 1, 0, S_ARMB30}, // S_ARMB29 + {SPR_ARMF, FF_FULLBRIGHT|13, 2, {NULL}, 1, 0, S_ARMB31}, // S_ARMB30 + {SPR_ARMF, FF_FULLBRIGHT|14, 2, {NULL}, 1, 0, S_ARMB32}, // S_ARMB31 + {SPR_ARMF, FF_FULLBRIGHT|15, 2, {NULL}, 1, 0, S_ARMB1 }, // S_ARMB32 {SPR_WIND, FF_TRANS70 , 2, {NULL}, 0, 0, S_WIND2}, // S_WIND1 {SPR_WIND, FF_TRANS70|1, 2, {NULL}, 0, 0, S_WIND3}, // S_WIND2 diff --git a/src/info.h b/src/info.h index f9052b5da..d0e75e2e8 100644 --- a/src/info.h +++ b/src/info.h @@ -2330,6 +2330,22 @@ typedef enum state S_ARMF14, S_ARMF15, S_ARMF16, + S_ARMF17, + S_ARMF18, + S_ARMF19, + S_ARMF20, + S_ARMF21, + S_ARMF22, + S_ARMF23, + S_ARMF24, + S_ARMF25, + S_ARMF26, + S_ARMF27, + S_ARMF28, + S_ARMF29, + S_ARMF30, + S_ARMF31, + S_ARMF32, S_ARMB1, S_ARMB2, @@ -2347,6 +2363,22 @@ typedef enum state S_ARMB14, S_ARMB15, S_ARMB16, + S_ARMB17, + S_ARMB18, + S_ARMB19, + S_ARMB20, + S_ARMB21, + S_ARMB22, + S_ARMB23, + S_ARMB24, + S_ARMB25, + S_ARMB26, + S_ARMB27, + S_ARMB28, + S_ARMB29, + S_ARMB30, + S_ARMB31, + S_ARMB32, S_WIND1, S_WIND2, diff --git a/src/p_inter.c b/src/p_inter.c index 833a9ba52..c57d348fc 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -577,25 +577,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_TOKEN: if (player->bot) return; - tokenlist += special->health; P_AddPlayerScore(player, 1000); - if (!modeattacking) // score only there... + if (gametype != GT_COOP || modeattacking) // score only? + break; + + tokenlist += special->health; + + if (ALL7EMERALDS(emeralds)) // Got all 7 { - if (ALL7EMERALDS(emeralds)) // Got all 7 + if (!(netgame || multiplayer)) { - if (!(netgame || multiplayer)) - { - player->continues += 1; - players->gotcontinue = true; - if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_s3kac); - } + player->continues += 1; + players->gotcontinue = true; + if (P_IsLocalPlayer(player)) + S_StartSound(NULL, sfx_s3kac); } - else - token++; } + else + token++; + break; // Emerald Hunt diff --git a/src/p_mobj.c b/src/p_mobj.c index 8695d57e4..64756c55a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9539,7 +9539,7 @@ void P_SpawnMapThing(mapthing_t *mthing) // They're likely facets of the level's design and therefore required to progress. } - if (i == MT_TOKEN && (gametype != GT_COOP || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++))) + if (i == MT_TOKEN && ((gametype != GT_COOP && gametype != GT_COMPETITION) || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++))) return; // you already got this token, or there are too many, or the gametype's not right // Objectplace landing point diff --git a/src/p_user.c b/src/p_user.c index b8634afa8..b3a8bcf4b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2336,12 +2336,17 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) { tic_t timeleft = (player->powers[pw_spacetime]) ? player->powers[pw_spacetime] : player->powers[pw_underwater]; - if ((timeleft == 11*TICRATE + 1) // 5 - || (timeleft == 9*TICRATE + 1) // 4 - || (timeleft == 7*TICRATE + 1) // 3 - || (timeleft == 5*TICRATE + 1) // 2 - || (timeleft == 3*TICRATE + 1) // 1 - || (timeleft == 1*TICRATE + 1) // 0 + if (player->exiting) + player->powers[pw_underwater] = player->powers[pw_spacetime] = 0; + + timeleft--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity + + if ((timeleft == 11*TICRATE) // 5 + || (timeleft == 9*TICRATE) // 4 + || (timeleft == 7*TICRATE) // 3 + || (timeleft == 5*TICRATE) // 2 + || (timeleft == 3*TICRATE) // 1 + || (timeleft == 1*TICRATE) // 0 ) { fixed_t height = (player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->z - FixedMul(8*FRACUNIT + mobjinfo[MT_DROWNNUMBERS].height, FixedMul(player->mo->scale, player->shieldscale)) @@ -2349,7 +2354,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) mobj_t *numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be (((timeleft - 1)/TICRATE) - 1)/2, but integer division rounds down for us + timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be ((timeleft/TICRATE) - 1)/2, but integer division rounds down for us if (player->charflags & SF_MACHINE) { @@ -2408,14 +2413,6 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) S_ChangeMusicInternal("_drown", false); } } - - if (player->exiting) - { - if (player->powers[pw_underwater] > 1) - player->powers[pw_underwater] = 0; - - player->powers[pw_spacetime] = 0; - } } // diff --git a/src/st_stuff.c b/src/st_stuff.c index 3ae212bc1..6a909580d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1251,7 +1251,6 @@ static void ST_drawFirstPersonHUD(void) { patch_t *p = NULL; UINT32 airtime; - UINT32 frame = 0; spriteframe_t *sprframe; // If both air timers are active, use the air timer with the least time left if (stplyr->powers[pw_underwater] && stplyr->powers[pw_spacetime]) @@ -1259,34 +1258,32 @@ static void ST_drawFirstPersonHUD(void) else // Use whichever one is active otherwise airtime = (stplyr->powers[pw_spacetime]) ? stplyr->powers[pw_spacetime] : stplyr->powers[pw_underwater]; - if (!airtime) + if (airtime < 1) return; // No air timers are active, nothing would be drawn anyway airtime--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity if (airtime > 11*TICRATE) return; // Not time to draw any drown numbers yet - // Choose which frame to use based on time left - if (airtime <= 11*TICRATE && airtime >= 10*TICRATE) - frame = 5; - else if (airtime <= 9*TICRATE && airtime >= 8*TICRATE) - frame = 4; - else if (airtime <= 7*TICRATE && airtime >= 6*TICRATE) - frame = 3; - else if (airtime <= 5*TICRATE && airtime >= 4*TICRATE) - frame = 2; - else if (airtime <= 3*TICRATE && airtime >= 2*TICRATE) - frame = 1; - else if (airtime <= 1*TICRATE && airtime > 0) - frame = 0; - else + + if (!((airtime > 10*TICRATE - 5) + || (airtime <= 9*TICRATE && airtime > 8*TICRATE - 5) + || (airtime <= 7*TICRATE && airtime > 6*TICRATE - 5) + || (airtime <= 5*TICRATE && airtime > 4*TICRATE - 5) + || (airtime <= 3*TICRATE && airtime > 2*TICRATE - 5) + || (airtime <= 1*TICRATE))) return; // Don't draw anything between numbers + if (!((airtime % 10) < 5)) + return; // Keep in line with the flashing thing from third person. + + airtime /= (2*TICRATE); // To be strictly accurate it'd need to be ((airtime/TICRATE) - 1)/2, but integer division rounds down for us + if (stplyr->charflags & SF_MACHINE) - frame += 6; // Robots use different drown numbers + airtime += 6; // Robots use different drown numbers // Get the front angle patch for the frame - sprframe = &sprites[SPR_DRWN].spriteframes[frame]; + sprframe = &sprites[SPR_DRWN].spriteframes[airtime]; p = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); // Display the countdown drown numbers! From 0fbebcaa08e5a64e457f84a2e748d065ffc9cdc0 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 30 Mar 2018 22:03:14 +0100 Subject: [PATCH 090/122] Make special stage tallies do the token noise if you cash in a token! --- src/y_inter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 7ac28018b..c86dee758 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -825,7 +825,7 @@ void Y_Ticker(void) { tallydonetic = intertic; endtic = intertic + 3*TICRATE; // 3 second pause after end of tally - S_StartSound(NULL, sfx_chchng); // cha-ching! + S_StartSound(NULL, (gottoken ? sfx_token : sfx_chchng)); // cha-ching! // Update when done with tally if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) @@ -870,7 +870,7 @@ void Y_Ticker(void) if ((intertic - tallydonetic) > (3*TICRATE)/2) { endtic = intertic + 4*TICRATE; // 4 second pause after end of tally - S_StartSound(NULL, sfx_s3kac); // cha-ching! + S_StartSound(NULL, sfx_s3kac); // bingly-bingly-bing! } return; } @@ -890,7 +890,7 @@ void Y_Ticker(void) if (!(data.spec.continues & 0x80)) // don't set endtic yet! endtic = intertic + 4*TICRATE; // 4 second pause after end of tally - S_StartSound(NULL, sfx_chchng); // cha-ching! + S_StartSound(NULL, (gottoken ? sfx_token : sfx_chchng)); // cha-ching! // Update when done with tally if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) From 6f2de824fb015d71940e9c4d12b321b30bcb63b2 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 30 Mar 2018 23:12:44 +0100 Subject: [PATCH 091/122] Uncomment HWR_CorrectSWTricks but set gr_correcttricks to be off by default I wasn't aware of the cvar, this should do for now since I don't believe any maps use these software tricks, probably an old leftover from DOOM. --- src/hardware/hw_main.c | 2 +- src/p_setup.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index becd1b1c2..81021ef7f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -117,7 +117,7 @@ consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL, grfiltermode_c consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t, CV_anisotropic_ONChange, 0, NULL, NULL, 0, 0, NULL}; //static consvar_t cv_grzbuffer = {"gr_zbuffer", "On", 0, CV_OnOff}; -consvar_t cv_grcorrecttricks = {"gr_correcttricks", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static void CV_FogDensity_ONChange(void) diff --git a/src/p_setup.c b/src/p_setup.c index e93cbed51..8e746457b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2718,7 +2718,7 @@ boolean P_SetupLevel(boolean skipprecip) HWR_ResetLights(); #endif // Correct missing sidedefs & deep water trick - //HWR_CorrectSWTricks(); + HWR_CorrectSWTricks(); HWR_CreatePlanePolygons((INT32)numnodes - 1); } #endif From 6d59551afdac6bf20c5add5f6a86c169c9db431f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 1 Apr 2018 20:54:19 +0100 Subject: [PATCH 092/122] Mace optimisation! * Handle all chain objects as a hnext/hprev chain. * When removing mobjs with hnext/hprev, "repair the chain" (make the h links meet). * Fix hidden slings, which I accidentially broke when I revamped maces the first time. * Kill MF2_MACEROTATE. Not needed for anything anymore. * P_MaceRotate now available to Lua to make up for it. * Related: Made modifying hnext/hprev using Lua safer, so it keeps the reference counts in play. --- src/dehacked.c | 1 - src/info.c | 14 +-- src/lua_baselib.c | 14 +++ src/lua_mobjlib.c | 16 ++- src/p_enemy.c | 11 +- src/p_local.h | 2 + src/p_mobj.c | 260 +++++++++++++++++++++++++++++----------------- src/p_mobj.h | 2 - 8 files changed, 209 insertions(+), 111 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c172549e1..ced71f079 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6515,7 +6515,6 @@ static const char *const MOBJFLAG2_LIST[] = { "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH "LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) "SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) - "MACEROTATE", // Thinker calls P_MaceRotate around tracer NULL }; diff --git a/src/info.c b/src/info.c index acb12379a..f11d88af8 100644 --- a/src/info.c +++ b/src/info.c @@ -9011,7 +9011,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 10000, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9038,7 +9038,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 10000, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9065,7 +9065,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 10000, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9092,7 +9092,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 10000, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9119,7 +9119,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9146,7 +9146,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 200, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9173,7 +9173,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 200, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9d65a5832..4040e271d 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -776,6 +776,19 @@ static int lib_pCanRunOnWater(lua_State *L) return 1; } +static int lib_pMaceRotate(lua_State *L) +{ + mobj_t *center = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + INT32 baserot = luaL_checkinteger(L, 2); + INT32 baseprevrot = luaL_checkinteger(L, 3); + NOHUD + INLEVEL + if (!center) + return LUA_ErrInvalid(L, "mobj_t"); + P_MaceRotate(center, baserot, baseprevrot); + return 0; +} + // P_USER //////////// @@ -2526,6 +2539,7 @@ static luaL_Reg lib[] = { {"P_CheckDeathPitCollide",lib_pCheckDeathPitCollide}, {"P_CheckSolidLava",lib_pCheckSolidLava}, {"P_CanRunOnWater",lib_pCanRunOnWater}, + {"P_MaceRotate",lib_pMaceRotate}, // p_user {"P_GetPlayerHeight",lib_pGetPlayerHeight}, diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index d384b75d1..1583bd3c4 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -530,10 +530,22 @@ static int mobj_set(lua_State *L) case mobj_bprev: return UNIMPLEMENTED; case mobj_hnext: - mo->hnext = luaL_checkudata(L, 3, META_MOBJ); + if (lua_isnil(L, 3)) + P_SetTarget(&mo->hnext, NULL); + else + { + mobj_t *hnext = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->hnext, hnext); + } break; case mobj_hprev: - mo->hprev = luaL_checkudata(L, 3, META_MOBJ); + if (lua_isnil(L, 3)) + P_SetTarget(&mo->hprev, NULL); + else + { + mobj_t *hprev = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->hprev, hprev); + } break; case mobj_type: // yeah sure, we'll let you change the mobj's type. { diff --git a/src/p_enemy.c b/src/p_enemy.c index 9acc8430e..a8ce7869c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4917,6 +4917,7 @@ void A_SlingAppear(mobj_t *actor) boolean firsttime = true; UINT8 mlength = 4; mobj_t *spawnee; + mobj_t *hprev = actor; #ifdef HAVE_BLUA if (LUA_CallAction("A_SlingAppear", actor)) return; @@ -4927,7 +4928,6 @@ void A_SlingAppear(mobj_t *actor) P_SetThingPosition(actor); actor->lastlook = 128; actor->movecount = actor->lastlook; - actor->health = actor->angle>>ANGLETOFINESHIFT; actor->threshold = 0; actor->movefactor = actor->threshold; actor->friction = 128; @@ -4936,10 +4936,13 @@ void A_SlingAppear(mobj_t *actor) { spawnee = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMALLMACECHAIN); - P_SetTarget(&spawnee->target, actor); + P_SetTarget(&spawnee->tracer, actor); + P_SetTarget(&spawnee->hprev, hprev); + P_SetTarget(&hprev->hnext, spawnee); + hprev = spawnee; - spawnee->threshold = 0; - spawnee->reactiontime = mlength; + spawnee->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; + spawnee->movecount = mlength; if (firsttime) { diff --git a/src/p_local.h b/src/p_local.h index 54ae37ed2..49d3ed614 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -280,6 +280,8 @@ mobj_t *P_GetClosestAxis(mobj_t *source); boolean P_CanRunOnWater(player_t *player, ffloor_t *rover); +void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot); + void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration); #define PAL_WHITE 1 #define PAL_MIXUP 2 diff --git a/src/p_mobj.c b/src/p_mobj.c index 8695d57e4..2e78c098e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6176,98 +6176,149 @@ static void P_NightsItemChase(mobj_t *thing) // // P_MaceRotate -// Spins an object around its target, or, swings it from side to side. +// Spins a hnext-chain of objects around its centerpoint, side to side or periodically. // -static void P_MaceRotate(mobj_t *mobj) +void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) { - TVector v; + TVector unit, baseuo, unitoffset; TVector *res; - fixed_t radius, dist; + fixed_t radius, dist, wah; angle_t fa; - INT32 prevswing; - boolean donetwice = false; + //boolean donetwice = false; + boolean dosound = false; + mobj_t *mobj = center->hnext, *hnext = NULL; // Tracer was removed. - if (!mobj->health) + /*if (!mobj->health) return; else if (!mobj->tracer) { P_KillMobj(mobj, NULL, NULL, 0); return; - } + }*/ - mobj->momx = mobj->momy = mobj->momz = 0; + INT32 rot = (baserot &= FINEMASK); + INT32 prevrot = (baseprevrot &= FINEMASK); - prevswing = mobj->threshold; - mobj->threshold += mobj->tracer->lastlook; - mobj->threshold &= FINEMASK; + INT32 lastthreshold = FINEMASK; // needs to never be equal at start of loop + fixed_t lastfriction = INT32_MIN; // ditto; almost certainly never, but... - dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); + fixed_t movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = 0; - // Radius of the link's rotation. - radius = FixedMul(dist * mobj->movecount, mobj->tracer->scale) + mobj->tracer->extravalue1; + baseuo[3] = 0; -maceretry: - - fa = (FixedAngle(mobj->tracer->movefactor*FRACUNIT) >> ANGLETOFINESHIFT); - radius = FixedMul(FINECOSINE(fa), radius); - v[1] = -FixedMul(FINESINE(fa), radius) - + FixedMul(dist * mobj->movefactor, mobj->tracer->scale); - v[3] = FRACUNIT; - - // Swinging Chain. - if (mobj->tracer->flags2 & MF2_STRONGBOX) + while (mobj) { - fixed_t swingmagnitude = FixedMul(FINECOSINE(mobj->threshold), mobj->tracer->lastlook << FRACBITS); - prevswing = FINECOSINE(prevswing); + mobj->momx = mobj->momy = mobj->momz = 0; - if (!donetwice - && (mobj->flags2 & MF2_BOSSNOTRAP) // at the end of the chain and can play a sound - && ((prevswing > 0) != (swingmagnitude > 0))) // just passed its lowest point + if (mobj->threshold != lastthreshold + || mobj->friction != lastfriction) + { + rot = (baserot + mobj->threshold) & FINEMASK; + prevrot = (baseprevrot + mobj->threshold) & FINEMASK; + + fa = (FixedAngle(center->movefactor*FRACUNIT) >> ANGLETOFINESHIFT); // mpinch + radius = FINECOSINE(fa); + unit[1] = -FixedMul(FINESINE(fa), radius); + unit[3] = center->scale; + + // Swinging Chain. + if (center->flags2 & MF2_STRONGBOX) + { + fixed_t swingmag = FixedMul(FINECOSINE(rot), center->lastlook << FRACBITS); + fixed_t prevswingmag = FINECOSINE(prevrot); + + if ((prevswingmag > 0) != (swingmag > 0)) // just passed its lowest point + dosound = true; + //S_StartSound(mobj, mobj->info->activesound); + + fa = ((FixedAngle(swingmag) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK; + + unit[0] = FixedMul(FINESINE(fa), -radius); + unit[2] = FixedMul(FINECOSINE(fa), -radius); + } + // Rotating Chain. + else + { + angle_t prevfa = (prevrot + mobj->friction) & FINEMASK; + fa = (rot + mobj->friction) & FINEMASK; + + if (!(prevfa > (FINEMASK/2)) && (fa > (FINEMASK/2))) // completed a full swing + dosound = true; + + unit[0] = FixedMul(FINECOSINE(fa), radius); + unit[2] = FixedMul(FINESINE(fa), radius); + } + + // Calculate the angle matrixes for the link. + res = VectorMatrixMultiply(unit, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&unit, res, sizeof(unit)); + res = VectorMatrixMultiply(unit, *RotateZMatrix(center->angle)); + M_Memcpy(&unit, res, sizeof(unit)); + } + + if (dosound && (mobj->flags2 & MF2_BOSSNOTRAP)) + { S_StartSound(mobj, mobj->info->activesound); + dosound = false; + } - fa = ((FixedAngle(swingmagnitude) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK; + dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); - v[0] = FixedMul(FINESINE(fa), -radius); - v[2] = FixedMul(FINECOSINE(fa), -radius); - } - // Rotating Chain. - else - { - prevswing = (prevswing + mobj->friction) & FINEMASK; - fa = (mobj->threshold + mobj->friction) & FINEMASK; + if (dist*mobj->movefactor != movefac) + { + if (!baseuo[3]) + { + baseuo[1] = FRACUNIT; + baseuo[3] = center->scale; + baseuo[0] = baseuo[2] = 0; - if (!donetwice - && (mobj->flags2 & MF2_BOSSNOTRAP) // at the end of the chain and can play a sound - && (!(prevswing > (FINEMASK/2)) && (fa > (FINEMASK/2)))) // completed a full swing - S_StartSound(mobj, mobj->info->activesound); + res = VectorMatrixMultiply(baseuo, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&baseuo, res, sizeof(unit)); + res = VectorMatrixMultiply(baseuo, *RotateZMatrix(center->angle)); + M_Memcpy(&baseuo, res, sizeof(unit)); - v[0] = FixedMul(FINECOSINE(fa), radius); - v[2] = FixedMul(FINESINE(fa), radius); + lastthreshold = mobj->threshold; + lastfriction = mobj->friction; + } + + if (mobj->movefactor) + { + movefac = dist*mobj->movefactor; + unitoffset[0] = FixedMul(movefac, baseuo[0]); + unitoffset[1] = FixedMul(movefac, baseuo[1]); + unitoffset[2] = FixedMul(movefac, baseuo[2]); + } + else + movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = 0; + } + + //maceretry: + + hnext = mobj->hnext; // just in case the mobj is removed + + P_UnsetThingPosition(mobj); + + // Radius of the link's rotation. + wah = (dist * mobj->movecount) + center->extravalue1; + + // Add on the appropriate distances to the center's co-ordinates. + mobj->x = center->x + FixedMul(unit[0], wah) + unitoffset[0]; + mobj->y = center->y + FixedMul(unit[1], wah) + unitoffset[1]; + mobj->z = center->z + FixedMul(unit[2], wah) + unitoffset[2]; + + // Cut the height to align the link with the axis. + if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN) + mobj->z -= P_MobjFlip(mobj)*mobj->height/4; + else + mobj->z -= P_MobjFlip(mobj)*mobj->height/2; + + P_SetThingPosition(mobj); + + mobj = hnext; } - // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(v, *RotateXMatrix(mobj->tracer->threshold << ANGLETOFINESHIFT)); - M_Memcpy(&v, res, sizeof(v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(mobj->tracer->health << ANGLETOFINESHIFT)); - M_Memcpy(&v, res, sizeof(v)); - - // Cut the height to align the link with the axis. - if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN) - v[2] -= P_MobjFlip(mobj)*mobj->height/4; - else - v[2] -= P_MobjFlip(mobj)*mobj->height/2; - - P_UnsetThingPosition(mobj); - - // Add on the appropriate distances to the center's co-ordinates. - mobj->x = mobj->tracer->x + v[0]; - mobj->y = mobj->tracer->y + v[1]; - mobj->z = mobj->tracer->z + v[2]; - - P_SetThingPosition(mobj); - - if (donetwice || P_MobjWasRemoved(mobj)) + /*if (donetwice || P_MobjWasRemoved(mobj)) return; if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) @@ -6293,7 +6344,7 @@ maceretry: radius = FixedMul(radius, dist); donetwice = true; dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); - goto maceretry; + goto maceretry;*/ } static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) @@ -6664,13 +6715,6 @@ void P_MobjThinker(mobj_t *mobj) } } - if (mobj->flags2 & MF2_MACEROTATE) - { - P_MaceRotate(mobj); - if (P_MobjWasRemoved(mobj)) - return; - } - // Special thinker for scenery objects if (mobj->flags & MF_SCENERY) { @@ -6687,6 +6731,29 @@ void P_MobjThinker(mobj_t *mobj) switch (mobj->type) { + case MT_CHAINPOINT: + case MT_CHAINMACEPOINT: + if (leveltime & 1) + { + if (mobj->lastlook > mobj->movecount) + mobj->lastlook--; + /* + if (mobj->threshold > mobj->movefactor) + mobj->threshold -= FRACUNIT; + else if (mobj->threshold < mobj->movefactor) + mobj->threshold += FRACUNIT;*/ + } + /* FALLTHRU */ + case MT_MACEPOINT: + case MT_SPRINGBALLPOINT: + case MT_FIREBARPOINT: + case MT_CUSTOMMACEPOINT: + case MT_HIDDEN_SLING: + // The following was pretty good, but liked breaking whenever mobj->lastlook changed. + //P_MaceRotate(mobj, ((leveltime + 1) * mobj->lastlook), (leveltime * mobj->lastlook)); + P_MaceRotate(mobj, mobj->movedir + mobj->lastlook, mobj->movedir); + mobj->movedir = (mobj->movedir + mobj->lastlook) & FINEMASK; + break; case MT_HOOP: if (mobj->fuse > 1) P_MoveHoop(mobj); @@ -7337,19 +7404,6 @@ void P_MobjThinker(mobj_t *mobj) } } break; - case MT_CHAINPOINT: - case MT_CHAINMACEPOINT: - if (leveltime & 1) - { - if (mobj->lastlook > mobj->movecount) - mobj->lastlook--; -/* - if (mobj->threshold > mobj->movefactor) - mobj->threshold -= FRACUNIT; - else if (mobj->threshold < mobj->movefactor) - mobj->threshold += FRACUNIT;*/ - } - break; case MT_EGGCAPSULE: if (!mobj->reactiontime) { @@ -8615,6 +8669,13 @@ void P_RemoveMobj(mobj_t *mobj) // Remove any references to other mobjs. P_SetTarget(&mobj->target, P_SetTarget(&mobj->tracer, NULL)); + if (mobj->hnext) + P_SetTarget(&mobj->hnext->hprev, mobj->hprev); + if (mobj->hprev) + P_SetTarget(&mobj->hprev->hnext, mobj->hnext); + + P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL)); + // free block // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. if (mobj->flags & MF_NOTHINK && !mobj->thinker.next) @@ -9301,6 +9362,7 @@ void P_SpawnMapThing(mapthing_t *mthing) mobj_t *mobj; fixed_t x, y, z; subsector_t *ss; + boolean doangle = true; if (!mthing->type) return; // Ignore type-0 things as NOPs @@ -9710,7 +9772,7 @@ void P_SpawnMapThing(mapthing_t *mthing) angle_t mspokeangle; mobjtype_t chainlink, macetype, firsttype, linktype; boolean mdoall = true; - mobj_t *spawnee; + mobj_t *spawnee, *hprev; mobjflag_t mflagsapply; mobjflag2_t mflags2apply; mobjeflag_t meflagsapply; @@ -9748,7 +9810,7 @@ ML_EFFECT4 : Don't clip inside the ground mspeed = abs(lines[line].dy >> (FRACBITS - 4)); mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; if ((mmaxspeed = sides[lines[line].sidenum[0]].rowoffset >> (FRACBITS - 4)) < mspeed) - mmaxspeed = mspeed << 1; + mmaxspeed = mspeed; mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; @@ -9787,10 +9849,12 @@ ML_EFFECT4 : Don't clip inside the ground mobj->lastlook = mspeed; mobj->movecount = mobj->lastlook; - mobj->health = (FixedAngle(myaw*FRACUNIT)>>ANGLETOFINESHIFT); + mobj->angle = FixedAngle(myaw*FRACUNIT); + doangle = false; mobj->threshold = (FixedAngle(mpitch*FRACUNIT)>>ANGLETOFINESHIFT); mobj->friction = mmaxspeed; mobj->movefactor = mpinch; + mobj->movedir = 0; // Mobjtype selection switch(mobj->type) @@ -9857,7 +9921,7 @@ ML_EFFECT4 : Don't clip inside the ground mmin = mnumspokes; // Make the links the same type as the end - repeated below - if ((mobj->type != MT_CHAINPOINT) && ((lines[line].flags & ML_EFFECT2) != (mobj->type == MT_FIREBARPOINT))) // exclusive or + if ((mobj->type != MT_CHAINPOINT) && (((lines[line].flags & ML_EFFECT2) == ML_EFFECT2) != (mobj->type == MT_FIREBARPOINT))) // exclusive or { linktype = macetype; radiusfactor = 2; // Double the radius. @@ -9866,7 +9930,7 @@ ML_EFFECT4 : Don't clip inside the ground radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP|MF_NOCLIPHEIGHT)); - mflags2apply = (MF2_MACEROTATE|((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0)); + mflags2apply = ((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0); meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0); msound = ((firsttype == chainlink) ? 0 : (mwidth & 1)); @@ -9875,6 +9939,8 @@ ML_EFFECT4 : Don't clip inside the ground mphase = (FixedAngle(mphase*FRACUNIT)>>ANGLETOFINESHIFT); mroll = (FixedAngle(mroll*FRACUNIT)>>ANGLETOFINESHIFT); + hprev = mobj; + #define makemace(mobjtype, dist, moreflags2) P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ P_SetTarget(&spawnee->tracer, mobj);\ spawnee->threshold = mphase;\ @@ -9884,7 +9950,10 @@ ML_EFFECT4 : Don't clip inside the ground spawnee->angle = myaw;\ spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ spawnee->flags2 |= (mflags2apply|moreflags2);\ - spawnee->eflags |= meflagsapply + spawnee->eflags |= meflagsapply;\ + P_SetTarget(&hprev->hnext, spawnee);\ + P_SetTarget(&spawnee->hprev, hprev);\ + hprev = spawnee domaceagain: mnumspokesset = mnumspokes; @@ -10264,7 +10333,8 @@ domaceagain: } } - mobj->angle = FixedAngle(mthing->angle*FRACUNIT); + if (doangle) + mobj->angle = FixedAngle(mthing->angle*FRACUNIT); if ((mthing->options & MTF_AMBUSH) && (mthing->options & MTF_OBJECTSPECIAL) diff --git a/src/p_mobj.h b/src/p_mobj.h index c6e1bfbf2..ec25855d8 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -194,8 +194,6 @@ typedef enum MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) MF2_SHIELD = 1<<29, // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) - MF2_MACEROTATE = 1<<30, // Thinker calls P_MaceRotate around tracer - // free: to and including 1<<31 } mobjflag2_t; typedef enum From 97ddb8881d5a5af40097f8f8480200c91262a60e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 1 Apr 2018 22:05:59 +0100 Subject: [PATCH 093/122] * Remove ability to change speed of chains. * Fix ability to turn chains (still disabled by default, just at least want the option...) * Replace max speed setting with a "minimum chainlink distance" setting - if greater than zero, that many chains will not be spawned from the center outwards. Doesn't affect the head of the chain at all, since otherwise what's the point? :V --- src/p_mobj.c | 32 +++++++++----------------------- src/p_user.c | 13 +------------ 2 files changed, 10 insertions(+), 35 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 2e78c098e..17775b0ef 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6731,21 +6731,10 @@ void P_MobjThinker(mobj_t *mobj) switch (mobj->type) { - case MT_CHAINPOINT: - case MT_CHAINMACEPOINT: - if (leveltime & 1) - { - if (mobj->lastlook > mobj->movecount) - mobj->lastlook--; - /* - if (mobj->threshold > mobj->movefactor) - mobj->threshold -= FRACUNIT; - else if (mobj->threshold < mobj->movefactor) - mobj->threshold += FRACUNIT;*/ - } - /* FALLTHRU */ case MT_MACEPOINT: + case MT_CHAINMACEPOINT: case MT_SPRINGBALLPOINT: + case MT_CHAINPOINT: case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: case MT_HIDDEN_SLING: @@ -9768,7 +9757,7 @@ void P_SpawnMapThing(mapthing_t *mthing) case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: { - fixed_t mlength, mlengthset, mspeed, mphase, myaw, mpitch, mmaxspeed, mnumspokes, mnumspokesset, mpinch, mroll, mnumnospokes, mwidth, mmin, msound, radiusfactor; + fixed_t mlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mnumspokesset, mpinch, mroll, mnumnospokes, mwidth, mmin, msound, radiusfactor; angle_t mspokeangle; mobjtype_t chainlink, macetype, firsttype, linktype; boolean mdoall = true; @@ -9809,8 +9798,8 @@ ML_EFFECT4 : Don't clip inside the ground mlength = abs(lines[line].dx >> FRACBITS); mspeed = abs(lines[line].dy >> (FRACBITS - 4)); mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; - if ((mmaxspeed = sides[lines[line].sidenum[0]].rowoffset >> (FRACBITS - 4)) < mspeed) - mmaxspeed = mspeed; + if ((mminlength = sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0) + mminlength = 0; mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; @@ -9829,18 +9818,16 @@ ML_EFFECT4 : Don't clip inside the ground mpinch = mroll = mnumnospokes = mwidth = 0; CONS_Debug(DBG_GAMELOGIC, "Mace/Chain (mapthing #%s):\n" - "Length is %d\n" + "Length is %d (minus %d)\n" "Speed is %d\n" "Phase is %d\n" "Yaw is %d\n" "Pitch is %d\n" - "Max. speed is %d\n" - "No. of spokes is %d\n" + "No. of spokes is %d (%d antispokes)\n" "Pinch is %d\n" "Roll is %d\n" - "No. of antispokes is %d\n" "Width is %d\n", - sizeu1(mthingi), mlength, mspeed, mphase, myaw, mpitch, mmaxspeed, mnumspokes, mpinch, mroll, mnumnospokes, mwidth); + sizeu1(mthingi), mlength, mminlength, mspeed, mphase, myaw, mpitch, mnumspokes, mnumnospokes, mpinch, mroll, mwidth); if (mnumnospokes > 0 && (mnumnospokes < mnumspokes)) mnumnospokes = mnumspokes/mnumnospokes; @@ -9852,7 +9839,6 @@ ML_EFFECT4 : Don't clip inside the ground mobj->angle = FixedAngle(myaw*FRACUNIT); doangle = false; mobj->threshold = (FixedAngle(mpitch*FRACUNIT)>>ANGLETOFINESHIFT); - mobj->friction = mmaxspeed; mobj->movefactor = mpinch; mobj->movedir = 0; @@ -10011,7 +9997,7 @@ domaceagain: continue; // The rest of the links - while (mlengthset > 0) + while (mlengthset > mminlength) { spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); } } diff --git a/src/p_user.c b/src/p_user.c index f422e9b65..c0fd01000 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10421,21 +10421,10 @@ void P_PlayerAfterThink(player_t *player) player->secondjump = 0; player->pflags &= ~PF_THOKKED; - if (cmd->forwardmove > 0) - { - if ((player->mo->tracer->tracer->lastlook += 2) > player->mo->tracer->tracer->friction) - player->mo->tracer->tracer->lastlook = player->mo->tracer->tracer->friction; - } - else if (cmd->forwardmove < 0) - { - if ((player->mo->tracer->tracer->lastlook -= 2) < player->mo->tracer->tracer->movecount) - player->mo->tracer->tracer->lastlook = player->mo->tracer->tracer->movecount; - } - if ((player->mo->tracer->tracer->flags & MF_SLIDEME) // Noclimb on chain parameters gives this && !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode? { - player->mo->tracer->tracer->health += cmd->sidemove; + player->mo->tracer->tracer->angle += cmd->sidemove<mo->angle += cmd->sidemove< ANGLE_MAX if (!demoplayback || P_AnalogMove(player)) From 5ac70bbb7e286c1908ed5056af530940ef1c00d8 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 2 Apr 2018 01:08:31 +0100 Subject: [PATCH 094/122] * Fix multispoke mace/chainbars having problems. * Completely rework how mace/chainbars are spawned to reduce the number of matrix multiplications required EVEN FURTHER! * Reimplement the maceretry solidity stuff (effect 4). * Flip the mminlength stuff so that existing dev maps don't break badly. * Fix hacky chainbar grabbing. * Tweak height of tinychain a smidge. --- src/info.c | 2 +- src/p_inter.c | 4 +- src/p_mobj.c | 197 ++++++++++++++++++++++++++++---------------------- 3 files changed, 112 insertions(+), 91 deletions(-) diff --git a/src/info.c b/src/info.c index f11d88af8..673c18ac6 100644 --- a/src/info.c +++ b/src/info.c @@ -9195,7 +9195,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 24*FRACUNIT, // speed 24*FRACUNIT, // radius - 48*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass 1, // damage diff --git a/src/p_inter.c b/src/p_inter.c index 4c9e231fe..82187f533 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1503,10 +1503,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_flashing]) return; - if (special->movefactor && special->tracer && (angle_t)special->tracer->health != ANGLE_90 && (angle_t)special->tracer->health != ANGLE_270) + if (special->movefactor && special->tracer && (angle_t)special->tracer->angle != ANGLE_90 && (angle_t)special->tracer->angle != ANGLE_270) { // I don't expect you to understand this, Mr Bond... angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->threshold; - if ((special->movefactor > 0) == ((angle_t)special->tracer->health > ANGLE_90 && (angle_t)special->tracer->health < ANGLE_270)) + if ((special->movefactor > 0) == ((angle_t)special->tracer->angle > ANGLE_90 && (angle_t)special->tracer->angle < ANGLE_270)) ang += ANGLE_180; if (ang < ANGLE_180) return; // I expect you to die. diff --git a/src/p_mobj.c b/src/p_mobj.c index 17775b0ef..f98943d84 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6182,33 +6182,28 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) { TVector unit, baseuo, unitoffset; TVector *res; - fixed_t radius, dist, wah; + fixed_t radius, dist, mag, zstore; angle_t fa; - //boolean donetwice = false; + boolean donetwice = false; boolean dosound = false; mobj_t *mobj = center->hnext, *hnext = NULL; - // Tracer was removed. - /*if (!mobj->health) - return; - else if (!mobj->tracer) - { - P_KillMobj(mobj, NULL, NULL, 0); - return; - }*/ - INT32 rot = (baserot &= FINEMASK); INT32 prevrot = (baseprevrot &= FINEMASK); INT32 lastthreshold = FINEMASK; // needs to never be equal at start of loop fixed_t lastfriction = INT32_MIN; // ditto; almost certainly never, but... - fixed_t movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = 0; - - baseuo[3] = 0; + fixed_t movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = baseuo[3] = 0; while (mobj) { + if (!mobj->health) + { + mobj = mobj->hnext; + continue; + } + mobj->momx = mobj->momy = mobj->momz = 0; if (mobj->threshold != lastthreshold @@ -6255,6 +6250,9 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) M_Memcpy(&unit, res, sizeof(unit)); res = VectorMatrixMultiply(unit, *RotateZMatrix(center->angle)); M_Memcpy(&unit, res, sizeof(unit)); + + lastthreshold = mobj->threshold; + lastfriction = mobj->friction; } if (dosound && (mobj->flags2 & MF2_BOSSNOTRAP)) @@ -6277,9 +6275,6 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) M_Memcpy(&baseuo, res, sizeof(unit)); res = VectorMatrixMultiply(baseuo, *RotateZMatrix(center->angle)); M_Memcpy(&baseuo, res, sizeof(unit)); - - lastthreshold = mobj->threshold; - lastfriction = mobj->friction; } if (mobj->movefactor) @@ -6293,58 +6288,78 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = 0; } - //maceretry: - hnext = mobj->hnext; // just in case the mobj is removed + // Radius of the link's rotation. + mag = (dist * mobj->movecount) + mobj->extravalue1; + +maceretry: P_UnsetThingPosition(mobj); - // Radius of the link's rotation. - wah = (dist * mobj->movecount) + center->extravalue1; + mobj->x = center->x; + mobj->y = center->y; + mobj->z = center->z; // Add on the appropriate distances to the center's co-ordinates. - mobj->x = center->x + FixedMul(unit[0], wah) + unitoffset[0]; - mobj->y = center->y + FixedMul(unit[1], wah) + unitoffset[1]; - mobj->z = center->z + FixedMul(unit[2], wah) + unitoffset[2]; + if (mag) + { + zstore = FixedMul(unit[2], mag); + mobj->x += FixedMul(unit[0], mag); + mobj->y += FixedMul(unit[1], mag); + } + else + zstore = 0; + zstore += unitoffset[2]; + + mobj->x += unitoffset[0]; + mobj->y += unitoffset[1]; // Cut the height to align the link with the axis. if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN) - mobj->z -= P_MobjFlip(mobj)*mobj->height/4; + zstore -= P_MobjFlip(mobj)*mobj->height/4; else - mobj->z -= P_MobjFlip(mobj)*mobj->height/2; + zstore -= P_MobjFlip(mobj)*mobj->height/2; + + mobj->z += zstore; + +#if 0 // toaster's testing flashie! + if (!mobj->threshold && !mobj->friction && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. + mobj->flags2 ^= MF2_DONTDRAW; +#endif P_SetThingPosition(mobj); + if (!mag || donetwice || P_MobjWasRemoved(mobj)) + goto cont; + + if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) + goto cont; + + if ((fa = ((mobj->tracer->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it + goto cont; + + if (mobj->subsector->sector->ffloors) + P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2); + + // Variable reuse + if (mobj->floorz > mobj->z) + dist = (mobj->floorz - mobj->tracer->z); + else if (mobj->ceilingz < mobj->z) + dist = (mobj->ceilingz - mobj->tracer->z); + else + goto cont; + + if ((dist = FixedDiv(dist, zstore)) > FRACUNIT) + goto cont; + + mag = FixedMul(mag, dist); + donetwice = true; + dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); + goto maceretry; + +cont: mobj = hnext; } - - /*if (donetwice || P_MobjWasRemoved(mobj)) - return; - - if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) - return; - - if ((fa = ((mobj->tracer->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it - return; - - if (mobj->subsector->sector->ffloors) - P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2); - - // Variable reuse - if (mobj->floorz > mobj->z) - dist = (mobj->floorz - mobj->tracer->z); - else if (mobj->ceilingz < mobj->z) - dist = (mobj->ceilingz - mobj->tracer->z); - else - return; - - if ((dist = FixedDiv(dist, v[2])) > FRACUNIT) - return; - - radius = FixedMul(radius, dist); - donetwice = true; - dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); - goto maceretry;*/ } static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) @@ -9757,10 +9772,10 @@ void P_SpawnMapThing(mapthing_t *mthing) case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: { - fixed_t mlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mnumspokesset, mpinch, mroll, mnumnospokes, mwidth, mmin, msound, radiusfactor; + fixed_t mlength, mlengthmax, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor; angle_t mspokeangle; mobjtype_t chainlink, macetype, firsttype, linktype; - boolean mdoall = true; + boolean mdoall = true, mdocenter; mobj_t *spawnee, *hprev; mobjflag_t mflagsapply; mobjflag2_t mflags2apply; @@ -9798,7 +9813,7 @@ ML_EFFECT4 : Don't clip inside the ground mlength = abs(lines[line].dx >> FRACBITS); mspeed = abs(lines[line].dy >> (FRACBITS - 4)); mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; - if ((mminlength = sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0) + if ((mminlength = -sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0) mminlength = 0; mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; @@ -9931,7 +9946,7 @@ ML_EFFECT4 : Don't clip inside the ground P_SetTarget(&spawnee->tracer, mobj);\ spawnee->threshold = mphase;\ spawnee->friction = mroll;\ - spawnee->movefactor = mwidth;\ + spawnee->movefactor = mwidthset;\ spawnee->movecount = dist;\ spawnee->angle = myaw;\ spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ @@ -9941,14 +9956,10 @@ ML_EFFECT4 : Don't clip inside the ground P_SetTarget(&spawnee->hprev, hprev);\ hprev = spawnee -domaceagain: - mnumspokesset = mnumspokes; - - if (mdoall && lines[line].flags & ML_EFFECT3) // Innermost mace/link - { spawnee = makemace(macetype, 0, MF2_AMBUSH); } + mdocenter = (lines[line].flags & ML_EFFECT3); // The actual spawning of spokes - while (mnumspokesset-- > 0) + while (mnumspokes-- > 0) { // Offsets if (lines[line].flags & ML_EFFECT1) // Swinging @@ -9956,13 +9967,13 @@ domaceagain: else // Spinning mphase = (mphase - mspokeangle) & FINEMASK; - if (mnumnospokes && !(mnumspokesset % mnumnospokes)) // Skipping a "missing" spoke + if (mnumnospokes && !(mnumspokes % mnumnospokes)) // Skipping a "missing" spoke { if (mobj->type != MT_CHAINMACEPOINT) continue; firsttype = linktype = chainlink; - mlengthset = 1 + (mlength - 1)*radiusfactor; + mlengthmax = 1 + (mlength - 1)*radiusfactor; radiusfactor = 1; } else @@ -9984,34 +9995,44 @@ domaceagain: firsttype = macetype; } - mlengthset = mlength; + mlengthmax = mlength; } - // Outermost mace/link - spawnee = makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); + mwidthset = mwidth; + mdoall = true; + while (1) + { + mlengthset = mlengthmax; - if (mspeed && (mwidth == msound) && !(mthing->options & MTF_OBJECTSPECIAL) && mnumspokesset <= mmin) // Can it make a sound? - spawnee->flags2 |= MF2_BOSSNOTRAP; + if (mdocenter) // Innermost mace/link + { + spawnee = makemace(macetype, 0, 0); + } - if (!mdoall || !linktype) - continue; + // Outermost mace/link + spawnee = makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); - // The rest of the links - while (mlengthset > mminlength) - { spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); } - } + if (mspeed && (mwidthset == msound) && !(mthing->options & MTF_OBJECTSPECIAL) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; - if (mwidth > 0) - { - mwidth *= -1; - goto domaceagain; - } - else if (mwidth != 0) - { - if ((mwidth = -(mwidth + ((firsttype == chainlink) ? 1 : 2))) < 0) - break; - mdoall = false; - goto domaceagain; + if (mdoall && linktype) + { + // The rest of the links + while (mlengthset > mminlength) + { + spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); + } + } + + if (mwidthset > 0) + mwidthset *= -1; + else if (!mwidthset + || ((mwidthset = -(mwidthset + ((firsttype == chainlink) ? 1 : 2))) < 0)) + break; + else + mdocenter = mdoall = false; + + } } #undef makemace From 0102da824e462a344ef38c8a868bbe51a3eaea78 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 2 Apr 2018 01:20:32 +0100 Subject: [PATCH 095/122] Make the h-chain repairing safer. --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index f98943d84..4e1356d61 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8673,9 +8673,9 @@ void P_RemoveMobj(mobj_t *mobj) // Remove any references to other mobjs. P_SetTarget(&mobj->target, P_SetTarget(&mobj->tracer, NULL)); - if (mobj->hnext) + if (mobj->hnext && !P_MobjWasRemoved(mobj->hnext)) P_SetTarget(&mobj->hnext->hprev, mobj->hprev); - if (mobj->hprev) + if (mobj->hprev && !P_MobjWasRemoved(mobj->hprev)) P_SetTarget(&mobj->hprev->hnext, mobj->hnext); P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL)); From 4051ae8915525d850b754ee12e3e6895ffdfa509 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 2 Apr 2018 21:36:12 +0100 Subject: [PATCH 096/122] * Revamp mace creation again to potentially serve as the foundation for further optimisation (and also not rely on a while (1) loop, which easily went wrong several times whilst I was making changes to it). * Fix minor typoes and other small tweaks in the P_MaceRotate function, which I'm probably about to rewrite again anyways... --- src/p_mobj.c | 123 +++++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 59 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4e1356d61..63d3aa666 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6184,8 +6184,7 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) TVector *res; fixed_t radius, dist, mag, zstore; angle_t fa; - boolean donetwice = false; - boolean dosound = false; + boolean donetwice, dosound = false; mobj_t *mobj = center->hnext, *hnext = NULL; INT32 rot = (baserot &= FINEMASK); @@ -6268,13 +6267,13 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) if (!baseuo[3]) { baseuo[1] = FRACUNIT; - baseuo[3] = center->scale; baseuo[0] = baseuo[2] = 0; + baseuo[3] = center->scale; res = VectorMatrixMultiply(baseuo, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); - M_Memcpy(&baseuo, res, sizeof(unit)); + M_Memcpy(&baseuo, res, sizeof(baseuo)); res = VectorMatrixMultiply(baseuo, *RotateZMatrix(center->angle)); - M_Memcpy(&baseuo, res, sizeof(unit)); + M_Memcpy(&baseuo, res, sizeof(baseuo)); } if (mobj->movefactor) @@ -6293,6 +6292,7 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) // Radius of the link's rotation. mag = (dist * mobj->movecount) + mobj->extravalue1; + donetwice = false; maceretry: P_UnsetThingPosition(mobj); @@ -6303,13 +6303,12 @@ maceretry: // Add on the appropriate distances to the center's co-ordinates. if (mag) { - zstore = FixedMul(unit[2], mag); mobj->x += FixedMul(unit[0], mag); mobj->y += FixedMul(unit[1], mag); + zstore = FixedMul(unit[2], mag) + unitoffset[2]; } else - zstore = 0; - zstore += unitoffset[2]; + zstore = unitoffset[2]; mobj->x += unitoffset[0]; mobj->y += unitoffset[1]; @@ -6323,7 +6322,7 @@ maceretry: mobj->z += zstore; #if 0 // toaster's testing flashie! - if (!mobj->threshold && !mobj->friction && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. + if (!donetwice && mobj->movefactor != -5 && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. mobj->flags2 ^= MF2_DONTDRAW; #endif @@ -9772,11 +9771,11 @@ void P_SpawnMapThing(mapthing_t *mthing) case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: { - fixed_t mlength, mlengthmax, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor; + fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor; angle_t mspokeangle; mobjtype_t chainlink, macetype, firsttype, linktype; - boolean mdoall = true, mdocenter; - mobj_t *spawnee, *hprev; + boolean mdosound, mdocenter; + mobj_t *spawnee = NULL, *hprev = mobj; mobjflag_t mflagsapply; mobjflag2_t mflags2apply; mobjeflag_t meflagsapply; @@ -9815,6 +9814,8 @@ ML_EFFECT4 : Don't clip inside the ground mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; if ((mminlength = -sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0) mminlength = 0; + else if (mminlength > mlength-1) + mminlength = mlength-1; mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; @@ -9940,22 +9941,23 @@ ML_EFFECT4 : Don't clip inside the ground mphase = (FixedAngle(mphase*FRACUNIT)>>ANGLETOFINESHIFT); mroll = (FixedAngle(mroll*FRACUNIT)>>ANGLETOFINESHIFT); - hprev = mobj; - -#define makemace(mobjtype, dist, moreflags2) P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ - P_SetTarget(&spawnee->tracer, mobj);\ - spawnee->threshold = mphase;\ - spawnee->friction = mroll;\ - spawnee->movefactor = mwidthset;\ - spawnee->movecount = dist;\ - spawnee->angle = myaw;\ - spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ - spawnee->flags2 |= (mflags2apply|moreflags2);\ - spawnee->eflags |= meflagsapply;\ - P_SetTarget(&hprev->hnext, spawnee);\ - P_SetTarget(&spawnee->hprev, hprev);\ - hprev = spawnee +#define makemace(mobjtype, dist, moreflags2) {\ + spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ + P_SetTarget(&spawnee->tracer, mobj);\ + spawnee->threshold = mphase;\ + spawnee->friction = mroll;\ + spawnee->movefactor = mwidthset;\ + spawnee->movecount = dist;\ + spawnee->angle = myaw;\ + spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ + spawnee->flags2 |= (mflags2apply|moreflags2);\ + spawnee->eflags |= meflagsapply;\ + P_SetTarget(&hprev->hnext, spawnee);\ + P_SetTarget(&spawnee->hprev, hprev);\ + hprev = spawnee;\ +} + mdosound = (mspeed && !(mthing->options & MTF_OBJECTSPECIAL)); mdocenter = (lines[line].flags & ML_EFFECT3); // The actual spawning of spokes @@ -9973,7 +9975,7 @@ ML_EFFECT4 : Don't clip inside the ground continue; firsttype = linktype = chainlink; - mlengthmax = 1 + (mlength - 1)*radiusfactor; + mmaxlength = 1 + (mlength - 1)*radiusfactor; radiusfactor = 1; } else @@ -9995,43 +9997,46 @@ ML_EFFECT4 : Don't clip inside the ground firsttype = macetype; } - mlengthmax = mlength; + mmaxlength = mlength; } mwidthset = mwidth; - mdoall = true; - while (1) + //fixed_t base = 0; + mlengthset = mminlength; + + if (mdocenter) // Innermost mace/link + makemace(macetype, 0, 0); + + //base = mlengthset*((mobjinfo[macetype].speed) ? mobjinfo[macetype].speed : mobjinfo[MT_SMALLMACECHAIN].speed); + + while ((++mlengthset) < mmaxlength) + makemace(linktype, radiusfactor*mlengthset, 0); + + // Outermost mace/link + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + + if (!mwidth) { - mlengthset = mlengthmax; + if (mdosound && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + else + { + while ((mwidthset -= ((firsttype == chainlink) ? 1 : 2)) > -mwidth) + { + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + + // Outermost mace/link again! + makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); + + while (mlengthset > mminlength) + makemace(linktype, radiusfactor*(mlengthset--), 0); if (mdocenter) // Innermost mace/link - { - spawnee = makemace(macetype, 0, 0); - } - - // Outermost mace/link - spawnee = makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); - - if (mspeed && (mwidthset == msound) && !(mthing->options & MTF_OBJECTSPECIAL) && mnumspokes <= mmin) // Can it make a sound? - spawnee->flags2 |= MF2_BOSSNOTRAP; - - if (mdoall && linktype) - { - // The rest of the links - while (mlengthset > mminlength) - { - spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); - } - } - - if (mwidthset > 0) - mwidthset *= -1; - else if (!mwidthset - || ((mwidthset = -(mwidthset + ((firsttype == chainlink) ? 1 : 2))) < 0)) - break; - else - mdocenter = mdoall = false; - + makemace(macetype, 0, 0); } } From 156cc031ea22d59296644c7f5d2c836746ad0937 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 3 Apr 2018 01:10:10 +0100 Subject: [PATCH 097/122] * Optimise them even further... AGAIN! Using an offset-based system rather than a multiplication-based one... * Again, tweak the spawning code to take maximum advantage of these gains. * Fix potential crashes with MT_NULL mace/chain types supplied. * #ifdef out the height-clipping code. It needs more TLC than I can give it right now, and the existing behaviour is less obviously broken (sadly enough). * Fix chainmace points, which were apparently broken without anyone realising. --- src/p_mobj.c | 203 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 129 insertions(+), 74 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 63d3aa666..286357964 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6180,11 +6180,11 @@ static void P_NightsItemChase(mobj_t *thing) // void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) { - TVector unit, baseuo, unitoffset; + TVector unit_lengthways, unit_sideways, pos_lengthways, pos_sideways; TVector *res; - fixed_t radius, dist, mag, zstore; + fixed_t radius, dist, zstore; angle_t fa; - boolean donetwice, dosound = false; + boolean dosound = false; mobj_t *mobj = center->hnext, *hnext = NULL; INT32 rot = (baserot &= FINEMASK); @@ -6193,7 +6193,7 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) INT32 lastthreshold = FINEMASK; // needs to never be equal at start of loop fixed_t lastfriction = INT32_MIN; // ditto; almost certainly never, but... - fixed_t movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = baseuo[3] = 0; + dist = pos_sideways[0] = pos_sideways[1] = pos_sideways[2] = pos_sideways[3] = unit_sideways[3] = pos_lengthways[0] = pos_lengthways[1] = pos_lengthways[2] = pos_lengthways[3] = 0; while (mobj) { @@ -6211,10 +6211,15 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) rot = (baserot + mobj->threshold) & FINEMASK; prevrot = (baseprevrot + mobj->threshold) & FINEMASK; - fa = (FixedAngle(center->movefactor*FRACUNIT) >> ANGLETOFINESHIFT); // mpinch - radius = FINECOSINE(fa); - unit[1] = -FixedMul(FINESINE(fa), radius); - unit[3] = center->scale; + pos_lengthways[0] = pos_lengthways[1] = pos_lengthways[2] = pos_lengthways[3] = 0; + + dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); + dist = ((center->scale == FRACUNIT) ? dist : FixedMul(dist, center->scale)); + + fa = (FixedAngle(center->movefactor*FRACUNIT) >> ANGLETOFINESHIFT); + radius = FixedMul(dist, FINECOSINE(fa)); + unit_lengthways[1] = -FixedMul(dist, FINESINE(fa)); + unit_lengthways[3] = FRACUNIT; // Swinging Chain. if (center->flags2 & MF2_STRONGBOX) @@ -6224,12 +6229,11 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) if ((prevswingmag > 0) != (swingmag > 0)) // just passed its lowest point dosound = true; - //S_StartSound(mobj, mobj->info->activesound); fa = ((FixedAngle(swingmag) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK; - unit[0] = FixedMul(FINESINE(fa), -radius); - unit[2] = FixedMul(FINECOSINE(fa), -radius); + unit_lengthways[0] = FixedMul(FINESINE(fa), -radius); + unit_lengthways[2] = FixedMul(FINECOSINE(fa), -radius); } // Rotating Chain. else @@ -6240,15 +6244,15 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) if (!(prevfa > (FINEMASK/2)) && (fa > (FINEMASK/2))) // completed a full swing dosound = true; - unit[0] = FixedMul(FINECOSINE(fa), radius); - unit[2] = FixedMul(FINESINE(fa), radius); + unit_lengthways[0] = FixedMul(FINECOSINE(fa), radius); + unit_lengthways[2] = FixedMul(FINESINE(fa), radius); } // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(unit, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); - M_Memcpy(&unit, res, sizeof(unit)); - res = VectorMatrixMultiply(unit, *RotateZMatrix(center->angle)); - M_Memcpy(&unit, res, sizeof(unit)); + res = VectorMatrixMultiply(unit_lengthways, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&unit_lengthways, res, sizeof(unit_lengthways)); + res = VectorMatrixMultiply(unit_lengthways, *RotateZMatrix(center->angle)); + M_Memcpy(&unit_lengthways, res, sizeof(unit_lengthways)); lastthreshold = mobj->threshold; lastfriction = mobj->friction; @@ -6260,40 +6264,65 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) dosound = false; } - dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); - - if (dist*mobj->movefactor != movefac) + if (pos_sideways[3] != mobj->movefactor) { - if (!baseuo[3]) + if (!unit_sideways[3]) { - baseuo[1] = FRACUNIT; - baseuo[0] = baseuo[2] = 0; - baseuo[3] = center->scale; + unit_sideways[1] = dist; + unit_sideways[0] = unit_sideways[2] = 0; + unit_sideways[3] = FRACUNIT; - res = VectorMatrixMultiply(baseuo, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); - M_Memcpy(&baseuo, res, sizeof(baseuo)); - res = VectorMatrixMultiply(baseuo, *RotateZMatrix(center->angle)); - M_Memcpy(&baseuo, res, sizeof(baseuo)); + res = VectorMatrixMultiply(unit_sideways, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&unit_sideways, res, sizeof(unit_sideways)); + res = VectorMatrixMultiply(unit_sideways, *RotateZMatrix(center->angle)); + M_Memcpy(&unit_sideways, res, sizeof(unit_sideways)); } - if (mobj->movefactor) + if (pos_sideways[3] > mobj->movefactor) { - movefac = dist*mobj->movefactor; - unitoffset[0] = FixedMul(movefac, baseuo[0]); - unitoffset[1] = FixedMul(movefac, baseuo[1]); - unitoffset[2] = FixedMul(movefac, baseuo[2]); + do + { + pos_sideways[0] -= unit_sideways[0]; + pos_sideways[1] -= unit_sideways[1]; + pos_sideways[2] -= unit_sideways[2]; + } + while ((--pos_sideways[3]) != mobj->movefactor); } else - movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = 0; + { + do + { + pos_sideways[0] += unit_sideways[0]; + pos_sideways[1] += unit_sideways[1]; + pos_sideways[2] += unit_sideways[2]; + } + while ((++pos_sideways[3]) != mobj->movefactor); + } } hnext = mobj->hnext; // just in case the mobj is removed - // Radius of the link's rotation. - mag = (dist * mobj->movecount) + mobj->extravalue1; + if (pos_lengthways[3] > mobj->movecount) + { + do + { + pos_lengthways[0] -= unit_lengthways[0]; + pos_lengthways[1] -= unit_lengthways[1]; + pos_lengthways[2] -= unit_lengthways[2]; + } + while ((--pos_lengthways[3]) != mobj->movecount); + } + else if (pos_lengthways[3] < mobj->movecount) + { + do + { + pos_lengthways[0] += unit_lengthways[0]; + pos_lengthways[1] += unit_lengthways[1]; + pos_lengthways[2] += unit_lengthways[2]; + } + while ((++pos_lengthways[3]) != mobj->movecount); + } - donetwice = false; -maceretry: P_UnsetThingPosition(mobj); mobj->x = center->x; @@ -6301,17 +6330,17 @@ maceretry: mobj->z = center->z; // Add on the appropriate distances to the center's co-ordinates. - if (mag) + if (pos_lengthways[3]) { - mobj->x += FixedMul(unit[0], mag); - mobj->y += FixedMul(unit[1], mag); - zstore = FixedMul(unit[2], mag) + unitoffset[2]; + mobj->x += pos_lengthways[0]; + mobj->y += pos_lengthways[1]; + zstore = pos_lengthways[2] + pos_sideways[2]; } else - zstore = unitoffset[2]; + zstore = pos_sideways[2]; - mobj->x += unitoffset[0]; - mobj->y += unitoffset[1]; + mobj->x += pos_sideways[0]; + mobj->y += pos_sideways[1]; // Cut the height to align the link with the axis. if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN) @@ -6322,41 +6351,40 @@ maceretry: mobj->z += zstore; #if 0 // toaster's testing flashie! - if (!donetwice && mobj->movefactor != -5 && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. + if (!(mobj->movecount & 1) && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. mobj->flags2 ^= MF2_DONTDRAW; #endif P_SetThingPosition(mobj); - if (!mag || donetwice || P_MobjWasRemoved(mobj)) +#if 0 // toaster's height-clipping dealie! + if (!pos_lengthways[3] || P_MobjWasRemoved(mobj) || (mobj->flags & MF_NOCLIPHEIGHT)) goto cont; - if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) - goto cont; - - if ((fa = ((mobj->tracer->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it + if ((fa = ((center->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it goto cont; if (mobj->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2); - // Variable reuse if (mobj->floorz > mobj->z) - dist = (mobj->floorz - mobj->tracer->z); + zstore = (mobj->floorz - zstore); else if (mobj->ceilingz < mobj->z) - dist = (mobj->ceilingz - mobj->tracer->z); + zstore = (mobj->ceilingz - mobj->height - zstore); else goto cont; - if ((dist = FixedDiv(dist, zstore)) > FRACUNIT) - goto cont; + zstore = FixedDiv(zstore, dist); // Still needs work... scaling factor is wrong! - mag = FixedMul(mag, dist); - donetwice = true; - dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); - goto maceretry; + P_UnsetThingPosition(mobj); + + mobj->x -= FixedMul(unit_lengthways[0], zstore); + mobj->y -= FixedMul(unit_lengthways[1], zstore); + + P_SetThingPosition(mobj); cont: +#endif mobj = hnext; } } @@ -9771,7 +9799,7 @@ void P_SpawnMapThing(mapthing_t *mthing) case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: { - fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor; + fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor, widthfactor; angle_t mspokeangle; mobjtype_t chainlink, macetype, firsttype, linktype; boolean mdosound, mdocenter; @@ -9848,7 +9876,7 @@ ML_EFFECT4 : Don't clip inside the ground if (mnumnospokes > 0 && (mnumnospokes < mnumspokes)) mnumnospokes = mnumspokes/mnumnospokes; else - mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes - 1) : 0); + mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes) : 0); mobj->lastlook = mspeed; mobj->movecount = mobj->lastlook; @@ -9894,7 +9922,7 @@ ML_EFFECT4 : Don't clip inside the ground break; } - if (!macetype) + if (!macetype && !chainlink) break; if (mobj->type != MT_CHAINPOINT) @@ -9958,7 +9986,7 @@ ML_EFFECT4 : Don't clip inside the ground } mdosound = (mspeed && !(mthing->options & MTF_OBJECTSPECIAL)); - mdocenter = (lines[line].flags & ML_EFFECT3); + mdocenter = (macetype && (lines[line].flags & ML_EFFECT3)); // The actual spawning of spokes while (mnumspokes-- > 0) @@ -9999,6 +10027,7 @@ ML_EFFECT4 : Don't clip inside the ground mmaxlength = mlength; } + widthfactor = ((firsttype == chainlink) ? 1 : 2); mwidthset = mwidth; //fixed_t base = 0; @@ -10009,11 +10038,18 @@ ML_EFFECT4 : Don't clip inside the ground //base = mlengthset*((mobjinfo[macetype].speed) ? mobjinfo[macetype].speed : mobjinfo[MT_SMALLMACECHAIN].speed); - while ((++mlengthset) < mmaxlength) - makemace(linktype, radiusfactor*mlengthset, 0); + // Out from the center... + if (linktype) + { + while ((++mlengthset) < mmaxlength) + makemace(linktype, radiusfactor*mlengthset, 0); + } + else + mlengthset = mmaxlength; // Outermost mace/link - makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (firsttype) + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); if (!mwidth) { @@ -10022,18 +10058,37 @@ ML_EFFECT4 : Don't clip inside the ground } else { - while ((mwidthset -= ((firsttype == chainlink) ? 1 : 2)) > -mwidth) + // Across the bar! + if (!firsttype) + mwidthset = -mwidth; + else if (mwidth > 0) { - makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); - if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? - spawnee->flags2 |= MF2_BOSSNOTRAP; + while ((mwidthset -= widthfactor) > -mwidth) + { + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } } + else + { + while ((mwidthset += widthfactor) < -mwidth) + { + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + } + mwidth = -mwidth; // Outermost mace/link again! - makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); + if (firsttype) + makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); - while (mlengthset > mminlength) - makemace(linktype, radiusfactor*(mlengthset--), 0); + // ...and then back into the center! + if (linktype) + while (mlengthset > mminlength) + makemace(linktype, radiusfactor*(mlengthset--), 0); if (mdocenter) // Innermost mace/link makemace(macetype, 0, 0); From 4f3f647f5b31266445307a470a3f771bfe567721 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 3 Apr 2018 01:46:42 +0100 Subject: [PATCH 098/122] A minor assortment of changes. --- src/p_inter.c | 6 +++--- src/p_mobj.c | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 82187f533..88fa7d57b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1503,10 +1503,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_flashing]) return; - if (special->movefactor && special->tracer && (angle_t)special->tracer->angle != ANGLE_90 && (angle_t)special->tracer->angle != ANGLE_270) + if (special->movefactor && special->tracer && special->tracer->angle != ANGLE_90 && special->tracer->angle != ANGLE_270) { // I don't expect you to understand this, Mr Bond... - angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->threshold; - if ((special->movefactor > 0) == ((angle_t)special->tracer->angle > ANGLE_90 && (angle_t)special->tracer->angle < ANGLE_270)) + angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->angle; + if ((special->movefactor > 0) == (special->tracer->angle > ANGLE_90 && special->tracer->angle < ANGLE_270)) ang += ANGLE_180; if (ang < ANGLE_180) return; // I expect you to die. diff --git a/src/p_mobj.c b/src/p_mobj.c index 286357964..3660f1e5e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9959,6 +9959,8 @@ ML_EFFECT4 : Don't clip inside the ground else radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); + widthfactor = ((firsttype == chainlink) ? 1 : 2); + mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP|MF_NOCLIPHEIGHT)); mflags2apply = ((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0); meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0); @@ -10004,7 +10006,7 @@ ML_EFFECT4 : Don't clip inside the ground firsttype = linktype = chainlink; mmaxlength = 1 + (mlength - 1)*radiusfactor; - radiusfactor = 1; + radiusfactor = widthfactor = 1; } else { @@ -10023,21 +10025,18 @@ ML_EFFECT4 : Don't clip inside the ground } firsttype = macetype; + widthfactor = 2; } mmaxlength = mlength; } - widthfactor = ((firsttype == chainlink) ? 1 : 2); mwidthset = mwidth; - //fixed_t base = 0; mlengthset = mminlength; if (mdocenter) // Innermost mace/link makemace(macetype, 0, 0); - //base = mlengthset*((mobjinfo[macetype].speed) ? mobjinfo[macetype].speed : mobjinfo[MT_SMALLMACECHAIN].speed); - // Out from the center... if (linktype) { From 759ea8cb4200e1c99e9450595965db23c798e8dc Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 3 Apr 2018 16:11:07 -0400 Subject: [PATCH 099/122] Indentation fixup --- src/d_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index ea24430ec..b8f24e4b6 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1230,7 +1230,9 @@ void D_SRB2Main(void) nomidimusic = nodigimusic = true; } else - CONS_Printf("S_Init(): Setting up sound.\n"); + { + CONS_Printf("S_Init(): Setting up sound.\n"); + } if (M_CheckParm("-nosound")) nosound = true; if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic @@ -1245,7 +1247,7 @@ void D_SRB2Main(void) I_StartupSound(); I_InitMusic(); S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); - + CONS_Printf("ST_Init(): Init status bar.\n"); ST_Init(); From 8bd91bd2f2772b4c4392b161f846fd3029eea09a Mon Sep 17 00:00:00 2001 From: Wolfy Date: Thu, 5 Apr 2018 03:23:27 -0500 Subject: [PATCH 100/122] THZ Hardcoding Feel free to reorganize as necessary. --- src/dehacked.c | 20 ++++++++++ src/info.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ src/info.h | 22 +++++++++++ src/p_mobj.c | 11 ++++++ 4 files changed, 155 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index c172549e1..b2d3bff3a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4700,6 +4700,23 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // THZ Plant "S_THZFLOWERA", "S_THZFLOWERB", + "S_YELLOWSPINFLOWER", + + // THZ Tree + "S_THZTREE", + "S_THZTREEBRANCH1", + "S_THZTREEBRANCH2", + "S_THZTREEBRANCH3", + "S_THZTREEBRANCH4", + "S_THZTREEBRANCH5", + "S_THZTREEBRANCH6", + "S_THZTREEBRANCH7", + "S_THZTREEBRANCH8", + "S_THZTREEBRANCH9", + "S_THZTREEBRANCH10", + "S_THZTREEBRANCH11", + "S_THZTREEBRANCH12", + "S_THZTREEBRANCH13", // THZ Alarm "S_ALARM1", @@ -6129,7 +6146,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Techno Hill Scenery "MT_THZFLOWER1", + "MT_THZTREE", + "MT_THZTREEBRANCH", "MT_THZFLOWER2", + "MT_YELLOWSPINFLOWER", "MT_ALARM", // Deep Sea Scenery diff --git a/src/info.c b/src/info.c index acb12379a..256d430ae 100644 --- a/src/info.c +++ b/src/info.c @@ -191,7 +191,9 @@ char sprnames[NUMSPRITES + 1][5] = // Techno Hill Scenery "THZP", // Techno Hill Zone Plant + "THZT", // THZ Tree "FWR5", // Another one + "FWR6", "ALRM", // THZ2 Alarm // Deep Sea Scenery @@ -1911,6 +1913,25 @@ state_t states[NUMSTATES] = {SPR_THZP, FF_ANIMATE, -1, {NULL}, 7, 4, S_NULL}, // S_THZFLOWERA {SPR_FWR5, FF_ANIMATE, -1, {NULL}, 19, 2, S_NULL}, // S_THZFLOWERB + {SPR_FWR6, FF_ANIMATE, 0, {NULL}, 19, 2, S_NULL}, // S_YELLOWSPINFLOWER + + // THZ Tree + {SPR_THZT, 0, -1, {NULL}, 0, 0, S_THZTREE}, // S_THZTREE + + // THZ Tree Branches + {SPR_THZT, 1|FF_PAPERSPRITE, 40, {NULL}, 0, 0, S_THZTREEBRANCH2}, // S_THZTREEBRANCH1 + {SPR_THZT, 2|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH3}, // S_THZTREEBRANCH2 + {SPR_THZT, 3|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH4}, // S_THZTREEBRANCH3 + {SPR_THZT, 4|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH5}, // S_THZTREEBRANCH4 + {SPR_THZT, 5|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH6}, // S_THZTREEBRANCH5 + {SPR_THZT, 6|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH7}, // S_THZTREEBRANCH6 + {SPR_THZT, 7|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH8}, // S_THZTREEBRANCH7 + {SPR_THZT, 8|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH9}, // S_THZTREEBRANCH8 + {SPR_THZT, 9|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH10}, // S_THZTREEBRANCH9 + {SPR_THZT, 10|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH11},// S_THZTREEBRANCH10 + {SPR_THZT, 11|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH12},// S_THZTREEBRANCH11 + {SPR_THZT, 12|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH13},// S_THZTREEBRANCH12 + {SPR_THZT, 13|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH1}, // S_THZTREEBRANCH13 // THZ Alarm {SPR_ALRM, FF_FULLBRIGHT, 35, {A_Scream}, 0, 0, S_ALARM1}, // S_ALARM1 @@ -8583,6 +8604,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_THZTREE + 904, // doomednum + S_THZTREE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 16*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_THZTREEBRANCH + -1, // doomednum + S_THZTREEBRANCH1,// spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 1*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_SCENERY, // flags + S_NULL // raisestate + }, + { // MT_THZFLOWER2 902, // doomednum S_THZFLOWERB, // spawnstate @@ -8609,6 +8684,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, + + { // MT_YELLOWSPINFLOWER + 903, // doomednum + S_YELLOWSPINFLOWER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 16*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, { // MT_ALARM 901, // doomednum diff --git a/src/info.h b/src/info.h index 35a3f5f15..2d368094d 100644 --- a/src/info.h +++ b/src/info.h @@ -390,7 +390,9 @@ typedef enum sprite // Techno Hill Scenery SPR_THZP, // THZ1 Flower + SPR_THZT, // THZ Tree SPR_FWR5, // Another flower + SPR_FWR6, SPR_ALRM, // THZ2 Alarm // Deep Sea Scenery @@ -2019,6 +2021,23 @@ typedef enum state // THZ Plant S_THZFLOWERA, S_THZFLOWERB, + S_YELLOWSPINFLOWER, + + // THZ Tree + S_THZTREE, + S_THZTREEBRANCH1, + S_THZTREEBRANCH2, + S_THZTREEBRANCH3, + S_THZTREEBRANCH4, + S_THZTREEBRANCH5, + S_THZTREEBRANCH6, + S_THZTREEBRANCH7, + S_THZTREEBRANCH8, + S_THZTREEBRANCH9, + S_THZTREEBRANCH10, + S_THZTREEBRANCH11, + S_THZTREEBRANCH12, + S_THZTREEBRANCH13, // THZ Alarm S_ALARM1, @@ -3468,7 +3487,10 @@ typedef enum mobj_type // Techno Hill Scenery MT_THZFLOWER1, + MT_THZTREE, + MT_THZTREEBRANCH, MT_THZFLOWER2, + MT_YELLOWSPINFLOWER, MT_ALARM, // Deep Sea Scenery diff --git a/src/p_mobj.c b/src/p_mobj.c index 8695d57e4..cfc43cda2 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8433,6 +8433,17 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BLUETEAMRING: mobj->color = skincolor_blueteam; break; + case MT_THZTREE: + { + mobj_t *branch1 = P_SpawnMobj(mobj->x+FRACUNIT, mobj->y, mobj->z, MT_THZTREEBRANCH); + mobj_t *branch2 = P_SpawnMobj(mobj->x, mobj->y+FRACUNIT, mobj->z, MT_THZTREEBRANCH); + mobj_t *branch3 = P_SpawnMobj(mobj->x-FRACUNIT, mobj->y, mobj->z, MT_THZTREEBRANCH); + + branch1->angle = mobj->angle + ANGLE_22h; + branch2->angle = mobj->angle + ANGLE_157h; + branch3->angle = mobj->angle + ANGLE_270; + } + break; case MT_RING: case MT_COIN: case MT_BLUEBALL: From ca8e14d5e9137e3fb838731c98d96025a9f3426b Mon Sep 17 00:00:00 2001 From: Wolfy Date: Thu, 5 Apr 2018 12:49:39 -0500 Subject: [PATCH 101/122] Revert "THZ Hardcoding" This reverts commit 8bd91bd2f2772b4c4392b161f846fd3029eea09a. Note to self: read through the fucking merge requests --- src/dehacked.c | 20 ---------- src/info.c | 102 ------------------------------------------------- src/info.h | 22 ----------- src/p_mobj.c | 11 ------ 4 files changed, 155 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b2d3bff3a..c172549e1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4700,23 +4700,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // THZ Plant "S_THZFLOWERA", "S_THZFLOWERB", - "S_YELLOWSPINFLOWER", - - // THZ Tree - "S_THZTREE", - "S_THZTREEBRANCH1", - "S_THZTREEBRANCH2", - "S_THZTREEBRANCH3", - "S_THZTREEBRANCH4", - "S_THZTREEBRANCH5", - "S_THZTREEBRANCH6", - "S_THZTREEBRANCH7", - "S_THZTREEBRANCH8", - "S_THZTREEBRANCH9", - "S_THZTREEBRANCH10", - "S_THZTREEBRANCH11", - "S_THZTREEBRANCH12", - "S_THZTREEBRANCH13", // THZ Alarm "S_ALARM1", @@ -6146,10 +6129,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Techno Hill Scenery "MT_THZFLOWER1", - "MT_THZTREE", - "MT_THZTREEBRANCH", "MT_THZFLOWER2", - "MT_YELLOWSPINFLOWER", "MT_ALARM", // Deep Sea Scenery diff --git a/src/info.c b/src/info.c index 256d430ae..acb12379a 100644 --- a/src/info.c +++ b/src/info.c @@ -191,9 +191,7 @@ char sprnames[NUMSPRITES + 1][5] = // Techno Hill Scenery "THZP", // Techno Hill Zone Plant - "THZT", // THZ Tree "FWR5", // Another one - "FWR6", "ALRM", // THZ2 Alarm // Deep Sea Scenery @@ -1913,25 +1911,6 @@ state_t states[NUMSTATES] = {SPR_THZP, FF_ANIMATE, -1, {NULL}, 7, 4, S_NULL}, // S_THZFLOWERA {SPR_FWR5, FF_ANIMATE, -1, {NULL}, 19, 2, S_NULL}, // S_THZFLOWERB - {SPR_FWR6, FF_ANIMATE, 0, {NULL}, 19, 2, S_NULL}, // S_YELLOWSPINFLOWER - - // THZ Tree - {SPR_THZT, 0, -1, {NULL}, 0, 0, S_THZTREE}, // S_THZTREE - - // THZ Tree Branches - {SPR_THZT, 1|FF_PAPERSPRITE, 40, {NULL}, 0, 0, S_THZTREEBRANCH2}, // S_THZTREEBRANCH1 - {SPR_THZT, 2|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH3}, // S_THZTREEBRANCH2 - {SPR_THZT, 3|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH4}, // S_THZTREEBRANCH3 - {SPR_THZT, 4|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH5}, // S_THZTREEBRANCH4 - {SPR_THZT, 5|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH6}, // S_THZTREEBRANCH5 - {SPR_THZT, 6|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH7}, // S_THZTREEBRANCH6 - {SPR_THZT, 7|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH8}, // S_THZTREEBRANCH7 - {SPR_THZT, 8|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH9}, // S_THZTREEBRANCH8 - {SPR_THZT, 9|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH10}, // S_THZTREEBRANCH9 - {SPR_THZT, 10|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH11},// S_THZTREEBRANCH10 - {SPR_THZT, 11|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH12},// S_THZTREEBRANCH11 - {SPR_THZT, 12|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH13},// S_THZTREEBRANCH12 - {SPR_THZT, 13|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH1}, // S_THZTREEBRANCH13 // THZ Alarm {SPR_ALRM, FF_FULLBRIGHT, 35, {A_Scream}, 0, 0, S_ALARM1}, // S_ALARM1 @@ -8604,60 +8583,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_THZTREE - 904, // doomednum - S_THZTREE, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 8, // speed - 16*FRACUNIT, // radius - 64*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_SCENERY, // flags - S_NULL // raisestate - }, - - { // MT_THZTREEBRANCH - -1, // doomednum - S_THZTREEBRANCH1,// spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 8, // speed - 1*FRACUNIT, // radius - 1*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_SCENERY, // flags - S_NULL // raisestate - }, - { // MT_THZFLOWER2 902, // doomednum S_THZFLOWERB, // spawnstate @@ -8684,33 +8609,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - - { // MT_YELLOWSPINFLOWER - 903, // doomednum - S_YELLOWSPINFLOWER, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 8, // speed - 16*FRACUNIT, // radius - 64*FRACUNIT, // height - 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags - S_NULL // raisestate - }, { // MT_ALARM 901, // doomednum diff --git a/src/info.h b/src/info.h index 2d368094d..35a3f5f15 100644 --- a/src/info.h +++ b/src/info.h @@ -390,9 +390,7 @@ typedef enum sprite // Techno Hill Scenery SPR_THZP, // THZ1 Flower - SPR_THZT, // THZ Tree SPR_FWR5, // Another flower - SPR_FWR6, SPR_ALRM, // THZ2 Alarm // Deep Sea Scenery @@ -2021,23 +2019,6 @@ typedef enum state // THZ Plant S_THZFLOWERA, S_THZFLOWERB, - S_YELLOWSPINFLOWER, - - // THZ Tree - S_THZTREE, - S_THZTREEBRANCH1, - S_THZTREEBRANCH2, - S_THZTREEBRANCH3, - S_THZTREEBRANCH4, - S_THZTREEBRANCH5, - S_THZTREEBRANCH6, - S_THZTREEBRANCH7, - S_THZTREEBRANCH8, - S_THZTREEBRANCH9, - S_THZTREEBRANCH10, - S_THZTREEBRANCH11, - S_THZTREEBRANCH12, - S_THZTREEBRANCH13, // THZ Alarm S_ALARM1, @@ -3487,10 +3468,7 @@ typedef enum mobj_type // Techno Hill Scenery MT_THZFLOWER1, - MT_THZTREE, - MT_THZTREEBRANCH, MT_THZFLOWER2, - MT_YELLOWSPINFLOWER, MT_ALARM, // Deep Sea Scenery diff --git a/src/p_mobj.c b/src/p_mobj.c index cfc43cda2..8695d57e4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8433,17 +8433,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BLUETEAMRING: mobj->color = skincolor_blueteam; break; - case MT_THZTREE: - { - mobj_t *branch1 = P_SpawnMobj(mobj->x+FRACUNIT, mobj->y, mobj->z, MT_THZTREEBRANCH); - mobj_t *branch2 = P_SpawnMobj(mobj->x, mobj->y+FRACUNIT, mobj->z, MT_THZTREEBRANCH); - mobj_t *branch3 = P_SpawnMobj(mobj->x-FRACUNIT, mobj->y, mobj->z, MT_THZTREEBRANCH); - - branch1->angle = mobj->angle + ANGLE_22h; - branch2->angle = mobj->angle + ANGLE_157h; - branch3->angle = mobj->angle + ANGLE_270; - } - break; case MT_RING: case MT_COIN: case MT_BLUEBALL: From 15903c6271e8c215a73ef3baa78015704b2ef3cf Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 6 Apr 2018 14:42:49 +0100 Subject: [PATCH 102/122] * Correct V_PERPLAYER's screen-centered (no snapto flags on a given axis) behaviour. * Fix that one comment Digiku mentioned. ;P * Make extra lives/100 ring rewards consistent between lives being relevant and lives being infinite/not present, which was a problem this branch made evident when Race ended up getting the infinite lives symbol! --- src/p_enemy.c | 9 +---- src/p_user.c | 44 +++++++++++++++++---- src/st_stuff.c | 2 +- src/v_video.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ src/y_inter.c | 11 +++--- 5 files changed, 145 insertions(+), 23 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 9acc8430e..331202cbe 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3243,14 +3243,7 @@ void A_ExtraLife(mobj_t *actor) return; } - // In shooter gametypes, give the player 100 rings instead of an extra life. - if (gametype != GT_COOP && gametype != GT_COMPETITION) - { - P_GivePlayerRings(player, 100); - P_PlayLivesJingle(player); - } - else - P_GiveCoopLives(player, 1, true); + P_GiveCoopLives(player, 1, true); } // Function: A_GiveShield diff --git a/src/p_user.c b/src/p_user.c index b3a8bcf4b..9fb9d4262 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -909,8 +909,12 @@ void P_ResetPlayer(player_t *player) // Gives rings to the player, and does any special things required. // Call this function when you want to increment the player's health. // + void P_GivePlayerRings(player_t *player, INT32 num_rings) { + if (!player) + return; + if (player->bot) player = &players[consoleplayer]; @@ -929,7 +933,7 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) player->rings = 0; // Now extra life bonuses are handled here instead of in P_MovePlayer, since why not? - if (!ultimatemode && !modeattacking && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives()) + if (!ultimatemode && !modeattacking && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives() && player->lives != 0x7f) { INT32 gainlives = 0; @@ -941,7 +945,12 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (gainlives) { - P_GivePlayerLives(player, gainlives); + player->lives += gainlives; + if (player->lives > 99) + player->lives = 99; + else if (player->lives < 1) + player->lives = 1; + P_PlayLivesJingle(player); } } @@ -955,7 +964,30 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) // void P_GivePlayerLives(player_t *player, INT32 numlives) { - if (player->lives == 0x7f) return; + if (!player) + return; + + if (player->bot) + player = &players[consoleplayer]; + + if (gamestate == GS_LEVEL) + { + if (player->lives == 0x7f || (gametype != GT_COOP && gametype != GT_COMPETITION)) + { + P_GivePlayerRings(player, 100*numlives); + return; + } + + if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) + { + UINT8 prevlives = player->lives; + P_GivePlayerRings(player, 100*numlives); + if (player->lives - prevlives >= numlives) + return; + + numlives = (numlives + prevlives - player->lives); + } + } player->lives += numlives; @@ -1159,11 +1191,7 @@ void P_PlayLivesJingle(player_t *player) if (player && !P_IsLocalPlayer(player)) return; - if ((player && player->lives == 0x7f) - || (!player && &players[consoleplayer] && players[consoleplayer].lives == 0x7f) - || (gametype == GT_COOP && (netgame || multiplayer) && cv_cooplives.value == 0)) - S_StartSound(NULL, sfx_lose); - else if (use1upSound) + if (use1upSound) S_StartSound(NULL, sfx_oneup); else if (mariomode) S_StartSound(NULL, sfx_marioa); diff --git a/src/st_stuff.c b/src/st_stuff.c index 6a909580d..ab78595b4 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -776,7 +776,7 @@ static void ST_drawLivesArea(void) } else { - livescount = ((cv_cooplives.value == 0) ? 0x7f : stplyr->lives); + livescount = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0x7f : stplyr->lives); notgreyedout = true; } diff --git a/src/v_video.c b/src/v_video.c index d23e5f4f5..685cd053f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -542,6 +542,8 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t fixed_t pwidth; // patch width fixed_t offx = 0; // x offset + UINT8 perplayershuffle = 0; + if (rendermode == render_none) return; @@ -639,19 +641,37 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t colfrac <<= 1; x >>= 1; if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; scrn &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } else if (stplyr == &players[secondarydisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; } else if (stplyr == &players[thirddisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; y += adjusty; scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; } else //if (stplyr == &players[fourthdisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; y += adjusty; scrn &= ~V_SNAPTOTOP|V_SNAPTOLEFT; @@ -662,9 +682,15 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t // 2 players { if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle = 1; scrn &= ~V_SNAPTOBOTTOM; + } else //if (stplyr == &players[secondarydisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle = 2; y += adjusty; scrn &= ~V_SNAPTOTOP; } @@ -710,6 +736,10 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t x += (vid.width - (BASEVIDWIDTH * dupx)); else if (!(scrn & V_SNAPTOLEFT)) x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + if (perplayershuffle & 4) + x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4; + else if (perplayershuffle & 8) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 4; } if (vid.height != BASEVIDHEIGHT * dupy) { @@ -718,6 +748,10 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + if (perplayershuffle & 1) + y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4; + else if (perplayershuffle & 2) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4; } } @@ -792,6 +826,8 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ UINT8 *desttop, *dest; const UINT8 *source, *deststop; + UINT8 perplayershuffle = 0; + if (rendermode == render_none) return; @@ -852,21 +888,39 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ sx >>= 1; w >>= 1; if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; scrn &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } else if (stplyr == &players[secondarydisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; sx += adjustx; scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; } else if (stplyr == &players[thirddisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; y += adjusty; sy += adjusty; scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; } else //if (stplyr == &players[fourthdisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; sx += adjustx; y += adjusty; @@ -879,9 +933,15 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ // 2 players { if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; scrn &= ~V_SNAPTOBOTTOM; + } else //if (stplyr == &players[secondarydisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; y += adjusty; sy += adjusty; scrn &= ~V_SNAPTOTOP; @@ -927,6 +987,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ x += (vid.width - (BASEVIDWIDTH * dupx)); else if (!(scrn & V_SNAPTOLEFT)) x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + if (perplayershuffle & 4) + x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4; + else if (perplayershuffle & 8) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 4; } if (vid.height != BASEVIDHEIGHT * dupy) { @@ -935,6 +999,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + if (perplayershuffle & 1) + y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4; + else if (perplayershuffle & 2) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4; } } @@ -1081,6 +1149,8 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) UINT8 *dest; const UINT8 *deststop; + UINT8 perplayershuffle = 0; + if (rendermode == render_none) return; @@ -1104,19 +1174,37 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) w >>= 1; x >>= 1; if (stplyr == &players[displayplayer]) + { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; c &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } else if (stplyr == &players[secondarydisplayplayer]) { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; c &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; } else if (stplyr == &players[thirddisplayplayer]) { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; y += adjusty; c &= ~V_SNAPTOTOP|V_SNAPTORIGHT; } else //if (stplyr == &players[fourthdisplayplayer]) { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; y += adjusty; c &= ~V_SNAPTOTOP|V_SNAPTOLEFT; @@ -1127,9 +1215,15 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) // 2 players { if (stplyr == &players[displayplayer]) + { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; c &= ~V_SNAPTOBOTTOM; + } else //if (stplyr == &players[secondarydisplayplayer]) { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; y += adjusty; c &= ~V_SNAPTOTOP; } @@ -1160,6 +1254,10 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) x += (vid.width - (BASEVIDWIDTH * dupx)); else if (!(c & V_SNAPTOLEFT)) x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + if (perplayershuffle & 4) + x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4; + else if (perplayershuffle & 8) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 4; } if (vid.height != BASEVIDHEIGHT * dupy) { @@ -1168,6 +1266,10 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(c & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + if (perplayershuffle & 1) + y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4; + else if (perplayershuffle & 2) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4; } } diff --git a/src/y_inter.c b/src/y_inter.c index c86dee758..ed9cc4185 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -858,7 +858,7 @@ void Y_Ticker(void) tallydonetic = -1; } - if (intertic < 2*TICRATE) // one second pause before tally begins + if (intertic < 2*TICRATE) // TWO second pause before tally begins, thank you mazmazz return; for (i = 0; i < MAXPLAYERS; i++) @@ -1822,13 +1822,13 @@ static void Y_AwardCoopBonuses(void) players[i].score = MAXSCORE; } - ptlives = (!ultimatemode && !modeattacking) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; + ptlives = (!ultimatemode && !modeattacking && players[i].lives != 0x7f) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; if (ptlives) P_GivePlayerLives(&players[i], ptlives); if (i == consoleplayer) { - data.coop.gotlife = ptlives; + data.coop.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives); M_Memcpy(&data.coop.bonuses, &localbonuses, sizeof(data.coop.bonuses)); } } @@ -1866,16 +1866,15 @@ static void Y_AwardSpecialStageBonus(void) players[i].score = MAXSCORE; // grant extra lives right away since tally is faked - ptlives = (!ultimatemode && !modeattacking) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; + ptlives = (!ultimatemode && !modeattacking && players[i].lives != 0x7f) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; if (ptlives) P_GivePlayerLives(&players[i], ptlives); if (i == consoleplayer) { + data.spec.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives); M_Memcpy(&data.spec.bonus, &localbonus, sizeof(data.spec.bonus)); - data.spec.gotlife = ptlives; - // Continues related data.spec.continues = min(players[i].continues, 8); if (players[i].gotcontinue) From 3f427d0161a79cfecb447269c873bb66bcd81e76 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 6 Apr 2018 18:40:08 +0100 Subject: [PATCH 103/122] * Improve devmode text. * Make sure showfps never covers anything relevant to the base game. * Tweak spectator text for raising/lowering. * Minor code-smell squishes. --- src/d_netcmd.c | 2 +- src/m_menu.c | 2 +- src/screen.c | 8 +- src/st_stuff.c | 197 ++++++++++++++++++++++++++++++++----------------- 4 files changed, 137 insertions(+), 72 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index cc641b8b0..e01178155 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -313,7 +313,7 @@ static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Centiseconds"} consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}}; -consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display +consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/m_menu.c b/src/m_menu.c index 4857df104..f10c6b653 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1188,7 +1188,7 @@ static menuitem_t OP_VideoOptionsMenu[] = #endif {IT_HEADER, NULL, "Color Profile", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness (F11)", &cv_globalgamma, 36}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness (F11)", &cv_globalgamma,36}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_globalsaturation, 41}, {IT_SUBMENU|IT_STRING, NULL, "Advanced Settings...", &OP_ColorOptionsDef, 46}, diff --git a/src/screen.c b/src/screen.c index 5b16992c7..cd97b62fa 100644 --- a/src/screen.c +++ b/src/screen.c @@ -414,7 +414,7 @@ void SCR_DisplayTicRate(void) tic_t ontic = I_GetTime(); tic_t totaltics = 0; INT32 ticcntcolor = 0; - INT32 offs = (cv_debug ? 8 : 0); + const INT32 h = vid.height-(8*vid.dupy); for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i) fpsgraph[i % TICRATE] = false; @@ -428,9 +428,9 @@ void SCR_DisplayTicRate(void) if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP; else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP; - V_DrawString(vid.width-((24+(6*offs))*vid.dupx), vid.height-((16-offs)*vid.dupy), - V_YELLOWMAP|V_NOSCALESTART, "FPS"); - V_DrawString(vid.width-(40*vid.dupx), vid.height-(8*vid.dupy), + V_DrawString(vid.width-(72*vid.dupx), h, + V_YELLOWMAP|V_NOSCALESTART, "FPS:"); + V_DrawString(vid.width-(40*vid.dupx), h, ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE)); lasttic = ontic; diff --git a/src/st_stuff.c b/src/st_stuff.c index ab78595b4..3b07d375e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -453,80 +453,145 @@ static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fix // Devmode information static void ST_drawDebugInfo(void) { - INT32 height = 192; + INT32 height = 0; if (!(stplyr->mo && cv_debug)) return; - if (cv_ticrate.value) - height -= 12; +#define VFLAGS V_MONOSPACE|V_SNAPTOTOP|V_SNAPTORIGHT -#define dist 4 -#define VFLAGS V_MONOSPACE|V_SNAPTOBOTTOM|V_SNAPTORIGHT - - if (cv_debug & DBG_BASIC) + if (vid.dupx == 1) { - const fixed_t d = AngleFixed(stplyr->mo->angle); - V_DrawRightAlignedString(320, height - 24, VFLAGS, va("X: %6d", stplyr->mo->x>>FRACBITS)); - V_DrawRightAlignedString(320, height - 16, VFLAGS, va("Y: %6d", stplyr->mo->y>>FRACBITS)); - V_DrawRightAlignedString(320, height - 8, VFLAGS, va("Z: %6d", stplyr->mo->z>>FRACBITS)); - V_DrawRightAlignedString(320, height, VFLAGS, va("A: %6d", FixedInt(d))); + if (cv_debug & DBG_BASIC) + { + const fixed_t d = AngleFixed(stplyr->mo->angle); + V_DrawRightAlignedString(320, 0, VFLAGS, va("X: %6d", stplyr->mo->x>>FRACBITS)); + V_DrawRightAlignedString(320, 8, VFLAGS, va("Y: %6d", stplyr->mo->y>>FRACBITS)); + V_DrawRightAlignedString(320, 16, VFLAGS, va("Z: %6d", stplyr->mo->z>>FRACBITS)); + V_DrawRightAlignedString(320, 24, VFLAGS, va("A: %6d", FixedInt(d))); - height -= (32+dist); + height += 4*9; + } + + if (cv_debug & (DBG_MEMORY|DBG_RANDOMIZER|DBG_DETAILED)) + { + V_DrawRightAlignedThinString(320, height, VFLAGS|V_REDMAP, "INFO NOT AVAILABLE"); + V_DrawRightAlignedThinString(320, 8+height, VFLAGS|V_REDMAP, "AT THIS RESOLUTION"); + } + } + else + { +#define h 4 +#define dist 2 +#define V_DrawDebugLine(str) V_DrawRightAlignedSmallString(320, height, VFLAGS, str);\ + height += h + + if (cv_debug & DBG_MEMORY) + { + V_DrawDebugLine(va("Heap: %8sKB", sizeu1(Z_TotalUsage()>>10))); + + height += dist; + } + + if (cv_debug & DBG_RANDOMIZER) // randomizer testing + { + fixed_t peekres = P_RandomPeek(); + peekres *= 10000; // Change from fixed point + peekres >>= FRACBITS; // to displayable decimal + + V_DrawDebugLine(va("Init: %08x", P_GetInitSeed())); + V_DrawDebugLine(va("Seed: %08x", P_GetRandSeed())); + V_DrawDebugLine(va("== : .%04d", peekres)); + + height += dist; + } + + if (cv_debug & DBG_DETAILED) + { +#define V_DrawDebugFlag(f, str) V_DrawRightAlignedSmallString(w, height, VFLAGS|f, str);\ + w -= 9 + const fixed_t d = AngleFixed(stplyr->drawangle); + INT32 w = 320; + + V_DrawDebugLine(va("SHIELD: %5x", stplyr->powers[pw_shield])); + V_DrawDebugLine(va("SCALE: %5d%%", (stplyr->mo->scale*100)>>FRACBITS)); + V_DrawDebugLine(va("CARRY: %5x", stplyr->powers[pw_carry])); + V_DrawDebugLine(va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); + V_DrawDebugLine(va("ABILITY: %3d, %3d", stplyr->charability, stplyr->charability2)); + V_DrawDebugLine(va("ACTIONSPD: %5d", stplyr->actionspd>>FRACBITS)); + V_DrawDebugLine(va("PEEL: %3d", stplyr->dashmode)); + V_DrawDebugLine(va("SCOREADD: %3d", stplyr->scoreadd)); + + // Flags + V_DrawDebugFlag(((stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP), "SH"); + V_DrawDebugFlag(((stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP), "TH"); + V_DrawDebugFlag(((stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP), "ST"); + V_DrawDebugFlag(((stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP), "SP"); + V_DrawDebugFlag(((stplyr->pflags & PF_NOJUMPDAMAGE) ? V_GREENMAP : V_REDMAP), "ND"); + V_DrawDebugFlag(((stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP), "JD"); + V_DrawDebugFlag(((stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP), "SJ"); + V_DrawDebugFlag(0, "PF/SF:"); + height += h; + w = 320; + V_DrawDebugFlag(((stplyr->pflags & PF_INVIS) ? V_GREENMAP : V_REDMAP), "*I"); + V_DrawDebugFlag(((stplyr->pflags & PF_NOCLIP) ? V_GREENMAP : V_REDMAP), "*C"); + V_DrawDebugFlag(((stplyr->pflags & PF_GODMODE) ? V_GREENMAP : V_REDMAP), "*G"); + V_DrawDebugFlag(((stplyr->charflags & SF_SUPER) ? V_GREENMAP : V_REDMAP), "SU"); + V_DrawDebugFlag(((stplyr->pflags & PF_APPLYAUTOBRAKE) ? V_GREENMAP : V_REDMAP), "AA"); + V_DrawDebugFlag(((stplyr->pflags & PF_SLIDING) ? V_GREENMAP : V_REDMAP), "SL"); + V_DrawDebugFlag(((stplyr->pflags & PF_BOUNCING) ? V_GREENMAP : V_REDMAP), "BO"); + V_DrawDebugFlag(((stplyr->pflags & PF_GLIDING) ? V_GREENMAP : V_REDMAP), "GL"); + height += h; + + V_DrawDebugLine(va("CEILINGZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); + V_DrawDebugLine(va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); + + V_DrawDebugLine(va("CMOMX: %6d", stplyr->cmomx>>FRACBITS)); + V_DrawDebugLine(va("CMOMY: %6d", stplyr->cmomy>>FRACBITS)); + V_DrawDebugLine(va("PMOMZ: %6d", stplyr->mo->pmomz>>FRACBITS)); + + w = 320; + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_APPLYPMOMZ) ? V_GREENMAP : V_REDMAP), "AP"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_SPRUNG) ? V_GREENMAP : V_REDMAP), "SP"); + //V_DrawDebugFlag(((stplyr->mo->eflags & MFE_PUSHED) ? V_GREENMAP : V_REDMAP), "PU"); -- not relevant to players + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_GOOWATER) ? V_GREENMAP : V_REDMAP), "GW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_VERTICALFLIP) ? V_GREENMAP : V_REDMAP), "VF"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTSTEPPEDDOWN) ? V_GREENMAP : V_REDMAP), "JS"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_UNDERWATER) ? V_GREENMAP : V_REDMAP), "UW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_TOUCHWATER) ? V_GREENMAP : V_REDMAP), "TW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTHITFLOOR) ? V_GREENMAP : V_REDMAP), "JH"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_ONGROUND) ? V_GREENMAP : V_REDMAP), "OG"); + V_DrawDebugFlag(0, "MFE:"); + height += h; + + V_DrawDebugLine(va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); + V_DrawDebugLine(va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); + V_DrawDebugLine(va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); + + V_DrawDebugLine(va("SPEED: %6d", stplyr->speed>>FRACBITS)); + + V_DrawDebugLine(va("DRAWANGLE: %6d", FixedInt(d))); + + height += dist; +#undef V_DrawDebugFlag + } + + if (cv_debug & DBG_BASIC) + { + const fixed_t d = AngleFixed(stplyr->mo->angle); + V_DrawDebugLine(va("X: %6d", stplyr->mo->x>>FRACBITS)); + V_DrawDebugLine(va("Y: %6d", stplyr->mo->y>>FRACBITS)); + V_DrawDebugLine(va("Z: %6d", stplyr->mo->z>>FRACBITS)); + V_DrawDebugLine(va("A: %6d", FixedInt(d))); + + //height += dist; + } } - if (cv_debug & DBG_DETAILED) - { - V_DrawRightAlignedString(320, height - 104, VFLAGS, va("SHIELD: %5x", stplyr->powers[pw_shield])); - V_DrawRightAlignedString(320, height - 96, VFLAGS, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT)); - V_DrawRightAlignedString(320, height - 88, VFLAGS, va("CARRY: %5x", stplyr->powers[pw_carry])); - V_DrawRightAlignedString(320, height - 80, VFLAGS, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); - - // Flags - V_DrawRightAlignedString(304-92, height - 72, VFLAGS, "PF:"); - V_DrawString(304-90, height - 72, VFLAGS|((stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP), "SJ"); - V_DrawString(304-72, height - 72, VFLAGS|((stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP), "JD"); - V_DrawString(304-54, height - 72, VFLAGS|((stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP), "SP"); - V_DrawString(304-36, height - 72, VFLAGS|((stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP), "ST"); - V_DrawString(304-18, height - 72, VFLAGS|((stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP), "TH"); - V_DrawString(304, height - 72, VFLAGS|((stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP), "SH"); - - V_DrawRightAlignedString(320, height - 64, VFLAGS, va("CEILZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); - V_DrawRightAlignedString(320, height - 56, VFLAGS, va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); - - V_DrawRightAlignedString(320, height - 48, VFLAGS, va("CNVX: %6d", stplyr->cmomx>>FRACBITS)); - V_DrawRightAlignedString(320, height - 40, VFLAGS, va("CNVY: %6d", stplyr->cmomy>>FRACBITS)); - V_DrawRightAlignedString(320, height - 32, VFLAGS, va("PLTZ: %6d", stplyr->mo->pmomz>>FRACBITS)); - - V_DrawRightAlignedString(320, height - 24, VFLAGS, va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); - V_DrawRightAlignedString(320, height - 16, VFLAGS, va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); - V_DrawRightAlignedString(320, height - 8, VFLAGS, va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); - - V_DrawRightAlignedString(320, height, VFLAGS, va("SPEED: %6d", stplyr->speed>>FRACBITS)); - - height -= (112+dist); - } - - if (cv_debug & DBG_RANDOMIZER) // randomizer testing - { - fixed_t peekres = P_RandomPeek(); - peekres *= 10000; // Change from fixed point - peekres >>= FRACBITS; // to displayable decimal - - V_DrawRightAlignedString(320, height - 16, VFLAGS, va("Init: %08x", P_GetInitSeed())); - V_DrawRightAlignedString(320, height - 8, VFLAGS, va("Seed: %08x", P_GetRandSeed())); - V_DrawRightAlignedString(320, height, VFLAGS, va("== : .%04d", peekres)); - - height -= (24+dist); - } - - if (cv_debug & DBG_MEMORY) - { - V_DrawRightAlignedString(320, height, VFLAGS, va("Heap: %7sKB", sizeu1(Z_TotalUsage()>>10))); - } - -#undef VFLAGS +#undef V_DrawDebugLine #undef dist +#undef h +#undef VFLAGS } static void ST_drawScore(void) @@ -1917,8 +1982,8 @@ static void ST_drawTextHUD(void) else textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game")) - textHUDdraw(M_GetText("\x82""SPIN:""\x80 Sink")) - textHUDdraw(M_GetText("\x82""JUMP:""\x80 Float")) + textHUDdraw(M_GetText("\x82""SPIN:""\x80 Lower")) + textHUDdraw(M_GetText("\x82""JUMP:""\x80 Rise")) dof12 = true; dospecheader = true; From 790e334d19692498466ca2ce30fdd1cc8fc817fa Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 7 Apr 2018 23:10:34 +0100 Subject: [PATCH 104/122] comment goof --- src/p_mobj.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_mobj.h b/src/p_mobj.h index ec25855d8..f6ebd3cad 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -194,6 +194,7 @@ typedef enum MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) MF2_SHIELD = 1<<29, // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) + // free: to and including 1<<31 } mobjflag2_t; typedef enum From 375c3c584e412e52f57b94f5f991d8735f7e87da Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 8 Apr 2018 13:03:40 +0100 Subject: [PATCH 105/122] =?UTF-8?q?[13:01]=20toaster:=20hey=20[13:01]=20to?= =?UTF-8?q?aster:=20would=20anyone=20object=20if=20i=20pushed=20this=20to?= =?UTF-8?q?=20master=20[13:02]=20toaster:=20so=20my=20changes=20to=20devmo?= =?UTF-8?q?de=20don't=20fuck=20with=20gifs,=20for=20example=20https://cdn.?= =?UTF-8?q?discordapp.com/attachments/428262628893261828/43250092077377126?= =?UTF-8?q?4/srb20575.gif=20[13:02]=20NEV3R:=20=C2=AF\=5F(=E3=83=84)=5F/?= =?UTF-8?q?=C2=AF=20[13:02]=20toaster:=20ok=20i'll=20just=20do=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/st_stuff.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 3b07d375e..a513a028c 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -27,6 +27,8 @@ #include "i_system.h" #include "m_menu.h" #include "m_cheat.h" +#include "m_misc.h" // moviemode +#include "m_anigif.h" // cv_gif_downscale #include "p_setup.h" // NiGHTS grading //random index @@ -460,7 +462,7 @@ static void ST_drawDebugInfo(void) #define VFLAGS V_MONOSPACE|V_SNAPTOTOP|V_SNAPTORIGHT - if (vid.dupx == 1) + if ((moviemode == MM_GIF && cv_gif_downscale.value) || vid.dupx == 1) { if (cv_debug & DBG_BASIC) { From 3fb12cf337dd02bf559b2c7986978d7d56a68d61 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 15 Apr 2018 19:59:57 +0100 Subject: [PATCH 106/122] Don't use CV_StealthSetValue on cv_itemfinder if running the game in dedicated mode --- src/g_game.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index d3c55e0cc..bcae69fda 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3588,7 +3588,8 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean unlocktriggers = 0; // clear itemfinder, just in case - CV_StealthSetValue(&cv_itemfinder, 0); + if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds + CV_StealthSetValue(&cv_itemfinder, 0); } // internal game map From 9cdf87404e3a2e2a0acc6b7861e90c9426f30dd3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 15 Apr 2018 22:00:31 +0100 Subject: [PATCH 107/122] Rewrote findfile to store whether any of the three paths searched had a bad MD5 rather than just simply being not there. This means that, if the three paths are not the same, you should be able to tell if at least one of them has a file that just had a bad MD5. Most relevant for Linux peeps I expect. Note: Untested as of writing --- src/d_netfil.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 172624ad2..6742cfe28 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -990,19 +990,41 @@ filestatus_t checkfilemd5(char *filename, const UINT8 *wantedmd5sum) return FS_FOUND; // will never happen, but makes the compiler shut up } +// Rewritten by Monster Iestyn to be less stupid +// Note: if completepath is true, "filename" is modified, but only if FS_FOUND is going to be returned +// (Don't worry about WinCE's version of filesearch, nobody cares about that OS anymore) filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean completepath) { - filestatus_t homecheck = filesearch(filename, srb2home, wantedmd5sum, false, 10); - if (homecheck == FS_FOUND) - return filesearch(filename, srb2home, wantedmd5sum, completepath, 10); + filestatus_t homecheck; // store result of last file search + boolean badmd5 = false; // store whether md5 was bad from either of the first two searches (if nothing was found in the third) - homecheck = filesearch(filename, srb2path, wantedmd5sum, false, 10); - if (homecheck == FS_FOUND) - return filesearch(filename, srb2path, wantedmd5sum, completepath, 10); + // first, check SRB2's "home" directory + homecheck = filesearch(filename, srb2home, wantedmd5sum, completepath, 10); + if (homecheck == FS_FOUND) // we found the file, so return that we have :) + return FS_FOUND; + else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5 + badmd5 = true; + // if not found at all, just move on without doing anything + + // next, check SRB2's "path" directory + homecheck = filesearch(filename, srb2path, wantedmd5sum, completepath, 10); + + if (homecheck == FS_FOUND) // we found the file, so return that we have :) + return FS_FOUND; + else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5 + badmd5 = true; + // if not found at all, just move on without doing anything + + // finally check "." directory #ifdef _arch_dreamcast - return filesearch(filename, "/cd", wantedmd5sum, completepath, 10); + homecheck = filesearch(filename, "/cd", wantedmd5sum, completepath, 10); #else - return filesearch(filename, ".", wantedmd5sum, completepath, 10); + homecheck = filesearch(filename, ".", wantedmd5sum, completepath, 10); #endif + + if (homecheck != FS_NOTFOUND) // if not found this time, fall back on the below return statement + return homecheck; // otherwise return the result we got + + return (badmd5 ? FS_MD5SUMBAD : FS_NOTFOUND); // md5 sum bad or file not found } From 29e80c53005ee3fe2e9cf4cd07ebfdacaf294aa8 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 8 May 2018 18:14:39 -0400 Subject: [PATCH 108/122] Don't increment totalplaytime if a demo is playing. --- src/p_tick.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_tick.c b/src/p_tick.c index f4bc59323..e81d0e5b6 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -607,6 +607,7 @@ void P_Ticker(boolean run) } // Keep track of how long they've been playing! + if (!demoplayback) // Don't incerment if a demo is playing. totalplaytime++; if (!useNightsSS && G_IsSpecialStage(gamemap)) From 9ff491dd78f295412170832ff268d0b5aec24c99 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 8 May 2018 18:36:47 -0400 Subject: [PATCH 109/122] Add indentation --- src/p_tick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_tick.c b/src/p_tick.c index e81d0e5b6..aaf44f5e1 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -608,7 +608,7 @@ void P_Ticker(boolean run) // Keep track of how long they've been playing! if (!demoplayback) // Don't incerment if a demo is playing. - totalplaytime++; + totalplaytime++; if (!useNightsSS && G_IsSpecialStage(gamemap)) P_DoSpecialStageStuff(); From a1d696b38e650e4f2e05d01a50d63756200782b9 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 8 May 2018 18:38:28 -0400 Subject: [PATCH 110/122] Fix small typo --- src/p_tick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_tick.c b/src/p_tick.c index aaf44f5e1..4c59f8b48 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -607,7 +607,7 @@ void P_Ticker(boolean run) } // Keep track of how long they've been playing! - if (!demoplayback) // Don't incerment if a demo is playing. + if (!demoplayback) // Don't increment if a demo is playing. totalplaytime++; if (!useNightsSS && G_IsSpecialStage(gamemap)) From 4f75ae3a6819b68b476542abce497eea213a168e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 11 May 2018 20:35:46 +0100 Subject: [PATCH 111/122] Fix both Bouncy FOF and Space Countdown sector specials working on FOFs without the FF_EXISTS flag Also move the Bouncy FOF sector special check above the FOF heights checking in P_CheckBouncySectors, because it means not having to waste time calculating FOF heights only for it not to be bouncy anyway :P --- src/p_user.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 7abf85347..da8e19caa 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1621,6 +1621,9 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space for (rover = sector->ffloors; rover; rover = rover->next) { + if (!(rover->flags & FF_EXISTS)) + continue; + if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL) continue; #ifdef ESLOPE @@ -1835,6 +1838,12 @@ static void P_CheckBouncySectors(player_t *player) for (rover = node->m_sector->ffloors; rover; rover = rover->next) { + if (!(rover->flags & FF_EXISTS)) + continue; // FOFs should not be bouncy if they don't even "exist" + + if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 15) + continue; // this sector type is required for FOFs to be bouncy + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); @@ -1848,7 +1857,6 @@ static void P_CheckBouncySectors(player_t *player) && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) top = false; - if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15) { fixed_t linedist; From 975a318460710576bee86ea66af68a0573bf5b31 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 14 May 2018 19:34:22 +0200 Subject: [PATCH 112/122] Change to linedef type 7 (flat alignment): If no tag is given, affect front sector. --- src/p_spec.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 595473a5c..faec226ad 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5527,6 +5527,30 @@ void P_InitSpecials(void) P_InitTagLists(); // Create xref tables for tags } +static void P_ApplyFlatAlignment(line_t* master, sector_t* sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs) +{ + if (!(master->flags & ML_NOSONIC)) // Modify floor flat alignment unless NOSONIC flag is set + { + sector->spawn_flrpic_angle = sector->floorpic_angle = flatangle; + sector->floor_xoffs += xoffs; + sector->floor_yoffs += yoffs; + // saved for netgames + sector->spawn_flr_xoffs = sector->floor_xoffs; + sector->spawn_flr_yoffs = sector->floor_yoffs; + } + + if (!(master->flags & ML_NOTAILS)) // Modify ceiling flat alignment unless NOTAILS flag is set + { + sector->spawn_ceilpic_angle = sector->ceilingpic_angle = flatangle; + sector->ceiling_xoffs += xoffs; + sector->ceiling_yoffs += yoffs; + // saved for netgames + sector->spawn_ceil_xoffs = sector->ceiling_xoffs; + sector->spawn_ceil_yoffs = sector->ceiling_yoffs; + } + +} + /** After the map has loaded, scans for specials that spawn 3Dfloors and * thinkers. * @@ -5730,27 +5754,13 @@ void P_SpawnSpecials(INT32 fromnetsave) yoffs = lines[i].v1->y; } - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + //If no tag is given, apply to front sector + if (lines[i].tag == 0) + P_ApplyFlatAlignment(lines + i, lines[i].frontsector, flatangle, xoffs, yoffs); + else { - if (!(lines[i].flags & ML_NOSONIC)) // Modify floor flat alignment unless NOSONIC flag is set - { - sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = flatangle; - sectors[s].floor_xoffs += xoffs; - sectors[s].floor_yoffs += yoffs; - // saved for netgames - sectors[s].spawn_flr_xoffs = sectors[s].floor_xoffs; - sectors[s].spawn_flr_yoffs = sectors[s].floor_yoffs; - } - - if (!(lines[i].flags & ML_NOTAILS)) // Modify ceiling flat alignment unless NOTAILS flag is set - { - sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = flatangle; - sectors[s].ceiling_xoffs += xoffs; - sectors[s].ceiling_yoffs += yoffs; - // saved for netgames - sectors[s].spawn_ceil_xoffs = sectors[s].ceiling_xoffs; - sectors[s].spawn_ceil_yoffs = sectors[s].ceiling_yoffs; - } + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0;) + P_ApplyFlatAlignment(lines + i, sectors + s, flatangle, xoffs, yoffs); } } else // Otherwise, print a helpful warning. Can I do no less? From 2e8cb9582afc081c36695f5099f6bcf32a4c52a6 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 15 May 2018 09:39:52 +0200 Subject: [PATCH 113/122] Consistency: Pointer declarations next to the variable name instead of the type --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index faec226ad..e77a783e9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5527,7 +5527,7 @@ void P_InitSpecials(void) P_InitTagLists(); // Create xref tables for tags } -static void P_ApplyFlatAlignment(line_t* master, sector_t* sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs) +static void P_ApplyFlatAlignment(line_t *master, sector_t *sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs) { if (!(master->flags & ML_NOSONIC)) // Modify floor flat alignment unless NOSONIC flag is set { From badbb4324eb3f0b29ba0462753de45f5a9743dd3 Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 16 May 2018 21:04:57 +0100 Subject: [PATCH 114/122] Fix FF_FULLBRIGHT not working in sectors with multiple light levels in OpenGL --- src/hardware/hw_main.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 81021ef7f..b758c828e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4228,6 +4228,9 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) i = 0; temp = FLOAT_TO_FIXED(realtop); + if (spr->mobj->frame & FF_FULLBRIGHT) + lightlevel = 255; + #ifdef ESLOPE for (i = 1; i < sector->numlights; i++) { @@ -4235,14 +4238,16 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) : sector->lightlist[i].height; if (h <= temp) { - lightlevel = *list[i-1].lightlevel; + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *list[i-1].lightlevel; colormap = list[i-1].extra_colormap; break; } } #else i = R_GetPlaneLight(sector, temp, false); - lightlevel = *list[i].lightlevel; + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *list[i].lightlevel; colormap = list[i].extra_colormap; #endif @@ -4257,7 +4262,8 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) // even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES)) { - lightlevel = *list[i].lightlevel; + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *list[i].lightlevel; colormap = list[i].extra_colormap; } From 0bef99f5666ca80bdbcf867814a9e0c75d89fca4 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 17 May 2018 13:57:19 -0400 Subject: [PATCH 115/122] Fix console typo --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 52cd6ddbb..362e0966d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3003,7 +3003,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX) { - CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename); + CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename); return false; } else wadnum = (UINT16)(numwadfiles-1); From 092e70923573cf365a4035fc1c10148f5d9becb1 Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 17 May 2018 22:17:20 +0100 Subject: [PATCH 116/122] OpenGL Map Specific palettes working This makes OpenGL stop using a specific function that doesn't really do anything for it anymore. It looks like it was used for a hack that would change the colour of polygons for the flashpal equivalent in DOOM. I made it so ST_DoPaletteStuff doesn't set the flashpal in OpenGL as it already does its own hacky overlay and doing that would cause all the textures to be flushed more mid-level, it could be enabled for more correct flashpals, but they still wouldn't effect fog or lighting. This means the palette will be set when going to the title screen, and twice when starting a map, (causing the OpenGL cached textures to also be flushed at those times) --- src/d_main.c | 7 +------ src/p_setup.c | 5 ----- src/st_stuff.c | 10 +++++----- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 4cdfb13d9..fbec5f7d8 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -730,11 +730,6 @@ void D_StartTitle(void) CON_ToggleOff(); // Reset the palette -#ifdef HWRENDER - if (rendermode == render_opengl) - HWR_SetPaletteColor(0); - else -#endif if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); } @@ -1223,7 +1218,7 @@ void D_SRB2Main(void) CONS_Printf("R_Init(): Init SRB2 refresh daemon.\n"); R_Init(); - // setting up sound + // setting up sound if (dedicated) { nosound = true; diff --git a/src/p_setup.c b/src/p_setup.c index 52cd6ddbb..c3aa9884d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2503,11 +2503,6 @@ boolean P_SetupLevel(boolean skipprecip) // Reset the palette -#ifdef HWRENDER - if (rendermode == render_opengl) - HWR_SetPaletteColor(0); - else -#endif if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); diff --git a/src/st_stuff.c b/src/st_stuff.c index 3562a9b71..72e0b6b94 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -210,17 +210,17 @@ void ST_doPaletteStuff(void) else palette = 0; +#ifdef HWRENDER + if (rendermode == render_opengl) + palette = 0; // No flashpals here in OpenGL +#endif + palette = min(max(palette, 0), 13); if (palette != st_palette) { st_palette = palette; -#ifdef HWRENDER - if (rendermode == render_opengl) - HWR_SetPaletteColor(0); - else -#endif if (rendermode != render_none) { V_SetPaletteLump(GetPalette()); // Reset the palette From 001e4e11ca1dfd0ded1bbc29e26f71be50c86aac Mon Sep 17 00:00:00 2001 From: Tasos Sahanidis Date: Thu, 17 May 2018 17:55:38 +0300 Subject: [PATCH 117/122] Correct C FixedMul() off-by-one errors The FixedMul() C implementation would produce off by one results, causing constant desyncs on 64 bit builds and builds without an ASM implementation of the function. This is fixed by shifting instead of dividing, possibly avoiding rounding errors. --- src/m_fixed.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/m_fixed.c b/src/m_fixed.c index ce7471a28..014457386 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -33,7 +33,9 @@ */ fixed_t FixedMul(fixed_t a, fixed_t b) { - return (fixed_t)((((INT64)a * b) ) / FRACUNIT); + // Need to cast to unsigned before shifting to avoid undefined behaviour + // for negative integers + return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS); } #endif //__USE_C_FIXEDMUL__ From f061ffa00ebb6bf748505666c98623794e588df3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 21 May 2018 20:02:30 +0100 Subject: [PATCH 118/122] Stop Each Time trigger linedefs and object-carrying scrollers from doing anything with FOFs without FF_EXISTS --- src/p_floor.c | 14 ++++++++++++++ src/p_spec.c | 27 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/p_floor.c b/src/p_floor.c index 35c743a07..f30637659 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2103,6 +2103,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) boolean floortouch = false; fixed_t bottomheight, topheight; msecnode_t *node; + ffloor_t *rover; for (i = 0; i < MAXPLAYERS; i++) { @@ -2150,6 +2151,19 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) { targetsec = §ors[targetsecnum]; + // Find the FOF corresponding to the control linedef + for (rover = targetsec->ffloors; rover; rover = rover->next) + { + if (rover->master == sec->lines[i]) + break; + } + + if (!rover) // This should be impossible, but don't complain if it is the case somehow + continue; + + if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there + continue; + for (j = 0; j < MAXPLAYERS; j++) { if (!playeringame[j]) diff --git a/src/p_spec.c b/src/p_spec.c index c62c3b209..d308a9b3f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6628,6 +6628,7 @@ void T_Scroll(scroll_t *s) line_t *line; size_t i; INT32 sect; + ffloor_t *rover; case sc_side: // scroll wall texture side = sides + s->affectee; @@ -6669,6 +6670,19 @@ void T_Scroll(scroll_t *s) sector_t *psec; psec = sectors + sect; + // Find the FOF corresponding to the control linedef + for (rover = psec->ffloors; rover; rover = rover->next) + { + if (rover->master == sec->lines[i]) + break; + } + + if (!rover) // This should be impossible, but don't complain if it is the case somehow + continue; + + if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there + continue; + for (node = psec->touching_thinglist; node; node = node->m_thinglist_next) { thing = node->m_thing; @@ -6732,6 +6746,19 @@ void T_Scroll(scroll_t *s) sector_t *psec; psec = sectors + sect; + // Find the FOF corresponding to the control linedef + for (rover = psec->ffloors; rover; rover = rover->next) + { + if (rover->master == sec->lines[i]) + break; + } + + if (!rover) // This should be impossible, but don't complain if it is the case somehow + continue; + + if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there + continue; + for (node = psec->touching_thinglist; node; node = node->m_thinglist_next) { thing = node->m_thing; From f4181f7eb6203af8d8363cd03a351d8b780061da Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 26 May 2018 13:13:37 +0100 Subject: [PATCH 119/122] Very large map rendering issue fixed Move old fix for too large maps having rendering issues from R_CheckBBox to OpenGL's HWR_CheckBBox From what I know, this effects at least Aerial Garden and Seraphic Skylands --- src/hardware/hw_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 81021ef7f..059a09b15 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2901,8 +2901,8 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) py2 = bspcoord[checkcoord[boxpos][3]]; // check clip list for an open space - angle1 = R_PointToAngle(px1, py1) - dup_viewangle; - angle2 = R_PointToAngle(px2, py2) - dup_viewangle; + angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle; + angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle; span = angle1 - angle2; From 41e9c20c04bde872c794e2a8287baba627bedc25 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 28 May 2018 21:29:46 +0100 Subject: [PATCH 120/122] Ignore mouse button events if the mouse's focus is not actually on the window at the moment. This should hopefully kill the F12 getting stuck issue once and for all. --- src/sdl/i_video.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 87ce84158..4eab0ae3c 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -658,6 +658,14 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type) SDL_memset(&event, 0, sizeof(event_t)); + // Ignore the event if the mouse is not actually focused on the window. + // This can happen if you used the mouse to restore keyboard focus; + // this apparently makes a mouse button down event but not a mouse button up event, + // resulting in whatever key was pressed down getting "stuck" if we don't ignore it. + // -- Monster Iestyn (28/05/18) + if (SDL_GetMouseFocus() != window) + return; + /// \todo inputEvent.button.which if (USE_MOUSEINPUT) { From ea915e5778702dbb86cb88a42c165f45489199a2 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 9 Jun 2018 22:58:03 +0100 Subject: [PATCH 121/122] Fix papersprites more for real this time (Seperate AL and AR sprites were broken, I figured out I was a dunce, oh noey) --- src/hardware/hw_main.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 72c487565..2f49ed7d1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5248,8 +5248,7 @@ static void HWR_ProjectSprite(mobj_t *thing) I_Error("sprframes NULL for sprite %d\n", thing->sprite); #endif - if (sprframe->rotate != SRF_SINGLE) - ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + ang = R_PointToAngle (thing->x, thing->y) - thing->angle; if (sprframe->rotate == SRF_SINGLE) { @@ -5258,7 +5257,7 @@ static void HWR_ProjectSprite(mobj_t *thing) lumpoff = sprframe->lumpid[0]; //Fab: see note above flip = sprframe->flip; // Will only be 0x00 or 0xFF - if (papersprite && (R_PointToAngle (thing->x, thing->y) - thing->angle < ANGLE_180)) + if (papersprite && ang < ANGLE_180) { if (flip) flip = 0; @@ -5279,6 +5278,14 @@ static void HWR_ProjectSprite(mobj_t *thing) //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) @@ -5286,16 +5293,8 @@ static void HWR_ProjectSprite(mobj_t *thing) if (papersprite) { - if (flip && sprframe->rotate != SRF_SINGLE) - { - rightsin = FIXED_TO_FLOAT(FINESINE((thing->angle+ANGLE_180)>>ANGLETOFINESHIFT)); - rightcos = FIXED_TO_FLOAT(FINECOSINE((thing->angle+ANGLE_180)>>ANGLETOFINESHIFT)); - } - else - { - rightsin = FIXED_TO_FLOAT(FINESINE((thing->angle)>>ANGLETOFINESHIFT)); - rightcos = FIXED_TO_FLOAT(FINECOSINE((thing->angle)>>ANGLETOFINESHIFT)); - } + rightsin = FIXED_TO_FLOAT(FINESINE((thing->angle)>>ANGLETOFINESHIFT)); + rightcos = FIXED_TO_FLOAT(FINECOSINE((thing->angle)>>ANGLETOFINESHIFT)); } else { From 54e92a96b35dedce8cbbd4ab597da1d2ef52973c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 11 Jun 2018 19:36:47 +0100 Subject: [PATCH 122/122] backport fix to L/R sprite loading code from internal basically we don't want L/R sprites to always be flipped, for obvious reasons --- src/r_things.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 1352209d7..fa0316bf7 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -148,7 +148,11 @@ 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<