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 4876fbc4bd49b75b42558c512cec402b56e8bcf5 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 7266c7b3ecf1d3a498c65c1c20258e431452d389 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 72433559234ec35e76a5d7171d410000dedacce2 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 b0888c44bd9a9b990eb236837bea2e7cd3cc0022 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 fa1173ed10de2d41549e909a462fdb5eb6024223 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 4383d1fdd2e92898c72cb7a87ea76237ac734d4c 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 c5261c1133a20ea893609b2471080dbf12e55d04 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 afe4178fd7661a1297a32c5b75bf6faf9800d2f4 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 5c6755df7f1446430447e3cd83e3d0c8a647f55f 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 64eba826929536b285fe63a2ad2bf12189ec7d64 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 8ba644679b6fbddb39431a7138359a9ff6100b96 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 6d663fefa7f2a886ff09f861ece2015d81d6d5e0 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 bef710aa8f9c5fcaaff9e5b6b6b1f6d7bafaf463 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 628f9921a857feae147ee158d8d3c79732c06591 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 ce78df03d0ffeaaf21da7732cb8c1a85364cc37e 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 a4637a6dec2b48af990109a2eb66b7541e3438f3 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 39949392ca276b5676a6916dfd27c38ddd2f9092 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 5e42d1dfad7e8baa3700676c7cdb1541568b9576 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 ac645decfab7b5b991e92444317e541b73da4d78 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 426983ff110376c9e2b0cf5f8c65a3c0e6b97864 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 b060d98c288262e4e8fc2f4d2d56fd28fb9341ce 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 3f61a1608d1b93f233b58944fd3c5f17575cc389 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 954850b2216287049d880d33fba344219db0e190 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 e6dff75aab3801fc72bf9d2c814d56bc458955e6 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 83d4f29367decbaa17716092aed7cfcf65681376 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 4114464930cca48d3aec0611fd34d7ee8c0996b8 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 dc02ef886fe62fe67ce8d14335d6977628f795cf 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 429a293a1b7db9df1d366a520b27985338b5a989 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 cb0511a912e541206d23645a6438b82a0bf9cc9e 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 5f4fa843c2f1860679da49b9a577cd32b69b23e0 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 07426558926719a467364e0ccb760af6028fe1ee 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 5c3f203d91dded5e560e7145a60255f92c65b65a 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 7812c55e5786c8e263612ac5f6b7d78b083d4041 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 7308e391a93c9099b515df7d309e4cd6daf98051 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 8ed6d9c31cb1163c5cbed72fb57fe15b2591a795 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 7df299d5e4eb3c4699871097008067b1a1624f05 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 1275c214adf1088b94f5ae8ee1574e22c64f98f3 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 467d24be8ce67079ae0646c510d487598ab44dbe 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 8e18d804fe18c5447043292c9c4b6f9b4cee9ef0 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 4e40a810f7ec10320fd4b1dae07095c6217f243f 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 9c1bf9798a0b8b1ae65a3a8a61200c85d2a9c65f 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 83d4f29367decbaa17716092aed7cfcf65681376. 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 b9dbbef05786d02e8669e2c07c5ed68f65ecaafe 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 28d294933111b8813dcfccb281be8327ab9bfba2 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 9cb3b395eb0d3bcb239a64c46211fcc37253e314 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 07e47f6ccb02acaf4e8a5cf38fb18adf11b670de 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 61ec4911a55aeec135834fd5cc9f876cf32a6797 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 9502d87d8684d50c715af5d3b5a31850a801b4a9 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 c959806e232ea9f9826e9ae9e1aa39536f1ac260 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 d79541e63ce27245accb8ff55671567c32f4888f 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 38cdee2532134878a8ba08aeb43e4bfc58258a54 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 59c14884357c8ef0589ac0ba625fabfbbcdb91c8 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 fd64227e954d034e186f9a3222c098158fa7a0ed 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 0e788e8cfe189d17365b279a9c2bb1376c835440 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 3898fbadf84f94cac8495e326b98c0fac7853fbc 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 8623322bfcdc4d17b8542b3d2526b59b2a8998e1 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 94d7f3b03195d000d60280054501f609521e63a2 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 0ffcc5037e55516ff0bd7c31b2b1bb1c59101e21 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 117017b0a0613d5542b5e47fb1c427441181ce69 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 0e5a389d015babfb0eb108bdd553be0c6d879e59 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 d27b10d5eb8b8a70c390f4c41465256c31a842f3 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 371bbf48aa1a7901a1529af9ce31e968ac1c7ff1 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 5981fb5efc9ced47984f3f1985867fba55008a79 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 8757f6b9339113206afa9f185908016d111ff6f0 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 3004b143a6e1d5c854b2338422b05207e9106467 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 a1da5a272366927e886341ce629d5cc255a2e32f 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 347651ffb1fd183402c333b1f2531cb048ff8824 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 1ac48b08d03598b2b39150da51c342ee191e367d 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 b17629aee63413279a23f361b6577602c3e53f1c 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 1c51872033f8555d349666c449a332721fa82b8e 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 bc6bfec7ea0d70beb561325cefcd33a677be955b 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 2ceba0e71989703b683a617479806694e36737f4 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 8f8ac3810f29d17d224caca6ef56c5243d67aa3a 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 73fdba9941d528e5eafc2e71bd87ca78daa3806e 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 91d2ffd660ca6f9da58c22d2d4765e8bcf909ee0 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 c6fc4256486210b2e8e8067e70e9a7d8f7184612 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 b62752a7b4e15a040890202a67e4944d8dc1599e 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 c6fc4256486210b2e8e8067e70e9a7d8f7184612. 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 4a2cad49fcde0a9504d7fbba6987a8e4a985c20d 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 6a037d09e5ab9165dedd362e5392f8c0151ddfbf 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 52c7a5705262ba23a4438122229433acfec3e087 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 8fdbb3a97b657ad7810bfc536d93466cf9b0337d 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 a3b345f6b1ea8a55996172eb9cf3735184ae5902 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 df7c54d620c07f5db96f6737d8147ed6639c12e9 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 d85f42689b71f4a737e3ae263e9ba01023f00e8c 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 a41f8756e10a9f75c9227fa017f2203cd2e0ac1e 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 9bd92b7e2d4cf8c5f752b2000c90376537299cdc 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 3b7bf18971ea86eb5e2be40319eb3c2a5d819230 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 3e994565423afc236fccbba3d7e7055dc1998138 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 ba7fa3a4072b711aaf23213fca7150bedd5c00c4 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 85aff6fa6b574d1e77239f0ba3948e8107635203 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 0c0d54c98c1b3954204d9c88ed68937ee489c2c0 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 424b66d09b6f3c74af10b61651bad9ee8dfadac0 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 2d3ae11d6f25168516f04429856e92eeb247e03e 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 745be2c641722280469f4b003a7d71ff54bb4fba 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 51606f675f90c37d20924312b64dc004766cec21 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 71fa00e4235b5448513d503221395db74b573e57 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 ca4da924706dd30641b7688a47433c61eb78792f 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 358a47967bfd2376e1e9692122290c3f295e2c00 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<