From b6a8df557ea5290b11d65cc0bd11d11ce58fa53d Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 27 May 2015 00:45:34 -0400 Subject: [PATCH 01/50] New Match weapon/ammo dropping method. P_PlayerWeaponPanelOrAmmoBurst will go through all of the player's weapon rings and either drop the weapon panel itself (with no ammo attached, and no ammo taken away!) OR if the player has ammo but no weapon, it drops the ammo instead (and you lose it). --- src/lua_baselib.c | 11 +++++++ src/p_inter.c | 77 +++++++++++++++++++++++++++++++++++++++++++---- src/p_local.h | 1 + 3 files changed, 83 insertions(+), 6 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9b0a34f17..57bee95ed 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1100,6 +1100,16 @@ static int lib_pPlayerWeaponAmmoBurst(lua_State *L) return 0; } +static int lib_pPlayerWeaponPanelOrAmmoBurst(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_PlayerWeaponPanelOrAmmoBurst(player); + return 0; +} + static int lib_pPlayerEmeraldBurst(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -1965,6 +1975,7 @@ static luaL_Reg lib[] = { {"P_PlayerRingBurst",lib_pPlayerRingBurst}, {"P_PlayerWeaponPanelBurst",lib_pPlayerWeaponPanelBurst}, {"P_PlayerWeaponAmmoBurst",lib_pPlayerWeaponAmmoBurst}, + {"P_PlayerWeaponPanelOrAmmoBurst", lib_pPlayerWeaponPanelOrAmmoBurst}, {"P_PlayerEmeraldBurst",lib_pPlayerEmeraldBurst}, {"P_PlayerFlagBurst",lib_pPlayerFlagBurst}, {"P_PlayRinglossSound",lib_pPlayRinglossSound}, diff --git a/src/p_inter.c b/src/p_inter.c index d305cfc83..97a8624c1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -437,7 +437,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { INT32 pindex = special->info->mass - (INT32)pw_infinityring; - player->powers[special->info->mass] += (UINT16)special->info->reactiontime; + player->powers[special->info->mass] += (UINT16)special->reactiontime; player->ringweapons |= 1 << (pindex-1); if (player->powers[special->info->mass] > rw_maximums[pindex]) @@ -3093,11 +3093,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) P_PlayerEmeraldBurst(player, false); // Spill weapons first - if (player->ringweapons) - P_PlayerWeaponPanelBurst(player); - - // Spill the ammo - P_PlayerWeaponAmmoBurst(player); + P_PlayerWeaponPanelOrAmmoBurst(player); for (i = 0; i < num_rings; i++) { @@ -3354,6 +3350,75 @@ void P_PlayerWeaponAmmoBurst(player_t *player) } } +void P_PlayerWeaponPanelOrAmmoBurst(player_t *player) +{ + mobj_t *mo; + angle_t fa; + fixed_t ns; + INT32 i = 0; + fixed_t z; + + #define SETUP_DROP(thingtype) \ + z = player->mo->z; \ + if (player->mo->eflags & MFE_VERTICALFLIP) \ + z += player->mo->height - mobjinfo[thingtype].height; \ + fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; \ + ns = FixedMul(3*FRACUNIT, player->mo->scale); \ + + #define DROP_WEAPON(rwflag, pickup, ammo, power) \ + if (player->ringweapons & rwflag) \ + { \ + player->ringweapons &= ~rwflag; \ + SETUP_DROP(pickup) \ + mo = P_SpawnMobj(player->mo->x, player->mo->y, z, pickup); \ + mo->reactiontime = 0; \ + mo->flags2 |= MF2_DONTRESPAWN; \ + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ + P_SetTarget(&mo->target, player->mo); \ + mo->fuse = 12*TICRATE; \ + mo->destscale = player->mo->scale; \ + P_SetScale(mo, player->mo->scale); \ + mo->momx = FixedMul(FINECOSINE(fa),ns); \ + if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ + mo->momy = FixedMul(FINESINE(fa),ns); \ + P_SetObjectMomZ(mo, 4*FRACUNIT, false); \ + if (i & 1) \ + P_SetObjectMomZ(mo, 4*FRACUNIT, true); \ + ++i; \ + } \ + else if (player->powers[power] > 0) \ + { \ + SETUP_DROP(ammo) \ + mo = P_SpawnMobj(player->mo->x, player->mo->y, z, ammo); \ + mo->health = player->powers[power]; \ + mo->flags2 |= MF2_DONTRESPAWN; \ + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ + P_SetTarget(&mo->target, player->mo); \ + mo->fuse = 12*TICRATE; \ + mo->destscale = player->mo->scale; \ + P_SetScale(mo, player->mo->scale); \ + mo->momx = FixedMul(FINECOSINE(fa),ns); \ + if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ + mo->momy = FixedMul(FINESINE(fa),ns); \ + P_SetObjectMomZ(mo, 3*FRACUNIT, false); \ + if (i & 1) \ + P_SetObjectMomZ(mo, 3*FRACUNIT, true); \ + player->powers[power] = 0; \ + ++i; \ + } + + DROP_WEAPON(RW_BOUNCE, MT_BOUNCEPICKUP, MT_BOUNCERING, pw_bouncering); + DROP_WEAPON(RW_RAIL, MT_RAILPICKUP, MT_RAILRING, pw_railring); + DROP_WEAPON(RW_AUTO, MT_AUTOPICKUP, MT_AUTOMATICRING, pw_automaticring); + DROP_WEAPON(RW_EXPLODE, MT_EXPLODEPICKUP, MT_EXPLOSIONRING, pw_explosionring); + DROP_WEAPON(RW_SCATTER, MT_SCATTERPICKUP, MT_SCATTERRING, pw_scatterring); + DROP_WEAPON(RW_GRENADE, MT_GRENADEPICKUP, MT_GRENADERING, pw_grenadering); + DROP_WEAPON(0, 0, MT_INFINITYRING, pw_infinityring); + + #undef DROP_WEAPON + #undef SETUP_DROP +} + // // P_PlayerEmeraldBurst // diff --git a/src/p_local.h b/src/p_local.h index 1e0a9e2eb..337cc3663 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -371,6 +371,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget void P_PlayerRingBurst(player_t *player, INT32 num_rings); /// \todo better fit in p_user.c void P_PlayerWeaponPanelBurst(player_t *player); void P_PlayerWeaponAmmoBurst(player_t *player); +void P_PlayerWeaponPanelOrAmmoBurst(player_t *player); void P_PlayerEmeraldBurst(player_t *player, boolean toss); void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck); From 67fcff7ee7260e75cb6be8e708fc9ce44fe0bee3 Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 27 May 2015 01:13:26 -0400 Subject: [PATCH 02/50] New Match ammo consumption rules. Weapon rings can now be fired with no rings at double the ammo cost. --- src/p_user.c | 61 +++++++++++++++++--------------------------------- src/st_stuff.c | 2 +- 2 files changed, 22 insertions(+), 41 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 32dc8733f..1f13e6c38 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3130,72 +3130,64 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) mobj_t *mo = NULL; player->pflags |= PF_ATTACKDOWN; + #define TAKE_AMMO(player, power) \ + player->powers[power]--; \ + if (player->health <= 1) \ + { \ + if (player->powers[power] > 0) \ + player->powers[power]--; \ + } \ + else \ + { \ + player->health--; \ + player->mo->health--; \ + } + if (cmd->buttons & BT_FIRENORMAL) // No powers, just a regular ring. goto firenormal; //code repetition sucks. // Bounce ring else if (player->currentweapon == WEP_BOUNCE && player->powers[pw_bouncering]) { - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_bouncering); P_SetWeaponDelay(player, TICRATE/4); mo = P_SpawnPlayerMissile(player->mo, MT_THROWNBOUNCE, MF2_BOUNCERING); if (mo) mo->fuse = 3*TICRATE; // Bounce Ring time - - player->powers[pw_bouncering]--; - player->mo->health--; - player->health--; } // Rail ring else if (player->currentweapon == WEP_RAIL && player->powers[pw_railring]) { - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_railring); P_SetWeaponDelay(player, (3*TICRATE)/2); mo = P_SpawnPlayerMissile(player->mo, MT_REDRING, MF2_RAILRING|MF2_DONTDRAW); // Rail has no unique thrown object, therefore its sound plays here. S_StartSound(player->mo, sfx_rail1); - - player->powers[pw_railring]--; - player->mo->health--; - player->health--; } // Automatic else if (player->currentweapon == WEP_AUTO && player->powers[pw_automaticring]) { - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_automaticring); player->pflags &= ~PF_ATTACKDOWN; P_SetWeaponDelay(player, 2); mo = P_SpawnPlayerMissile(player->mo, MT_THROWNAUTOMATIC, MF2_AUTOMATIC); - - player->powers[pw_automaticring]--; - player->mo->health--; - player->health--; } // Explosion else if (player->currentweapon == WEP_EXPLODE && player->powers[pw_explosionring]) { - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_explosionring); P_SetWeaponDelay(player, (3*TICRATE)/2); mo = P_SpawnPlayerMissile(player->mo, MT_THROWNEXPLOSION, MF2_EXPLOSION); - - player->powers[pw_explosionring]--; - player->mo->health--; - player->health--; } // Grenade else if (player->currentweapon == WEP_GRENADE && player->powers[pw_grenadering]) { - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_grenadering); P_SetWeaponDelay(player, TICRATE/3); mo = P_SpawnPlayerMissile(player->mo, MT_THROWNGRENADE, MF2_EXPLOSION); @@ -3205,10 +3197,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) //P_InstaThrust(mo, player->mo->angle, FixedMul(mo->info->speed, player->mo->scale)); mo->fuse = mo->info->mass; } - - player->powers[pw_grenadering]--; - player->mo->health--; - player->health--; } // Scatter // Note: Ignores MF2_RAILRING @@ -3218,8 +3206,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) angle_t shotangle = player->mo->angle; angle_t oldaiming = player->aiming; - if (player->health <= 1) - return; + TAKE_AMMO(player, pw_scatterring); P_SetWeaponDelay(player, (2*TICRATE)/3); // Center @@ -3245,10 +3232,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) player->mo->z = oldz; player->aiming = oldaiming; - - player->powers[pw_scatterring]--; - player->mo->health--; - player->health--; return; } // No powers, just a regular ring. @@ -3286,6 +3269,8 @@ firenormal: } } + #undef TAKE_AMMO + if (mo) { if (mo->flags & MF_MISSILE && mo->flags2 & MF2_RAILRING) @@ -9223,10 +9208,6 @@ void P_PlayerAfterThink(player_t *player) if (player->currentweapon == WEP_RAIL && (!(player->ringweapons & RW_RAIL) || !player->powers[pw_railring])) player->currentweapon = 0; - // If you're out of rings, but have Infinity Rings left, switch to that. - if (player->currentweapon != 0 && player->health <= 1 && player->powers[pw_infinityring]) - player->currentweapon = 0; - if (P_IsLocalPlayer(player) && (player->pflags & PF_WPNDOWN) && player->currentweapon != oldweapon) S_StartSound(NULL, sfx_wepchg); diff --git a/src/st_stuff.c b/src/st_stuff.c index 6e19b92ff..940d0f6fa 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1349,7 +1349,7 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I txtflags |= V_YELLOWMAP; if (weapon == pw_infinityring - || (stplyr->ringweapons & rwflag && stplyr->health > 1)) + || (stplyr->ringweapons & rwflag)) txtflags |= V_20TRANS; else { From c6c4ab7c53bbe3a70bbdd3f033dac83f7a4e9c7f Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 27 May 2015 02:08:18 -0400 Subject: [PATCH 03/50] New emerald behavior in Match. No longer turns you super, instead emeralds steal points from enemy players and give you (and relevant teammates) an invincibility + super sneakers monitor. --- src/lua_baselib.c | 23 ++++++++ src/p_inter.c | 132 +++++++++++++++++++++++++++------------------- src/p_local.h | 1 + src/p_user.c | 80 ++++++++++++++++------------ 4 files changed, 147 insertions(+), 89 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 57bee95ed..411dc00cf 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -561,6 +561,17 @@ static int lib_pAddPlayerScore(lua_State *L) return 0; } +static int lib_pStealPlayerScore(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + UINT32 amount = (UINT32)luaL_checkinteger(L, 2); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_StealPlayerScore(player, amount); + return 0; +} + static int lib_pPlayerInPain(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -1217,6 +1228,16 @@ static int lib_pDoNightsScore(lua_State *L) return 0; } +static int lib_pDoMatchSuper(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_DoMatchSuper(player); + return 0; +} + // P_SPEC //////////// @@ -1925,6 +1946,7 @@ static luaL_Reg lib[] = { {"P_GetPlayerSpinHeight",lib_pGetPlayerSpinHeight}, {"P_GetPlayerControlDirection",lib_pGetPlayerControlDirection}, {"P_AddPlayerScore",lib_pAddPlayerScore}, + {"P_StealPlayerScore",lib_pStealPlayerScore}, {"P_PlayerInPain",lib_pPlayerInPain}, {"P_DoPlayerPain",lib_pDoPlayerPain}, {"P_ResetPlayer",lib_pResetPlayer}, @@ -1984,6 +2006,7 @@ static luaL_Reg lib[] = { {"P_PlayLivesJingle",lib_pPlayLivesJingle}, {"P_CanPickupItem",lib_pCanPickupItem}, {"P_DoNightsScore",lib_pDoNightsScore}, + {"P_DoMatchSuper",lib_pDoMatchSuper}, // p_spec {"P_Thrust",lib_pThrust}, diff --git a/src/p_inter.c b/src/p_inter.c index 97a8624c1..e7f671ad1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -217,6 +217,72 @@ void P_DoNightsScore(player_t *player) dummymo->destscale = 2*FRACUNIT; } +// +// P_DoMatchSuper +// +// Checks if you have all 7 pw_emeralds, then turns you "super". =P +// +void P_DoMatchSuper(player_t *player) +{ + UINT16 match_emeralds = player->powers[pw_emeralds]; + boolean doteams = false; + int i; + + // If this gametype has teams, check every player on your team for emeralds. + if (G_GametypeHasTeams()) + { + doteams = true; + for (i = 0; i < MAXPLAYERS; i++) + if (players[i].ctfteam == player->ctfteam) + match_emeralds |= players[i].powers[pw_emeralds]; + } + + if (!ALL7EMERALDS(match_emeralds)) + return; + + // Got 'em all? Turn "super"! + player->powers[pw_emeralds] = 0; + player->powers[pw_invulnerability] = invulntics + 1; + player->powers[pw_sneakers] = player->powers[pw_invulnerability]; + if (P_IsLocalPlayer(player) && !player->powers[pw_super]) + { + S_StopMusic(); + if (mariomode) + { + S_ChangeMusic(mus_minvnc, false); + G_GhostAddColor(GHC_INVINCIBLE); + } + else + S_ChangeMusic(mus_invinc, false); + } + + // Also steal 50 points from every enemy, sealing your victory. + P_StealPlayerScore(player, 50); + + // In a team game? + // Check everyone else on your team for emeralds, and turn those helpful assisting players invincible too. + if (doteams) + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].ctfteam == player->ctfteam + && players[i].powers[pw_emeralds] != 0) + { + players[i].powers[pw_emeralds] = 0; + player->powers[pw_invulnerability] = invulntics + 1; + player->powers[pw_sneakers] = player->powers[pw_invulnerability]; + if (P_IsLocalPlayer(player) && !player->powers[pw_super]) + { + S_StopMusic(); + if (mariomode) + { + S_ChangeMusic(mus_minvnc, false); + G_GhostAddColor(GHC_INVINCIBLE); + } + else + S_ChangeMusic(mus_invinc, false); + } + } +} + /** Takes action based on a ::MF_SPECIAL thing touched by a player. * Actually, this just checks a few things (heights, toucher->player, no * objectplace, no dead or disappearing things) @@ -524,7 +590,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; if (special->threshold) + { player->powers[pw_emeralds] |= special->info->speed; + P_DoMatchSuper(player); + } else emeralds |= special->info->speed; @@ -545,6 +614,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; player->powers[pw_emeralds] |= special->threshold; + P_DoMatchSuper(player); break; // Secret emblem thingy @@ -1356,7 +1426,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } if (player->powers[pw_invulnerability] || player->powers[pw_flashing] - || (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds])))) + || player->powers[pw_super]) return; if (player->powers[pw_shield] || player->bot) //If One-Hit Shield { @@ -2434,16 +2504,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou P_PlayerRingBurst(player, player->mo->health - 1); } - if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - { - player->health -= 10; - if (player->health < 2) - player->health = 2; - target->health = player->health; - } - else - player->health = target->health = 1; - + player->health = target->health = 1; return true; } @@ -2654,16 +2715,6 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { - if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - { - P_DoPlayerPain(player, source, inflictor); - - P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - - if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes - S_StartSound(player->mo, sfx_spkdth); - } - if (source && source->player && !player->powers[pw_super]) //don't score points against super players { // Award no points when players shoot each other when cv_friendlyfire is on. @@ -2913,7 +2964,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } } else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] // ignore bouncing & such in invulnerability - || (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player)))) + || player->powers[pw_super]) { if (force || (inflictor && (inflictor->flags & MF_MISSILE) && (inflictor->flags2 & MF2_SUPERFIRE) @@ -2960,24 +3011,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } } - if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - { - if (player->powers[pw_shield]) - { - P_RemoveShield(player); - return true; - } - else - { - player->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); - if (player->health < 2) - player->health = 2; - } - - if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) - P_PlayerFlagBurst(player, false); - } - else if (damagetype & DMG_DEATHMASK) + if (damagetype & DMG_DEATHMASK) player->health = 0; else { @@ -3001,13 +3035,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_DamageMobj(source, target, target, 1, 0); // do the damage - if (player && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player)) - { - target->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); - if (target->health < 2) - target->health = 2; - } - else if (damagetype & DMG_DEATHMASK) + if (damagetype & DMG_DEATHMASK) target->health = 0; else target->health -= damage; @@ -3022,10 +3050,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } if (player) - { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_ResetPlayer(target->player); - } + P_ResetPlayer(target->player); else switch (target->type) { @@ -3051,10 +3076,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) { if (player) - { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_SetPlayerMobjState(target, target->info->seestate); - } + P_SetPlayerMobjState(target, target->info->seestate); else P_SetMobjState(target, target->info->seestate); } diff --git a/src/p_local.h b/src/p_local.h index 337cc3663..b23f9fdf8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -385,6 +385,7 @@ void P_ResetStarposts(void); boolean P_CanPickupItem(player_t *player, boolean weapon); void P_DoNightsScore(player_t *player); +void P_DoMatchSuper(player_t *player); // // P_SPEC diff --git a/src/p_user.c b/src/p_user.c index 1f13e6c38..14c87a503 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -997,6 +997,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) P_PlayerFlagBurst(player, false); } + // Adds to the player's score void P_AddPlayerScore(player_t *player, UINT32 amount) { @@ -1083,6 +1084,42 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) } } +// Steals from every enemy's score. +void P_StealPlayerScore(player_t *player, UINT32 amount) +{ + boolean teams = G_GametypeHasTeams(); + UINT32 stolen = 0; + int i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (&players[i] == player + || (teams && players[i].ctfteam == player->ctfteam)) + continue; + if (players[i].score >= amount) + { + stolen += amount; + players[i].score -= amount; + } + else + { + stolen += players[i].score; + players[i].score = 0; + } + } + if (stolen > 0) + { + // In team match, all stolen points are removed from the enemy team's running score. + if (gametype == GT_TEAMMATCH) + { + if (player->ctfteam == 1) + bluescore -= amount; + else if (player->ctfteam == 2) + redscore -= amount; + } + P_AddPlayerScore(player, stolen); + } +} + // // P_PlayLivesJingle // @@ -3321,7 +3358,7 @@ static void P_DoSuperStuff(player_t *player) return; // NiGHTS Super doesn't mix with normal super // Does player have all emeralds? If so, flag the "Ready For Super!" - if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->health > 50) + if (ALL7EMERALDS(emeralds) && player->health > 50) player->pflags |= PF_SUPERREADY; else player->pflags &= ~PF_SUPERREADY; @@ -3329,7 +3366,7 @@ static void P_DoSuperStuff(player_t *player) if (player->powers[pw_super]) { // If you're super and not Sonic, de-superize! - if (!((ALL7EMERALDS(emeralds)) && (player->charflags & SF_SUPER)) && !(ALL7EMERALDS(player->powers[pw_emeralds]))) + if (!(ALL7EMERALDS(emeralds) && player->charflags & SF_SUPER)) { player->powers[pw_super] = 0; P_SetPlayerMobjState(player->mo, S_PLAY_STND); @@ -3462,12 +3499,12 @@ static void P_DoSuperStuff(player_t *player) // boolean P_SuperReady(player_t *player) { - if ((player->pflags & PF_SUPERREADY) && !player->powers[pw_super] && !player->powers[pw_tailsfly] + if (player->pflags & PF_SUPERREADY && !player->powers[pw_super] && !player->powers[pw_tailsfly] && !(player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_invulnerability] && !(maptol & TOL_NIGHTS) // don't turn 'regular super' in nights levels && player->pflags & PF_JUMPED - && ((player->charflags & SF_SUPER) || ALL7EMERALDS(player->powers[pw_emeralds]))) + && player->charflags & SF_SUPER) return true; return false; @@ -3995,13 +4032,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags |= PF_GLIDING|PF_THOKKED; player->glidetime = 0; - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - { - // Glide at double speed while super. - glidespeed *= 2; - player->pflags &= ~PF_THOKKED; - } - P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); P_InstaThrust(player->mo, player->mo->angle, FixedMul(glidespeed, player->mo->scale)); player->pflags &= ~(PF_SPINNING|PF_STARTDASH); @@ -4115,8 +4145,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags &= ~PF_JUMPDOWN; // Repeat abilities, but not double jump! - if ((player->charability2 == CA2_MULTIABILITY && player->charability != CA_DOUBLEJUMP) - || (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) + if (player->charability2 == CA2_MULTIABILITY && player->charability != CA_DOUBLEJUMP) player->secondjump = 0; else if (player->charability == CA_FLOAT && player->secondjump == 1) player->secondjump = 2; @@ -4360,9 +4389,6 @@ static void P_2dMovement(player_t *player) if (cmd->forwardmove != 0) P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT,10*FRACUNIT), false); - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - player->mo->momz *= 2; - player->mo->momx = 0; } else if (cmd->sidemove != 0 && !(player->pflags & PF_GLIDING || player->exiting @@ -4556,11 +4582,7 @@ static void P_3dMovement(player_t *player) if (player->climbing) { if (cmd->forwardmove) - { P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 10*FRACUNIT), false); - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - player->mo->momz *= 2; - } } else if (!analogmove && cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting @@ -4601,12 +4623,7 @@ static void P_3dMovement(player_t *player) } // Sideways movement if (player->climbing) - { - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 5*FRACUNIT), player->mo->scale)); - else - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 10*FRACUNIT), player->mo->scale)); - } + P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 10*FRACUNIT), player->mo->scale)); // Analog movement control else if (analogmove) { @@ -6510,8 +6527,8 @@ static void P_MovePlayer(player_t *player) P_ResetPlayer(player); // down, stop gliding. if (onground) P_SetPlayerMobjState(player->mo, S_PLAY_WALK); - else if ((player->charability2 == CA2_MULTIABILITY) - || (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && player->charability == CA_GLIDEANDCLIMB)) + else if (player->charability2 == CA2_MULTIABILITY + && player->charability == CA_GLIDEANDCLIMB) { player->pflags |= PF_JUMPED; P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); @@ -6764,11 +6781,6 @@ static void P_MovePlayer(player_t *player) { if ((player->powers[pw_shield] & SH_NOSTACK) == SH_JUMP && !player->powers[pw_super]) P_DoJumpShield(player); - else if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && player->charability == CA_FLY) - { - P_DoJumpShield(player); - player->mo->momz *= 2; - } } // Bomb shield activation if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) @@ -8924,7 +8936,7 @@ void P_PlayerThink(player_t *player) if (player->powers[pw_flashing] && player->powers[pw_flashing] < UINT16_MAX && ((player->pflags & PF_NIGHTSMODE) || player->powers[pw_flashing] < flashingtics)) player->powers[pw_flashing]--; - if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM && !(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) // tails fly counter + if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM) // tails fly counter player->powers[pw_tailsfly]--; if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)) From 1c1acb9f0e9ac543b33604a7173b7c6d78291f19 Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 27 May 2015 04:01:58 -0400 Subject: [PATCH 04/50] Add emeraldspawndelay for Match "super" Emeralds will not spawn while players are still enjoying their victory dance now. --- src/g_game.c | 1 + src/p_inter.c | 5 +++-- src/p_mobj.c | 8 +++----- src/p_mobj.h | 1 + src/p_setup.c | 1 + 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 643ec8c93..7176d90dc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -86,6 +86,7 @@ UINT8 modeattacking = ATTACKING_NONE; boolean disableSpeedAdjust = false; boolean imcontinuing = false; boolean runemeraldmanager = false; +UINT16 emeraldspawndelay = 60*TICRATE; // menu demo things UINT8 numDemos = 3; diff --git a/src/p_inter.c b/src/p_inter.c index e7f671ad1..d5c82fefc 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -241,9 +241,10 @@ void P_DoMatchSuper(player_t *player) return; // Got 'em all? Turn "super"! + emeraldspawndelay = invulntics + 1; player->powers[pw_emeralds] = 0; - player->powers[pw_invulnerability] = invulntics + 1; - player->powers[pw_sneakers] = player->powers[pw_invulnerability]; + player->powers[pw_invulnerability] = emeraldspawndelay; + player->powers[pw_sneakers] = emeraldspawndelay; if (P_IsLocalPlayer(player) && !player->powers[pw_super]) { S_StopMusic(); diff --git a/src/p_mobj.c b/src/p_mobj.c index 9565648c2..7742d63e1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -657,14 +657,12 @@ void P_EmeraldManager(void) else break; - if (leveltime < TICRATE) // Start of map - spawnpoints[j]->threshold = 60*TICRATE + P_Random() * (TICRATE/5); - else - spawnpoints[j]->threshold = P_Random() * (TICRATE/5); - + spawnpoints[j]->threshold = emeraldspawndelay + P_Random() * (TICRATE/5); break; } } + + emeraldspawndelay = 0; } // diff --git a/src/p_mobj.h b/src/p_mobj.h index 8e782b92e..5a4e01caf 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -444,5 +444,6 @@ void P_EmeraldManager(void); extern mapthing_t *huntemeralds[MAXHUNTEMERALDS]; extern INT32 numhuntemeralds; extern boolean runemeraldmanager; +extern UINT16 emeraldspawndelay; extern INT32 numstarposts; #endif diff --git a/src/p_setup.c b/src/p_setup.c index f2b0c49d8..196f6a471 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2015,6 +2015,7 @@ static void P_LevelInitStuff(void) // special stage tokens, emeralds, and ring total tokenbits = 0; runemeraldmanager = false; + emeraldspawndelay = 60*TICRATE; nummaprings = 0; // emerald hunt From 7118925959f16fab6be85c3138280f78640fe92c Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Wed, 27 May 2015 06:43:24 -0400 Subject: [PATCH 05/50] Fix broken P_RingDamage bug from c6c4ab7c Accidentally snipped too much out of P_DamageMobj's subfunctions... --- src/p_inter.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index d5c82fefc..7fb81dede 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2716,6 +2716,13 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { + P_DoPlayerPain(player, source, inflictor); + + P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); + + if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes + S_StartSound(player->mo, sfx_spkdth); + if (source && source->player && !player->powers[pw_super]) //don't score points against super players { // Award no points when players shoot each other when cv_friendlyfire is on. From bed8dc4c7c8c87a4af19fb75ac27bb2b00259413 Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Thu, 28 May 2015 03:24:55 -0400 Subject: [PATCH 06/50] Tails ringslinger buff. Any character with CA_FLY will now throw rings 1.5x as fast. --- src/p_mobj.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7742d63e1..3f6d039a0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9534,7 +9534,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai { mobj_t *th; angle_t an; - fixed_t x, y, z, slope = 0; + fixed_t x, y, z, slope = 0, speed; // angle at which you fire, is player angle an = angle; @@ -9566,9 +9566,13 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai P_SetTarget(&th->target, source); + speed = th->info->speed; + if (source->player && source->player->charability == CA_FLY) + speed = FixedMul(speed, 3*FRACUNIT/2); + th->angle = an; - th->momx = FixedMul(th->info->speed, FINECOSINE(an>>ANGLETOFINESHIFT)); - th->momy = FixedMul(th->info->speed, FINESINE(an>>ANGLETOFINESHIFT)); + th->momx = FixedMul(speed, FINECOSINE(an>>ANGLETOFINESHIFT)); + th->momy = FixedMul(speed, FINESINE(an>>ANGLETOFINESHIFT)); if (allowaim) { @@ -9576,7 +9580,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai th->momy = FixedMul(th->momy,FINECOSINE(source->player->aiming>>ANGLETOFINESHIFT)); } - th->momz = FixedMul(th->info->speed, slope); + th->momz = FixedMul(speed, slope); //scaling done here so it doesn't clutter up the code above th->momx = FixedMul(th->momx, th->scale); From 8cde0121d03f140c476e538be88b063c286f835c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 14 Aug 2015 15:55:24 +0100 Subject: [PATCH 07/50] Remove the switch-to-seestate behavior in P_DamageMobj. In Doom there was a random chance of enemies either being stunned (painstate) or instead just deciding to attack you (seetstate), but in SRB2 painstate is ALWAYS used beforehand. --- src/p_inter.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index d305cfc83..146be5077 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3048,16 +3048,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // if not intent on another player, // chase after this one P_SetTarget(&target->target, source); - if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) - { - if (player) - { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_SetPlayerMobjState(target, target->info->seestate); - } - else - P_SetMobjState(target, target->info->seestate); - } } return true; From 6bc1a5fdefbeeb710cab5ebd8ddf7cd161f0cd24 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 15 Aug 2015 21:07:16 +0100 Subject: [PATCH 08/50] Okay, major overhaul time! *player->health (formerly the "HUD" health) is now to be known as player->rings, and now acts as the player's actual ring count *player->mo->health (formerly rings + 1) is now always 1 when alive, regardless of ring count; if player with rings is damaged, this is untouched Damage in normal SP/Coop gameplay has been tested and still works fine; still a lot of mess to clear up though Tag damaging probably is broken now, I'll fix this later --- src/d_clisrv.c | 7 ++- src/d_clisrv.h | 3 +- src/d_netcmd.c | 2 +- src/d_player.h | 6 +-- src/g_game.c | 2 +- src/hu_stuff.c | 36 +++++++------- src/lua_baselib.c | 2 +- src/lua_playerlib.c | 8 ++-- src/m_cheat.c | 6 +-- src/m_menu.c | 4 +- src/p_enemy.c | 18 +++---- src/p_inter.c | 79 +++++++++++++++---------------- src/p_mobj.c | 17 +++---- src/p_saveg.c | 4 +- src/p_setup.c | 2 +- src/p_spec.c | 22 ++++----- src/p_tick.c | 2 +- src/p_user.c | 113 ++++++++++++++++---------------------------- src/st_stuff.c | 18 +++---- src/y_inter.c | 14 +++--- 20 files changed, 164 insertions(+), 201 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c0179ca1b..d08badd4a 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -495,7 +495,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]); // Score is resynched in the rspfirm resync packet - rsp->health = 0; // resynched with mo health + rsp->rings = LONG(players[i].rings); rsp->lives = players[i].lives; rsp->continues = players[i].continues; rsp->scoreadd = players[i].scoreadd; @@ -577,7 +577,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->hasmo = true; rsp->health = LONG(players[i].mo->health); - rsp->angle = (angle_t)LONG(players[i].mo->angle); rsp->x = LONG(players[i].mo->x); rsp->y = LONG(players[i].mo->y); @@ -620,7 +619,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]); // Score is resynched in the rspfirm resync packet - players[i].health = rsp->health; + players[i].rings = LONG(rsp->rings); players[i].lives = rsp->lives; players[i].continues = rsp->continues; players[i].scoreadd = rsp->scoreadd; @@ -2244,7 +2243,7 @@ static void CL_RemovePlayer(INT32 playernum) } count--; - rings = players[playernum].health - 1; + rings = players[playernum].rings; increment = rings/count; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 6bc06f13a..bf07f035c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -155,7 +155,7 @@ typedef struct UINT16 powers[NUMPOWERS]; // Score is resynched in the confirm resync packet - INT32 health; + INT32 rings; SINT8 lives; SINT8 continues; UINT8 scoreadd; @@ -231,6 +231,7 @@ typedef struct //player->mo stuff UINT8 hasmo; //boolean + INT32 health; angle_t angle; fixed_t x; fixed_t y; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 557715064..537588e4b 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2558,7 +2558,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (players[playernum].spectator) { players[playernum].score = 0; - players[playernum].health = 1; + players[playernum].rings = 0; if (players[playernum].mo) players[playernum].mo->health = 1; } diff --git a/src/d_player.h b/src/d_player.h index e2a1081b0..8c3df4883 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -278,10 +278,8 @@ typedef struct player_s // It is updated with cmd->aiming. angle_t aiming; - // This is only used between levels, - // mo->health is used during levels. - /// \todo Remove this. We don't need a second health definition for players. - INT32 health; + // player's ring count + INT32 rings; SINT8 pity; // i pity the fool. INT32 currentweapon; // current weapon selected. diff --git a/src/g_game.c b/src/g_game.c index 643ec8c93..41b875ce7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2177,7 +2177,7 @@ void G_PlayerReborn(INT32 player) p->pflags |= PF_JUMPDOWN; p->playerstate = PST_LIVE; - p->health = 1; // 0 rings + p->rings = 0; // 0 rings p->panim = PA_IDLE; // standing animation if ((netgame || multiplayer) && !p->spectator) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 80e30beb5..dd7418f60 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1198,7 +1198,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_60TRANS) + | ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS) | V_ALLOWLOWERCASE, tab[i].name); // Draw emeralds @@ -1208,7 +1208,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I HU_DrawEmeralds(x-12,y+2,tab[i].emeralds); } - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentPatch (x, y-4, V_80TRANS, livesback); else V_DrawSmallScaledPatch (x, y-4, 0, livesback); @@ -1220,7 +1220,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I V_DrawSmallScaledPatch(x, y-4, 0, superprefix[players[tab[i].num].skin]); else { - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentPatch(x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin]); else V_DrawSmallScaledPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin]); @@ -1236,7 +1236,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); @@ -1244,10 +1244,10 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } if (G_GametypeUsesLives()) //show lives - V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%dx", players[tab[i].num].lives)); + V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) { - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentPatch(x-32, y-4, V_60TRANS, tagico); else V_DrawSmallScaledPatch(x-32, y-4, 0, tagico); @@ -1260,13 +1260,13 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I if (players[tab[i].num].exiting) V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); } else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); } else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); y += 16; } @@ -1311,7 +1311,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) strlcpy(name, tab[i].name, 9); V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) + | ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT) | V_ALLOWLOWERCASE, name); if (gametype == GT_CTF) @@ -1337,12 +1337,12 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); } - V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); } } @@ -1367,7 +1367,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline strlcpy(name, tab[i].name, 9); V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) + | ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT) | V_ALLOWLOWERCASE, name); if (G_GametypeUsesLives()) //show lives @@ -1390,7 +1390,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline V_DrawSmallScaledPatch (x, y-4, 0, superprefix[players[tab[i].num].skin]); else { - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]); else V_DrawSmallScaledPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]); @@ -1406,7 +1406,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); @@ -1421,13 +1421,13 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline if (players[tab[i].num].exiting) V_DrawRightAlignedThinString(x+156, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); } else - V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); } else - V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); y += 16; if (y > 160) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 2a5ff8d65..50324d8f2 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1068,7 +1068,7 @@ static int lib_pPlayerRingBurst(lua_State *L) if (!player) return LUA_ErrInvalid(L, "player_t"); if (num_rings == -1) - num_rings = player->health - 1; + num_rings = player->rings; P_PlayerRingBurst(player, num_rings); return 0; } diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 64513ab97..64396670b 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -118,8 +118,8 @@ static int player_get(lua_State *L) lua_pushfixed(L, plr->bob); else if (fastcmp(field,"aiming")) lua_pushangle(L, plr->aiming); - else if (fastcmp(field,"health")) - lua_pushinteger(L, plr->health); + else if (fastcmp(field,"rings")) + lua_pushinteger(L, plr->rings); else if (fastcmp(field,"pity")) lua_pushinteger(L, plr->pity); else if (fastcmp(field,"currentweapon")) @@ -368,8 +368,8 @@ static int player_set(lua_State *L) else if (plr == &players[secondarydisplayplayer]) localaiming2 = plr->aiming; } - else if (fastcmp(field,"health")) - plr->health = (INT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"rings")) + plr->rings = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"pity")) plr->pity = (SINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"currentweapon")) diff --git a/src/m_cheat.c b/src/m_cheat.c index 4da9b3ba7..dde3376f8 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -625,7 +625,7 @@ void Command_CauseCfail_f(void) players[consoleplayer].mo->y = 123311; //cfail cansuled kthxbye players[consoleplayer].mo->z = 123311; players[consoleplayer].score = 1337; - players[consoleplayer].health = 1337; + players[consoleplayer].rings = 1337; players[consoleplayer].mo->destscale = 25; P_SetThingPosition(players[consoleplayer].mo); @@ -739,7 +739,7 @@ void Command_Setrings_f(void) if (COM_Argc() > 1) { // P_GivePlayerRings does value clamping - players[consoleplayer].health = players[consoleplayer].mo->health = 1; + players[consoleplayer].rings = 0; P_GivePlayerRings(&players[consoleplayer], atoi(COM_Argv(1))); if (!G_IsSpecialStage(gamemap) || !useNightsSS) players[consoleplayer].totalring -= atoi(COM_Argv(1)); //undo totalring addition done in P_GivePlayerRings @@ -1241,7 +1241,7 @@ void Command_ObjectPlace_f(void) // Like the classics, recover from death by entering objectplace if (players[0].mo->health <= 0) { - players[0].mo->health = players[0].health = 1; + players[0].mo->health = 1; players[0].deadtimer = 0; op_oldflags1 = mobjinfo[MT_PLAYER].flags; ++players[0].lives; diff --git a/src/m_menu.c b/src/m_menu.c index 88893b3c6..f19c4da3d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3789,7 +3789,7 @@ static void M_HandleImageDef(INT32 choice) static void M_PandorasBox(INT32 choice) { (void)choice; - CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].health - 1, 0)); + CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].rings, 0)); CV_StealthSetValue(&cv_dummylives, players[consoleplayer].lives); CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues); M_SetupNextMenu(&SR_PandoraDef); @@ -3797,7 +3797,7 @@ static void M_PandorasBox(INT32 choice) static boolean M_ExitPandorasBox(void) { - if (cv_dummyrings.value != max(players[consoleplayer].health - 1, 0)) + if (cv_dummyrings.value != max(players[consoleplayer].rings, 0)) COM_ImmedExecute(va("setrings %d", cv_dummyrings.value)); if (cv_dummylives.value != players[consoleplayer].lives) COM_ImmedExecute(va("setlives %d", cv_dummylives.value)); diff --git a/src/p_enemy.c b/src/p_enemy.c index 3cc9aaca2..303e74880 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -655,15 +655,15 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed if ((netgame || multiplayer) && player->spectator) continue; - if (player->health <= 0) - continue; // dead - if (player->pflags & PF_INVIS) continue; // ignore notarget if (!player->mo || P_MobjWasRemoved(player->mo)) continue; + if (player->mo->health <= 0) + continue; // dead + if (dist > 0 && P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist) continue; // Too far away @@ -727,7 +727,7 @@ static boolean P_LookForShield(mobj_t *actor) player = &players[actor->lastlook]; - if (player->health <= 0 || !player->mo) + if (!player->mo || player->mo->health <= 0) continue; // dead //When in CTF, don't pull rings that you cannot pick up. @@ -2721,7 +2721,7 @@ void A_BossDeath(mobj_t *mo) // make sure there is a player alive for victory for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (players[i].health > 0 + if (playeringame[i] && ((players[i].mo && players[i].mo->health > 0) || ((netgame || multiplayer) && (players[i].lives > 0 || players[i].continues > 0)))) break; @@ -8268,7 +8268,7 @@ void A_RingDrain(mobj_t *actor) } player = actor->target->player; - P_GivePlayerRings(player, -min(locvar1, player->mo->health-1)); + P_GivePlayerRings(player, -min(locvar1, player->rings)); } // Function: A_SplitShot @@ -8578,7 +8578,7 @@ void A_CheckTargetRings(mobj_t *actor) if (!(actor->target) || !(actor->target->player)) return; - if (actor->target->player->health >= locvar1) + if (actor->target->player->rings >= locvar1) P_SetMobjState(actor, locvar2); } @@ -8600,7 +8600,7 @@ void A_CheckRings(mobj_t *actor) #endif for (i = 0; i < MAXPLAYERS; i++) - cntr += players[i].health-1; + cntr += players[i].rings; if (cntr >= locvar1) P_SetMobjState(actor, locvar2); @@ -9172,7 +9172,7 @@ void A_ForceWin(mobj_t *actor) for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && (players[i].health > 0 + if (playeringame[i] && ((players[i].mo && players[i].mo->health > 0) || ((netgame || multiplayer) && (players[i].lives > 0 || players[i].continues > 0)))) break; } diff --git a/src/p_inter.c b/src/p_inter.c index de90f419e..3bf0e68a5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -796,16 +796,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (G_IsSpecialStage(gamemap) && !player->exiting) { // In special stages, share rings. Everyone gives up theirs to the player who touched the capsule for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (&players[i] != player) && players[i].mo->health > 1) + if (playeringame[i] && (&players[i] != player) && players[i].rings > 0) { - toucher->health += players[i].mo->health-1; - player->health = toucher->health; - players[i].mo->health = 1; - players[i].health = players[i].mo->health; + player->rings += players[i].rings; + players[i].rings = 0; } } - if (!(player->health > 1) || player->exiting) + if (player->rings <= 0 || player->exiting) return; // Mark the player as 'pull into the capsule' @@ -1366,11 +1364,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) else { P_PlayRinglossSound(toucher); - if (toucher->health > 10) - toucher->health -= 10; + if (player->rings >= 10) + player->rings -= 10; else - toucher->health = 1; - player->health = toucher->health; + player->rings = 0; } P_DoPlayerPain(player, special, NULL); @@ -1475,6 +1472,9 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour if (!player) return; // Impossible! + if (!player->mo) + return; // Also impossible! + if (!netgame) return; // Presumably it's obvious what's happening in splitscreen. @@ -1483,7 +1483,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour return; #endif - deadtarget = (player->health <= 0); + deadtarget = (player->mo->health <= 0); // Target's name snprintf(targetname, sizeof(targetname), "%s%s%s", @@ -2428,26 +2428,25 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou return true; } - if (target->health <= 1) // Death + if (player->rings > 0) // Ring loss + { + P_PlayRinglossSound(target); + P_PlayerRingBurst(player, player->rings); + } + else // Death { P_PlayDeathSound(target); P_PlayVictorySound(source); // Killer laughs at you! LAUGHS! BWAHAHAHHAHAA!! } - else if (target->health > 1) // Ring loss - { - P_PlayRinglossSound(target); - P_PlayerRingBurst(player, player->mo->health - 1); - } if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) { - player->health -= 10; - if (player->health < 2) - player->health = 2; - target->health = player->health; + player->rings -= 10; + if (player->rings < 1) + player->rings = 1; } else - player->health = target->health = 1; + player->rings = 0; return true; } @@ -2497,7 +2496,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) // Burst weapons and emeralds in Match/CTF only if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)) { - P_PlayerRingBurst(player, player->health - 1); + P_PlayerRingBurst(player, player->rings); P_PlayerEmeraldBurst(player, false); } @@ -2942,9 +2941,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_ShieldDamage(player, inflictor, source, damage); damage = 0; } - else if (player->mo->health > 1) // No shield but have rings. + else if (player->rings > 0) // No shield but have rings. { - damage = player->mo->health - 1; + damage = player->rings; P_RingDamage(player, inflictor, source, damage, damagetype); } else // No shield, no rings, no invincibility. @@ -2974,26 +2973,28 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } else { - player->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); - if (player->health < 2) - player->health = 2; + player->rings -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); + if (player->rings < 1) + player->rings = 1; } if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) P_PlayerFlagBurst(player, false); + damage = 0; } else if (damagetype & DMG_DEATHMASK) - player->health = 0; - else + player->rings = 0; + else if (damage == 0 || player->rings) //quickfix to just get things back to normal ...for now (sans Tag, I'll deal with that later) { - player->health -= damage; // mirror mobj health here - target->player->powers[pw_flashing] = flashingtics; if (damage > 0) // don't spill emeralds/ammo/panels for shield damage P_PlayerRingBurst(player, damage); + player->rings -= damage; + target->player->powers[pw_flashing] = flashingtics; + damage = 0; } - if (player->health < 0) - player->health = 0; + if (player->rings < 0) + player->rings = 0; P_HitDeathMessages(player, inflictor, source, damagetype); @@ -3006,13 +3007,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_DamageMobj(source, target, target, 1, 0); // do the damage - if (player && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player)) - { - target->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); - if (target->health < 2) - target->health = 2; - } - else if (damagetype & DMG_DEATHMASK) + if (damagetype & DMG_DEATHMASK) target->health = 0; else target->health -= damage; @@ -3078,7 +3073,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) return; // If no health, don't spawn ring! - if (player->mo->health <= 1) + if (player->rings <= 0) num_rings = 0; if (num_rings > 32 && !(player->pflags & PF_NIGHTSFALL)) diff --git a/src/p_mobj.c b/src/p_mobj.c index 8ea71d6c7..d0a6b2432 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3357,15 +3357,15 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) player = &players[actor->lastlook]; - if (player->health <= 0) - continue; // dead - if (player->pflags & PF_INVIS || player->bot || player->spectator) continue; // ignore notarget if (!player->mo || P_MobjWasRemoved(player->mo)) continue; + if (player->mo->health <= 0) + continue; //dead + if (!P_CheckSight(actor, player->mo)) continue; // out of sight @@ -3395,15 +3395,15 @@ boolean P_SupermanLook4Players(mobj_t *actor) { if (playeringame[c]) { - if (players[c].health <= 0) - continue; // dead - if (players[c].pflags & PF_INVIS) continue; // ignore notarget if (!players[c].mo || players[c].bot) continue; + if (players[c].mo->health <= 0) + continue; // dead + playersinthegame[stop] = &players[c]; stop++; } @@ -6175,7 +6175,7 @@ void P_MobjThinker(mobj_t *mobj) P_SetTarget(&mobj->target, NULL); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo - && players[i].mare == mobj->threshold && players[i].health > 1) + && players[i].mare == mobj->threshold && players[i].rings > 0) { fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); if (dist < shortest) @@ -7819,7 +7819,8 @@ void P_SpawnPlayer(INT32 playernum) // the dead body mobj retains the skin through the 'spritedef' override). mobj->skin = &skins[p->skin]; - mobj->health = p->health; + mobj->health = 1; + p->rings = 0; p->playerstate = PST_LIVE; p->bonustime = false; diff --git a/src/p_saveg.c b/src/p_saveg.c index 2afcfd0ef..5a2da118b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -125,7 +125,7 @@ static inline void P_NetArchivePlayers(void) WRITEANGLE(save_p, players[i].aiming); WRITEANGLE(save_p, players[i].awayviewaiming); WRITEINT32(save_p, players[i].awayviewtics); - WRITEINT32(save_p, players[i].health); + WRITEINT32(save_p, players[i].rings); WRITESINT8(save_p, players[i].pity); WRITEINT32(save_p, players[i].currentweapon); @@ -300,7 +300,7 @@ static inline void P_NetUnArchivePlayers(void) players[i].aiming = READANGLE(save_p); players[i].awayviewaiming = READANGLE(save_p); players[i].awayviewtics = READINT32(save_p); - players[i].health = READINT32(save_p); + players[i].rings = READINT32(save_p); players[i].pity = READSINT8(save_p); players[i].currentweapon = READINT32(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index f2b0c49d8..10f4f4bc3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2057,7 +2057,7 @@ static void P_LevelInitStuff(void) players[i].gotcontinue = false; players[i].xtralife = players[i].deadtimer = players[i].numboxes = players[i].totalring = players[i].laps = 0; - players[i].health = 1; + players[i].rings = 0; players[i].aiming = 0; players[i].pflags &= ~PF_TIMEOVER; diff --git a/src/p_spec.c b/src/p_spec.c index cb3340ee4..6712f40ec 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1592,10 +1592,10 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (!playeringame[i] || players[i].spectator) continue; - if (!players[i].mo || players[i].mo->health < 1) + if (!players[i].mo || players[i].rings <= 0) continue; - rings += players[i].mo->health-1; + rings += players[i].rings; } } else @@ -1603,7 +1603,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (!(actor && actor->player)) return false; // no player to count rings from here, sorry - rings = actor->health-1; + rings = actor->player->rings; } if (triggerline->flags & ML_NOCLIMB) @@ -3499,10 +3499,9 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers break; case 9: // Ring Drainer (Floor Touch) case 10: // Ring Drainer (No Floor Touch) - if (leveltime % (TICRATE/2) == 0 && player->mo->health > 1) + if (leveltime % (TICRATE/2) == 0 && player->rings > 0) { - player->mo->health--; - player->health--; + player->rings--; S_StartSound(player->mo, sfx_itemup); } break; @@ -3510,7 +3509,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super] || player->exiting || player->bot) break; - if (!(player->powers[pw_shield] || player->mo->health > 1)) // Don't do anything if no shield or rings anyway + if (!(player->powers[pw_shield] || player->rings > 0)) // Don't do anything if no shield or rings anyway break; if (player->powers[pw_shield]) @@ -3518,14 +3517,13 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers P_RemoveShield(player); S_StartSound(player->mo, sfx_shldls); // Ba-Dum! Shield loss. } - else if (player->mo->health > 1) + else if (player->rings > 0) { P_PlayRinglossSound(player->mo); - if (player->mo->health > 10) - player->mo->health -= 10; + if (player->rings >= 10) + player->rings -= 10; else - player->mo->health = 1; - player->health = player->mo->health; + player->rings = 0; } P_DoPlayerPain(player, NULL, NULL); // this does basically everything that was here before diff --git a/src/p_tick.c b/src/p_tick.c index 15d3abc80..3c7820c2d 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -469,7 +469,7 @@ static inline void P_DoSpecialStageStuff(void) for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) { - ssrings += (players[i].mo->health-1); + ssrings += players[i].rings; // If in water, deplete timer 6x as fast. if ((players[i].mo->eflags & MFE_TOUCHWATER) diff --git a/src/p_user.c b/src/p_user.c index c7d612efc..2f384de34 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -704,7 +704,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) { for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]/* && players[i].pflags & PF_NIGHTSMODE*/) - total_rings += players[i].health-1; + total_rings += players[i].rings; } for (i = 0; i < MAXPLAYERS; i++) @@ -722,8 +722,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) } else { - players[i].finishedrings = (INT16)(players[i].health - 1); - P_AddPlayerScore(&players[i], (players[i].health - 1) * 50); + players[i].finishedrings = (INT16)(players[i].rings); + P_AddPlayerScore(&players[i], (players[i].rings) * 50); } // Add score to leaderboards now @@ -734,7 +734,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) players[i].lastmarescore = players[i].marescore; players[i].marescore = 0; - players[i].mo->health = players[i].health = 1; + players[i].rings = 0; P_DoPlayerExit(&players[i]); } } @@ -742,12 +742,12 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) { /// \todo Handle multi-mare special stages. // Ring bonus - P_AddPlayerScore(player, (player->health - 1) * 50); + P_AddPlayerScore(player, (player->rings) * 50); player->lastmare = (UINT8)oldmare; player->texttimer = 4*TICRATE; player->textvar = 4; // Score and grades - player->finishedrings = (INT16)(player->health - 1); + player->finishedrings = (INT16)(player->rings); // Add score to temp leaderboards if (!(netgame||multiplayer) && P_IsLocalPlayer(player)) @@ -758,7 +758,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->marescore = 0; player->marebegunat = leveltime; - player->mo->health = player->health = 1; + player->rings = 0; } else { @@ -901,30 +901,23 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (!player->mo) return; - player->mo->health += num_rings; - player->health += num_rings; + player->rings += num_rings; if (!G_IsSpecialStage(gamemap) || !useNightsSS) player->totalring += num_rings; // Can only get up to 9999 rings, sorry! - if (player->mo->health > 10000) - { - player->mo->health = 10000; - player->health = 10000; - } - else if (player->mo->health < 1) - { - player->mo->health = 1; - player->health = 1; - } + if (player->rings > 9999) + player->rings = 9999; + else if (player->rings < 0) + 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()) { INT32 gainlives = 0; - while (player->xtralife < maxXtraLife && player->health > 100 * (player->xtralife+1)) + while (player->xtralife < maxXtraLife && player->rings >= 100 * (player->xtralife+1)) { ++gainlives; ++player->xtralife; @@ -975,10 +968,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) player->mo->momx = player->mo->momy = player->mo->momz = 0; if (giverings) - { - player->mo->health = 51; - player->health = player->mo->health; - } + player->rings = 50; // Just in case. if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) @@ -3135,7 +3125,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) // Bounce ring else if (player->currentweapon == WEP_BOUNCE && player->powers[pw_bouncering]) { - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, TICRATE/4); @@ -3145,13 +3135,12 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) mo->fuse = 3*TICRATE; // Bounce Ring time player->powers[pw_bouncering]--; - player->mo->health--; - player->health--; + player->rings--; } // Rail ring else if (player->currentweapon == WEP_RAIL && player->powers[pw_railring]) { - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, (3*TICRATE)/2); @@ -3161,13 +3150,12 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) S_StartSound(player->mo, sfx_rail1); player->powers[pw_railring]--; - player->mo->health--; - player->health--; + player->rings--; } // Automatic else if (player->currentweapon == WEP_AUTO && player->powers[pw_automaticring]) { - if (player->health <= 1) + if (player->rings <= 0) return; player->pflags &= ~PF_ATTACKDOWN; P_SetWeaponDelay(player, 2); @@ -3175,26 +3163,24 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) mo = P_SpawnPlayerMissile(player->mo, MT_THROWNAUTOMATIC, MF2_AUTOMATIC); player->powers[pw_automaticring]--; - player->mo->health--; - player->health--; + player->rings--; } // Explosion else if (player->currentweapon == WEP_EXPLODE && player->powers[pw_explosionring]) { - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, (3*TICRATE)/2); mo = P_SpawnPlayerMissile(player->mo, MT_THROWNEXPLOSION, MF2_EXPLOSION); player->powers[pw_explosionring]--; - player->mo->health--; - player->health--; + player->rings--; } // Grenade else if (player->currentweapon == WEP_GRENADE && player->powers[pw_grenadering]) { - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, TICRATE/3); @@ -3207,8 +3193,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) } player->powers[pw_grenadering]--; - player->mo->health--; - player->health--; + player->rings--; } // Scatter // Note: Ignores MF2_RAILRING @@ -3218,7 +3203,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) angle_t shotangle = player->mo->angle; angle_t oldaiming = player->aiming; - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, (2*TICRATE)/3); @@ -3247,8 +3232,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) player->aiming = oldaiming; player->powers[pw_scatterring]--; - player->mo->health--; - player->health--; + player->rings--; return; } // No powers, just a regular ring. @@ -3272,7 +3256,7 @@ firenormal: // Red Ring else { - if (player->health <= 1) + if (player->rings <= 0) return; P_SetWeaponDelay(player, TICRATE/4); @@ -3281,8 +3265,7 @@ firenormal: if (mo) P_ColorTeamMissile(mo, player); - player->mo->health--; - player->health--; + player->rings--; } } @@ -3336,7 +3319,7 @@ static void P_DoSuperStuff(player_t *player) return; // NiGHTS Super doesn't mix with normal super // Does player have all emeralds? If so, flag the "Ready For Super!" - if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->health > 50) + if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->rings >= 50) player->pflags |= PF_SUPERREADY; else player->pflags &= ~PF_SUPERREADY; @@ -3374,10 +3357,7 @@ static void P_DoSuperStuff(player_t *player) // Deplete one ring every second while super if ((leveltime % TICRATE == 0) && !(player->exiting)) - { - player->health--; - player->mo->health--; - } + player->rings--; switch (player->skin) { @@ -3412,7 +3392,7 @@ static void P_DoSuperStuff(player_t *player) G_GhostAddColor(GHC_SUPER); // Ran out of rings while super! - if (player->health <= 1 || player->exiting) + if (player->rings <= 0 || player->exiting) { player->powers[pw_emeralds] = 0; // lost the power stones P_SpawnGhostMobj(player->mo); @@ -3465,12 +3445,6 @@ static void P_DoSuperStuff(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); break; } - - if (!player->exiting) - { - player->health = 1; - player->mo->health = 1; - } } // Inform the netgame that the champion has fallen in the heat of battle. @@ -5392,12 +5366,10 @@ static void P_DoNiGHTSCapsule(player_t *player) if (G_IsSpecialStage(gamemap)) { // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here! for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (&players[i] != player) && players[i].mo->health > 1) + if (playeringame[i] && (&players[i] != player) && players[i].rings > 0) { - player->mo->health += players[i].mo->health-1; - player->health = player->mo->health; - players[i].mo->health = 1; - players[i].health = players[i].mo->health; + player->rings += players[i].rings; + players[i].rings = 0; } } @@ -5406,10 +5378,9 @@ static void P_DoNiGHTSCapsule(player_t *player) && player->mo->y == player->capsule->y && player->mo->z == player->capsule->z+(player->capsule->height/3)) { - if (player->mo->health > 1) + if (player->rings > 0) { - player->mo->health--; - player->health--; + player->rings--; player->capsule->health--; player->capsule->extravalue1++; @@ -6129,7 +6100,7 @@ static void P_PlayerDropWeapon(player_t *player) if (mo) { - player->mo->health--; + player->rings--; P_InstaThrust(mo, player->mo->angle-ANGLE_180, 8*FRACUNIT); P_SetObjectMomZ(mo, 4*FRACUNIT, false); mo->flags2 |= MF2_DONTRESPAWN; @@ -6416,7 +6387,7 @@ static void P_MovePlayer(player_t *player) if (playeringame[i]) players[i].exiting = (14*TICRATE)/5 + 1; } - else if (player->health > 1) + else if (player->rings > 0) P_DamageMobj(player->mo, NULL, NULL, 1, 0); player->pflags &= ~PF_NIGHTSFALL; } @@ -8613,7 +8584,7 @@ void P_PlayerThink(player_t *player) #endif // todo: Figure out what is actually causing these problems in the first place... - if ((player->health <= 0 || player->mo->health <= 0) && player->playerstate == PST_LIVE) //you should be DEAD! + if (player->mo->health <= 0 && player->playerstate == PST_LIVE) //you should be DEAD! { CONS_Debug(DBG_GAMELOGIC, "P_PlayerThink: Player %s in PST_LIVE with 0 health. (\"Zombie bug\")\n", sizeu1(playeri)); player->playerstate = PST_DEAD; @@ -8713,7 +8684,7 @@ void P_PlayerThink(player_t *player) // it to the exit, you're a goner! else if (countdown == 1 && !player->exiting && player->lives > 0) { - if (netgame && player->health > 0) + if (netgame && player->mo->health > 0) CONS_Printf(M_GetText("%s ran out of time.\n"), player_names[player-players]); player->pflags |= PF_TIMEOVER; @@ -8802,7 +8773,7 @@ void P_PlayerThink(player_t *player) { player->score = 0; player->mo->health = 1; - player->health = 1; + player->rings = 0; } if ((netgame || multiplayer) && player->lives <= 0) @@ -9270,7 +9241,7 @@ void P_PlayerAfterThink(player_t *player) player->currentweapon = 0; // If you're out of rings, but have Infinity Rings left, switch to that. - if (player->currentweapon != 0 && player->health <= 1 && player->powers[pw_infinityring]) + if (player->currentweapon != 0 && player->rings <= 0 && player->powers[pw_infinityring]) player->currentweapon = 0; if (P_IsLocalPlayer(player) && (player->pflags & PF_WPNDOWN) && player->currentweapon != oldweapon) diff --git a/src/st_stuff.c b/src/st_stuff.c index 6e19b92ff..65a52d60e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -660,9 +660,9 @@ static void ST_drawTime(void) static inline void ST_drawRings(void) { - INT32 ringnum = max(stplyr->health-1, 0); + INT32 ringnum = max(stplyr->rings, 0); - ST_DrawPatchFromHudWS(HUD_RINGS, ((stplyr->health <= 1 && leveltime/5 & 1) ? rrings : sborings)); + ST_DrawPatchFromHudWS(HUD_RINGS, ((stplyr->rings <= 0 && leveltime/5 & 1) ? rrings : sborings)); if (objectplacing) ringnum = op_currentdoomednum; @@ -671,8 +671,8 @@ static inline void ST_drawRings(void) INT32 i; ringnum = 0; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].mo && players[i].mo->health > 1) - ringnum += players[i].mo->health - 1; + if (playeringame[i] && players[i].mo && players[i].rings > 0) + ringnum += players[i].rings; } ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum); @@ -1133,11 +1133,11 @@ static void ST_drawNiGHTSHUD(void) INT32 i; total_ringcount = 0; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] /*&& players[i].pflags & PF_NIGHTSMODE*/ && players[i].health) - total_ringcount += players[i].health - 1; + if (playeringame[i] /*&& players[i].pflags & PF_NIGHTSMODE*/ && players[i].rings) + total_ringcount += players[i].rings; } else - total_ringcount = stplyr->health-1; + total_ringcount = stplyr->rings; if (stplyr->capsule) { @@ -1349,7 +1349,7 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I txtflags |= V_YELLOWMAP; if (weapon == pw_infinityring - || (stplyr->ringweapons & rwflag && stplyr->health > 1)) + || (stplyr->ringweapons & rwflag && stplyr->rings > 0)) txtflags |= V_20TRANS; else { @@ -1383,7 +1383,7 @@ static void ST_drawMatchHUD(void) if (stplyr->powers[pw_infinityring]) ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring); - else if (stplyr->health > 1) + else if (stplyr->rings > 0) V_DrawScaledPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT, normring); else V_DrawTranslucentPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT|V_80TRANS, normring); diff --git a/src/y_inter.c b/src/y_inter.c index 2f2edf7ca..37a8bc4cc 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -792,13 +792,13 @@ static void Y_UpdateRecordReplays(void) if ((mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < mainrecords[gamemap-1]->time)) mainrecords[gamemap-1]->time = players[consoleplayer].realtime; - if ((UINT16)(players[consoleplayer].health - 1) > mainrecords[gamemap-1]->rings) - mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].health - 1); + if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings) + mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings); // Save demo! bestdemo[255] = '\0'; lastdemo[255] = '\0'; - G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].health-1)); + G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].rings)); G_CheckDemoStatus(); I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); @@ -1373,7 +1373,7 @@ static void Y_CalculateCompetitionWinners(void) bestat[j] = true; times[i] = players[i].realtime; - rings[i] = (UINT32)max(players[i].health-1, 0); + rings[i] = (UINT32)max(players[i].rings, 0); maxrings[i] = (UINT32)players[i].totalring; monitors[i] = (UINT32)players[i].numboxes; scores[i] = (UINT32)min(players[i].score, 99999990); @@ -1388,7 +1388,7 @@ static void Y_CalculateCompetitionWinners(void) else bestat[0] = false; - if (max(players[i].health-1, 0) >= max(players[j].health-1, 0)) + if (max(players[i].rings, 0) >= max(players[j].rings, 0)) points[i]++; else bestat[1] = false; @@ -1511,7 +1511,7 @@ static void Y_SetRingBonus(player_t *player, y_bonus_t *bstruct) { strncpy(bstruct->patch, "YB_RING", sizeof(bstruct->patch)); bstruct->display = true; - bstruct->points = max(0, (player->health-1) * 100); + bstruct->points = max(0, (player->rings) * 100); } // @@ -1559,7 +1559,7 @@ static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct) for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) continue; - sharedringtotal += players[i].health - 1; + sharedringtotal += players[i].rings; } if (!sharedringtotal || sharedringtotal < nummaprings) data.coop.gotperfbonus = 0; From 7dcf0d3d09564fdab4163b33a58b864fb4bab04e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 1 Oct 2015 20:02:44 +0100 Subject: [PATCH 09/50] Fix an error from match-balancing being merged in. Apparently match-balancing also doesn't have a prototype for P_StealPlayerScore for whatever reason. --- src/p_inter.c | 1 - src/p_local.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 60ba32c90..9f29401a0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3025,7 +3025,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } if (damagetype & DMG_DEATHMASK) - damage = 0; player->rings = 0; else if (damage == 0 || player->rings) //quickfix to just get things back to normal ...for now (sans Tag, I'll deal with that later) { diff --git a/src/p_local.h b/src/p_local.h index 359b7b842..30582ba1a 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -123,6 +123,7 @@ fixed_t P_GetPlayerHeight(player_t *player); fixed_t P_GetPlayerSpinHeight(player_t *player); INT32 P_GetPlayerControlDirection(player_t *player); void P_AddPlayerScore(player_t *player, UINT32 amount); +void P_StealPlayerScore(player_t *player, UINT32 amount); void P_ResetCamera(player_t *player, camera_t *thiscam); boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam); void P_SlideCameraMove(camera_t *thiscam); From 175561cc7f34cd8f02162605b00731dc5e55074f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Oct 2015 17:13:34 +0100 Subject: [PATCH 10/50] Check if God mode is one before even going to NiGHTS or player vs player damaging code or whatever. --- src/p_inter.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 9f29401a0..83d20689e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2383,8 +2383,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) player_t *player = target->player; tic_t oldnightstime = player->nightstime; - if (!player->powers[pw_flashing] - && !(player->pflags & PF_GODMODE)) + if (!player->powers[pw_flashing]) { angle_t fa; @@ -2891,6 +2890,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (player->exiting) return false; + if (player->pflags & PF_GODMODE) + return false; + if (!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS)) return false; @@ -2953,9 +2955,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; } - if (!force && player->pflags & PF_GODMODE) - return false; - // Instant-Death if (damagetype & DMG_DEATHMASK) P_KillPlayer(player, source, damage); From 31b2919847abbc79b33723e0f2495e3ce4aac5ad Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Oct 2015 20:18:45 +0100 Subject: [PATCH 11/50] Added a "damagetype" argument to P_ShieldDamage. We don't use MT_NULL to hack in damage for sector specials anymore, after all. Must have forgotten to do this back when I originally implemented damage types, oh well. --- src/p_inter.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 83d20689e..af8b90040 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2686,7 +2686,7 @@ void P_RemoveShield(player_t *player) player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK; } -static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) +static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { // Must do pain first to set flashing -- P_RemoveShield can cause damage P_DoPlayerPain(player, source, inflictor); @@ -2695,7 +2695,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes + if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes S_StartSound(player->mo, sfx_spkdth); else S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss. @@ -2971,7 +2971,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; // Metal Sonic walk through flame !! else { // Oh no! Metal Sonic is hit !! - P_ShieldDamage(player, inflictor, source, damage); + P_ShieldDamage(player, inflictor, source, damage, damagetype); return true; } } @@ -2997,7 +2997,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da #endif else if (!player->powers[pw_super] && (player->powers[pw_shield] || player->bot)) //If One-Hit Shield { - P_ShieldDamage(player, inflictor, source, damage); + P_ShieldDamage(player, inflictor, source, damage, damagetype); damage = 0; } else if (player->rings > 0) // No shield but have rings. @@ -3019,7 +3019,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da else { damage = 0; - P_ShieldDamage(player, inflictor, source, damage); + P_ShieldDamage(player, inflictor, source, damage, damagetype); } } From a84c2c6081e1dd0329556da8b04c6b716a7e492f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 6 Oct 2015 21:14:11 +0100 Subject: [PATCH 12/50] Some cleanup and reordering --- src/p_inter.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index af8b90040..b7f581abb 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2920,7 +2920,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; // Don't hit yourself with your own paraloop, baka if (source && source->player && !cv_friendlyfire.value && (gametype == GT_COOP - || (G_GametypeHasTeams() && target->player->ctfteam == source->player->ctfteam))) + || (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam))) return false; // Don't run eachother over in special stages and team games and such } #ifdef HAVE_BLUA @@ -2995,7 +2995,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da else if (LUAh_MobjDamage(target, inflictor, source, damage)) return true; #endif - else if (!player->powers[pw_super] && (player->powers[pw_shield] || player->bot)) //If One-Hit Shield + else if (player->powers[pw_shield] || player->bot) //If One-Hit Shield { P_ShieldDamage(player, inflictor, source, damage, damagetype); damage = 0; @@ -3005,22 +3005,19 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da damage = player->rings; P_RingDamage(player, inflictor, source, damage, damagetype); } + // To reduce griefing potential, don't allow players to be killed + // by friendly fire. Spilling their rings and other items is enough. + else if (!force && G_GametypeHasTeams() + && source && source->player && (source->player->ctfteam == player->ctfteam) + && cv_friendlyfire.value) + { + damage = 0; + P_ShieldDamage(player, inflictor, source, damage, damagetype); + } else // No shield, no rings, no invincibility. { - // To reduce griefing potential, don't allow players to be killed - // by friendly fire. Spilling their rings and other items is enough. - if (force || !(G_GametypeHasTeams() - && source && source->player && (source->player->ctfteam == player->ctfteam) - && cv_friendlyfire.value)) - { - damage = 1; - P_KillPlayer(player, source, damage); - } - else - { - damage = 0; - P_ShieldDamage(player, inflictor, source, damage, damagetype); - } + damage = 1; + P_KillPlayer(player, source, damage); } if (damagetype & DMG_DEATHMASK) From d7b402e3c4c63139791ff8b05a760c340001a571 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 6 Oct 2015 22:05:32 +0100 Subject: [PATCH 13/50] More cleanup, most notably dumping ring spilling code in P_RingDamage ...one wonders why P_RingDamage didn't already do that in the first place --- src/p_inter.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index b7f581abb..d5eff8d2a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2747,6 +2747,10 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN // Ring loss sound plays despite hitting spikes P_PlayRinglossSound(player->mo); // Ringledingle! + P_PlayerRingBurst(player, damage); + player->rings -= damage; + if (player->rings < 0) + player->rings = 0; } /** Damages an object, which may or may not be a player. @@ -2957,7 +2961,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Instant-Death if (damagetype & DMG_DEATHMASK) + { P_KillPlayer(player, source, damage); + player->rings = 0; + } else if (metalrecording) { if (!inflictor) @@ -3004,6 +3011,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { damage = player->rings; P_RingDamage(player, inflictor, source, damage, damagetype); + damage = 0; } // To reduce griefing potential, don't allow players to be killed // by friendly fire. Spilling their rings and other items is enough. @@ -3020,20 +3028,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_KillPlayer(player, source, damage); } - if (damagetype & DMG_DEATHMASK) - player->rings = 0; - else if (damage == 0 || player->rings) //quickfix to just get things back to normal ...for now (sans Tag, I'll deal with that later) - { - if (damage > 0) // don't spill emeralds/ammo/panels for shield damage - P_PlayerRingBurst(player, damage); - player->rings -= damage; - target->player->powers[pw_flashing] = flashingtics; - damage = 0; - } - - if (player->rings < 0) - player->rings = 0; - P_HitDeathMessages(player, inflictor, source, damagetype); P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); From a749d79aa5c0ba68abe99b91bacca2b2e1aa19a6 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 13 Mar 2016 20:53:10 +0000 Subject: [PATCH 14/50] Fix up S_ChangeMusic usage from merge so things can compile again --- src/p_inter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 2a6c0bd21..bc1857c20 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -250,11 +250,11 @@ void P_DoMatchSuper(player_t *player) S_StopMusic(); if (mariomode) { - S_ChangeMusic(mus_minvnc, false); + S_ChangeMusicInternal("minvnc", false); G_GhostAddColor(GHC_INVINCIBLE); } else - S_ChangeMusic(mus_invinc, false); + S_ChangeMusicInternal("invinc", false); } // Also steal 50 points from every enemy, sealing your victory. @@ -275,11 +275,11 @@ void P_DoMatchSuper(player_t *player) S_StopMusic(); if (mariomode) { - S_ChangeMusic(mus_minvnc, false); + S_ChangeMusicInternal("minvnc", false); G_GhostAddColor(GHC_INVINCIBLE); } else - S_ChangeMusic(mus_invinc, false); + S_ChangeMusicInternal("invinc", false); } } } From d31fd95d7574d8cc50caa597e8ac45bbf8e75b95 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 7 Apr 2016 22:02:52 +0100 Subject: [PATCH 15/50] Armageddon & Sparkles confusion is no more, DMG_NUKE exists to sort that out now --- src/p_inter.c | 2 +- src/p_local.h | 3 ++- src/p_user.c | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index bc1857c20..14667d21f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1586,7 +1586,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour else switch (inflictor->type) { case MT_PLAYER: - if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) + if (damagetype == DMG_NUKE) // SH_BOMB, armageddon shield str = M_GetText("%s%s's armageddon blast %s %s.\n"); else if (inflictor->player->powers[pw_invulnerability]) str = M_GetText("%s%s's invincibility aura %s %s.\n"); diff --git a/src/p_local.h b/src/p_local.h index 583f115ef..717f66d69 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -376,7 +376,8 @@ typedef struct BasicFF_s #define DMG_FIRE 2 #define DMG_ELECTRIC 3 #define DMG_SPIKE 4 -//#define DMG_SPECIALSTAGE 5 +#define DMG_NUKE 5 // bomb shield +//#define DMG_SPECIALSTAGE 6 //// Death types - cannot be combined with damage types #define DMG_INSTAKILL 0x80 #define DMG_DROWNED 0x80+1 diff --git a/src/p_user.c b/src/p_user.c index 4f9bca55e..4cf75ef33 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7440,12 +7440,12 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) mo->flags |= MF_SPECIAL|MF_SHOOTABLE; if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield! - P_KillMobj(mo->tracer, inflictor, source, 0); + P_KillMobj(mo->tracer, inflictor, source, DMG_NUKE); if (mo->flags & MF_BOSS || mo->type == MT_PLAYER) //don't OHKO bosses nor players! - P_DamageMobj(mo, inflictor, source, 1, 0); + P_DamageMobj(mo, inflictor, source, 1, DMG_NUKE); else - P_DamageMobj(mo, inflictor, source, 1000, 0); + P_DamageMobj(mo, inflictor, source, 1000, DMG_NUKE); } } From 35d89a4fbfb1002199cefe22ce177e31be703c98 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 20 Jul 2016 21:21:14 +0100 Subject: [PATCH 16/50] add DMG_* constants to dehacked.c lists --- src/dehacked.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 75235e054..023a872cf 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7165,6 +7165,22 @@ struct { {"PAL_MIXUP",PAL_MIXUP}, {"PAL_RECYCLE",PAL_RECYCLE}, {"PAL_NUKE",PAL_NUKE}, + // for P_DamageMobj + //// Damage types + {"DMG_WATER",DMG_WATER}, + {"DMG_FIRE",DMG_FIRE}, + {"DMG_ELECTRIC",DMG_ELECTRIC}, + {"DMG_SPIKE",DMG_SPIKE}, + {"DMG_NUKE",DMG_NUKE}, + //// Death types + {"DMG_INSTAKILL",DMG_INSTAKILL}, + {"DMG_DROWNED",DMG_DROWNED}, + {"DMG_SPACEDROWN",DMG_SPACEDROWN}, + {"DMG_DEATHPIT",DMG_DEATHPIT}, + {"DMG_CRUSHED",DMG_CRUSHED}, + {"DMG_SPECTATOR",DMG_SPECTATOR}, + //// Masks + {"DMG_DEATHMASK",DMG_DEATHMASK}, // Gametypes, for use with global var "gametype" {"GT_COOP",GT_COOP}, From ea65e9e54f40c43914f5a4bc0a29da2c5ae55cd8 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 20 Jul 2016 22:02:02 +0100 Subject: [PATCH 17/50] Add "damagetype" argument to functions for Lua hooks ShouldDamage, MobjDamage, MobjDeath and HurtMsg --- src/lua_hook.h | 8 ++++---- src/lua_hooklib.c | 52 +++++++++++++++++++++++++++-------------------- src/p_inter.c | 18 ++++++++-------- 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 804d99e12..d2ce0d826 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -62,9 +62,9 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_Touch #define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type #define LUAh_MobjThinker(mo) LUAh_MobjHook(mo, hook_MobjThinker) // Hook for P_MobjThinker or P_SceneryThinker by mobj type #define LUAh_BossThinker(mo) LUAh_MobjHook(mo, hook_BossThinker) // Hook for P_GenericBossThinker by mobj type -UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); // Hook for P_DamageMobj by mobj type (Should mobj take damage?) -boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) -boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source); // Hook for P_KillMobj by mobj type +UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Should mobj take damage?) +boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) +boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for P_KillMobj by mobj type #define LUAh_BossDeath(mo) LUAh_MobjHook(mo, hook_BossDeath) // Hook for A_BossDeath by mobj type #define LUAh_MobjRemoved(mo) LUAh_MobjHook(mo, hook_MobjRemoved) // Hook for P_RemoveMobj by mobj type #define LUAh_JumpSpecial(player) LUAh_PlayerHook(player, hook_JumpSpecial) // Hook for P_DoJumpStuff (Any-jumping) @@ -75,7 +75,7 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages -boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages +boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 1b9652571..e95b75eda 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -412,7 +412,7 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) } // Hook for P_DamageMobj by mobj type (Should mobj take damage?) -UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) +UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. @@ -431,14 +431,16 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + if (lua_pcall(gL, 5, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -460,7 +462,7 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 } // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) -boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) +boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { hook_p hookp; boolean hooked = false; @@ -479,14 +481,16 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + if (lua_pcall(gL, 5, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -503,7 +507,7 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 } // Hook for P_KillMobj by mobj type -boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) +boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { hook_p hookp; boolean hooked = false; @@ -521,13 +525,15 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - if (lua_pcall(gL, 3, 1, 0)) { + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -729,7 +735,7 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) } // Hook for hurt messages -boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) +boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { hook_p hookp; boolean hooked = false; @@ -747,13 +753,15 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - if (lua_pcall(gL, 3, 1, 0)) { + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); diff --git a/src/p_inter.c b/src/p_inter.c index 4a6a4445f..dee2aa824 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1565,7 +1565,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour return; // Presumably it's obvious what's happening in splitscreen. #ifdef HAVE_BLUA - if (LUAh_HurtMsg(player, inflictor, source)) + if (LUAh_HurtMsg(player, inflictor, source, damagetype)) return; #endif @@ -2037,7 +2037,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->health = 0; // This makes it easy to check if something's dead elsewhere. #ifdef HAVE_BLUA - if (LUAh_MobjDeath(target, inflictor, source) || P_MobjWasRemoved(target)) + if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) return; #endif @@ -2917,7 +2917,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Everything above here can't be forced. if (!metalrecording) { - UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage); + UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage, damagetype); if (P_MobjWasRemoved(target)) return (shouldForce == 1); // mobj was removed if (shouldForce == 1) @@ -2960,7 +2960,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; #ifdef HAVE_BLUA - if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target)) + if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) return true; #endif @@ -2988,7 +2988,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; #ifdef HAVE_BLUA - if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target)) + if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) return true; #endif @@ -2998,7 +2998,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da #ifdef HAVE_BLUA else if (target->flags & MF_ENEMY) { - if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target)) + if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) return true; } #endif @@ -3046,7 +3046,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; // Don't run eachother over in special stages and team games and such } #ifdef HAVE_BLUA - if (LUAh_MobjDamage(target, inflictor, source, damage)) + if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) return true; #endif P_NiGHTSDamage(target, source); // -5s :( @@ -3108,7 +3108,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da && player->powers[pw_super])) { #ifdef HAVE_BLUA - if (!LUAh_MobjDamage(target, inflictor, source, damage)) + if (!LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) #endif P_SuperDamage(player, inflictor, source, damage); return true; @@ -3117,7 +3117,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; } #ifdef HAVE_BLUA - else if (LUAh_MobjDamage(target, inflictor, source, damage)) + else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) return true; #endif else if (player->powers[pw_shield] || player->bot) //If One-Hit Shield From c977d174166142a47b5aa7a2d32f57a2a5412702 Mon Sep 17 00:00:00 2001 From: ilag11111 Date: Sun, 11 Sep 2016 09:41:18 -0700 Subject: [PATCH 18/50] Prevent truncation when resampling sounds with non-multiples of 11250. --- src/sdl/mixer_sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 4a46813c1..88bbadd20 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -220,7 +220,7 @@ static Mix_Chunk *ds2chunk(void *stream) break; default: // convert arbitrary hz to 44100. step = 0; - frac = ((UINT32)freq << FRACBITS) / 44100; + frac = ((UINT32)freq << FRACBITS) / 44100 + 1; //Add 1 to counter truncation. while (i < samples) { o = (INT16)(*s+0x80)<<8; // changed signedness and shift up to 16 bits From 67d2211bca273e880cad44620da274fb93be5226 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Tue, 1 Nov 2016 15:54:52 -0400 Subject: [PATCH 19/50] whitespace: cleanup --- src/p_mobj.c | 1 - src/r_things.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 27897be2b..e9bcd193a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10817,4 +10817,3 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo P_SetScale(newmobj, mobj->scale); return newmobj; } - diff --git a/src/r_things.c b/src/r_things.c index e8aa2956f..9f6cad529 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1349,7 +1349,7 @@ static void R_ProjectSprite(mobj_t *thing) if (sortscale < linkscale) dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0) - sortscale = linkscale; // now make sure it's linked + sortscale = linkscale; // now make sure it's linked } // PORTAL SPRITE CLIPPING From 2d72b2fac6c2d227b11ea31826d6afd4d30337ac Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 2 Nov 2016 19:31:06 +0100 Subject: [PATCH 20/50] You can now move the cursor in command prompt and chat, using left/right, ctrl+left/right, home/end, and select text with shift --- src/console.c | 213 ++++++++++++++++++++++-- src/hu_stuff.c | 437 +++++++++++++++++++++++++++++++++---------------- src/hu_stuff.h | 1 - 3 files changed, 498 insertions(+), 153 deletions(-) diff --git a/src/console.c b/src/console.c index 025bc1c19..44819fb4f 100644 --- a/src/console.c +++ b/src/console.c @@ -91,11 +91,13 @@ static char inputlines[32][CON_MAXPROMPTCHARS]; // hold last 32 prompt lines static INT32 inputline; // current input line number static INT32 inputhist; // line number of history input line to restore static size_t input_cx; // position in current input line +static INT32 input_selection; // selection border in current input line, -1 if no selection // protos. static void CON_InputInit(void); static void CON_RecalcSize(void); +static void CON_DeleteSelectedText(void); static void CONS_hudlines_Change(void); static void CON_DrawBackpic(patch_t *pic, INT32 startx, INT32 destwidth); //static void CON_DrawBackpic2(pic_t *pic, INT32 startx, INT32 destwidth); @@ -394,6 +396,7 @@ static void CON_InputInit(void) inputlines[i][0] = CON_PROMPTCHAR; inputline = 0; input_cx = 1; + input_selection = -1; } //====================================================================== @@ -618,6 +621,25 @@ void CON_Ticker(void) } } +// Deletes selected text, assuming there is, and resets selection. +// Also sets the cursor to the correct position. +// +static void CON_DeleteSelectedText(void) +{ + UINT32 i, j; + char *line = inputlines[inputline]; + size_t selstart = min(input_cx, input_selection); + size_t selend = max(input_cx, input_selection); + + for (i = selstart, j = selend; line[j]; ++i, ++j) + line[i] = line[j]; + while (line[i]) + line[i++] = 0; + + input_cx = selstart; + input_selection = -1; +} + // Handles console key input // boolean CON_Responder(event_t *ev) @@ -704,6 +726,9 @@ boolean CON_Responder(event_t *ev) // command completion forward (tab) and backward (shift-tab) if (key == KEY_TAB) { + input_cx = strlen(inputlines[inputline]); // make sure the cursor is at the end of the string, in case we were inserting + input_selection = -1; // make sure there is no text selected, it would look odd + // show all cvars/commands that match what we have inputted if (ctrldown) { @@ -839,21 +864,51 @@ boolean CON_Responder(event_t *ev) return true; } - if (key == KEY_HOME) // oldest text in buffer + if (key == KEY_HOME) { - con_scrollup = (con_totallines-((con_curlines-16)>>3)); + if (shiftdown) + { + if (input_selection == -1) + input_selection = input_cx; + } + else + input_selection = -1; + + if (ctrldown) + con_scrollup = (con_totallines-((con_curlines-16)>>3)); // oldest text in buffer + else + input_cx = 1; + + if (input_cx == input_selection) + input_selection = -1; + return true; } - else if (key == KEY_END) // most recent text in buffer + else if (key == KEY_END) { - con_scrollup = 0; + if (shiftdown) + { + if (input_selection == -1) + input_selection = input_cx; + } + else + input_selection = -1; + + if (ctrldown) + con_scrollup = 0; // most recent text in buffer + else + input_cx = strlen(inputlines[inputline]); + + if (input_cx == input_selection) + input_selection = -1; + return true; } // command enter if (key == KEY_ENTER) { - if (input_cx < 2) + if (strlen(inputlines[inputline]) < 2) return true; // push the command @@ -868,18 +923,107 @@ boolean CON_Responder(event_t *ev) memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); inputlines[inputline][0] = CON_PROMPTCHAR; input_cx = 1; + input_selection = -1; return true; } - // backspace command prompt + // backspace command prompt or delete selected text if (key == KEY_BACKSPACE) { - if (input_cx > 1) + if (input_selection == -1) { - input_cx--; - inputlines[inputline][input_cx] = 0; + if (input_cx > 1) + { + UINT32 i, j; + char *line = inputlines[inputline]; + + for (i = input_cx - 1, j = input_cx; line[j]; ++i, ++j) + line[i] = line[j]; + line[i] = 0; + input_cx--; + } } + else + CON_DeleteSelectedText(); + return true; + } + + // delete character under cursor or selected text + if (key == KEY_DEL) + { + if (input_selection == -1) + { + UINT32 i, j; + char *line = inputlines[inputline]; + + for (i = input_cx, j = input_cx + 1; line[j]; ++i, ++j) + line[i] = line[j]; + line[i] = 0; + } + else + CON_DeleteSelectedText(); + + return true; + } + + if (key == KEY_LEFTARROW) + { + if (shiftdown) + { + if (input_selection == -1) + input_selection = input_cx; + } + else + input_selection = -1; + + // move cursor to previous word + if (ctrldown) + { + char *line = inputlines[inputline]; + + while (input_cx > 1 && line[input_cx - 1] == ' ') + input_cx--; + while (input_cx > 1 && line[input_cx - 1] != ' ') + input_cx--; + } + // move cursor left + else if (input_cx > 1) + input_cx--; + + if (input_cx == input_selection) + input_selection = -1; + + return true; + } + + if (key == KEY_RIGHTARROW) + { + if (shiftdown) + { + if (input_selection == -1) + input_selection = input_cx; + } + else + input_selection = -1; + + // move cursor to next word + if (ctrldown) + { + char *line = inputlines[inputline]; + + while (line[input_cx] && line[input_cx] != ' ') + input_cx++; + while (line[input_cx] && line[input_cx] == ' ') + input_cx++; + } + // move cursor right + else if (inputlines[inputline][input_cx]) + input_cx++; + + if (input_cx == input_selection) + input_selection = -1; + return true; } @@ -950,13 +1094,21 @@ boolean CON_Responder(event_t *ev) return false; // add key to cmd line here - if (input_cx < CON_MAXPROMPTCHARS) + if (strlen(inputlines[inputline]) < CON_MAXPROMPTCHARS - 1) { + INT32 i, j; + char *line = inputlines[inputline]; + if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers key = key + 'a' - 'A'; - inputlines[inputline][input_cx] = (char)key; - inputlines[inputline][input_cx + 1] = 0; + if (input_selection != -1) + CON_DeleteSelectedText(); + + for (i = strlen(line), j = i + 1; j > (INT32)input_cx; --i, --j) + line[j] = line[i]; + + line[input_cx] = (char)key; input_cx++; } @@ -1246,6 +1398,7 @@ static void CON_DrawInput(void) size_t c; INT32 x, y; INT32 charwidth = (INT32)con_scalefactor << 3; + INT32 f = cv_constextsize.value | V_NOSCALESTART; // input line scrolls left if it gets too long p = inputlines[inputline]; @@ -1254,14 +1407,44 @@ static void CON_DrawInput(void) y = con_curlines - 12 * con_scalefactor; - for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + if (input_selection == -1) + { + for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) + V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); + } + else + { + size_t selstart = min(input_cx, input_selection); + size_t selend = max(input_cx, input_selection); + + for (c = 0, x = charwidth; c < selstart && c < con_width-11; c++, x += charwidth) + V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); + + f |= V_YELLOWMAP; + for (; c < selend && c < con_width-11; c++, x += charwidth) + V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); + f &= ~V_YELLOWMAP; + + for (; c < con_width-11; c++, x += charwidth) + V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); + } + //for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) + //V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); // draw the blinking cursor // x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth); if (con_tick < 4) - V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + { + if (inputlines[inputline][input_cx]) + //V_DrawCharacter(x - 2 * con_scalefactor, y, '|' | f, !cv_allcaps.value); + V_DrawCharacter(x, y + 2 * con_scalefactor, '_' | f, !cv_allcaps.value); + else + V_DrawCharacter(x, y, '_' | f, !cv_allcaps.value); + } + /*x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth); + if (con_tick < 4) + V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);*/ } // draw the last lines of console text to the top of the screen diff --git a/src/hu_stuff.c b/src/hu_stuff.c index ec747305e..9f1cea13f 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -73,6 +73,9 @@ patch_t *cred_font[CRED_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? static char w_chat[HU_MAXMSGLEN]; +static size_t chat_pos; // position of the cursor in the chat +static INT32 chat_selection; // selection border in current input line, -1 if no selection +static boolean teamtalk = false; static boolean headsupactive = false; boolean hu_showscores; // draw rankings static char hu_tick; @@ -106,6 +109,7 @@ static patch_t *crosshair[HU_CROSSHAIRS]; // 3 precached crosshair graphics static void HU_DrawRankings(void); static void HU_DrawCoopOverlay(void); static void HU_DrawNetplayCoopOverlay(void); +static void HU_DeleteSelectedText(void); //====================================================================== // KEYBOARD LAYOUTS FOR ENTERING TEXT @@ -621,36 +625,183 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } #endif +// Deletes selected text, assuming there is, and resets selection. +// Also sets the cursor to the correct position. +// +static void HU_DeleteSelectedText(void) +{ + UINT32 i, j; + size_t selstart = min(chat_pos, chat_selection); + size_t selend = max(chat_pos, chat_selection); + + for (i = selstart, j = selend; w_chat[j]; ++i, ++j) + w_chat[i] = w_chat[j]; + while (w_chat[i]) + w_chat[i++] = 0; + + chat_pos = selstart; + chat_selection = -1; +} + // Handles key input and string input // -static inline boolean HU_keyInChatString(char *s, char ch) +static inline void HU_keyInChatString(char *s, UINT32 key, boolean shiftdown, boolean ctrldown) { - size_t l; - - if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART]) - || ch == ' ') // Allow spaces, of course + switch (key) { - l = strlen(s); - if (l < HU_MAXMSGLEN - 1) + case KEY_ESCAPE: + chat_on = false; + break; + case KEY_ENTER: + { + // send automatically the message (no more chat char) + char buf[2+256]; + size_t ci = 2; + char *cp = w_chat; + + while (*cp) { - s[l++] = ch; - s[l]=0; - return true; + if (*cp >= ' ' && !(*cp & 0x80)) + buf[ci++] = *cp; + cp++; } - return false; - } - else if (ch == KEY_BACKSPACE) - { - l = strlen(s); - if (l) - s[--l] = 0; - else - return false; - } - else if (ch != KEY_ENTER) - return false; // did not eat key + buf[ci] = 0; - return true; // ate the key + // last minute mute check + if (cv_mute.value && !(server || adminplayer == consoleplayer)) + { + CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); + return; + } + + if (ci > 2) // don't send target+flags+empty message. + { + if (teamtalk) + buf[0] = -1; // target + else + buf[0] = 0; // target + buf[1] = 0; // flags + SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); + } + + chat_on = false; + break; + } + // cursor moving + case KEY_LEFTARROW: + case KEY_RIGHTARROW: + case KEY_HOME: + case KEY_END: + if (shiftdown) + { + if (chat_selection == -1) + chat_selection = chat_pos; + } + else + chat_selection = -1; + + switch (key) + { + case KEY_LEFTARROW: + // move cursor to previous word + if (ctrldown) + { + while (chat_pos > 0 && w_chat[chat_pos - 1] == ' ') + chat_pos--; + while (chat_pos > 0 && w_chat[chat_pos - 1] != ' ') + chat_pos--; + } + // move cursor left + else if (chat_pos > 0) + chat_pos--; + break; + case KEY_RIGHTARROW: + // move cursor to next word + if (ctrldown) + { + while (w_chat[chat_pos] && w_chat[chat_pos] != ' ') + chat_pos++; + while (w_chat[chat_pos] && w_chat[chat_pos] == ' ') + chat_pos++; + } + // move cursor right + else if (w_chat[chat_pos]) + chat_pos++; + break; + case KEY_HOME: + chat_pos = 0; + break; + case KEY_END: + chat_pos = strlen(w_chat); + } + + if (chat_pos == chat_selection) + chat_selection = -1; + break; + // backspace or delete selected text + case KEY_BACKSPACE: + if (chat_selection == -1) + { + if (chat_pos > 0) + { + UINT32 i, j; + for (i = chat_pos - 1, j = chat_pos; w_chat[j]; ++i, ++j) + w_chat[i] = w_chat[j]; + w_chat[i] = 0; + chat_pos--; + } + } + else + HU_DeleteSelectedText(); + break; + // delete character under cursor + case KEY_DEL: + if (chat_selection == -1) + { + UINT32 i, j; + + for (i = chat_pos, j = chat_pos + 1; w_chat[j]; ++i, ++j) + w_chat[i] = w_chat[j]; + w_chat[i] = 0; + } + else + HU_DeleteSelectedText(); + break; + default: + // allow people to use keypad in chat + if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL) + { + XBOXSTATIC char keypad_translation[] = {'7','8','9','-', + '4','5','6','+', + '1','2','3', + '0','.'}; + + key = keypad_translation[key - KEY_KEYPAD7]; + } + else if (key == KEY_KPADSLASH) + key = '/'; + + // use console translations + if (shiftdown) + key = shiftxform[key]; + + if ((key >= HU_FONTSTART && key <= HU_FONTEND && hu_font[key-HU_FONTSTART]) + || key == ' ') // Allow spaces, of course + { + if (strlen(w_chat) < HU_MAXMSGLEN - 1) + { + UINT32 i, j; + + if (chat_selection != -1) + HU_DeleteSelectedText(); + + for (i = strlen(w_chat), j = i + 1; j > chat_pos; --i, --j) + w_chat[j] = w_chat[i]; + w_chat[chat_pos] = (char)key; + chat_pos++; + } + } + } } // @@ -669,86 +820,9 @@ void HU_Ticker(void) hu_showscores = false; } -#define QUEUESIZE 256 - -static boolean teamtalk = false; -static char chatchars[QUEUESIZE]; -static INT32 head = 0, tail = 0; - -// -// HU_dequeueChatChar -// -char HU_dequeueChatChar(void) -{ - char c; - - if (head != tail) - { - c = chatchars[tail]; - tail = (tail + 1) & (QUEUESIZE-1); - } - else - c = 0; - - return c; -} - -// -// -static void HU_queueChatChar(char c) -{ - // send automaticly the message (no more chat char) - if (c == KEY_ENTER) - { - char buf[2+256]; - size_t ci = 2; - - do { - c = HU_dequeueChatChar(); - if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only. - buf[ci++]=c; - } while (c); - - // last minute mute check - if (cv_mute.value && !(server || adminplayer == consoleplayer)) - { - CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); - return; - } - - if (ci > 3) // don't send target+flags+empty message. - { - if (teamtalk) - buf[0] = -1; // target - else - buf[0] = 0; // target - buf[1] = 0; // flags - SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); - } - return; - } - - if (((head + 1) & (QUEUESIZE-1)) == tail) - CONS_Printf(M_GetText("[Message unsent]\n")); // message not sent - else - { - if (c == KEY_BACKSPACE) - { - if (tail != head) - head = (head - 1) & (QUEUESIZE-1); - } - else - { - chatchars[head] = c; - head = (head + 1) & (QUEUESIZE-1); - } - } -} - +// REMOVE? Now this has become pretty useless IMO void HU_clearChatChars(void) { - while (tail != head) - HU_queueChatChar(KEY_BACKSPACE); chat_on = false; } @@ -758,13 +832,19 @@ void HU_clearChatChars(void) boolean HU_Responder(event_t *ev) { static boolean shiftdown = false; - UINT8 c; + static boolean ctrldown = false; + INT32 key = ev->data1; // only valid if ev->type is a key event - if (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT) + if (key == KEY_LSHIFT || key == KEY_RSHIFT) { shiftdown = (ev->type == ev_keydown); return chat_on; } + else if (key == KEY_LCTRL || key == KEY_RCTRL) + { + ctrldown = (ev->type == ev_keydown); + return chat_on; + } if (ev->type != ev_keydown) return false; @@ -774,42 +854,36 @@ boolean HU_Responder(event_t *ev) if (!chat_on) { // enter chat mode - if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1]) + if ((key == gamecontrol[gc_talkkey][0] || key == gamecontrol[gc_talkkey][1]) && netgame && (!cv_mute.value || server || (adminplayer == consoleplayer))) { - if (cv_mute.value && !(server || adminplayer == consoleplayer)) - return false; + // we already checked for this two lines before... + //if (cv_mute.value && !(server || adminplayer == consoleplayer)) + //return false; chat_on = true; w_chat[0] = 0; + chat_pos = 0; + chat_selection = -1; teamtalk = false; return true; } - if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1]) + if ((key == gamecontrol[gc_teamkey][0] || key == gamecontrol[gc_teamkey][1]) && netgame && (!cv_mute.value || server || (adminplayer == consoleplayer))) { - if (cv_mute.value && !(server || adminplayer == consoleplayer)) - return false; + // we already checked for this two lines before... + //if (cv_mute.value && !(server || adminplayer == consoleplayer)) + //return false; chat_on = true; w_chat[0] = 0; + chat_pos = 0; + chat_selection = -1; teamtalk = true; return true; } } else // if chat_on { - c = (UINT8)ev->data1; - - // use console translations - if (shiftdown) - c = shiftxform[c]; - - if (HU_keyInChatString(w_chat,c)) - HU_queueChatChar(c); - if (c == KEY_ENTER) - chat_on = false; - else if (c == KEY_ESCAPE) - chat_on = false; - + HU_keyInChatString(w_chat, key, shiftdown, ctrldown); return true; } return false; @@ -826,7 +900,7 @@ boolean HU_Responder(event_t *ev) // static void HU_DrawChat(void) { - INT32 t = 0, c = 0, y = HU_INPUTY; + INT32 t = 0, f = 0, c = 0, y = HU_INPUTY; size_t i = 0; const char *ntalk = "Say: ", *ttalk = "Say-Team: "; const char *talk = ntalk; @@ -844,6 +918,8 @@ static void HU_DrawChat(void) #endif } + f = cv_constextsize.value | V_NOSCALESTART; + while (talk[i]) { if (talk[i] < HU_FONTSTART) @@ -854,36 +930,123 @@ static void HU_DrawChat(void) else { //charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | f, !cv_allcaps.value); } c += charwidth; } + f |= t; i = 0; - while (w_chat[i]) + if (chat_selection == -1) { - //Hurdler: isn't it better like that? - if (w_chat[i] < HU_FONTSTART) + while (w_chat[i]) { - ++i; - //charwidth = 4 * con_scalefactor; + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) + { + ++i; + //charwidth = 4 * con_scalefactor; + } + else + { + //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); + } + + c += charwidth; + if (c >= vid.width) + { + c = 0; + y += charheight; + } } - else + } + else + { + size_t selstart = min(chat_pos, chat_selection); + size_t selend = max(chat_pos, chat_selection); + + while (i < selstart) { - //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value); + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) + { + ++i; + //charwidth = 4 * con_scalefactor; + } + else + { + //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); + } + + c += charwidth; + if (c >= vid.width) + { + c = 0; + y += charheight; + } } - c += charwidth; - if (c >= vid.width) + f &= ~t; + f |= V_YELLOWMAP; + while (i < selend) { - c = 0; - y += charheight; + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) + { + ++i; + //charwidth = 4 * con_scalefactor; + } + else + { + //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); + } + + c += charwidth; + if (c >= vid.width) + { + c = 0; + y += charheight; + } + } + f &= ~V_YELLOWMAP; + f |= t; + + while (w_chat[i]) + { + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) + { + ++i; + //charwidth = 4 * con_scalefactor; + } + else + { + //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); + } + + c += charwidth; + if (c >= vid.width) + { + c = 0; + y += charheight; + } } } if (hu_tick < 4) - V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, !cv_allcaps.value); + { + if (w_chat[chat_pos]) + { + i = (strlen(talk) + chat_pos) * charwidth; + c = i % vid.width; + y = HU_INPUTY + i / vid.width * charheight + 2 * con_scalefactor; + } + V_DrawCharacter(HU_INPUTX + c, y, '_' | f, !cv_allcaps.value); + } } diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 7b22f33f1..5dca10981 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -93,7 +93,6 @@ boolean HU_Responder(event_t *ev); void HU_Ticker(void); void HU_Drawer(void); -char HU_dequeueChatChar(void); void HU_Erase(void); void HU_clearChatChars(void); void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); From 8b72b553be7e28da023ee15298a40fa02755fbab Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 2 Nov 2016 20:10:08 +0100 Subject: [PATCH 21/50] Fixed warnings --- src/console.c | 16 ++++++++-------- src/hu_stuff.c | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/console.c b/src/console.c index 44819fb4f..f4a1e4f82 100644 --- a/src/console.c +++ b/src/console.c @@ -628,8 +628,8 @@ static void CON_DeleteSelectedText(void) { UINT32 i, j; char *line = inputlines[inputline]; - size_t selstart = min(input_cx, input_selection); - size_t selend = max(input_cx, input_selection); + size_t selstart = min(input_cx, (size_t)input_selection); + size_t selend = max(input_cx, (size_t)input_selection); for (i = selstart, j = selend; line[j]; ++i, ++j) line[i] = line[j]; @@ -879,7 +879,7 @@ boolean CON_Responder(event_t *ev) else input_cx = 1; - if (input_cx == input_selection) + if ((INT32)input_cx == input_selection) input_selection = -1; return true; @@ -899,7 +899,7 @@ boolean CON_Responder(event_t *ev) else input_cx = strlen(inputlines[inputline]); - if (input_cx == input_selection) + if ((INT32)input_cx == input_selection) input_selection = -1; return true; @@ -991,7 +991,7 @@ boolean CON_Responder(event_t *ev) else if (input_cx > 1) input_cx--; - if (input_cx == input_selection) + if ((INT32)input_cx == input_selection) input_selection = -1; return true; @@ -1021,7 +1021,7 @@ boolean CON_Responder(event_t *ev) else if (inputlines[inputline][input_cx]) input_cx++; - if (input_cx == input_selection) + if ((INT32)input_cx == input_selection) input_selection = -1; return true; @@ -1414,8 +1414,8 @@ static void CON_DrawInput(void) } else { - size_t selstart = min(input_cx, input_selection); - size_t selend = max(input_cx, input_selection); + size_t selstart = min(input_cx, (size_t)input_selection); + size_t selend = max(input_cx, (size_t)input_selection); for (c = 0, x = charwidth; c < selstart && c < con_width-11; c++, x += charwidth) V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 9f1cea13f..80e7cf714 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -631,8 +631,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) static void HU_DeleteSelectedText(void) { UINT32 i, j; - size_t selstart = min(chat_pos, chat_selection); - size_t selend = max(chat_pos, chat_selection); + size_t selstart = min(chat_pos, (size_t)chat_selection); + size_t selend = max(chat_pos, (size_t)chat_selection); for (i = selstart, j = selend; w_chat[j]; ++i, ++j) w_chat[i] = w_chat[j]; @@ -645,7 +645,7 @@ static void HU_DeleteSelectedText(void) // Handles key input and string input // -static inline void HU_keyInChatString(char *s, UINT32 key, boolean shiftdown, boolean ctrldown) +static void HU_keyInChatString(UINT32 key, boolean shiftdown, boolean ctrldown) { switch (key) { @@ -735,7 +735,7 @@ static inline void HU_keyInChatString(char *s, UINT32 key, boolean shiftdown, bo chat_pos = strlen(w_chat); } - if (chat_pos == chat_selection) + if ((INT32)chat_pos == chat_selection) chat_selection = -1; break; // backspace or delete selected text @@ -883,7 +883,7 @@ boolean HU_Responder(event_t *ev) } else // if chat_on { - HU_keyInChatString(w_chat, key, shiftdown, ctrldown); + HU_keyInChatString(key, shiftdown, ctrldown); return true; } return false; @@ -963,8 +963,8 @@ static void HU_DrawChat(void) } else { - size_t selstart = min(chat_pos, chat_selection); - size_t selend = max(chat_pos, chat_selection); + size_t selstart = min(chat_pos, (size_t)chat_selection); + size_t selend = max(chat_pos, (size_t)chat_selection); while (i < selstart) { From 81077656772cbd91ceee32e919fa7fb68f2dbc83 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Wed, 2 Nov 2016 14:26:35 -0700 Subject: [PATCH 22/50] make console back color use just one section of memory let's be honest, it's pretty dumb to have every single possible back colormap in memory when only one is being used at a time --- src/console.c | 99 +++++++++++++++++++++++++-------------------------- src/console.h | 7 ++-- src/p_setup.c | 2 +- src/v_video.c | 37 ++++++++----------- src/v_video.h | 2 +- 5 files changed, 68 insertions(+), 79 deletions(-) diff --git a/src/console.c b/src/console.c index 025bc1c19..3fa9b8a97 100644 --- a/src/console.c +++ b/src/console.c @@ -97,6 +97,7 @@ static void CON_InputInit(void); static void CON_RecalcSize(void); static void CONS_hudlines_Change(void); +static void CONS_backcolor_Change(void); static void CON_DrawBackpic(patch_t *pic, INT32 startx, INT32 destwidth); //static void CON_DrawBackpic2(pic_t *pic, INT32 startx, INT32 destwidth); @@ -129,10 +130,11 @@ static CV_PossibleValue_t backpic_cons_t[] = {{0, "translucent"}, {1, "picture"} // whether to use console background picture, or translucent mode static consvar_t cons_backpic = {"con_backpic", "translucent", CV_SAVE, backpic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Orange"}, - {2, "Blue"}, {3, "Green"}, {4, "Gray"}, - {5, "Red"}, {0, NULL}}; -consvar_t cons_backcolor = {"con_backcolor", "3", CV_SAVE, backcolor_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Gray"}, {2, "Brown"}, + {3, "Red"}, {4, "Orange"}, {5, "Yellow"}, + {6, "Green"}, {7, "Blue"}, {8, "Cyan"}, + {0, NULL}}; +consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL}; static void CON_Print(char *msg); @@ -219,8 +221,9 @@ static void CONS_Bind_f(void) // CONSOLE SETUP //====================================================================== -// Prepare a colormap for GREEN ONLY translucency over background -// +// 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; @@ -229,44 +232,49 @@ UINT8 *graymap; UINT8 *redmap; UINT8 *orangemap; -// Console BG colors -UINT8 *cwhitemap; -UINT8 *corangemap; -UINT8 *cbluemap; -UINT8 *cgreenmap; -UINT8 *cgraymap; -UINT8 *credmap; +// Console BG color +UINT8 *consolebgmap = NULL; -void CON_ReSetupBackColormap(UINT16 num) +void CON_SetupBackColormap(void) { - UINT16 i, j; - UINT8 k; - UINT8 *pal = W_CacheLumpName(R_GetPalname(num), PU_CACHE); + UINT16 i, palsum; + UINT8 j, palindex; + UINT8 *pal = W_CacheLumpName(GetPalette(), PU_CACHE); - // setup the green translucent background colormaps - for (i = 0, k = 0; i < 768; i += 3, k++) + if (!consolebgmap) + consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + + switch (cons_backcolor.value) { - j = pal[i] + pal[i+1] + pal[i+2]; - cwhitemap[k] = (UINT8)(15 - (j>>6)); - corangemap[k] = (UINT8)(95 - (j>>6)); - cbluemap[k] = (UINT8)(239 - (j>>6)); - cgreenmap[k] = (UINT8)(175 - (j>>6)); - cgraymap[k] = (UINT8)(31 - (j>>6)); - credmap[k] = (UINT8)(143 - (j>>6)); + case 0: palindex = 15; break; // White + case 1: palindex = 31; break; // Gray + case 2: palindex = 63; break; // Brown + case 3: palindex = 143; break; // Red + case 4: palindex = 95; break; // Orange + case 5: palindex = 111; break; // Yellow + case 6: palindex = 175; break; // Green + case 7: palindex = 239; break; // Blue + case 8: palindex = 219; break; // Cyan + // Default green + default: palindex = 175; break; +} + + // setup background colormap + for (i = 0, j = 0; i < 768; i += 3, j++) + { + palsum = (pal[i] + pal[i+1] + pal[i+2]) >> 6; + consolebgmap[j] = (UINT8)(palindex - palsum); } } -static void CON_SetupBackColormap(void) +static void CONS_backcolor_Change(void) { - INT32 i, j, k; - UINT8 *pal; + CON_SetupBackColormap(); +} - cwhitemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - corangemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - cbluemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - cgreenmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - cgraymap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - credmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); +static void CON_SetupColormaps(void) +{ + INT32 i; yellowmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); graymap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); @@ -276,20 +284,6 @@ static void CON_SetupBackColormap(void) redmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); orangemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - pal = W_CacheLumpName("PLAYPAL", PU_CACHE); - - // setup the green translucent background colormaps - for (i = 0, k = 0; i < 768; i += 3, k++) - { - j = pal[i] + pal[i+1] + pal[i+2]; - cwhitemap[k] = (UINT8)(15 - (j>>6)); - corangemap[k] = (UINT8)(95 - (j>>6)); - cbluemap[k] = (UINT8)(239 - (j>>6)); - cgreenmap[k] = (UINT8)(175 - (j>>6)); - cgraymap[k] = (UINT8)(31 - (j>>6)); - credmap[k] = (UINT8)(143 - (j>>6)); - } - // setup the other colormaps, for console text // these don't need to be aligned, unless you convert the @@ -320,6 +314,9 @@ static void CON_SetupBackColormap(void) redmap[9] = (UINT8)127; orangemap[3] = (UINT8)85; orangemap[9] = (UINT8)90; + + // Init back colormap + CON_SetupBackColormap(); } // Setup the console text buffer @@ -343,7 +340,7 @@ void CON_Init(void) con_width = 0; CON_RecalcSize(); - CON_SetupBackColormap(); + CON_SetupColormaps(); //note: CON_Ticker should always execute at least once before D_Display() con_clipviewtop = -1; // -1 does not clip @@ -1417,7 +1414,7 @@ static void CON_DrawConsole(void) { // inu: no more width (was always 0 and vid.width) if (rendermode != render_none) - V_DrawFadeConsBack(con_curlines, cons_backcolor.value); // translucent background + V_DrawFadeConsBack(con_curlines); // translucent background } // draw console text lines from top to bottom diff --git a/src/console.h b/src/console.h index 47af65e21..8cf6483ff 100644 --- a/src/console.h +++ b/src/console.h @@ -40,11 +40,10 @@ extern consvar_t cons_backcolor; extern UINT8 *yellowmap, *purplemap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap; -// Console bg colors: -extern UINT8 *cwhitemap, *corangemap, *cbluemap, *cgreenmap, *cgraymap, - *credmap; +// Console bg color (auto updated to match) +extern UINT8 *consolebgmap; -void CON_ReSetupBackColormap(UINT16 num); +void CON_SetupBackColormap(void); void CON_ClearHUD(void); // clear heads up messages void CON_Ticker(void); diff --git a/src/p_setup.c b/src/p_setup.c index e56c44c70..111c717d3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2585,7 +2585,7 @@ boolean P_SetupLevel(boolean skipprecip) lastloadedmaplumpnum = W_GetNumForName(maplumpname = G_BuildMapName(gamemap)); R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette); - CON_ReSetupBackColormap(mapheaderinfo[gamemap-1]->palette); + CON_SetupBackColormap(); // now part of level loading since in future each level may have // its own anim texture sequences, switches etc. diff --git a/src/v_video.c b/src/v_video.c index 3cc6d195f..43e3f0182 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -968,45 +968,38 @@ void V_DrawFadeScreen(void) } // Simple translucency with one color, over a set number of lines starting from the top. -void V_DrawFadeConsBack(INT32 plines, INT32 pcolor) +void V_DrawFadeConsBack(INT32 plines) { - UINT8 *deststop, *colormap, *buf; + UINT8 *deststop, *buf; #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode != render_soft && rendermode != render_none) { UINT32 hwcolor; - switch (pcolor) + switch (cons_backcolor.value) { - case 0: hwcolor = 0xffffff00; break; //white - case 1: hwcolor = 0xff800000; break; //orange - case 2: hwcolor = 0x0000ff00; break; //blue - case 3: hwcolor = 0x00800000; break; //green - case 4: hwcolor = 0x80808000; break; //gray - case 5: hwcolor = 0xff000000; break; //red - default: hwcolor = 0x00800000; break; //green + case 0: hwcolor = 0xffffff00; break; // White + case 1: hwcolor = 0x80808000; break; // Gray + case 2: hwcolor = 0x40201000; break; // Brown + case 3: hwcolor = 0xff000000; break; // Red + case 4: hwcolor = 0xff800000; break; // Orange + case 5: hwcolor = 0x80800000; break; // Yellow + case 6: hwcolor = 0x00800000; break; // Green + case 7: hwcolor = 0x0000ff00; break; // Blue + case 8: hwcolor = 0x4080ff00; break; // Cyan + // Default green + default: hwcolor = 0x00800000; break; } HWR_DrawConsoleBack(hwcolor, plines); return; } #endif - switch (pcolor) - { - case 0: colormap = cwhitemap; break; - case 1: colormap = corangemap; break; - case 2: colormap = cbluemap; break; - case 3: colormap = cgreenmap; break; - case 4: colormap = cgraymap; break; - case 5: colormap = credmap; break; - default: colormap = cgreenmap; break; - } - // heavily simplified -- we don't need to know x or y position, // just the stop position deststop = screens[0] + vid.rowbytes * min(plines, vid.height); for (buf = screens[0]; buf < deststop; ++buf) - *buf = colormap[*buf]; + *buf = consolebgmap[*buf]; } // Gets string colormap, used for 0x80 color codes diff --git a/src/v_video.h b/src/v_video.h index 70255d0ef..353f84c1d 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -145,7 +145,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); // fade down the screen buffer before drawing the menu over void V_DrawFadeScreen(void); -void V_DrawFadeConsBack(INT32 plines, INT32 pcolor); +void V_DrawFadeConsBack(INT32 plines); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); From c277125fe7bbf18639ae830b5b1b695179ac7f3b Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Wed, 2 Nov 2016 15:23:22 -0700 Subject: [PATCH 23/50] modifier key status made globally accessible now also properly handles L/R simultaneous presses --- src/console.c | 25 ++----------------------- src/d_main.c | 36 ++++++++++++++++++++++++++++++++++++ src/doomdef.h | 3 +++ src/hu_stuff.c | 7 ------- src/m_menu.c | 12 ------------ 5 files changed, 41 insertions(+), 42 deletions(-) diff --git a/src/console.c b/src/console.c index 3fa9b8a97..11aa5cd56 100644 --- a/src/console.c +++ b/src/console.c @@ -619,9 +619,7 @@ void CON_Ticker(void) // boolean CON_Responder(event_t *ev) { - static boolean consdown; - static boolean shiftdown; - static boolean ctrldown; + static UINT8 consdown = false; // console is treated differently due to rare usage // sequential completions a la 4dos static char completion[80]; @@ -636,13 +634,8 @@ boolean CON_Responder(event_t *ev) // let go keyup events, don't eat them if (ev->type != ev_keydown && ev->type != ev_console) { - if (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT) - shiftdown = false; - else if (ev->data1 == KEY_LCTRL || ev->data1 == KEY_RCTRL) - ctrldown = false; - else if (ev->data1 == gamecontrol[gc_console][0] || ev->data1 == gamecontrol[gc_console][1]) + if (ev->data1 == gamecontrol[gc_console][0] || ev->data1 == gamecontrol[gc_console][1]) consdown = false; - return false; } @@ -684,20 +677,6 @@ boolean CON_Responder(event_t *ev) } - // eat shift only if console active - if (key == KEY_LSHIFT || key == KEY_RSHIFT) - { - shiftdown = true; - return true; - } - - // same for ctrl - if (key == KEY_LCTRL || key == KEY_RCTRL) - { - ctrldown = true; - return true; - } - // command completion forward (tab) and backward (shift-tab) if (key == KEY_TAB) { diff --git a/src/d_main.c b/src/d_main.c index b61ec4143..2caf50087 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -73,6 +73,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "dehacked.h" // Dehacked list test #include "m_cond.h" // condition initialization #include "fastcmp.h" +#include "keys.h" #ifdef CMAKECONFIG #include "config.h" @@ -176,6 +177,38 @@ void D_PostEvent(const event_t *ev) void D_PostEvent_end(void) {}; #endif +// modifier keys +UINT8 shiftdown = 0; // 0x1 left, 0x2 right +UINT8 ctrldown = 0; // 0x1 left, 0x2 right +UINT8 altdown = 0; // 0x1 left, 0x2 right +// +// D_ModifierKeyResponder +// Sets global shift/ctrl/alt variables, never actually eats events +// +static inline void D_ModifierKeyResponder(event_t *ev) +{ + if (ev->type == ev_keydown) switch (ev->data1) + { + case KEY_LSHIFT: shiftdown |= 0x1; return; + case KEY_RSHIFT: shiftdown |= 0x2; return; + case KEY_LCTRL: ctrldown |= 0x1; return; + case KEY_RCTRL: ctrldown |= 0x2; return; + case KEY_LALT: altdown |= 0x1; return; + case KEY_RALT: altdown |= 0x2; return; + default: return; + } + else if (ev->type == ev_keyup) switch (ev->data1) + { + case KEY_LSHIFT: shiftdown &= ~0x1; return; + case KEY_RSHIFT: shiftdown &= ~0x2; return; + case KEY_LCTRL: ctrldown &= ~0x1; return; + case KEY_RCTRL: ctrldown &= ~0x2; return; + case KEY_LALT: altdown &= ~0x1; return; + case KEY_RALT: altdown &= ~0x2; return; + default: return; + } +} + // // D_ProcessEvents // Send all the events of the given timestamp down the responder chain @@ -188,6 +221,9 @@ void D_ProcessEvents(void) { ev = &events[eventtail]; + // Set global shift/ctrl/alt down variables + D_ModifierKeyResponder(ev); // never eats events + // Screenshots over everything so that they can be taken anywhere. if (M_ScreenshotResponder(ev)) continue; // ate the event diff --git a/src/doomdef.h b/src/doomdef.h index fb8ab1ca2..4b2d8c737 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -394,6 +394,9 @@ extern INT32 cv_debug; // Misc stuff for later... // ======================= +// Modifier key variables, accessible anywhere +extern UINT8 shiftdown, ctrldown, altdown; + // if we ever make our alloc stuff... #define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index ec747305e..e33a54305 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -757,15 +757,8 @@ void HU_clearChatChars(void) // boolean HU_Responder(event_t *ev) { - static boolean shiftdown = false; UINT8 c; - if (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT) - { - shiftdown = (ev->type == ev_keydown); - return chat_on; - } - if (ev->type != ev_keydown) return false; diff --git a/src/m_menu.c b/src/m_menu.c index 78c381273..d7b4d9080 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -182,9 +182,6 @@ static INT32 vidm_selected = 0; static INT32 vidm_nummodes; static INT32 vidm_column_size; -// what a headache. -static boolean shiftdown = false; - // // PROTOTYPES // @@ -2080,11 +2077,6 @@ boolean M_Responder(event_t *ev) || gamestate == GS_CREDITS || gamestate == GS_EVALUATION) return false; - if (ev->type == ev_keyup && (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT)) - { - shiftdown = false; - return false; - } if (noFurtherInput) { // Ignore input after enter/escape/other buttons @@ -2098,10 +2090,6 @@ boolean M_Responder(event_t *ev) // added 5-2-98 remap virtual keys (mouse & joystick buttons) switch (ch) { - case KEY_LSHIFT: - case KEY_RSHIFT: - shiftdown = true; - break; //return false; case KEY_MOUSE1: case KEY_JOY1: case KEY_JOY1 + 2: From b2c71944f6bedcf47462d852ba4bb23c14f655f5 Mon Sep 17 00:00:00 2001 From: STJrInuyasha Date: Thu, 3 Nov 2016 00:34:15 -0700 Subject: [PATCH 24/50] Revert "Chat and console improvements" --- src/console.c | 211 ++---------------------- src/hu_stuff.c | 437 ++++++++++++++++--------------------------------- src/hu_stuff.h | 1 + 3 files changed, 152 insertions(+), 497 deletions(-) diff --git a/src/console.c b/src/console.c index f4a1e4f82..025bc1c19 100644 --- a/src/console.c +++ b/src/console.c @@ -91,13 +91,11 @@ static char inputlines[32][CON_MAXPROMPTCHARS]; // hold last 32 prompt lines static INT32 inputline; // current input line number static INT32 inputhist; // line number of history input line to restore static size_t input_cx; // position in current input line -static INT32 input_selection; // selection border in current input line, -1 if no selection // protos. static void CON_InputInit(void); static void CON_RecalcSize(void); -static void CON_DeleteSelectedText(void); static void CONS_hudlines_Change(void); static void CON_DrawBackpic(patch_t *pic, INT32 startx, INT32 destwidth); //static void CON_DrawBackpic2(pic_t *pic, INT32 startx, INT32 destwidth); @@ -396,7 +394,6 @@ static void CON_InputInit(void) inputlines[i][0] = CON_PROMPTCHAR; inputline = 0; input_cx = 1; - input_selection = -1; } //====================================================================== @@ -621,25 +618,6 @@ void CON_Ticker(void) } } -// Deletes selected text, assuming there is, and resets selection. -// Also sets the cursor to the correct position. -// -static void CON_DeleteSelectedText(void) -{ - UINT32 i, j; - char *line = inputlines[inputline]; - size_t selstart = min(input_cx, (size_t)input_selection); - size_t selend = max(input_cx, (size_t)input_selection); - - for (i = selstart, j = selend; line[j]; ++i, ++j) - line[i] = line[j]; - while (line[i]) - line[i++] = 0; - - input_cx = selstart; - input_selection = -1; -} - // Handles console key input // boolean CON_Responder(event_t *ev) @@ -726,9 +704,6 @@ boolean CON_Responder(event_t *ev) // command completion forward (tab) and backward (shift-tab) if (key == KEY_TAB) { - input_cx = strlen(inputlines[inputline]); // make sure the cursor is at the end of the string, in case we were inserting - input_selection = -1; // make sure there is no text selected, it would look odd - // show all cvars/commands that match what we have inputted if (ctrldown) { @@ -864,51 +839,21 @@ boolean CON_Responder(event_t *ev) return true; } - if (key == KEY_HOME) + if (key == KEY_HOME) // oldest text in buffer { - if (shiftdown) - { - if (input_selection == -1) - input_selection = input_cx; - } - else - input_selection = -1; - - if (ctrldown) - con_scrollup = (con_totallines-((con_curlines-16)>>3)); // oldest text in buffer - else - input_cx = 1; - - if ((INT32)input_cx == input_selection) - input_selection = -1; - + con_scrollup = (con_totallines-((con_curlines-16)>>3)); return true; } - else if (key == KEY_END) + else if (key == KEY_END) // most recent text in buffer { - if (shiftdown) - { - if (input_selection == -1) - input_selection = input_cx; - } - else - input_selection = -1; - - if (ctrldown) - con_scrollup = 0; // most recent text in buffer - else - input_cx = strlen(inputlines[inputline]); - - if ((INT32)input_cx == input_selection) - input_selection = -1; - + con_scrollup = 0; return true; } // command enter if (key == KEY_ENTER) { - if (strlen(inputlines[inputline]) < 2) + if (input_cx < 2) return true; // push the command @@ -923,107 +868,18 @@ boolean CON_Responder(event_t *ev) memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); inputlines[inputline][0] = CON_PROMPTCHAR; input_cx = 1; - input_selection = -1; return true; } - // backspace command prompt or delete selected text + // backspace command prompt if (key == KEY_BACKSPACE) { - if (input_selection == -1) + if (input_cx > 1) { - if (input_cx > 1) - { - UINT32 i, j; - char *line = inputlines[inputline]; - - for (i = input_cx - 1, j = input_cx; line[j]; ++i, ++j) - line[i] = line[j]; - line[i] = 0; - input_cx--; - } - } - else - CON_DeleteSelectedText(); - return true; - } - - // delete character under cursor or selected text - if (key == KEY_DEL) - { - if (input_selection == -1) - { - UINT32 i, j; - char *line = inputlines[inputline]; - - for (i = input_cx, j = input_cx + 1; line[j]; ++i, ++j) - line[i] = line[j]; - line[i] = 0; - } - else - CON_DeleteSelectedText(); - - return true; - } - - if (key == KEY_LEFTARROW) - { - if (shiftdown) - { - if (input_selection == -1) - input_selection = input_cx; - } - else - input_selection = -1; - - // move cursor to previous word - if (ctrldown) - { - char *line = inputlines[inputline]; - - while (input_cx > 1 && line[input_cx - 1] == ' ') - input_cx--; - while (input_cx > 1 && line[input_cx - 1] != ' ') - input_cx--; - } - // move cursor left - else if (input_cx > 1) input_cx--; - - if ((INT32)input_cx == input_selection) - input_selection = -1; - - return true; - } - - if (key == KEY_RIGHTARROW) - { - if (shiftdown) - { - if (input_selection == -1) - input_selection = input_cx; + inputlines[inputline][input_cx] = 0; } - else - input_selection = -1; - - // move cursor to next word - if (ctrldown) - { - char *line = inputlines[inputline]; - - while (line[input_cx] && line[input_cx] != ' ') - input_cx++; - while (line[input_cx] && line[input_cx] == ' ') - input_cx++; - } - // move cursor right - else if (inputlines[inputline][input_cx]) - input_cx++; - - if ((INT32)input_cx == input_selection) - input_selection = -1; - return true; } @@ -1094,21 +950,13 @@ boolean CON_Responder(event_t *ev) return false; // add key to cmd line here - if (strlen(inputlines[inputline]) < CON_MAXPROMPTCHARS - 1) + if (input_cx < CON_MAXPROMPTCHARS) { - INT32 i, j; - char *line = inputlines[inputline]; - if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers key = key + 'a' - 'A'; - if (input_selection != -1) - CON_DeleteSelectedText(); - - for (i = strlen(line), j = i + 1; j > (INT32)input_cx; --i, --j) - line[j] = line[i]; - - line[input_cx] = (char)key; + inputlines[inputline][input_cx] = (char)key; + inputlines[inputline][input_cx + 1] = 0; input_cx++; } @@ -1398,7 +1246,6 @@ static void CON_DrawInput(void) size_t c; INT32 x, y; INT32 charwidth = (INT32)con_scalefactor << 3; - INT32 f = cv_constextsize.value | V_NOSCALESTART; // input line scrolls left if it gets too long p = inputlines[inputline]; @@ -1407,44 +1254,14 @@ static void CON_DrawInput(void) y = con_curlines - 12 * con_scalefactor; - if (input_selection == -1) - { - for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); - } - else - { - size_t selstart = min(input_cx, (size_t)input_selection); - size_t selend = max(input_cx, (size_t)input_selection); - - for (c = 0, x = charwidth; c < selstart && c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); - - f |= V_YELLOWMAP; - for (; c < selend && c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); - f &= ~V_YELLOWMAP; - - for (; c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value); - } - //for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) - //V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) + V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); // draw the blinking cursor // x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth); if (con_tick < 4) - { - if (inputlines[inputline][input_cx]) - //V_DrawCharacter(x - 2 * con_scalefactor, y, '|' | f, !cv_allcaps.value); - V_DrawCharacter(x, y + 2 * con_scalefactor, '_' | f, !cv_allcaps.value); - else - V_DrawCharacter(x, y, '_' | f, !cv_allcaps.value); - } - /*x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth); - if (con_tick < 4) - V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);*/ + V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); } // draw the last lines of console text to the top of the screen diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 80e7cf714..ec747305e 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -73,9 +73,6 @@ patch_t *cred_font[CRED_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? static char w_chat[HU_MAXMSGLEN]; -static size_t chat_pos; // position of the cursor in the chat -static INT32 chat_selection; // selection border in current input line, -1 if no selection -static boolean teamtalk = false; static boolean headsupactive = false; boolean hu_showscores; // draw rankings static char hu_tick; @@ -109,7 +106,6 @@ static patch_t *crosshair[HU_CROSSHAIRS]; // 3 precached crosshair graphics static void HU_DrawRankings(void); static void HU_DrawCoopOverlay(void); static void HU_DrawNetplayCoopOverlay(void); -static void HU_DeleteSelectedText(void); //====================================================================== // KEYBOARD LAYOUTS FOR ENTERING TEXT @@ -625,183 +621,36 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } #endif -// Deletes selected text, assuming there is, and resets selection. -// Also sets the cursor to the correct position. -// -static void HU_DeleteSelectedText(void) -{ - UINT32 i, j; - size_t selstart = min(chat_pos, (size_t)chat_selection); - size_t selend = max(chat_pos, (size_t)chat_selection); - - for (i = selstart, j = selend; w_chat[j]; ++i, ++j) - w_chat[i] = w_chat[j]; - while (w_chat[i]) - w_chat[i++] = 0; - - chat_pos = selstart; - chat_selection = -1; -} - // Handles key input and string input // -static void HU_keyInChatString(UINT32 key, boolean shiftdown, boolean ctrldown) +static inline boolean HU_keyInChatString(char *s, char ch) { - switch (key) + size_t l; + + if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART]) + || ch == ' ') // Allow spaces, of course { - case KEY_ESCAPE: - chat_on = false; - break; - case KEY_ENTER: + l = strlen(s); + if (l < HU_MAXMSGLEN - 1) + { + s[l++] = ch; + s[l]=0; + return true; + } + return false; + } + else if (ch == KEY_BACKSPACE) { - // send automatically the message (no more chat char) - char buf[2+256]; - size_t ci = 2; - char *cp = w_chat; - - while (*cp) - { - if (*cp >= ' ' && !(*cp & 0x80)) - buf[ci++] = *cp; - cp++; - } - buf[ci] = 0; - - // last minute mute check - if (cv_mute.value && !(server || adminplayer == consoleplayer)) - { - CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); - return; - } - - if (ci > 2) // don't send target+flags+empty message. - { - if (teamtalk) - buf[0] = -1; // target - else - buf[0] = 0; // target - buf[1] = 0; // flags - SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); - } - - chat_on = false; - break; + l = strlen(s); + if (l) + s[--l] = 0; + else + return false; } - // cursor moving - case KEY_LEFTARROW: - case KEY_RIGHTARROW: - case KEY_HOME: - case KEY_END: - if (shiftdown) - { - if (chat_selection == -1) - chat_selection = chat_pos; - } - else - chat_selection = -1; + else if (ch != KEY_ENTER) + return false; // did not eat key - switch (key) - { - case KEY_LEFTARROW: - // move cursor to previous word - if (ctrldown) - { - while (chat_pos > 0 && w_chat[chat_pos - 1] == ' ') - chat_pos--; - while (chat_pos > 0 && w_chat[chat_pos - 1] != ' ') - chat_pos--; - } - // move cursor left - else if (chat_pos > 0) - chat_pos--; - break; - case KEY_RIGHTARROW: - // move cursor to next word - if (ctrldown) - { - while (w_chat[chat_pos] && w_chat[chat_pos] != ' ') - chat_pos++; - while (w_chat[chat_pos] && w_chat[chat_pos] == ' ') - chat_pos++; - } - // move cursor right - else if (w_chat[chat_pos]) - chat_pos++; - break; - case KEY_HOME: - chat_pos = 0; - break; - case KEY_END: - chat_pos = strlen(w_chat); - } - - if ((INT32)chat_pos == chat_selection) - chat_selection = -1; - break; - // backspace or delete selected text - case KEY_BACKSPACE: - if (chat_selection == -1) - { - if (chat_pos > 0) - { - UINT32 i, j; - for (i = chat_pos - 1, j = chat_pos; w_chat[j]; ++i, ++j) - w_chat[i] = w_chat[j]; - w_chat[i] = 0; - chat_pos--; - } - } - else - HU_DeleteSelectedText(); - break; - // delete character under cursor - case KEY_DEL: - if (chat_selection == -1) - { - UINT32 i, j; - - for (i = chat_pos, j = chat_pos + 1; w_chat[j]; ++i, ++j) - w_chat[i] = w_chat[j]; - w_chat[i] = 0; - } - else - HU_DeleteSelectedText(); - break; - default: - // allow people to use keypad in chat - if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL) - { - XBOXSTATIC char keypad_translation[] = {'7','8','9','-', - '4','5','6','+', - '1','2','3', - '0','.'}; - - key = keypad_translation[key - KEY_KEYPAD7]; - } - else if (key == KEY_KPADSLASH) - key = '/'; - - // use console translations - if (shiftdown) - key = shiftxform[key]; - - if ((key >= HU_FONTSTART && key <= HU_FONTEND && hu_font[key-HU_FONTSTART]) - || key == ' ') // Allow spaces, of course - { - if (strlen(w_chat) < HU_MAXMSGLEN - 1) - { - UINT32 i, j; - - if (chat_selection != -1) - HU_DeleteSelectedText(); - - for (i = strlen(w_chat), j = i + 1; j > chat_pos; --i, --j) - w_chat[j] = w_chat[i]; - w_chat[chat_pos] = (char)key; - chat_pos++; - } - } - } + return true; // ate the key } // @@ -820,9 +669,86 @@ void HU_Ticker(void) hu_showscores = false; } -// REMOVE? Now this has become pretty useless IMO +#define QUEUESIZE 256 + +static boolean teamtalk = false; +static char chatchars[QUEUESIZE]; +static INT32 head = 0, tail = 0; + +// +// HU_dequeueChatChar +// +char HU_dequeueChatChar(void) +{ + char c; + + if (head != tail) + { + c = chatchars[tail]; + tail = (tail + 1) & (QUEUESIZE-1); + } + else + c = 0; + + return c; +} + +// +// +static void HU_queueChatChar(char c) +{ + // send automaticly the message (no more chat char) + if (c == KEY_ENTER) + { + char buf[2+256]; + size_t ci = 2; + + do { + c = HU_dequeueChatChar(); + if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only. + buf[ci++]=c; + } while (c); + + // last minute mute check + if (cv_mute.value && !(server || adminplayer == consoleplayer)) + { + CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); + return; + } + + if (ci > 3) // don't send target+flags+empty message. + { + if (teamtalk) + buf[0] = -1; // target + else + buf[0] = 0; // target + buf[1] = 0; // flags + SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); + } + return; + } + + if (((head + 1) & (QUEUESIZE-1)) == tail) + CONS_Printf(M_GetText("[Message unsent]\n")); // message not sent + else + { + if (c == KEY_BACKSPACE) + { + if (tail != head) + head = (head - 1) & (QUEUESIZE-1); + } + else + { + chatchars[head] = c; + head = (head + 1) & (QUEUESIZE-1); + } + } +} + void HU_clearChatChars(void) { + while (tail != head) + HU_queueChatChar(KEY_BACKSPACE); chat_on = false; } @@ -832,19 +758,13 @@ void HU_clearChatChars(void) boolean HU_Responder(event_t *ev) { static boolean shiftdown = false; - static boolean ctrldown = false; - INT32 key = ev->data1; // only valid if ev->type is a key event + UINT8 c; - if (key == KEY_LSHIFT || key == KEY_RSHIFT) + if (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT) { shiftdown = (ev->type == ev_keydown); return chat_on; } - else if (key == KEY_LCTRL || key == KEY_RCTRL) - { - ctrldown = (ev->type == ev_keydown); - return chat_on; - } if (ev->type != ev_keydown) return false; @@ -854,36 +774,42 @@ boolean HU_Responder(event_t *ev) if (!chat_on) { // enter chat mode - if ((key == gamecontrol[gc_talkkey][0] || key == gamecontrol[gc_talkkey][1]) + if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1]) && netgame && (!cv_mute.value || server || (adminplayer == consoleplayer))) { - // we already checked for this two lines before... - //if (cv_mute.value && !(server || adminplayer == consoleplayer)) - //return false; + if (cv_mute.value && !(server || adminplayer == consoleplayer)) + return false; chat_on = true; w_chat[0] = 0; - chat_pos = 0; - chat_selection = -1; teamtalk = false; return true; } - if ((key == gamecontrol[gc_teamkey][0] || key == gamecontrol[gc_teamkey][1]) + if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1]) && netgame && (!cv_mute.value || server || (adminplayer == consoleplayer))) { - // we already checked for this two lines before... - //if (cv_mute.value && !(server || adminplayer == consoleplayer)) - //return false; + if (cv_mute.value && !(server || adminplayer == consoleplayer)) + return false; chat_on = true; w_chat[0] = 0; - chat_pos = 0; - chat_selection = -1; teamtalk = true; return true; } } else // if chat_on { - HU_keyInChatString(key, shiftdown, ctrldown); + c = (UINT8)ev->data1; + + // use console translations + if (shiftdown) + c = shiftxform[c]; + + if (HU_keyInChatString(w_chat,c)) + HU_queueChatChar(c); + if (c == KEY_ENTER) + chat_on = false; + else if (c == KEY_ESCAPE) + chat_on = false; + return true; } return false; @@ -900,7 +826,7 @@ boolean HU_Responder(event_t *ev) // static void HU_DrawChat(void) { - INT32 t = 0, f = 0, c = 0, y = HU_INPUTY; + INT32 t = 0, c = 0, y = HU_INPUTY; size_t i = 0; const char *ntalk = "Say: ", *ttalk = "Say-Team: "; const char *talk = ntalk; @@ -918,8 +844,6 @@ static void HU_DrawChat(void) #endif } - f = cv_constextsize.value | V_NOSCALESTART; - while (talk[i]) { if (talk[i] < HU_FONTSTART) @@ -930,123 +854,36 @@ static void HU_DrawChat(void) else { //charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | f, !cv_allcaps.value); + V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); } c += charwidth; } - f |= t; i = 0; - if (chat_selection == -1) + while (w_chat[i]) { - while (w_chat[i]) + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) { - //Hurdler: isn't it better like that? - if (w_chat[i] < HU_FONTSTART) - { - ++i; - //charwidth = 4 * con_scalefactor; - } - else - { - //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); - } - - c += charwidth; - if (c >= vid.width) - { - c = 0; - y += charheight; - } + ++i; + //charwidth = 4 * con_scalefactor; } - } - else - { - size_t selstart = min(chat_pos, (size_t)chat_selection); - size_t selend = max(chat_pos, (size_t)chat_selection); - - while (i < selstart) + else { - //Hurdler: isn't it better like that? - if (w_chat[i] < HU_FONTSTART) - { - ++i; - //charwidth = 4 * con_scalefactor; - } - else - { - //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); - } - - c += charwidth; - if (c >= vid.width) - { - c = 0; - y += charheight; - } + //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value); } - f &= ~t; - f |= V_YELLOWMAP; - while (i < selend) + c += charwidth; + if (c >= vid.width) { - //Hurdler: isn't it better like that? - if (w_chat[i] < HU_FONTSTART) - { - ++i; - //charwidth = 4 * con_scalefactor; - } - else - { - //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); - } - - c += charwidth; - if (c >= vid.width) - { - c = 0; - y += charheight; - } - } - f &= ~V_YELLOWMAP; - f |= t; - - while (w_chat[i]) - { - //Hurdler: isn't it better like that? - if (w_chat[i] < HU_FONTSTART) - { - ++i; - //charwidth = 4 * con_scalefactor; - } - else - { - //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value); - } - - c += charwidth; - if (c >= vid.width) - { - c = 0; - y += charheight; - } + c = 0; + y += charheight; } } if (hu_tick < 4) - { - if (w_chat[chat_pos]) - { - i = (strlen(talk) + chat_pos) * charwidth; - c = i % vid.width; - y = HU_INPUTY + i / vid.width * charheight + 2 * con_scalefactor; - } - V_DrawCharacter(HU_INPUTX + c, y, '_' | f, !cv_allcaps.value); - } + V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, !cv_allcaps.value); } diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 5dca10981..7b22f33f1 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -93,6 +93,7 @@ boolean HU_Responder(event_t *ev); void HU_Ticker(void); void HU_Drawer(void); +char HU_dequeueChatChar(void); void HU_Erase(void); void HU_clearChatChars(void); void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); From bb20cfd6beb341c0774c473150ebb9e1d889cbfe Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Thu, 3 Nov 2016 01:43:57 -0700 Subject: [PATCH 25/50] Clipboard copy/paste testing (unfinished, but basics work) --- src/android/i_system.c | 12 +++++ src/console.c | 108 ++++++++++++++++++------------------- src/djgppdos/i_system.c | 12 +++++ src/dummy/i_system.c | 12 +++++ src/i_system.h | 8 +++ src/nds/i_system.c | 12 +++++ src/sdl/i_system.c | 115 ++++++++++++++++++++++++++++++++++++++++ src/sdl/ogl_sdl.h | 1 - src/sdl/sdlmain.h | 3 ++ src/sdl12/i_system.c | 12 +++++ src/win32/win_sys.c | 12 +++++ src/win32ce/win_sys.c | 12 +++++ 12 files changed, 264 insertions(+), 55 deletions(-) diff --git a/src/android/i_system.c b/src/android/i_system.c index 150cbd505..58fca7c19 100644 --- a/src/android/i_system.c +++ b/src/android/i_system.c @@ -258,6 +258,18 @@ INT32 I_PutEnv(char *variable) return -1; } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + void I_RegisterSysCommands(void) {} #include "../sdl/dosstr.c" diff --git a/src/console.c b/src/console.c index 11aa5cd56..02324ada2 100644 --- a/src/console.c +++ b/src/console.c @@ -641,6 +641,12 @@ boolean CON_Responder(event_t *ev) key = ev->data1; + // Always eat ctrl/shift/alt, so the menu doesn't get ideas + if (key == KEY_LSHIFT || key == KEY_RSHIFT + || key == KEY_LCTRL || key == KEY_RCTRL + || key == KEY_LALT || key == KEY_RALT) + return true; + // check for console toggle key if (ev->type != ev_console) { @@ -677,67 +683,70 @@ boolean CON_Responder(event_t *ev) } - // command completion forward (tab) and backward (shift-tab) - if (key == KEY_TAB) + // ctrl modifier -- changes behavior, adds shortcuts + if (ctrldown) { // show all cvars/commands that match what we have inputted - if (ctrldown) + if (key == KEY_TAB) { - UINT32 i; - size_t stop = input_cx - 1; - char nameremainder[255]; + size_t i, len = strlen(inputlines[inputline]+1); - if (input_cx < 2 || strlen(inputlines[inputline]+1) >= 80) + if (input_cx < 2 || len >= 80 || strchr(inputlines[inputline]+1, ' ')) return true; strcpy(completion, inputlines[inputline]+1); - // trimming: stop at the first newline - for (i = 0; i < input_cx - 1; ++i) - { - if (completion[i] == ' ') - { - completion[i] = '\0'; - stop = i; - break; - } - } - - i = 0; - //first check commands CONS_Printf("\nCommands:\n"); - - for (cmd = COM_CompleteCommand(completion, i); cmd; cmd = COM_CompleteCommand(completion, i)) - { - strncpy(nameremainder, cmd+(stop), strlen(cmd)-(stop)); - nameremainder[strlen(cmd)-(stop)] = '\0'; - - CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, nameremainder); - ++i; - } - if (i == 0) - CONS_Printf(" (none)\n"); - - i = 0; + for (i = 0, cmd = COM_CompleteCommand(completion, i); cmd; cmd = COM_CompleteCommand(completion, ++i)) + CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, cmd+len); + if (i == 0) CONS_Printf(" (none)\n"); //now we move on to CVARs CONS_Printf("Variables:\n"); - - for (cmd = CV_CompleteVar(completion, i); cmd; cmd = CV_CompleteVar(completion, i)) - { - strncpy(nameremainder, cmd+(stop), strlen(cmd)-(stop)); - nameremainder[strlen(cmd)-(stop)] = '\0'; - - CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, nameremainder); - ++i; - } - if (i == 0) - CONS_Printf(" (none)\n"); + for (i = 0, cmd = CV_CompleteVar(completion, i); cmd; cmd = CV_CompleteVar(completion, ++i)) + CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, cmd+len); + if (i == 0) CONS_Printf(" (none)\n"); return true; } + // --- + if (key == KEY_HOME) // oldest text in buffer + { + con_scrollup = (con_totallines-((con_curlines-16)>>3)); + return true; + } + else if (key == KEY_END) // most recent text in buffer + { + con_scrollup = 0; + return true; + } + + if (key == 'x' || key == 'X') + { + CONS_Printf("Cut\n"); + return true; + } + else if (key == 'c' || key == 'C') + { + CONS_Printf("Copy\n"); + I_ClipboardCopy(inputlines[inputline]+1, strlen(inputlines[inputline]+1)); + return true; + } + else if (key == 'v' || key == 'V') + { + CONS_Printf("Paste: %s\n", I_ClipboardPaste()); + return true; + } + + // don't eat the key + return false; + } + + // command completion forward (tab) and backward (shift-tab) + if (key == KEY_TAB) + { // sequential command completion forward and backward // remember typing for several completions (a-la-4dos) @@ -815,16 +824,7 @@ boolean CON_Responder(event_t *ev) return true; } - if (key == KEY_HOME) // oldest text in buffer - { - con_scrollup = (con_totallines-((con_curlines-16)>>3)); - return true; - } - else if (key == KEY_END) // most recent text in buffer - { - con_scrollup = 0; - return true; - } + // command enter if (key == KEY_ENTER) diff --git a/src/djgppdos/i_system.c b/src/djgppdos/i_system.c index 854d68f4d..dae9ed16e 100644 --- a/src/djgppdos/i_system.c +++ b/src/djgppdos/i_system.c @@ -1721,6 +1721,18 @@ INT32 I_PutEnv(char *variable) return putenv(variable); } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + const CPUInfoFlags *I_CPUInfo(void) { static CPUInfoFlags DOS_CPUInfo; diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index c1e48b60b..a3fe3077c 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -162,6 +162,18 @@ INT32 I_PutEnv(char *variable) return -1; } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + void I_RegisterSysCommands(void) {} #include "../sdl/dosstr.c" diff --git a/src/i_system.h b/src/i_system.h index c161851e0..d61f2d16e 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -296,6 +296,14 @@ char *I_GetEnv(const char *name); INT32 I_PutEnv(char *variable); +/** \brief Put data in system clipboard +*/ +INT32 I_ClipboardCopy(const char *data, size_t size); + +/** \brief Retrieve data from system clipboard +*/ +const char *I_ClipboardPaste(void); + void I_RegisterSysCommands(void); #endif diff --git a/src/nds/i_system.c b/src/nds/i_system.c index 0ed58029c..3e5c4b8c6 100644 --- a/src/nds/i_system.c +++ b/src/nds/i_system.c @@ -269,6 +269,18 @@ INT32 I_PutEnv(char *variable) return -1; } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + void I_RegisterSysCommands(void) {} #include "../sdl/dosstr.c" diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index ea8ade8c1..8c4331aa0 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -260,6 +260,18 @@ static char returnWadPath[256]; #include "../byteptr.h" #endif +// FAKE_CLIPBOARD simulates system clipboard, but is just local to our app +#ifndef FAKE_CLIPBOARD +#include "SDL_syswm.h" + +#if defined (_WIN32) && !defined (_XBOX) +#include +#endif + +// TODO: clipboard support for other OSes + +#endif + /** \brief The JoyReset function \param JoySet Joystick info to reset @@ -2647,6 +2659,109 @@ INT32 I_PutEnv(char *variable) #endif } +#ifdef FAKE_CLIPBOARD +static char __clipboard[512] = ""; +#endif + +INT32 I_ClipboardCopy(const char *data, size_t size) +{ +#ifdef FAKE_CLIPBOARD + if (size >= 512) size = 511; + memcpy(__clipboard, data, size); + __clipboard[size] = 0; + return 0; +#else // !FAKE_CLIPBOARD + +#if defined(_WIN32) && !defined(_XBOX) + SDL_SysWMinfo syswm; + HGLOBAL *storage_ptr; + char *storage_raw; + + SDL_VERSION(&syswm.version); + + // Get window (HWND) information, use that to open the clipboard + if (!SDL_GetWindowWMInfo(window, &syswm) || !(OpenClipboard(syswm.info.win.window))) + return -1; + + // Erase clipboard contents -- if we have nothing to copy, just leave them blank + EmptyClipboard(); + if (size == 0) + goto clipboardend; + + // Allocate movable global memory to store our text. + if (!(storage_ptr = GlobalAlloc(GMEM_MOVEABLE, size+1)) + || !(storage_raw = (char *)GlobalLock(storage_ptr))) // Lock our pointer (gives us access to its data) + goto clipboardfail; + memcpy(storage_raw, data, size); + storage_raw[size] = 0; + GlobalUnlock(storage_ptr); // Unlock it before sending it off + if (!SetClipboardData(CF_TEXT, storage_ptr)) // NOTE: this removes our permissions from the pointer + goto clipboardfail; + +clipboardend: + CloseClipboard(); + return 0; //OpenClipboard(); +clipboardfail: + CloseClipboard(); // Don't leave me hanging + return -1; +#else + (void)data; + (void)size; + return -1; +#endif + +#endif // FAKE_CLIPBOARD +} + +const char *I_ClipboardPaste(void) +{ +#ifdef FAKE_CLIPBOARD + return (const char *)&__clipboard; +#else // !FAKE_CLIPBOARD + +#if defined(_WIN32) && !defined(_XBOX) + HGLOBAL *clipboard_ptr; + const char *clipboard_raw; + static char clipboard_contents[512]; + char *i = clipboard_contents; + + if (!IsClipboardFormatAvailable(CF_TEXT)) + return NULL; // Data either unavailable, or in wrong format + OpenClipboard(NULL); // NOTE: Don't need window pointer to get, only to set + if (!(clipboard_ptr = GetClipboardData(CF_TEXT))) // Get global pointer + return NULL; + if (!(clipboard_raw = (const char *)GlobalLock(clipboard_ptr))) // Lock access -- gives us direct ptr to data + { + CloseClipboard(); // Don't leave me hanging if we fail + return NULL; + } + memcpy(clipboard_contents, clipboard_raw, 511); + GlobalUnlock(clipboard_ptr); // Unlock for other apps + CloseClipboard(); // And make sure to close the clipboard for other apps too + clipboard_contents[511] = 0; // Done after unlock to cause as little interference as possible + + while (*i) + { + if (*i == '\n' || *i == '\r') + { // End on newline + *i = 0; + break; + } + else if (*i == '\t') + *i = ' '; // Tabs become spaces + else if (*i < 32 || (unsigned)*i > 127) + *i = '?'; // Nonprintable chars become question marks + ++i; + } + + return (const char *)&clipboard_contents; +#else + return NULL; +#endif + +#endif // FAKE_CLIPBOARD +} + /** \brief The isWadPathOk function \param path string path to check diff --git a/src/sdl/ogl_sdl.h b/src/sdl/ogl_sdl.h index 7e144644c..2d6209f2b 100644 --- a/src/sdl/ogl_sdl.h +++ b/src/sdl/ogl_sdl.h @@ -24,7 +24,6 @@ boolean OglSdlSurface(INT32 w, INT32 h); void OglSdlFinishUpdate(boolean vidwait); -extern SDL_Window *window; extern SDL_Renderer *renderer; extern SDL_GLContext sdlglcontext; extern Uint16 realwidth; diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h index 7ac32f4b3..fea1e1648 100644 --- a/src/sdl/sdlmain.h +++ b/src/sdl/sdlmain.h @@ -71,4 +71,7 @@ void I_GetConsoleEvents(void); void SDLforceUngrabMouse(void); +// Needed for some WIN32 functions +extern SDL_Window *window; + #endif diff --git a/src/sdl12/i_system.c b/src/sdl12/i_system.c index 888a6a507..ed0db653d 100644 --- a/src/sdl12/i_system.c +++ b/src/sdl12/i_system.c @@ -2666,6 +2666,18 @@ INT32 I_PutEnv(char *variable) #endif } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + /** \brief The isWadPathOk function \param path string path to check diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index 0331080c8..eec043803 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -3598,6 +3598,18 @@ INT32 I_PutEnv(char *variable) return putenv(variable); } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + typedef BOOL (WINAPI *p_IsProcessorFeaturePresent) (DWORD); const CPUInfoFlags *I_CPUInfo(void) diff --git a/src/win32ce/win_sys.c b/src/win32ce/win_sys.c index 88764ef73..3b6a47258 100644 --- a/src/win32ce/win_sys.c +++ b/src/win32ce/win_sys.c @@ -3470,6 +3470,18 @@ INT32 I_PutEnv(char *variable) return putenv(variable); } +INT32 I_ClipboardCopy(const char *data, size_t size) +{ + (void)data; + (void)size; + return -1; +} + +char *I_ClipboardPaste(void) +{ + return NULL; +} + typedef BOOL (WINAPI *MyFunc3) (DWORD); const CPUInfoFlags *I_CPUInfo(void) From 8040a68fa087f4c09f60c5663fd08077830b8707 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 3 Nov 2016 14:29:51 -0400 Subject: [PATCH 26/50] Clipboard: remove Win32 code for SDL Clipboard API --- src/sdl/i_system.c | 107 ++------------------------------------------- 1 file changed, 4 insertions(+), 103 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 8c4331aa0..97746b6bf 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -260,18 +260,6 @@ static char returnWadPath[256]; #include "../byteptr.h" #endif -// FAKE_CLIPBOARD simulates system clipboard, but is just local to our app -#ifndef FAKE_CLIPBOARD -#include "SDL_syswm.h" - -#if defined (_WIN32) && !defined (_XBOX) -#include -#endif - -// TODO: clipboard support for other OSes - -#endif - /** \brief The JoyReset function \param JoySet Joystick info to reset @@ -2659,107 +2647,20 @@ INT32 I_PutEnv(char *variable) #endif } -#ifdef FAKE_CLIPBOARD -static char __clipboard[512] = ""; -#endif INT32 I_ClipboardCopy(const char *data, size_t size) { -#ifdef FAKE_CLIPBOARD - if (size >= 512) size = 511; - memcpy(__clipboard, data, size); - __clipboard[size] = 0; - return 0; -#else // !FAKE_CLIPBOARD - -#if defined(_WIN32) && !defined(_XBOX) - SDL_SysWMinfo syswm; - HGLOBAL *storage_ptr; - char *storage_raw; - - SDL_VERSION(&syswm.version); - - // Get window (HWND) information, use that to open the clipboard - if (!SDL_GetWindowWMInfo(window, &syswm) || !(OpenClipboard(syswm.info.win.window))) - return -1; - - // Erase clipboard contents -- if we have nothing to copy, just leave them blank - EmptyClipboard(); - if (size == 0) - goto clipboardend; - - // Allocate movable global memory to store our text. - if (!(storage_ptr = GlobalAlloc(GMEM_MOVEABLE, size+1)) - || !(storage_raw = (char *)GlobalLock(storage_ptr))) // Lock our pointer (gives us access to its data) - goto clipboardfail; - memcpy(storage_raw, data, size); - storage_raw[size] = 0; - GlobalUnlock(storage_ptr); // Unlock it before sending it off - if (!SetClipboardData(CF_TEXT, storage_ptr)) // NOTE: this removes our permissions from the pointer - goto clipboardfail; - -clipboardend: - CloseClipboard(); - return 0; //OpenClipboard(); -clipboardfail: - CloseClipboard(); // Don't leave me hanging - return -1; -#else - (void)data; (void)size; + if (SDL_SetClipboardText(data) == 0) + return 0; return -1; -#endif - -#endif // FAKE_CLIPBOARD } const char *I_ClipboardPaste(void) { -#ifdef FAKE_CLIPBOARD - return (const char *)&__clipboard; -#else // !FAKE_CLIPBOARD - -#if defined(_WIN32) && !defined(_XBOX) - HGLOBAL *clipboard_ptr; - const char *clipboard_raw; - static char clipboard_contents[512]; - char *i = clipboard_contents; - - if (!IsClipboardFormatAvailable(CF_TEXT)) - return NULL; // Data either unavailable, or in wrong format - OpenClipboard(NULL); // NOTE: Don't need window pointer to get, only to set - if (!(clipboard_ptr = GetClipboardData(CF_TEXT))) // Get global pointer - return NULL; - if (!(clipboard_raw = (const char *)GlobalLock(clipboard_ptr))) // Lock access -- gives us direct ptr to data - { - CloseClipboard(); // Don't leave me hanging if we fail - return NULL; - } - memcpy(clipboard_contents, clipboard_raw, 511); - GlobalUnlock(clipboard_ptr); // Unlock for other apps - CloseClipboard(); // And make sure to close the clipboard for other apps too - clipboard_contents[511] = 0; // Done after unlock to cause as little interference as possible - - while (*i) - { - if (*i == '\n' || *i == '\r') - { // End on newline - *i = 0; - break; - } - else if (*i == '\t') - *i = ' '; // Tabs become spaces - else if (*i < 32 || (unsigned)*i > 127) - *i = '?'; // Nonprintable chars become question marks - ++i; - } - - return (const char *)&clipboard_contents; -#else + if (SDL_HasClipboardText()) + return SDL_GetClipboardText(); return NULL; -#endif - -#endif // FAKE_CLIPBOARD } /** \brief The isWadPathOk function From 1f6388a2e0089c6004825fa7ef66c54c0800de73 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 3 Nov 2016 14:35:32 -0400 Subject: [PATCH 27/50] Fix up Win32 interface code misdeclaration of I_ClipboardPaste() --- src/win32/win_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index eec043803..80b89a6e6 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -3605,7 +3605,7 @@ INT32 I_ClipboardCopy(const char *data, size_t size) return -1; } -char *I_ClipboardPaste(void) +const char *I_ClipboardPaste(void) { return NULL; } From 2ec972af54fe9c8c241e89387f3516ebd4b68c3b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 3 Nov 2016 20:40:17 +0000 Subject: [PATCH 28/50] check numVertices, bail out and print error message if there are too many I added similar checks for the other num* but it seems some MD2s break the other limits without knowing anyway ...so I've commented these checks out for now, unless we have further discussion regarding them later on --- src/hardware/hw_md2.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8e48ec110..8e2b9a5b5 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -308,6 +308,23 @@ static md2_model_t *md2_readModel(const char *filename) model->header.numSkins = 1; +#define MD2LIMITCHECK(field, max, msgname) \ + if (field >= max) \ + { \ + CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \ + md2_freeModel (model); \ + return 0; \ + } + + // Uncomment if these are actually needed +// MD2LIMITCHECK(model->header.numSkins, MD2_MAX_SKINS, "skins") +// MD2LIMITCHECK(model->header.numTexCoords, MD2_MAX_TEXCOORDS, "texture coordinates") +// MD2LIMITCHECK(model->header.numTriangles, MD2_MAX_TRIANGLES, "triangles") +// MD2LIMITCHECK(model->header.numFrames, MD2_MAX_FRAMES, "frames") + MD2LIMITCHECK(model->header.numVertices, MD2_MAX_VERTICES, "vertices") + +#undef MD2LIMITCHECK + // read skins fseek(file, model->header.offsetSkins, SEEK_SET); if (model->header.numSkins > 0) @@ -319,8 +336,6 @@ static md2_model_t *md2_readModel(const char *filename) md2_freeModel (model); return 0; } - - ; } // read texture coordinates @@ -334,8 +349,6 @@ static md2_model_t *md2_readModel(const char *filename) md2_freeModel (model); return 0; } - - } // read triangles From 561a0fe76880455a97079a4a171c1cefad7fc70c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 3 Nov 2016 21:06:23 +0000 Subject: [PATCH 29/50] Attempt loading of an MD2 only once; if we failed then don't bother again This keeps my new error messages from flooding the console and log.txt --- src/hardware/hw_md2.c | 5 +++++ src/hardware/hw_md2.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8e2b9a5b5..2fcf252d2 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -782,6 +782,7 @@ void HWR_InitMD2(void) md2_playermodels[s].grpatch = NULL; md2_playermodels[s].skin = -1; md2_playermodels[s].notfound = true; + md2_playermodels[s].error = false; } for (i = 0; i < NUMSPRITES; i++) { @@ -790,6 +791,7 @@ void HWR_InitMD2(void) md2_models[i].grpatch = NULL; md2_models[i].skin = -1; md2_models[i].notfound = true; + md2_models[s].error = false; } // read the md2.dat file @@ -1282,6 +1284,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else md2 = &md2_models[spr->mobj->sprite]; + if (md2->error) + return; // we already failed loading this before :( if (!md2->model) { //CONS_Debug(DBG_RENDER, "Loading MD2... (%s)", sprnames[spr->mobj->sprite]); @@ -1295,6 +1299,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else { //CONS_Debug(DBG_RENDER, " FAILED\n"); + md2->error = true; // prevent endless fail return; } } diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 36078268b..5a7e6d2b3 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -123,6 +123,7 @@ typedef struct void *blendgrpatch; boolean notfound; INT32 skin; + boolean error; } md2_t; extern md2_t md2_models[NUMSPRITES]; From efe02e2a42b380003c07433d4a837e3011e732d7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 3 Nov 2016 22:53:49 +0000 Subject: [PATCH 30/50] allow triangle/frame limits too --- src/hardware/hw_md2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 2fcf252d2..a578e6b75 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -319,8 +319,8 @@ static md2_model_t *md2_readModel(const char *filename) // Uncomment if these are actually needed // MD2LIMITCHECK(model->header.numSkins, MD2_MAX_SKINS, "skins") // MD2LIMITCHECK(model->header.numTexCoords, MD2_MAX_TEXCOORDS, "texture coordinates") -// MD2LIMITCHECK(model->header.numTriangles, MD2_MAX_TRIANGLES, "triangles") -// MD2LIMITCHECK(model->header.numFrames, MD2_MAX_FRAMES, "frames") + MD2LIMITCHECK(model->header.numTriangles, MD2_MAX_TRIANGLES, "triangles") + MD2LIMITCHECK(model->header.numFrames, MD2_MAX_FRAMES, "frames") MD2LIMITCHECK(model->header.numVertices, MD2_MAX_VERTICES, "vertices") #undef MD2LIMITCHECK From e245cdfcbf41fed6667565c4f4fd3568eed297cd Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Thu, 3 Nov 2016 17:30:30 -0700 Subject: [PATCH 31/50] Console with moving cursor, selections, etc --- src/console.c | 355 +++++++++++++++++++++++++++++++++------------ src/sdl/i_system.c | 104 ++----------- src/v_video.c | 76 +++++----- 3 files changed, 322 insertions(+), 213 deletions(-) diff --git a/src/console.c b/src/console.c index 02324ada2..ea5999c0d 100644 --- a/src/console.c +++ b/src/console.c @@ -84,13 +84,16 @@ UINT32 con_scalefactor; // text size scale factor // hold 32 last lines of input for history #define CON_MAXPROMPTCHARS 256 -#define CON_PROMPTCHAR '>' +#define CON_PROMPTCHAR '$' static char inputlines[32][CON_MAXPROMPTCHARS]; // hold last 32 prompt lines static INT32 inputline; // current input line number static INT32 inputhist; // line number of history input line to restore -static size_t input_cx; // position in current input line +static size_t input_cur; // position of cursor in line +static size_t input_sel; // position of selection marker (I.E.: anything between this and input_cur is "selected") +static size_t input_len; // length of current line, used to bound cursor and such +// notice: input does NOT include the "$" at the start of the line. - 11/3/16 // protos. static void CON_InputInit(void); @@ -383,14 +386,10 @@ void CON_Init(void) // static void CON_InputInit(void) { - INT32 i; - // prepare the first prompt line memset(inputlines, 0, sizeof (inputlines)); - for (i = 0; i < 32; i++) - inputlines[i][0] = CON_PROMPTCHAR; inputline = 0; - input_cx = 1; + input_cur = input_sel = input_len = 0; } //====================================================================== @@ -615,6 +614,86 @@ void CON_Ticker(void) } } +// +// ---- +// +// Shortcuts for adding and deleting characters, strings, and sections +// Necessary due to moving cursor +// + +static inline void CON_InputClear(void) +{ + memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); + input_cur = input_sel = input_len = 0; +} + +static inline void CON_InputSetString(const char *c) +{ + memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); + strcpy(inputlines[inputline], c); + input_cur = input_sel = input_len = strlen(c); +} + +static inline void CON_InputAddString(const char *c) +{ + size_t csize = strlen(c); + if (input_len + csize > CON_MAXPROMPTCHARS-1) + return; + if (input_cur != input_len) + memmove(&inputlines[inputline][input_cur+csize], &inputlines[inputline][input_cur], input_len-input_cur); + memcpy(&inputlines[inputline][input_cur], c, csize); + input_len += csize; + input_sel = (input_cur += csize); +} + +static inline void CON_InputDelSelection(void) +{ + size_t start, end, len; + if (input_cur > input_sel) + { + start = input_sel; + end = input_cur; + } + else + { + start = input_cur; + end = input_sel; + } + len = (end - start); + + if (end != input_len) + memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-input_cur); + memset(&inputlines[inputline][input_len - len], 0, len); + + input_len -= len; + input_sel = input_cur = start; +} + +static inline void CON_InputAddChar(char c) +{ + if (input_len >= CON_MAXPROMPTCHARS-1) + return; + if (input_cur != input_len) + memmove(&inputlines[inputline][input_cur+1], &inputlines[inputline][input_cur], input_len-input_cur); + inputlines[inputline][input_cur++] = c; + inputlines[inputline][++input_len] = 0; + input_sel = input_cur; +} + +static inline void CON_InputDelChar(void) +{ + if (!input_cur) + return; + if (input_cur != input_len) + memmove(&inputlines[inputline][input_cur-1], &inputlines[inputline][input_cur], input_len-input_cur); + inputlines[inputline][--input_len] = 0; + input_sel = --input_cur; +} + +// +// ---- +// + // Handles console key input // boolean CON_Responder(event_t *ev) @@ -689,12 +768,16 @@ boolean CON_Responder(event_t *ev) // show all cvars/commands that match what we have inputted if (key == KEY_TAB) { - size_t i, len = strlen(inputlines[inputline]+1); + size_t i, len; - if (input_cx < 2 || len >= 80 || strchr(inputlines[inputline]+1, ' ')) - return true; - - strcpy(completion, inputlines[inputline]+1); + if (!completion[0]) + { + if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' ')) + return true; + strcpy(completion, inputlines[inputline]); + comskips = varskips = 0; + } + len = strlen(completion); //first check commands CONS_Printf("\nCommands:\n"); @@ -725,18 +808,38 @@ boolean CON_Responder(event_t *ev) if (key == 'x' || key == 'X') { - CONS_Printf("Cut\n"); + if (input_sel > input_cur) + I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur); + else + I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel); + CON_InputDelSelection(); + completion[0] = 0; return true; } else if (key == 'c' || key == 'C') { - CONS_Printf("Copy\n"); - I_ClipboardCopy(inputlines[inputline]+1, strlen(inputlines[inputline]+1)); + if (input_sel > input_cur) + I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur); + else + I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel); return true; } else if (key == 'v' || key == 'V') { - CONS_Printf("Paste: %s\n", I_ClipboardPaste()); + const char *paste = I_ClipboardPaste(); + if (input_sel != input_cur) + CON_InputDelSelection(); + if (paste != NULL) + CON_InputAddString(paste); + completion[0] = 0; + return true; + } + + // Select all + if (key == 'a' || key == 'A') + { + input_sel = 0; + input_cur = input_len; return true; } @@ -750,13 +853,11 @@ boolean CON_Responder(event_t *ev) // sequential command completion forward and backward // remember typing for several completions (a-la-4dos) - if (inputlines[inputline][input_cx-1] != ' ') + if (!completion[0]) { - if (strlen(inputlines[inputline]+1) < 80) - strcpy(completion, inputlines[inputline]+1); - else - completion[0] = 0; - + if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' ')) + return true; + strcpy(completion, inputlines[inputline]); comskips = varskips = 0; } else @@ -768,37 +869,26 @@ boolean CON_Responder(event_t *ev) if (--varskips < 0) comskips = -comskips - 2; } - else if (comskips > 0) - comskips--; + else if (comskips > 0) comskips--; } else { - if (comskips < 0) - varskips++; - else - comskips++; + if (comskips < 0) varskips++; + else comskips++; } } if (comskips >= 0) { cmd = COM_CompleteCommand(completion, comskips); - if (!cmd) - // dirty: make sure if comskips is zero, to have a neg value + if (!cmd) // dirty: make sure if comskips is zero, to have a neg value comskips = -comskips - 1; } if (comskips < 0) cmd = CV_CompleteVar(completion, varskips); if (cmd) - { - memset(inputlines[inputline]+1, 0, CON_MAXPROMPTCHARS-1); - strcpy(inputlines[inputline]+1, cmd); - input_cx = strlen(cmd) + 1; - inputlines[inputline][input_cx] = ' '; - input_cx++; - inputlines[inputline][input_cx] = 0; - } + CON_InputSetString(va("%s ", cmd)); else { if (comskips > 0) @@ -824,38 +914,80 @@ boolean CON_Responder(event_t *ev) return true; } + if (key == KEY_LEFTARROW) + { + if (input_cur != 0) + --input_cur; + if (!shiftdown) + input_sel = input_cur; + return true; + } + else if (key == KEY_RIGHTARROW) + { + if (input_cur < input_len) + ++input_cur; + if (!shiftdown) + input_sel = input_cur; + return true; + } + else if (key == KEY_HOME) + { + input_cur = 0; + if (!shiftdown) + input_sel = input_cur; + return true; + } + else if (key == KEY_END) + { + input_cur = input_len; + if (!shiftdown) + input_sel = input_cur; + return true; + } + // At this point we're messing with input + // Clear completion + completion[0] = 0; // command enter if (key == KEY_ENTER) { - if (input_cx < 2) + if (!input_len) return true; // push the command - COM_BufAddText(inputlines[inputline]+1); + COM_BufAddText(inputlines[inputline]); COM_BufAddText("\n"); - CONS_Printf("%s\n", inputlines[inputline]); + CONS_Printf("\x86""%c""\x80""%s\n", CON_PROMPTCHAR, inputlines[inputline]); inputline = (inputline+1) & 31; inputhist = inputline; - - memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); - inputlines[inputline][0] = CON_PROMPTCHAR; - input_cx = 1; + CON_InputClear(); return true; } - // backspace command prompt - if (key == KEY_BACKSPACE) + // backspace and delete command prompt + if (input_sel != input_cur) { - if (input_cx > 1) + if (key == KEY_BACKSPACE || key == KEY_DEL) { - input_cx--; - inputlines[inputline][input_cx] = 0; + CON_InputDelSelection(); + return true; } + } + else if (key == KEY_BACKSPACE) + { + CON_InputDelChar(); + return true; + } + else if (key == KEY_DEL) + { + if (input_cur == input_len) + return true; + ++input_cur; + CON_InputDelChar(); return true; } @@ -864,18 +996,15 @@ boolean CON_Responder(event_t *ev) { // copy one of the previous inputlines to the current do - { inputhist = (inputhist - 1) & 31; // cycle back - } while (inputhist != inputline && !inputlines[inputhist][1]); + while (inputhist != inputline && !inputlines[inputhist][0]); // stop at the last history input line, which is the // current line + 1 because we cycle through the 32 input lines if (inputhist == inputline) inputhist = (inputline + 1) & 31; - M_Memcpy(inputlines[inputline], inputlines[inputhist], CON_MAXPROMPTCHARS); - input_cx = strlen(inputlines[inputline]); - + CON_InputSetString(inputlines[inputhist]); return true; } @@ -885,23 +1014,14 @@ boolean CON_Responder(event_t *ev) if (inputhist == inputline) return true; do - { inputhist = (inputhist + 1) & 31; - } while (inputhist != inputline && !inputlines[inputhist][1]); - - memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); + while (inputhist != inputline && !inputlines[inputhist][0]); // back to currentline if (inputhist == inputline) - { - inputlines[inputline][0] = CON_PROMPTCHAR; - input_cx = 1; - } + CON_InputClear(); else - { - strcpy(inputlines[inputline], inputlines[inputhist]); - input_cx = strlen(inputlines[inputline]); - } + CON_InputSetString(inputlines[inputhist]); return true; } @@ -926,15 +1046,12 @@ boolean CON_Responder(event_t *ev) return false; // add key to cmd line here - if (input_cx < CON_MAXPROMPTCHARS) - { - if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers - key = key + 'a' - 'A'; + if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers + key = key + 'a' - 'A'; - inputlines[inputline][input_cx] = (char)key; - inputlines[inputline][input_cx + 1] = 0; - input_cx++; - } + if (input_sel != input_cur) + CON_InputDelSelection(); + CON_InputAddChar(key); return true; } @@ -1218,26 +1335,84 @@ void CONS_Error(const char *msg) // static void CON_DrawInput(void) { - char *p; - size_t c; - INT32 x, y; INT32 charwidth = (INT32)con_scalefactor << 3; - - // input line scrolls left if it gets too long - p = inputlines[inputline]; - if (input_cx >= con_width-11) - p += input_cx - (con_width-11) + 1; + const char *p = inputlines[inputline]; + size_t c, clen, cend; + UINT8 lellip = 0, rellip = 0; + INT32 x, y, i; y = con_curlines - 12 * con_scalefactor; + x = charwidth*2; - for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth) - V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + clen = con_width-12; - // draw the blinking cursor - // - x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth); - if (con_tick < 4) - V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + if (input_len <= clen) + { + c = 0; + clen = input_len; + } + else // input line scrolls left if it gets too long + { + clen -= 2; // There will always be some extra truncation -- but where is what we'll find out + + if (input_cur <= clen/2) + { + // Close enough to right edge to show all + c = 0; + // Always will truncate right side from this position, so always draw right ellipsis + rellip = 1; + } + else + { + // Cursor in the middle (or right side) of input + // Move over for the ellipsis + c = input_cur - (clen/2) + 2; + x += charwidth*2; + lellip = 1; + + if (c + clen >= input_len) + { + // Cursor in the right side of input + // We were too far over, so move back + c = input_len - clen; + } + else + { + // Cursor in the middle -- ellipses on both sides + clen -= 2; + rellip = 1; + } + } + } + + if (lellip) + { + for (i = 0, x -= charwidth*3; i < 3; ++i, x += charwidth) + V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + } + else + V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + + for (cend = c + clen; c < cend; ++c, x += charwidth) + { + if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c)) + { + V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 107 | V_NOSCALESTART); + V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, !cv_allcaps.value); + } + else + V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + + if (c == input_cur && con_tick >= 4) + V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + } + if (cend == input_cur && con_tick >= 4) + V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + if (rellip) + { + for (i = 0; i < 3; ++i, x += charwidth) + V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + } } // draw the last lines of console text to the top of the screen diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 8c4331aa0..71ee3f794 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -260,18 +260,6 @@ static char returnWadPath[256]; #include "../byteptr.h" #endif -// FAKE_CLIPBOARD simulates system clipboard, but is just local to our app -#ifndef FAKE_CLIPBOARD -#include "SDL_syswm.h" - -#if defined (_WIN32) && !defined (_XBOX) -#include -#endif - -// TODO: clipboard support for other OSes - -#endif - /** \brief The JoyReset function \param JoySet Joystick info to reset @@ -2659,86 +2647,30 @@ INT32 I_PutEnv(char *variable) #endif } -#ifdef FAKE_CLIPBOARD -static char __clipboard[512] = ""; -#endif - INT32 I_ClipboardCopy(const char *data, size_t size) { -#ifdef FAKE_CLIPBOARD - if (size >= 512) size = 511; - memcpy(__clipboard, data, size); - __clipboard[size] = 0; - return 0; -#else // !FAKE_CLIPBOARD + char storage[256]; + if (size > 255) + size = 255; + memcpy(storage, data, size); + storage[size] = 0; -#if defined(_WIN32) && !defined(_XBOX) - SDL_SysWMinfo syswm; - HGLOBAL *storage_ptr; - char *storage_raw; - - SDL_VERSION(&syswm.version); - - // Get window (HWND) information, use that to open the clipboard - if (!SDL_GetWindowWMInfo(window, &syswm) || !(OpenClipboard(syswm.info.win.window))) - return -1; - - // Erase clipboard contents -- if we have nothing to copy, just leave them blank - EmptyClipboard(); - if (size == 0) - goto clipboardend; - - // Allocate movable global memory to store our text. - if (!(storage_ptr = GlobalAlloc(GMEM_MOVEABLE, size+1)) - || !(storage_raw = (char *)GlobalLock(storage_ptr))) // Lock our pointer (gives us access to its data) - goto clipboardfail; - memcpy(storage_raw, data, size); - storage_raw[size] = 0; - GlobalUnlock(storage_ptr); // Unlock it before sending it off - if (!SetClipboardData(CF_TEXT, storage_ptr)) // NOTE: this removes our permissions from the pointer - goto clipboardfail; - -clipboardend: - CloseClipboard(); - return 0; //OpenClipboard(); -clipboardfail: - CloseClipboard(); // Don't leave me hanging + if (SDL_SetClipboardText(storage)) + return 0; return -1; -#else - (void)data; - (void)size; - return -1; -#endif - -#endif // FAKE_CLIPBOARD } const char *I_ClipboardPaste(void) { -#ifdef FAKE_CLIPBOARD - return (const char *)&__clipboard; -#else // !FAKE_CLIPBOARD + static char clipboard_modified[256]; + char *clipboard_contents, *i = clipboard_modified; -#if defined(_WIN32) && !defined(_XBOX) - HGLOBAL *clipboard_ptr; - const char *clipboard_raw; - static char clipboard_contents[512]; - char *i = clipboard_contents; - - if (!IsClipboardFormatAvailable(CF_TEXT)) - return NULL; // Data either unavailable, or in wrong format - OpenClipboard(NULL); // NOTE: Don't need window pointer to get, only to set - if (!(clipboard_ptr = GetClipboardData(CF_TEXT))) // Get global pointer + if (!SDL_HasClipboardText()) return NULL; - if (!(clipboard_raw = (const char *)GlobalLock(clipboard_ptr))) // Lock access -- gives us direct ptr to data - { - CloseClipboard(); // Don't leave me hanging if we fail - return NULL; - } - memcpy(clipboard_contents, clipboard_raw, 511); - GlobalUnlock(clipboard_ptr); // Unlock for other apps - CloseClipboard(); // And make sure to close the clipboard for other apps too - clipboard_contents[511] = 0; // Done after unlock to cause as little interference as possible + clipboard_contents = SDL_GetClipboardText(); + memcpy(clipboard_modified, clipboard_contents, 255); + SDL_free(clipboard_contents); + clipboard_modified[255] = 0; while (*i) { @@ -2753,13 +2685,7 @@ const char *I_ClipboardPaste(void) *i = '?'; // Nonprintable chars become question marks ++i; } - - return (const char *)&clipboard_contents; -#else - return NULL; -#endif - -#endif // FAKE_CLIPBOARD + return (const char *)&clipboard_modified; } /** \brief The isWadPathOk function diff --git a/src/v_video.c b/src/v_video.c index 43e3f0182..f6a966e67 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -774,43 +774,51 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) if (!screens[0]) return; - if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) - { // Clear the entire screen, from dest to deststop. Yes, this really works. - memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp); - return; - } - - dest = screens[0] + y*dupy*vid.width + x*dupx; - deststop = screens[0] + vid.rowbytes * vid.height; - - if (w == BASEVIDWIDTH) - w = vid.width; - else - w *= dupx; - if (h == BASEVIDHEIGHT) - h = vid.height; - else - h *= dupy; - - if (x && y && x + w < vid.width && y + h < vid.height) + if (c & V_NOSCALESTART) { - // Center it if necessary - if (vid.width != BASEVIDWIDTH * dupx) - { - // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, - // so center this imaginary screen - if (c & V_SNAPTORIGHT) - dest += (vid.width - (BASEVIDWIDTH * dupx)); - else if (!(c & V_SNAPTOLEFT)) - dest += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + dest = screens[0] + y*vid.width + x; + deststop = screens[0] + vid.rowbytes * vid.height; + } + else + { + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) + { // Clear the entire screen, from dest to deststop. Yes, this really works. + memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp); + return; } - if (vid.height != BASEVIDHEIGHT * dupy) + + dest = screens[0] + y*dupy*vid.width + x*dupx; + deststop = screens[0] + vid.rowbytes * vid.height; + + if (w == BASEVIDWIDTH) + w = vid.width; + else + w *= dupx; + if (h == BASEVIDHEIGHT) + h = vid.height; + else + h *= dupy; + + if (x && y && x + w < vid.width && y + h < vid.height) { - // same thing here - if (c & V_SNAPTOBOTTOM) - dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width; - else if (!(c & V_SNAPTOTOP)) - dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2; + // Center it if necessary + if (vid.width != BASEVIDWIDTH * dupx) + { + // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, + // so center this imaginary screen + if (c & V_SNAPTORIGHT) + dest += (vid.width - (BASEVIDWIDTH * dupx)); + else if (!(c & V_SNAPTOLEFT)) + dest += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (c & V_SNAPTOBOTTOM) + dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width; + else if (!(c & V_SNAPTOTOP)) + dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2; + } } } From 010c52aed2ad0e4ee0f38a1fcfa42b6a6bf671f0 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Thu, 3 Nov 2016 19:36:43 -0700 Subject: [PATCH 32/50] show highlight BG over ellipses if highlight extends offscreen + bug fixes --- src/console.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/console.c b/src/console.c index ea5999c0d..e06190975 100644 --- a/src/console.c +++ b/src/console.c @@ -662,7 +662,7 @@ static inline void CON_InputDelSelection(void) len = (end - start); if (end != input_len) - memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-input_cur); + memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-end); memset(&inputlines[inputline][input_len - len], 0, len); input_len -= len; @@ -720,12 +720,6 @@ boolean CON_Responder(event_t *ev) key = ev->data1; - // Always eat ctrl/shift/alt, so the menu doesn't get ideas - if (key == KEY_LSHIFT || key == KEY_RSHIFT - || key == KEY_LCTRL || key == KEY_RCTRL - || key == KEY_LALT || key == KEY_RALT) - return true; - // check for console toggle key if (ev->type != ev_console) { @@ -759,9 +753,14 @@ boolean CON_Responder(event_t *ev) consoletoggle = true; return true; } - } + // Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas + if (key == KEY_LSHIFT || key == KEY_RSHIFT + || key == KEY_LCTRL || key == KEY_RCTRL + || key == KEY_LALT || key == KEY_RALT) + return true; + // ctrl modifier -- changes behavior, adds shortcuts if (ctrldown) { @@ -1344,7 +1343,7 @@ static void CON_DrawInput(void) y = con_curlines - 12 * con_scalefactor; x = charwidth*2; - clen = con_width-12; + clen = con_width-13; if (input_len <= clen) { @@ -1387,7 +1386,10 @@ static void CON_DrawInput(void) if (lellip) { - for (i = 0, x -= charwidth*3; i < 3; ++i, x += charwidth) + x -= charwidth*3; + if (input_sel < c) + V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART); + for (i = 0; i < 3; ++i, x += charwidth) V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); } else @@ -1410,6 +1412,8 @@ static void CON_DrawInput(void) V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); if (rellip) { + if (input_sel > cend) + V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART); for (i = 0; i < 3; ++i, x += charwidth) V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); } From 55400a262d3cb0f29cdb51d1c4d2a7da93a91da8 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Fri, 4 Nov 2016 02:02:26 -0700 Subject: [PATCH 33/50] go fuck yourself stupid compiler ...your guesses should not be treated as errors. --- src/console.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/console.c b/src/console.c index e06190975..70f8ab6f8 100644 --- a/src/console.c +++ b/src/console.c @@ -621,20 +621,20 @@ void CON_Ticker(void) // Necessary due to moving cursor // -static inline void CON_InputClear(void) +static void CON_InputClear(void) { memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); input_cur = input_sel = input_len = 0; } -static inline void CON_InputSetString(const char *c) +static void CON_InputSetString(const char *c) { memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); strcpy(inputlines[inputline], c); input_cur = input_sel = input_len = strlen(c); } -static inline void CON_InputAddString(const char *c) +static void CON_InputAddString(const char *c) { size_t csize = strlen(c); if (input_len + csize > CON_MAXPROMPTCHARS-1) @@ -646,7 +646,7 @@ static inline void CON_InputAddString(const char *c) input_sel = (input_cur += csize); } -static inline void CON_InputDelSelection(void) +static void CON_InputDelSelection(void) { size_t start, end, len; if (input_cur > input_sel) @@ -669,7 +669,7 @@ static inline void CON_InputDelSelection(void) input_sel = input_cur = start; } -static inline void CON_InputAddChar(char c) +static void CON_InputAddChar(char c) { if (input_len >= CON_MAXPROMPTCHARS-1) return; @@ -680,7 +680,7 @@ static inline void CON_InputAddChar(char c) input_sel = input_cur; } -static inline void CON_InputDelChar(void) +static void CON_InputDelChar(void) { if (!input_cur) return; From 8909b7c27b16b49bba54e74f3a90ea7e3ce08205 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 5 Nov 2016 17:38:36 +0000 Subject: [PATCH 34/50] Change >= to >, I THINK having exactly 4096 vertices is safe? --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index a578e6b75..ca24b76d2 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -309,7 +309,7 @@ static md2_model_t *md2_readModel(const char *filename) model->header.numSkins = 1; #define MD2LIMITCHECK(field, max, msgname) \ - if (field >= max) \ + if (field > max) \ { \ CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \ md2_freeModel (model); \ From 2dfb841c381ded5f5da6fcdc495fce4b16ae25e0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 6 Nov 2016 17:50:04 +0000 Subject: [PATCH 35/50] Correcting slight mistake I made --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index ca24b76d2..4ec2e346a 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -791,7 +791,7 @@ void HWR_InitMD2(void) md2_models[i].grpatch = NULL; md2_models[i].skin = -1; md2_models[i].notfound = true; - md2_models[s].error = false; + md2_models[i].error = false; } // read the md2.dat file From 14cd274baa7b32f3c2075463653d9ee90ac90181 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 7 Nov 2016 20:27:12 +0000 Subject: [PATCH 36/50] Change 0xF7 to 0xFF in R_GenerateTexture --- src/r_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_data.c b/src/r_data.c index 87b6b1193..b92d88f19 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -263,7 +263,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) texturememory += blocksize; block = Z_Malloc(blocksize+1, PU_STATIC, &texturecache[texnum]); - memset(block, 0xF7, blocksize+1); // Transparency hack + memset(block, 0xFF, blocksize+1); // Transparency hack // columns lookup table colofs = (UINT32 *)(void *)block; From 080b3c1d6d36d4fa1e4ff0a6070e76738ebff2a5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 10 Nov 2016 16:05:40 +0000 Subject: [PATCH 37/50] Decouple the Sprite2 defaulting from P_SetPlayerMobjState. --- src/p_mobj.c | 424 +++++++++++++++++++++++++++------------------------ 1 file changed, 223 insertions(+), 201 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e9bcd193a..a776bc05c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -170,6 +170,223 @@ static void P_CyclePlayerMobjState(mobj_t *mobj) } } +// +// P_GetMobjSprite2 +// + +static UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2) +{ + player_t *player = mobj->player; + skin_t *skin = ((skin_t *)mobj->skin); + boolean noalt = false; + UINT8 numframes; + + while (skin && ((numframes = skin->sprites[spr2].numframes) <= 0) + && spr2 != SPR2_STND) + { + switch(spr2) + { + case SPR2_PEEL: + spr2 = SPR2_RUN; + break; + case SPR2_RUN: + spr2 = SPR2_WALK; + break; + case SPR2_DRWN: + spr2 = SPR2_DEAD; + break; + case SPR2_DASH: + spr2 = SPR2_SPIN; + break; + case SPR2_GASP: + spr2 = SPR2_SPNG; + break; + case SPR2_JUMP: + spr2 = ((player + ? player->charflags + : skin->flags) + & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_SPIN; + break; + case SPR2_SPNG: // spring + spr2 = SPR2_FALL; + break; + case SPR2_FALL: + spr2 = SPR2_WALK; + break; + case SPR2_RIDE: + spr2 = SPR2_FALL; + break; + + case SPR2_FLY: + spr2 = SPR2_SPNG; + break; + case SPR2_SWIM: + spr2 = SPR2_FLY; + break; + case SPR2_TIRE: + spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; + break; + + case SPR2_GLID: + spr2 = SPR2_FLY; + break; + case SPR2_CLMB: + spr2 = SPR2_SPIN; + break; + case SPR2_CLNG: + spr2 = SPR2_CLMB; + break; + + case SPR2_TWIN: + spr2 = SPR2_SPIN; + break; + + case SPR2_MLEE: + spr2 = SPR2_TWIN; + break; + + // Super sprites fallback to regular sprites + case SPR2_SWLK: + spr2 = SPR2_WALK; + break; + case SPR2_SRUN: + spr2 = SPR2_RUN; + break; + case SPR2_SPEE: + spr2 = SPR2_PEEL; + break; + case SPR2_SPAN: + spr2 = SPR2_PAIN; + break; + case SPR2_SSTN: + spr2 = SPR2_SPAN; + break; + case SPR2_SDTH: + spr2 = SPR2_DEAD; + break; + case SPR2_SDRN: + spr2 = SPR2_DRWN; + break; + case SPR2_SSPN: + spr2 = SPR2_SPIN; + break; + case SPR2_SGSP: + spr2 = SPR2_GASP; + break; + case SPR2_SJMP: + spr2 = ((player + ? player->charflags + : skin->flags) + & SF_NOJUMPSPIN) ? SPR2_SSPG : SPR2_SSPN; + break; + case SPR2_SSPG: + spr2 = SPR2_SPNG; + break; + case SPR2_SFAL: + spr2 = SPR2_FALL; + break; + case SPR2_SEDG: + spr2 = SPR2_EDGE; + break; + case SPR2_SRID: + spr2 = SPR2_RIDE; + break; + case SPR2_SFLT: + spr2 = SPR2_SWLK; + break; + + // NiGHTS sprites. + case SPR2_NTRN: + spr2 = SPR2_TRNS; + break; + case SPR2_NSTD: + spr2 = SPR2_SSTD; + break; + case SPR2_NFLT: + spr2 = (skin->flags & SF_SUPERANIMS) ? SPR2_SFLT : SPR2_FALL; // This is skin-exclusive so the default NiGHTS skin changing system plays nice. + break; + case SPR2_NPUL: + spr2 = SPR2_NFLT; + break; + case SPR2_NPAN: + spr2 = SPR2_NPUL; + break; + case SPR2_NATK: + spr2 = SPR2_SSPN; + break; + /*case SPR2_NGT0: + spr2 = SPR2_STND; + break;*/ + case SPR2_NGT1: + case SPR2_NGT7: + case SPR2_DRL0: + spr2 = SPR2_NGT0; + break; + case SPR2_NGT2: + case SPR2_DRL1: + spr2 = SPR2_NGT1; + break; + case SPR2_NGT3: + case SPR2_DRL2: + spr2 = SPR2_NGT2; + break; + case SPR2_NGT4: + case SPR2_DRL3: + spr2 = SPR2_NGT3; + break; + case SPR2_NGT5: + case SPR2_DRL4: + spr2 = SPR2_NGT4; + break; + case SPR2_NGT6: + case SPR2_DRL5: + spr2 = SPR2_NGT5; + break; + case SPR2_DRL6: + spr2 = SPR2_NGT6; + break; + case SPR2_NGT8: + case SPR2_DRL7: + spr2 = SPR2_NGT7; + break; + case SPR2_NGT9: + case SPR2_DRL8: + spr2 = SPR2_NGT8; + break; + case SPR2_NGTA: + case SPR2_DRL9: + spr2 = SPR2_NGT9; + break; + case SPR2_NGTB: + case SPR2_DRLA: + spr2 = SPR2_NGTA; + break; + case SPR2_NGTC: + case SPR2_DRLB: + spr2 = SPR2_NGTB; + break; + case SPR2_DRLC: + spr2 = SPR2_NGTC; + break; + + + // Sprites for non-player objects? There's nothing we can do. + case SPR2_SIGN: + case SPR2_LIFE: + noalt = true; + break; + + // Dunno? Just go to standing then. + default: + spr2 = SPR2_STND; + break; + } + if (noalt) + break; + } + return spr2; +} + // // P_SetPlayerMobjState // Returns true if the mobj is still present. @@ -402,210 +619,14 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) if (st->sprite == SPR_PLAY) { skin_t *skin = ((skin_t *)mobj->skin); - boolean noalt = false; - UINT8 spr2 = st->frame & FF_FRAMEMASK; UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; UINT8 numframes; - while (skin && ((numframes = skin->sprites[spr2].numframes) <= 0) - && spr2 != SPR2_STND) - { - switch(spr2) - { - case SPR2_PEEL: - spr2 = SPR2_RUN; - break; - case SPR2_RUN: - spr2 = SPR2_WALK; - break; - case SPR2_DRWN: - spr2 = SPR2_DEAD; - break; - case SPR2_DASH: - spr2 = SPR2_SPIN; - break; - case SPR2_GASP: - spr2 = SPR2_SPNG; - break; - case SPR2_JUMP: - spr2 = (player->charflags & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_SPIN; - break; - case SPR2_SPNG: // spring - spr2 = SPR2_FALL; - break; - case SPR2_FALL: - spr2 = SPR2_WALK; - break; - case SPR2_RIDE: - spr2 = SPR2_FALL; - break; + UINT8 spr2 = P_GetMobjSprite2(mobj, st->frame & FF_FRAMEMASK); - case SPR2_FLY: - spr2 = SPR2_SPNG; - break; - case SPR2_SWIM: - spr2 = SPR2_FLY; - break; - case SPR2_TIRE: - spr2 = (player->charability == CA_FLY) ? SPR2_FLY : SPR2_SWIM; - break; - - case SPR2_GLID: - spr2 = SPR2_FLY; - break; - case SPR2_CLMB: - spr2 = SPR2_SPIN; - break; - case SPR2_CLNG: - spr2 = SPR2_CLMB; - break; - - case SPR2_TWIN: - spr2 = SPR2_SPIN; - break; - - case SPR2_MLEE: - spr2 = SPR2_TWIN; - break; - - // Super sprites fallback to regular sprites - case SPR2_SWLK: - spr2 = SPR2_WALK; - break; - case SPR2_SRUN: - spr2 = SPR2_RUN; - break; - case SPR2_SPEE: - spr2 = SPR2_PEEL; - break; - case SPR2_SPAN: - spr2 = SPR2_PAIN; - break; - case SPR2_SSTN: - spr2 = SPR2_SPAN; - break; - case SPR2_SDTH: - spr2 = SPR2_DEAD; - break; - case SPR2_SDRN: - spr2 = SPR2_DRWN; - break; - case SPR2_SSPN: - spr2 = SPR2_SPIN; - break; - case SPR2_SGSP: - spr2 = SPR2_GASP; - break; - case SPR2_SJMP: - spr2 = (player->charflags & SF_NOJUMPSPIN) ? SPR2_SSPG : SPR2_SSPN; - break; - case SPR2_SSPG: - spr2 = SPR2_SPNG; - break; - case SPR2_SFAL: - spr2 = SPR2_FALL; - break; - case SPR2_SEDG: - spr2 = SPR2_EDGE; - break; - case SPR2_SRID: - spr2 = SPR2_RIDE; - break; - case SPR2_SFLT: - spr2 = SPR2_SWLK; - break; - - // NiGHTS sprites. - case SPR2_NTRN: - spr2 = SPR2_TRNS; - break; - case SPR2_NSTD: - spr2 = SPR2_SSTD; - break; - case SPR2_NFLT: - spr2 = (skin->flags & SF_SUPERANIMS) ? SPR2_SFLT : SPR2_FALL; // This is skin-exclusive so the default NiGHTS skin changing system plays nice. - break; - case SPR2_NPUL: - spr2 = SPR2_NFLT; - break; - case SPR2_NPAN: - spr2 = SPR2_NPUL; - break; - case SPR2_NATK: - spr2 = SPR2_SSPN; - break; - /*case SPR2_NGT0: - spr2 = SPR2_STND; - break;*/ - case SPR2_NGT1: - case SPR2_NGT7: - case SPR2_DRL0: - spr2 = SPR2_NGT0; - break; - case SPR2_NGT2: - case SPR2_DRL1: - spr2 = SPR2_NGT1; - break; - case SPR2_NGT3: - case SPR2_DRL2: - spr2 = SPR2_NGT2; - break; - case SPR2_NGT4: - case SPR2_DRL3: - spr2 = SPR2_NGT3; - break; - case SPR2_NGT5: - case SPR2_DRL4: - spr2 = SPR2_NGT4; - break; - case SPR2_NGT6: - case SPR2_DRL5: - spr2 = SPR2_NGT5; - break; - case SPR2_DRL6: - spr2 = SPR2_NGT6; - break; - case SPR2_NGT8: - case SPR2_DRL7: - spr2 = SPR2_NGT7; - break; - case SPR2_NGT9: - case SPR2_DRL8: - spr2 = SPR2_NGT8; - break; - case SPR2_NGTA: - case SPR2_DRL9: - spr2 = SPR2_NGT9; - break; - case SPR2_NGTB: - case SPR2_DRLA: - spr2 = SPR2_NGTA; - break; - case SPR2_NGTC: - case SPR2_DRLB: - spr2 = SPR2_NGTB; - break; - case SPR2_DRLC: - spr2 = SPR2_NGTC; - break; - - - // Sprites for non-player objects? There's nothing we can do. - case SPR2_SIGN: - case SPR2_LIFE: - noalt = true; - break; - - // Dunno? Just go to standing then. - default: - spr2 = SPR2_STND; - break; - } - if (noalt) - break; - } - - if (!skin) + if (skin) + numframes = skin->sprites[spr2].numframes; + else { frame = 0; numframes = 0; @@ -723,10 +744,11 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) if (st->sprite == SPR_PLAY) { skin_t *skin = ((skin_t *)mobj->skin); - UINT8 spr2 = st->frame & FF_FRAMEMASK; UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; UINT8 numframes; + UINT8 spr2 = P_GetMobjSprite2(mobj, st->frame & FF_FRAMEMASK); + if (skin) numframes = skin->sprites[spr2].numframes; else From fc64feee60a89ee24c7c06bc63f9d64b72c3cfb9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 10 Nov 2016 18:27:01 +0000 Subject: [PATCH 38/50] FF_ANIMATE now cooperates with Sprite2, and to this end a few player states which have non-varying animation speeds (some which previously had a speed of 0) now use it. --- src/info.c | 76 ++++++++++++++++++++++++++-------------------------- src/p_mobj.c | 45 ++++++++++++++++++------------- 2 files changed, 64 insertions(+), 57 deletions(-) diff --git a/src/info.c b/src/info.c index 9fb442883..8d4f1a5e2 100644 --- a/src/info.c +++ b/src/info.c @@ -479,32 +479,32 @@ state_t states[NUMSTATES] = {SPR_THOK, FF_TRANS50, 8, {NULL}, 0, 0, S_NULL}, // S_THOK // Player - {SPR_PLAY, SPR2_STND, 105, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_STND - {SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT - {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK - {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN - {SPR_PLAY, SPR2_PEEL, 2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL - {SPR_PLAY, SPR2_PAIN, 350, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_PAIN - {SPR_PLAY, SPR2_DEAD, 4, {NULL}, 0, 0, S_PLAY_DEAD}, // S_PLAY_DEAD - {SPR_PLAY, SPR2_DRWN, 4, {NULL}, 0, 0, S_PLAY_DRWN}, // S_PLAY_DRWN - {SPR_PLAY, SPR2_SPIN, 1, {NULL}, 0, 0, S_PLAY_SPIN}, // S_PLAY_SPIN - {SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH - {SPR_PLAY, SPR2_GASP, 14, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_GASP - {SPR_PLAY, SPR2_JUMP, 1, {NULL}, 0, 0, S_PLAY_JUMP}, // S_PLAY_JUMP - {SPR_PLAY, SPR2_SPNG, 2, {NULL}, 0, 0, S_PLAY_SPRING}, // S_PLAY_SPRING - {SPR_PLAY, SPR2_FALL, 2, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_FALL - {SPR_PLAY, SPR2_EDGE, 12, {NULL}, 0, 0, S_PLAY_EDGE}, // S_PLAY_EDGE - {SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE + {SPR_PLAY, SPR2_STND|FF_ANIMATE, 105, {NULL}, 0, 7, S_PLAY_WAIT}, // S_PLAY_STND + {SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT + {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK + {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN + {SPR_PLAY, SPR2_PEEL, 2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL + {SPR_PLAY, SPR2_PAIN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_FALL}, // S_PLAY_PAIN + {SPR_PLAY, SPR2_DEAD|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_DEAD}, // S_PLAY_DEAD + {SPR_PLAY, SPR2_DRWN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_DRWN}, // S_PLAY_DRWN + {SPR_PLAY, SPR2_SPIN, 1, {NULL}, 0, 0, S_PLAY_SPIN}, // S_PLAY_SPIN + {SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH + {SPR_PLAY, SPR2_GASP, 14, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_GASP + {SPR_PLAY, SPR2_JUMP, 1, {NULL}, 0, 0, S_PLAY_JUMP}, // S_PLAY_JUMP + {SPR_PLAY, SPR2_SPNG, 2, {NULL}, 0, 0, S_PLAY_SPRING}, // S_PLAY_SPRING + {SPR_PLAY, SPR2_FALL, 2, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_FALL + {SPR_PLAY, SPR2_EDGE|FF_ANIMATE, -1, {NULL}, 0, 12, S_PLAY_EDGE}, // S_PLAY_EDGE + {SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE // CA_FLY/CA_SWIM - {SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY - {SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM - {SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED + {SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY + {SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM + {SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED // CA_GLIDEANDCLIMB - {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE - {SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING - {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB + {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE + {SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING + {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB // CA_TWINSPIN {SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN @@ -514,22 +514,22 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_MLEE, 20, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_MELEE_FINISH // SF_SUPERANIMS - {SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND - {SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK - {SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN - {SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL - {SPR_PLAY, SPR2_SPAN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN - {SPR_PLAY, SPR2_SSTN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN - {SPR_PLAY, SPR2_SDTH, 4, {NULL}, 0, 0, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD - {SPR_PLAY, SPR2_SDRN, 4, {NULL}, 0, 0, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN - {SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN - {SPR_PLAY, SPR2_SGSP, 14, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_GASP - {SPR_PLAY, SPR2_SJMP, 1, {NULL}, 0, 0, S_PLAY_SUPER_JUMP}, // S_PLAY_SUPER_JUMP - {SPR_PLAY, SPR2_SSPG, 2, {NULL}, 0, 0, S_PLAY_SUPER_SPRING}, // S_PLAY_SUPER_SPRING - {SPR_PLAY, SPR2_SFAL, 2, {NULL}, 0, 0, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_FALL - {SPR_PLAY, SPR2_SEDG, 12, {NULL}, 0, 0, S_PLAY_SUPER_EDGE}, // S_PLAY_SUPER_EDGE - {SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE - {SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT + {SPR_PLAY, SPR2_SSTD|FF_ANIMATE, -1, {NULL}, 0, 7, S_NULL}, // S_PLAY_SUPER_STND + {SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK + {SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN + {SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL + {SPR_PLAY, SPR2_SPAN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN + {SPR_PLAY, SPR2_SSTN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN + {SPR_PLAY, SPR2_SDTH|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD + {SPR_PLAY, SPR2_SDRN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN + {SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN + {SPR_PLAY, SPR2_SGSP, 14, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_GASP + {SPR_PLAY, SPR2_SJMP, 1, {NULL}, 0, 0, S_PLAY_SUPER_JUMP}, // S_PLAY_SUPER_JUMP + {SPR_PLAY, SPR2_SSPG, 2, {NULL}, 0, 0, S_PLAY_SUPER_SPRING}, // S_PLAY_SUPER_SPRING + {SPR_PLAY, SPR2_SFAL, 2, {NULL}, 0, 0, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_FALL + {SPR_PLAY, SPR2_SEDG|FF_ANIMATE, -1, {NULL}, 0, 12, S_PLAY_SUPER_EDGE}, // S_PLAY_SUPER_EDGE + {SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE + {SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT // SF_SUPER {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS diff --git a/src/p_mobj.c b/src/p_mobj.c index a776bc05c..e21b93014 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -86,9 +86,14 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum) // FUNCINLINE static ATTRINLINE void P_SetupStateAnimation(mobj_t *mobj, state_t *st) { + INT32 animlength = (mobj->skin && mobj->sprite == SPR_PLAY) + ? (INT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes) - 1 + : st->var1; + if (!(st->frame & FF_ANIMATE)) return; - if (st->var1 == 0 || st->var2 == 0) + + if (animlength <= 0 || st->var2 == 0) { mobj->frame &= ~FF_ANIMATE; return; // Crash/stupidity prevention @@ -102,11 +107,11 @@ FUNCINLINE static ATTRINLINE void P_SetupStateAnimation(mobj_t *mobj, state_t *s if (!leveltime) return; mobj->anim_duration -= (leveltime + 2) % st->var2; // Duration synced to timer - mobj->frame += ((leveltime + 2) / st->var2) % (st->var1 + 1); // Frame synced to timer (duration taken into account) + mobj->frame += ((leveltime + 2) / st->var2) % (animlength + 1); // Frame synced to timer (duration taken into account) } else if (st->frame & FF_RANDOMANIM) { - mobj->frame += P_RandomKey(st->var1 + 1); // Random starting frame + mobj->frame += P_RandomKey(animlength + 1); // Random starting frame mobj->anim_duration -= P_RandomKey(st->var2); // Random duration for first frame } } @@ -119,8 +124,16 @@ FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj) // var2 determines delay between animation frames if (!(mobj->frame & FF_ANIMATE) || --mobj->anim_duration != 0) return; + mobj->anim_duration = (UINT16)mobj->state->var2; + if (mobj->sprite == SPR_PLAY) + { + if (mobj->skin && (((++mobj->frame) & FF_FRAMEMASK) >= (UINT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes))) + mobj->frame &= ~FF_FRAMEMASK; + return; + } + // compare the current sprite frame to the one we started from // if more than var1 away from it, swap back to the original // else just advance by one @@ -181,7 +194,10 @@ static UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2) boolean noalt = false; UINT8 numframes; - while (skin && ((numframes = skin->sprites[spr2].numframes) <= 0) + if (!skin) + return 0; + + while (((numframes = skin->sprites[spr2].numframes) <= 0) && spr2 != SPR2_STND) { switch(spr2) @@ -613,8 +629,6 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) } } - mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set - // Player animations if (st->sprite == SPR_PLAY) { @@ -672,9 +686,10 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) { mobj->sprite = st->sprite; mobj->frame = st->frame; - P_SetupStateAnimation(mobj, st); } + P_SetupStateAnimation(mobj, st); + // Modified handling. // Call action functions when the state is set @@ -786,9 +801,10 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) { mobj->sprite = st->sprite; mobj->frame = st->frame; - P_SetupStateAnimation(mobj, st); } + P_SetupStateAnimation(mobj, st); + // Modified handling. // Call action functions when the state is set @@ -4178,17 +4194,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) } animonly: - // cycle through states, - // calling action functions at transitions - if (mobj->tics != -1) - { - mobj->tics--; - - // you can cycle through multiple states in a tic - if (!mobj->tics) - if (!P_SetPlayerMobjState(mobj, mobj->state->nextstate)) - return; // freed itself - } + P_CyclePlayerMobjState(mobj); } static void CalculatePrecipFloor(precipmobj_t *mobj) @@ -8842,6 +8848,7 @@ void P_SpawnPlayer(INT32 playernum) // (usefulness: when body mobj is detached from player (who respawns), // the dead body mobj retains the skin through the 'spritedef' override). mobj->skin = &skins[p->skin]; + P_SetupStateAnimation(mobj, mobj->state); mobj->health = p->health; p->playerstate = PST_LIVE; From 07e5fe95467926520faa54365ae961c1e8625c93 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 10 Nov 2016 22:35:33 +0000 Subject: [PATCH 39/50] Swapped around in an attempt to streamline. --- src/p_mobj.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e21b93014..82a923279 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -127,18 +127,20 @@ FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj) mobj->anim_duration = (UINT16)mobj->state->var2; - if (mobj->sprite == SPR_PLAY) + if (mobj->sprite != SPR_PLAY) { - if (mobj->skin && (((++mobj->frame) & FF_FRAMEMASK) >= (UINT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes))) - mobj->frame &= ~FF_FRAMEMASK; + // compare the current sprite frame to the one we started from + // if more than var1 away from it, swap back to the original + // else just advance by one + if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > (UINT32)mobj->state->var1) + mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK); + return; } - // compare the current sprite frame to the one we started from - // if more than var1 away from it, swap back to the original - // else just advance by one - if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > (UINT32)mobj->state->var1) - mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK); + // sprite2 version of above + if (mobj->skin && (((++mobj->frame) & FF_FRAMEMASK) >= (UINT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes))) + mobj->frame &= ~FF_FRAMEMASK; } // From 6c1483266c05fe9fe496871ca0775dca349b37f2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 11 Nov 2016 00:15:41 +0000 Subject: [PATCH 40/50] You know, I should've converted these with the earlier commit. Silly me. --- src/info.c | 56 +++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/info.c b/src/info.c index 8d4f1a5e2..35abc4945 100644 --- a/src/info.c +++ b/src/info.c @@ -480,7 +480,7 @@ state_t states[NUMSTATES] = // Player {SPR_PLAY, SPR2_STND|FF_ANIMATE, 105, {NULL}, 0, 7, S_PLAY_WAIT}, // S_PLAY_STND - {SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT + {SPR_PLAY, SPR2_WAIT|FF_ANIMATE, -1, {NULL}, 0, 16, S_PLAY_WAIT}, // S_PLAY_WAIT {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN {SPR_PLAY, SPR2_PEEL, 2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL @@ -489,7 +489,7 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_DRWN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_DRWN}, // S_PLAY_DRWN {SPR_PLAY, SPR2_SPIN, 1, {NULL}, 0, 0, S_PLAY_SPIN}, // S_PLAY_SPIN {SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH - {SPR_PLAY, SPR2_GASP, 14, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_GASP + {SPR_PLAY, SPR2_GASP|FF_ANIMATE, 14, {NULL}, 0, 4, S_PLAY_WALK}, // S_PLAY_GASP {SPR_PLAY, SPR2_JUMP, 1, {NULL}, 0, 0, S_PLAY_JUMP}, // S_PLAY_JUMP {SPR_PLAY, SPR2_SPNG, 2, {NULL}, 0, 0, S_PLAY_SPRING}, // S_PLAY_SPRING {SPR_PLAY, SPR2_FALL, 2, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_FALL @@ -503,7 +503,7 @@ state_t states[NUMSTATES] = // CA_GLIDEANDCLIMB {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE - {SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING + {SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_CLING}, // S_PLAY_CLING {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB // CA_TWINSPIN @@ -514,33 +514,33 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_MLEE, 20, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_MELEE_FINISH // SF_SUPERANIMS - {SPR_PLAY, SPR2_SSTD|FF_ANIMATE, -1, {NULL}, 0, 7, S_NULL}, // S_PLAY_SUPER_STND - {SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK - {SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN - {SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL - {SPR_PLAY, SPR2_SPAN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN - {SPR_PLAY, SPR2_SSTN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN - {SPR_PLAY, SPR2_SDTH|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD - {SPR_PLAY, SPR2_SDRN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN - {SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN - {SPR_PLAY, SPR2_SGSP, 14, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_GASP - {SPR_PLAY, SPR2_SJMP, 1, {NULL}, 0, 0, S_PLAY_SUPER_JUMP}, // S_PLAY_SUPER_JUMP - {SPR_PLAY, SPR2_SSPG, 2, {NULL}, 0, 0, S_PLAY_SUPER_SPRING}, // S_PLAY_SUPER_SPRING - {SPR_PLAY, SPR2_SFAL, 2, {NULL}, 0, 0, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_FALL - {SPR_PLAY, SPR2_SEDG|FF_ANIMATE, -1, {NULL}, 0, 12, S_PLAY_SUPER_EDGE}, // S_PLAY_SUPER_EDGE - {SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE - {SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT + {SPR_PLAY, SPR2_SSTD|FF_ANIMATE, -1, {NULL}, 0, 7, S_NULL}, // S_PLAY_SUPER_STND + {SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK + {SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN + {SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL + {SPR_PLAY, SPR2_SPAN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN + {SPR_PLAY, SPR2_SSTN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN + {SPR_PLAY, SPR2_SDTH|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD + {SPR_PLAY, SPR2_SDRN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN + {SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN + {SPR_PLAY, SPR2_SGSP|FF_ANIMATE, 14, {NULL}, 0, 4, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_GASP + {SPR_PLAY, SPR2_SJMP, 1, {NULL}, 0, 0, S_PLAY_SUPER_JUMP}, // S_PLAY_SUPER_JUMP + {SPR_PLAY, SPR2_SSPG, 2, {NULL}, 0, 0, S_PLAY_SUPER_SPRING}, // S_PLAY_SUPER_SPRING + {SPR_PLAY, SPR2_SFAL, 2, {NULL}, 0, 0, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_FALL + {SPR_PLAY, SPR2_SEDG|FF_ANIMATE, -1, {NULL}, 0, 12, S_PLAY_SUPER_EDGE}, // S_PLAY_SUPER_EDGE + {SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE + {SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT // SF_SUPER - {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS - {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2 - {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3 - {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4 - {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5 - {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6 - {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7 - {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8 - {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9 + {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS + {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9 {SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY From d8096d237a59bfd3e8ff66b3a3945e9f9cf34e11 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 11 Nov 2016 00:30:49 +0000 Subject: [PATCH 41/50] Nullification of a lot of irrelevant nextstates for infinite length states. It makes sense. --- src/info.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/info.c b/src/info.c index 35abc4945..b58d09d06 100644 --- a/src/info.c +++ b/src/info.c @@ -480,20 +480,20 @@ state_t states[NUMSTATES] = // Player {SPR_PLAY, SPR2_STND|FF_ANIMATE, 105, {NULL}, 0, 7, S_PLAY_WAIT}, // S_PLAY_STND - {SPR_PLAY, SPR2_WAIT|FF_ANIMATE, -1, {NULL}, 0, 16, S_PLAY_WAIT}, // S_PLAY_WAIT + {SPR_PLAY, SPR2_WAIT|FF_ANIMATE, -1, {NULL}, 0, 16, S_NULL}, // S_PLAY_WAIT {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN {SPR_PLAY, SPR2_PEEL, 2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL {SPR_PLAY, SPR2_PAIN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_FALL}, // S_PLAY_PAIN - {SPR_PLAY, SPR2_DEAD|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_DEAD}, // S_PLAY_DEAD - {SPR_PLAY, SPR2_DRWN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_DRWN}, // S_PLAY_DRWN + {SPR_PLAY, SPR2_DEAD|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_DEAD + {SPR_PLAY, SPR2_DRWN|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_DRWN {SPR_PLAY, SPR2_SPIN, 1, {NULL}, 0, 0, S_PLAY_SPIN}, // S_PLAY_SPIN {SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH {SPR_PLAY, SPR2_GASP|FF_ANIMATE, 14, {NULL}, 0, 4, S_PLAY_WALK}, // S_PLAY_GASP {SPR_PLAY, SPR2_JUMP, 1, {NULL}, 0, 0, S_PLAY_JUMP}, // S_PLAY_JUMP {SPR_PLAY, SPR2_SPNG, 2, {NULL}, 0, 0, S_PLAY_SPRING}, // S_PLAY_SPRING {SPR_PLAY, SPR2_FALL, 2, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_FALL - {SPR_PLAY, SPR2_EDGE|FF_ANIMATE, -1, {NULL}, 0, 12, S_PLAY_EDGE}, // S_PLAY_EDGE + {SPR_PLAY, SPR2_EDGE|FF_ANIMATE, -1, {NULL}, 0, 12, S_NULL}, // S_PLAY_EDGE {SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE // CA_FLY/CA_SWIM @@ -503,7 +503,7 @@ state_t states[NUMSTATES] = // CA_GLIDEANDCLIMB {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE - {SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_CLING}, // S_PLAY_CLING + {SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_CLING {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB // CA_TWINSPIN @@ -514,20 +514,20 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_MLEE, 20, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_MELEE_FINISH // SF_SUPERANIMS - {SPR_PLAY, SPR2_SSTD|FF_ANIMATE, -1, {NULL}, 0, 7, S_NULL}, // S_PLAY_SUPER_STND + {SPR_PLAY, SPR2_SSTD|FF_ANIMATE, -1, {NULL}, 0, 7, S_NULL}, // S_PLAY_SUPER_STND {SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK {SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN {SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL - {SPR_PLAY, SPR2_SPAN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN - {SPR_PLAY, SPR2_SSTN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN - {SPR_PLAY, SPR2_SDTH|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD - {SPR_PLAY, SPR2_SDRN|FF_ANIMATE, -1, {NULL}, 0, 4, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN + {SPR_PLAY, SPR2_SPAN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_PAIN + {SPR_PLAY, SPR2_SSTN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_STUN + {SPR_PLAY, SPR2_SDTH|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_SUPER_DEAD + {SPR_PLAY, SPR2_SDRN|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_SUPER_DRWN {SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN {SPR_PLAY, SPR2_SGSP|FF_ANIMATE, 14, {NULL}, 0, 4, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_GASP {SPR_PLAY, SPR2_SJMP, 1, {NULL}, 0, 0, S_PLAY_SUPER_JUMP}, // S_PLAY_SUPER_JUMP {SPR_PLAY, SPR2_SSPG, 2, {NULL}, 0, 0, S_PLAY_SUPER_SPRING}, // S_PLAY_SUPER_SPRING {SPR_PLAY, SPR2_SFAL, 2, {NULL}, 0, 0, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_FALL - {SPR_PLAY, SPR2_SEDG|FF_ANIMATE, -1, {NULL}, 0, 12, S_PLAY_SUPER_EDGE}, // S_PLAY_SUPER_EDGE + {SPR_PLAY, SPR2_SEDG|FF_ANIMATE, -1, {NULL}, 0, 12, S_NULL}, // S_PLAY_SUPER_EDGE {SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE {SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT From c545194bef51cc75cc8954ded5e14e1874b84a9f Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Thu, 10 Nov 2016 16:53:27 -0800 Subject: [PATCH 42/50] update colors to new palette --- src/console.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/console.c b/src/console.c index de8b43d92..3702dd560 100644 --- a/src/console.c +++ b/src/console.c @@ -135,7 +135,8 @@ static consvar_t cons_backpic = {"con_backpic", "translucent", CV_SAVE, backpic_ static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Gray"}, {2, "Brown"}, {3, "Red"}, {4, "Orange"}, {5, "Yellow"}, - {6, "Green"}, {7, "Blue"}, {8, "Cyan"}, + {6, "Green"}, {7, "Blue"}, {8, "Purple"}, + {9, "Magenta"}, {10, "Aqua"}, {0, NULL}}; consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL}; @@ -241,23 +242,26 @@ UINT8 *consolebgmap = NULL; void CON_SetupBackColormap(void) { UINT16 i, palsum; - UINT8 j, palindex; + UINT8 j, palindex, shift; UINT8 *pal = W_CacheLumpName(GetPalette(), PU_CACHE); if (!consolebgmap) consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + shift = 6; // 12 colors -- shift of 7 means 6 colors switch (cons_backcolor.value) { case 0: palindex = 15; break; // White case 1: palindex = 31; break; // Gray - case 2: palindex = 63; break; // Brown - case 3: palindex = 143; break; // Red - case 4: palindex = 95; break; // Orange - case 5: palindex = 111; break; // Yellow - case 6: palindex = 175; break; // Green - case 7: palindex = 239; break; // Blue - case 8: palindex = 219; break; // Cyan + case 2: palindex = 239; break; // Brown + case 3: palindex = 47; break; // Red + case 4: palindex = 63; break; // Orange + case 5: palindex = 79; shift = 7; break; // Yellow + case 6: palindex = 111; break; // Green + case 7: palindex = 159; break; // Blue + case 8: palindex = 199; shift = 7; break; // Purple + case 9: palindex = 187; break; // Magenta + case 10: palindex = 139; break; // Aqua // Default green default: palindex = 175; break; } @@ -265,7 +269,7 @@ void CON_SetupBackColormap(void) // setup background colormap for (i = 0, j = 0; i < 768; i += 3, j++) { - palsum = (pal[i] + pal[i+1] + pal[i+2]) >> 6; + palsum = (pal[i] + pal[i+1] + pal[i+2]) >> shift; consolebgmap[j] = (UINT8)(palindex - palsum); } } @@ -1388,7 +1392,7 @@ static void CON_DrawInput(void) { x -= charwidth*3; if (input_sel < c) - V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART); + V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART); for (i = 0; i < 3; ++i, x += charwidth) V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); } @@ -1399,7 +1403,7 @@ static void CON_DrawInput(void) { if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c)) { - V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 107 | V_NOSCALESTART); + V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 77 | V_NOSCALESTART); V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, !cv_allcaps.value); } else @@ -1413,7 +1417,7 @@ static void CON_DrawInput(void) if (rellip) { if (input_sel > cend) - V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART); + V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART); for (i = 0; i < 3; ++i, x += charwidth) V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); } From 9aa41582c335ac7937c94d0577fbe970c79ebb75 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 11 Nov 2016 21:37:28 +0000 Subject: [PATCH 43/50] Lua support for sprite2. --- src/lua_mobjlib.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 6bb1388fc..58c1b14f2 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -34,6 +34,7 @@ enum mobj_e { mobj_angle, mobj_sprite, mobj_frame, + mobj_sprite2, mobj_anim_duration, mobj_touching_sectorlist, mobj_subsector, @@ -93,6 +94,7 @@ static const char *const mobj_opt[] = { "angle", "sprite", "frame", + "sprite2", "anim_duration", "touching_sectorlist", "subsector", @@ -189,6 +191,9 @@ static int mobj_get(lua_State *L) case mobj_frame: lua_pushinteger(L, mo->frame); break; + case mobj_sprite2: + lua_pushinteger(L, mo->sprite2); + break; case mobj_anim_duration: lua_pushinteger(L, mo->anim_duration); break; @@ -411,6 +416,9 @@ static int mobj_set(lua_State *L) case mobj_frame: mo->frame = (UINT32)luaL_checkinteger(L, 3); break; + case mobj_sprite2: + mo->sprite2 = (UINT8)luaL_checkinteger(L, 3); + break; case mobj_anim_duration: mo->anim_duration = (UINT16)luaL_checkinteger(L, 3); break; From 20677c7a660d1a7dd53ac0b17e9e99ae79ab16ed Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 11 Nov 2016 23:23:41 +0000 Subject: [PATCH 44/50] * Introducing new Lua-exclusive function, P_IsValidSprite2(mo, spr2). Basically just a wrapper for (((skin_t *)mobj->skin)->sprites[spr2].numframes > 0), useful for creating custom sprite2 defaulting functions since hooking into P_GetMobjSprite2 wouldn't be worth it. * All Lua-originated sprite2 settings are now forced through P_GetMobjSprite2. Makes sense because of SPR2_JUMP, which none of the main characters have sprites for yet all use. * Cleaned up P_GetMobjSprite2 to not set irrelevant, otherwise-unused variable. --- src/lua_baselib.c | 14 ++++++++++++++ src/lua_mobjlib.c | 2 +- src/p_local.h | 1 + src/p_mobj.c | 5 ++--- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index bbcec06d3..e6ab7a7e1 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -309,6 +309,19 @@ static int lib_pRemoveMobj(lua_State *L) return 0; } +// P_IsValidSprite2 technically doesn't exist, and probably never should... but too much would need to be exposed to allow this to be checked by other methods. + +static int lib_pIsValidSprite2(lua_State *L) +{ + mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + UINT8 spr2 = (UINT8)luaL_checkinteger(L, 2); + //HUDSAFE + if (!mobj) + return LUA_ErrInvalid(L, "mobj_t"); + lua_pushboolean(L, (mobj->skin && (((skin_t *)mobj->skin)->sprites[spr2].numframes > 0))); + return 1; +} + static int lib_pSpawnMissile(lua_State *L) { mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -2005,6 +2018,7 @@ static luaL_Reg lib[] = { // don't add P_SetMobjState or P_SetPlayerMobjState, use "mobj.state = S_NEWSTATE" instead. {"P_SpawnMobj",lib_pSpawnMobj}, {"P_RemoveMobj",lib_pRemoveMobj}, + {"P_IsValidSprite2", lib_pIsValidSprite2}, {"P_SpawnMissile",lib_pSpawnMissile}, {"P_SpawnXYZMissile",lib_pSpawnXYZMissile}, {"P_SpawnPointMissile",lib_pSpawnPointMissile}, diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 58c1b14f2..9ebc38a61 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -417,7 +417,7 @@ static int mobj_set(lua_State *L) mo->frame = (UINT32)luaL_checkinteger(L, 3); break; case mobj_sprite2: - mo->sprite2 = (UINT8)luaL_checkinteger(L, 3); + mo->sprite2 = P_GetMobjSprite2(mo, (UINT8)luaL_checkinteger(L, 3)); break; case mobj_anim_duration: mo->anim_duration = (UINT16)luaL_checkinteger(L, 3); diff --git a/src/p_local.h b/src/p_local.h index de717801e..ee1aacb4f 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -211,6 +211,7 @@ void P_PrecipitationEffects(void); void P_RemoveMobj(mobj_t *th); boolean P_MobjWasRemoved(mobj_t *th); void P_RemoveSavegameMobj(mobj_t *th); +UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2); boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state); void P_RunShields(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index 82a923279..669f8cd1f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -189,17 +189,16 @@ static void P_CyclePlayerMobjState(mobj_t *mobj) // P_GetMobjSprite2 // -static UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2) +UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2) { player_t *player = mobj->player; skin_t *skin = ((skin_t *)mobj->skin); boolean noalt = false; - UINT8 numframes; if (!skin) return 0; - while (((numframes = skin->sprites[spr2].numframes) <= 0) + while ((skin->sprites[spr2].numframes <= 0) && spr2 != SPR2_STND) { switch(spr2) From 11a391dbb564b2240fe650d6597301deebab2577 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 12 Nov 2016 15:06:49 +0000 Subject: [PATCH 45/50] Making FF_SPR2ENDSTATE consistent between P_SetMobjState and P_SetPlayerMobjState. --- src/p_mobj.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 669f8cd1f..ff805f4db 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -664,7 +664,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) { if (st->frame & FF_SPR2ENDSTATE) // no frame advancement { - if (st->var1 == S_NULL) + if (st->var1 == mobj->state-states) frame--; else { @@ -788,8 +788,17 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) if (frame >= numframes) { - if (st->frame & FF_SPR2ENDSTATE) - return P_SetPlayerMobjState(mobj, st->var1); // Differs from P_SetPlayerMobjState - allows object to be removed via S_NULL + if (st->frame & FF_SPR2ENDSTATE) // no frame advancement + { + if (st->var1 == mobj->state-states) + frame--; + else + { + if (mobj->frame & FF_FRAMEMASK) + mobj->frame--; + return P_SetMobjState(mobj, st->var1); + } + } else frame = 0; } From 63622cb2ddaf2a6bb19fc1fe2837c68bd6a47aaa Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Sun, 13 Nov 2016 13:55:32 -0800 Subject: [PATCH 46/50] Update new music cues to use correct names --- src/p_inter.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 26db656ad..6ad04f477 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -253,12 +253,8 @@ void P_DoMatchSuper(player_t *player) { S_StopMusic(); if (mariomode) - { - S_ChangeMusicInternal("minvnc", false); G_GhostAddColor(GHC_INVINCIBLE); - } - else - S_ChangeMusicInternal("invinc", false); + S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false); } // Also steal 50 points from every enemy, sealing your victory. @@ -278,12 +274,8 @@ void P_DoMatchSuper(player_t *player) { S_StopMusic(); if (mariomode) - { - S_ChangeMusicInternal("minvnc", false); G_GhostAddColor(GHC_INVINCIBLE); - } - else - S_ChangeMusicInternal("invinc", false); + S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false); } } } From c4996aad7eb14dad5a75d4807ac64e4671369066 Mon Sep 17 00:00:00 2001 From: Inuyasha Date: Sun, 13 Nov 2016 14:29:19 -0800 Subject: [PATCH 47/50] So how long have these been pulling the wrong sprites? --- src/st_stuff.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 05355cc1d..9a7f64986 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -288,15 +288,15 @@ 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("WHTVB0", PU_HUDGFX); - forceshield = W_CachePatchName("BLTVB0", PU_HUDGFX); - ringshield = W_CachePatchName("YLTVB0", PU_HUDGFX); - watershield = W_CachePatchName("ELTVB0", PU_HUDGFX); - bombshield = W_CachePatchName("BKTVB0", PU_HUDGFX); - pityshield = W_CachePatchName("GRTVB0", PU_HUDGFX); - invincibility = W_CachePatchName("PINVB0", PU_HUDGFX); - sneakers = W_CachePatchName("SHTVB0", PU_HUDGFX); - gravboots = W_CachePatchName("GBTVB0", 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); + invincibility = W_CachePatchName("TVIVC0", PU_HUDGFX); + sneakers = W_CachePatchName("TVSSC0", PU_HUDGFX); + gravboots = W_CachePatchName("TVGVC0", PU_HUDGFX); tagico = W_CachePatchName("TAGICO", PU_HUDGFX); rflagico = W_CachePatchName("RFLAGICO", PU_HUDGFX); From 7746553273a7be1229af4ee8ed571fb89aba2c5a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 13 Nov 2016 22:33:10 +0000 Subject: [PATCH 48/50] * Fixed A_1upThinker having a standing sprite for a single frame on spawn. * Removed the noalt stuff because it's not actually helpful. Everything's gotta come back to something at some point or there'll be errors. --- src/p_enemy.c | 1 + src/p_mobj.c | 10 ---------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index f21841d13..f2f92bf53 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2553,6 +2553,7 @@ void A_1upThinker(mobj_t *actor) { P_SetTarget(&actor->tracer, P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY)); P_SetTarget(&actor->tracer->target, actor); + actor->tracer->skin = &skins[players[closestplayer].skin]; // required here to prevent spr2 default showing stand for a single frame P_SetMobjState(actor->tracer, actor->info->seestate); // The overlay is going to be one tic early turning off and on diff --git a/src/p_mobj.c b/src/p_mobj.c index ff805f4db..3a6eda088 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -193,7 +193,6 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2) { player_t *player = mobj->player; skin_t *skin = ((skin_t *)mobj->skin); - boolean noalt = false; if (!skin) return 0; @@ -386,20 +385,11 @@ UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2) spr2 = SPR2_NGTC; break; - - // Sprites for non-player objects? There's nothing we can do. - case SPR2_SIGN: - case SPR2_LIFE: - noalt = true; - break; - // Dunno? Just go to standing then. default: spr2 = SPR2_STND; break; } - if (noalt) - break; } return spr2; } From 0726dbe0185e573335c7d4f280361093165021b7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 15 Nov 2016 20:33:07 +0000 Subject: [PATCH 49/50] Started work on making HWR_DrawFill support V_NOSCALESTART properly ...so far I've got the console text select highlight in the right place outside of 320x200 (and 320x200 is still fine), but for whatever reason it's too large in width and height Oh well, we're part of the way there, anyway --- src/hardware/hw_draw.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 60183b58e..c2d8dfdb9 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -656,6 +656,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) { FOutVector v[4]; FSurfaceInfo Surf; + float sdupx, sdupy, pdupx, pdupy; if (w < 0 || h < 0) return; // consistency w/ software @@ -664,10 +665,18 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) // | /| // |/ | // 0--1 - v[0].x = v[3].x = (x - 160.0f)/160.0f; - v[2].x = v[1].x = ((x+w) - 160.0f)/160.0f; - v[0].y = v[1].y = -(y - 100.0f)/100.0f; - v[2].y = v[3].y = -((y+h) - 100.0f)/100.0f; + sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; + sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; + pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; + pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; + + if (color & V_NOSCALESTART) + sdupx = sdupy = 2.0f; + + v[0].x = v[3].x = (x*sdupx)/vid.width - 1; + v[2].x = v[1].x = (x*sdupx + w*pdupx)/vid.width - 1; + v[0].y = v[1].y = 1-(y*sdupy)/vid.height; + v[2].y = v[3].y = 1-(y*sdupy + h*pdupy)/vid.height; //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 42f985cda537d769bbee6331aa2879daa3095e02 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 16 Nov 2016 12:10:56 +0000 Subject: [PATCH 50/50] Remove pdupx/y and just use sdupx/y for everything, thanks Inuyasha --- src/hardware/hw_draw.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index c2d8dfdb9..f23753ee5 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -656,7 +656,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) { FOutVector v[4]; FSurfaceInfo Surf; - float sdupx, sdupy, pdupx, pdupy; + float sdupx, sdupy; if (w < 0 || h < 0) return; // consistency w/ software @@ -667,16 +667,14 @@ 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; - pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; - pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; if (color & V_NOSCALESTART) sdupx = sdupy = 2.0f; v[0].x = v[3].x = (x*sdupx)/vid.width - 1; - v[2].x = v[1].x = (x*sdupx + w*pdupx)/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*pdupy)/vid.height; + v[2].y = v[3].y = 1-(y*sdupy + h*sdupy)/vid.height; //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; //;