Merge branch SRB2:next into mobj-alpha

This commit is contained in:
MIDIMan 2024-03-06 02:26:50 +00:00
commit 29378e7f94
43 changed files with 1228 additions and 1055 deletions

View file

@ -47,8 +47,6 @@
# HAVE_MINIUPNPC=1 - Enable automated port forwarding. # HAVE_MINIUPNPC=1 - Enable automated port forwarding.
# Already enabled by default for 32-bit # Already enabled by default for 32-bit
# Windows. # Windows.
# NOPNG=1 - Disable PNG graphics support. (TODO: double
# check netplay compatible.)
# NOCURL=1 - Disable libcurl--HTTP capability. # NOCURL=1 - Disable libcurl--HTTP capability.
# NOGME=1 - Disable game music emu, retro VGM support. # NOGME=1 - Disable game music emu, retro VGM support.
# NOOPENMPT=1 - Disable module (tracker) music support. # NOOPENMPT=1 - Disable module (tracker) music support.
@ -69,8 +67,6 @@
# NOEXECINFO=1 - Disable stack trace dump support # NOEXECINFO=1 - Disable stack trace dump support
# DEBUGMODE=1 - Enable various debugging capabilities. # DEBUGMODE=1 - Enable various debugging capabilities.
# Also disables optimizations. # Also disables optimizations.
# NOZLIB=1 - Disable some compression capability. Implies
# NOPNG=1.
# #
# Development flags: # Development flags:
# #

View file

@ -22,8 +22,6 @@ ifndef NOMD5
sources+=md5.c sources+=md5.c
endif endif
ifndef NOZLIB
ifndef NOPNG
ifdef PNG_PKGCONFIG ifdef PNG_PKGCONFIG
$(eval $(call Use_pkg_config,PNG_PKGCONFIG)) $(eval $(call Use_pkg_config,PNG_PKGCONFIG))
else else
@ -36,8 +34,6 @@ opts+=-D_LARGEFILE64_SOURCE
endif endif
opts+=-DHAVE_PNG opts+=-DHAVE_PNG
sources+=apng.c sources+=apng.c
endif
endif
ifndef NOCURL ifndef NOCURL
CURLCONFIG?=curl-config CURLCONFIG?=curl-config

View file

@ -589,8 +589,9 @@ void B_RespawnBot(INT32 playernum)
} }
else else
P_SetMobjState(tails, S_PLAY_FALL); P_SetMobjState(tails, S_PLAY_FALL);
P_SetScale(tails, sonic->scale); P_SetScale(tails, sonic->scale, false);
tails->destscale = sonic->destscale; tails->destscale = sonic->destscale;
tails->old_scale = sonic->old_scale;
} }
void B_HandleFlightIndicator(player_t *player) void B_HandleFlightIndicator(player_t *player)

View file

@ -861,12 +861,6 @@ static void CON_InputDelSelection(void)
Lock_state(); Lock_state();
if (!input_cur)
{
Unlock_state();
return;
}
if (input_cur > input_sel) if (input_cur > input_sel)
{ {
start = input_sel; start = input_sel;

View file

@ -476,6 +476,18 @@ static void D_Display(void)
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap))) if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap)))
{ {
// draw the view directly // draw the view directly
if (cv_debug)
{
r_renderwalls = cv_renderwalls.value;
r_renderfloors = cv_renderfloors.value;
r_renderthings = cv_renderthings.value;
}
else
{
r_renderwalls = true;
r_renderfloors = true;
r_renderthings = true;
}
if (!automapactive && !dedicated && cv_renderview.value) if (!automapactive && !dedicated && cv_renderview.value)
{ {

View file

@ -11,6 +11,7 @@
/// \brief Lua SOC library /// \brief Lua SOC library
#include "deh_lua.h" #include "deh_lua.h"
#include "g_input.h"
// freeslot takes a name (string only!) // freeslot takes a name (string only!)
// and allocates it to the appropriate free slot. // and allocates it to the appropriate free slot.
@ -596,12 +597,20 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
return luaL_error(L, "translation '%s' could not be found.\n", word); return luaL_error(L, "translation '%s' could not be found.\n", word);
} }
// TODO: 2.3: Delete this alias // TODO: 2.3: Delete these aliases
if (fastcmp(word, "BT_USE")) else if (fastcmp(word, "BT_USE"))
{ {
CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN); CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN);
return 1; return 1;
} }
else if (fastcmp(word, "GC_WEPSLOT8") || fastcmp(word, "GC_WEPSLOT9") || fastcmp(word, "GC_WEPSLOT10"))
{
// Using GC_WEPSLOT7 isn't accurate, but ensures that "if x >= GC_WEPSLOT1 and x <= GC_WEPSLOT10" keeps the intended effect
CacheAndPushConstant(L, word, (lua_Integer)GC_WEPSLOT7);
if (!mathlib)
LUA_Deprecated(L, "GC_WEPSLOT8\"-\"GC_WEPSLOT10", "GC_WEPSLOT1\"-\"GC_WEPSLOT7");
return 1;
}
for (i = 0; INT_CONST[i].n; i++) for (i = 0; INT_CONST[i].n; i++)
if (fastcmp(word,INT_CONST[i].n)) { if (fastcmp(word,INT_CONST[i].n)) {

View file

@ -5738,6 +5738,7 @@ struct int_const_s const INT_CONST[] = {
{"JA_DIGITAL",JA_DIGITAL}, {"JA_DIGITAL",JA_DIGITAL},
{"JA_JUMP",JA_JUMP}, {"JA_JUMP",JA_JUMP},
{"JA_SPIN",JA_SPIN}, {"JA_SPIN",JA_SPIN},
{"JA_SHIELD",JA_SHIELD},
{"JA_FIRE",JA_FIRE}, {"JA_FIRE",JA_FIRE},
{"JA_FIRENORMAL",JA_FIRENORMAL}, {"JA_FIRENORMAL",JA_FIRENORMAL},
{"JOYAXISRANGE",JOYAXISRANGE}, {"JOYAXISRANGE",JOYAXISRANGE},

View file

@ -82,6 +82,7 @@
#include "version.h" #include "version.h"
#include "doomtype.h" #include "doomtype.h"
#include <assert.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -648,6 +649,7 @@ UINT32 quickncasehash (const char *p, size_t n)
#else #else
#define I_Assert(e) ((void)0) #define I_Assert(e) ((void)0)
#endif #endif
#define I_StaticAssert(e) static_assert(e, "Static assertion failed: " #e)
// The character that separates pathnames. Forward slash on // The character that separates pathnames. Forward slash on
// most systems, but reverse solidus (\) on Windows. // most systems, but reverse solidus (\) on Windows.

View file

@ -98,7 +98,7 @@ demoghost *ghosts = NULL;
// DEMO RECORDING // DEMO RECORDING
// //
#define DEMOVERSION 0x0011 #define DEMOVERSION 0x0012
#define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F"
#define DF_GHOST 0x01 // This demo contains ghost data too! #define DF_GHOST 0x01 // This demo contains ghost data too!
@ -183,7 +183,11 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
if (ziptic & ZT_ANGLE) if (ziptic & ZT_ANGLE)
oldcmd.angleturn = READINT16(demo_p); oldcmd.angleturn = READINT16(demo_p);
if (ziptic & ZT_BUTTONS) if (ziptic & ZT_BUTTONS)
{
oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT)); oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT));
if (demoversion < 0x0012 && oldcmd.buttons & BT_SPIN)
oldcmd.buttons |= BT_SHIELD; // Copy BT_SPIN to BT_SHIELD for pre-Shield-button demos
}
if (ziptic & ZT_AIMING) if (ziptic & ZT_AIMING)
oldcmd.aiming = READINT16(demo_p); oldcmd.aiming = READINT16(demo_p);
if (ziptic & ZT_LATENCY) if (ziptic & ZT_LATENCY)
@ -771,7 +775,7 @@ void G_GhostTicker(void)
{ {
g->mo->destscale = READFIXED(g->p); g->mo->destscale = READFIXED(g->p);
if (g->mo->destscale != g->mo->scale) if (g->mo->destscale != g->mo->scale)
P_SetScale(g->mo, g->mo->destscale); P_SetScale(g->mo, g->mo->destscale, false);
} }
if (xziptic & EZT_THOKMASK) if (xziptic & EZT_THOKMASK)
{ // Let's only spawn ONE of these per frame, thanks. { // Let's only spawn ONE of these per frame, thanks.
@ -810,7 +814,7 @@ void G_GhostTicker(void)
mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT; mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
mobj->color = g->mo->color; mobj->color = g->mo->color;
mobj->skin = g->mo->skin; mobj->skin = g->mo->skin;
P_SetScale(mobj, (mobj->destscale = g->mo->scale)); P_SetScale(mobj, g->mo->scale, true);
if (type == MT_THOK) // spintrail-specific modification for MT_THOK if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{ {
@ -926,7 +930,7 @@ void G_GhostTicker(void)
else else
follow->destscale = g->mo->destscale; follow->destscale = g->mo->destscale;
if (follow->destscale != follow->scale) if (follow->destscale != follow->scale)
P_SetScale(follow, follow->destscale); P_SetScale(follow, follow->destscale, false);
P_UnsetThingPosition(follow); P_UnsetThingPosition(follow);
temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
@ -1079,7 +1083,7 @@ void G_ReadMetalTic(mobj_t *metal)
{ {
metal->destscale = READFIXED(metal_p); metal->destscale = READFIXED(metal_p);
if (metal->destscale != metal->scale) if (metal->destscale != metal->scale)
P_SetScale(metal, metal->destscale); P_SetScale(metal, metal->destscale, false);
} }
if (xziptic & EZT_THOKMASK) if (xziptic & EZT_THOKMASK)
{ // Let's only spawn ONE of these per frame, thanks. { // Let's only spawn ONE of these per frame, thanks.
@ -1117,7 +1121,7 @@ void G_ReadMetalTic(mobj_t *metal)
mobj->angle = metal->angle; mobj->angle = metal->angle;
mobj->color = metal->color; mobj->color = metal->color;
mobj->skin = metal->skin; mobj->skin = metal->skin;
P_SetScale(mobj, (mobj->destscale = metal->scale)); P_SetScale(mobj, metal->scale, true);
if (type == MT_THOK) // spintrail-specific modification for MT_THOK if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{ {
@ -1184,7 +1188,7 @@ void G_ReadMetalTic(mobj_t *metal)
else else
follow->destscale = metal->destscale; follow->destscale = metal->destscale;
if (follow->destscale != follow->scale) if (follow->destscale != follow->scale)
P_SetScale(follow, follow->destscale); P_SetScale(follow, follow->destscale, false);
P_UnsetThingPosition(follow); P_UnsetThingPosition(follow);
temp = (metalversion < 0x000e) ? READINT16(metal_p)<<8 : READFIXED(metal_p); temp = (metalversion < 0x000e) ? READINT16(metal_p)<<8 : READFIXED(metal_p);

View file

@ -403,27 +403,29 @@ consvar_t cv_cam_lockonboss[2] = {
CVAR_INIT ("cam2_lockaimassist", "Full", CV_SAVE|CV_ALLOWLUA, lockedassist_cons_t, NULL), CVAR_INIT ("cam2_lockaimassist", "Full", CV_SAVE|CV_ALLOWLUA, lockedassist_cons_t, NULL),
}; };
consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_shieldaxis = CVAR_INIT ("joyaxis_shield", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_digitaldeadzone = CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
consvar_t cv_digitaldeadzone = CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
consvar_t cv_moveaxis2 = CVAR_INIT ("joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_moveaxis2 = CVAR_INIT ("joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_sideaxis2 = CVAR_INIT ("joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_sideaxis2 = CVAR_INIT ("joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_shieldaxis2 = CVAR_INIT ("joyaxis2_shield", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
player_t *seenplayer; // player we're aiming at right now player_t *seenplayer; // player we're aiming at right now
@ -894,6 +896,9 @@ INT32 JoyAxis(joyaxis_e axissel)
case JA_SPIN: case JA_SPIN:
axisval = cv_spinaxis.value; axisval = cv_spinaxis.value;
break; break;
case JA_SHIELD:
axisval = cv_shieldaxis.value;
break;
case JA_FIRE: case JA_FIRE:
axisval = cv_fireaxis.value; axisval = cv_fireaxis.value;
break; break;
@ -967,6 +972,9 @@ INT32 Joy2Axis(joyaxis_e axissel)
case JA_SPIN: case JA_SPIN:
axisval = cv_spinaxis2.value; axisval = cv_spinaxis2.value;
break; break;
case JA_SHIELD:
axisval = cv_shieldaxis2.value;
break;
case JA_FIRE: case JA_FIRE:
axisval = cv_fireaxis2.value; axisval = cv_fireaxis2.value;
break; break;
@ -1334,8 +1342,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
if (PLAYERINPUTDOWN(ssplayer, GC_WEAPONPREV)) if (PLAYERINPUTDOWN(ssplayer, GC_WEAPONPREV))
cmd->buttons |= BT_WEAPONPREV; // Previous Weapon cmd->buttons |= BT_WEAPONPREV; // Previous Weapon
#if NUM_WEAPONS > 10 #if NUM_WEAPONS > 7
"Add extra inputs to g_input.h/gamecontrols_e" "Add extra inputs to g_input.h/gamecontrols_e, and fix conflicts in d_ticcmd.h/ticcmd_t/buttons"
#endif #endif
//use the three avaliable bits to determine the weapon. //use the three avaliable bits to determine the weapon.
cmd->buttons &= ~BT_WEAPONMASK; cmd->buttons &= ~BT_WEAPONMASK;
@ -1361,7 +1369,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
cmd->buttons |= BT_TOSSFLAG; cmd->buttons |= BT_TOSSFLAG;
// Shield button // Shield button
if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD)) axis = PlayerJoyAxis(ssplayer, JA_SHIELD);
if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD) || (usejoystick && axis > 0))
cmd->buttons |= BT_SHIELD; cmd->buttons |= BT_SHIELD;
// Lua scriptable buttons // Lua scriptable buttons

View file

@ -71,8 +71,8 @@ typedef enum {
#define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0)) #define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0))
extern consvar_t cv_autobrake, cv_autobrake2; extern consvar_t cv_autobrake, cv_autobrake2;
extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone; extern consvar_t cv_sideaxis, cv_turnaxis, cv_moveaxis, cv_lookaxis, cv_jumpaxis, cv_spinaxis, cv_shieldaxis, cv_fireaxis, cv_firenaxis, cv_deadzone, cv_digitaldeadzone;
extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_shieldaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2;
extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest;
// hi here's some new controls // hi here's some new controls
@ -100,6 +100,7 @@ typedef enum
JA_JUMP = JA_DIGITAL, JA_JUMP = JA_DIGITAL,
JA_SPIN, JA_SPIN,
JA_SHIELD,
JA_FIRE, JA_FIRE,
JA_FIRENORMAL, JA_FIRENORMAL,
} joyaxis_e; } joyaxis_e;

View file

@ -743,34 +743,34 @@ void G_DefineDefaultControls(void)
// Gamepad controls -- same for both schemes // Gamepad controls -- same for both schemes
gamecontroldefault[i][GC_JUMP ][1] = KEY_JOY1+0; // A gamecontroldefault[i][GC_JUMP ][1] = KEY_JOY1+0; // A
gamecontroldefault[i][GC_SPIN ][1] = KEY_JOY1+2; // X gamecontroldefault[i][GC_SPIN ][1] = KEY_JOY1+2; // X
gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+1; // B gamecontroldefault[i][GC_SHIELD ][1] = KEY_JOY1+1; // B
gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+3; // Y gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+3; // Y
gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+4; // LB
gamecontroldefault[i][GC_SHIELD ][1] = KEY_JOY1+4; // LB
gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB
gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick
gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_JOY1+9; // Right Stick
gamecontroldefault[i][GC_SCORES ][1] = KEY_JOY1+6; // Back gamecontroldefault[i][GC_SCORES ][1] = KEY_JOY1+6; // Back
gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start
gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_HAT1+0; // D-Pad Up
gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+1; // D-Pad Down
gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left
gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right
gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_JOY1+9; // Right Stick
gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+0; // D-Pad Up
gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_HAT1+1; // D-Pad Down
// Second player controls only have joypad defaults // Second player controls only have joypad defaults
gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A
gamecontrolbisdefault[i][GC_SPIN ][1] = KEY_2JOY1+2; // X gamecontrolbisdefault[i][GC_SPIN ][1] = KEY_2JOY1+2; // X
gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+1; // B gamecontrolbisdefault[i][GC_SHIELD ][1] = KEY_2JOY1+1; // B
gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+3; // Y gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+3; // Y
gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+4; // LB
gamecontrolbisdefault[i][GC_SHIELD ][1] = KEY_2JOY1+4; // LB
gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB
gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick
gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2JOY1+9; // Right Stick
//gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2JOY1+6; // Back //gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2JOY1+6; // Back
//gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start //gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start
gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2HAT1+0; // D-Pad Up
gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+1; // D-Pad Down
gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left
gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right
gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2JOY1+9; // Right Stick
gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+0; // D-Pad Up
gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2HAT1+1; // D-Pad Down
} }
} }
@ -1001,7 +1001,6 @@ static void setcontrol(INT32 (*gc)[2])
// TODO: 2.3: Delete the "use" alias // TODO: 2.3: Delete the "use" alias
namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin"; namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin";
for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]); for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]);
numctrl++) numctrl++)

View file

@ -98,13 +98,11 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
if (position + count >= pblockheight) if (position + count >= pblockheight)
count = pblockheight - position; count = pblockheight - position;
dest = block + (position*blockmodulo); for (dest = block + (position*blockmodulo); count > 0; count--, dest += blockmodulo, yfrac += yfracstep)
while (count > 0)
{ {
count--;
texel = source[yfrac>>FRACBITS]; texel = source[yfrac>>FRACBITS];
alpha = 0xFF; alpha = 0xFF;
// Make pixel transparent if chroma keyed // Make pixel transparent if chroma keyed
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00; alpha = 0x00;
@ -115,11 +113,20 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
switch (bpp) switch (bpp)
{ {
case 2: case 2:
{
texelu16 = *((UINT16*)dest);
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha); {
if (originPatch->style == AST_TRANSLUCENT && originPatch->alpha < ASTTextureBlendingThreshold[0])
continue;
if (!(texelu16 & 0xFF00) && originPatch->alpha <= ASTTextureBlendingThreshold[1])
continue;
texel = ASTBlendPaletteIndexes(texelu16 & 0xFF, texel, originPatch->style, originPatch->alpha);
}
texelu16 = (UINT16)((alpha<<8) | texel); texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16)); memcpy(dest, &texelu16, sizeof(UINT16));
break; break;
}
case 3: case 3:
colortemp = palette[texel]; colortemp = palette[texel];
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
@ -149,9 +156,6 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
*dest = texel; *dest = texel;
break; break;
} }
dest += blockmodulo;
yfrac += yfracstep;
} }
} }
} }
@ -202,13 +206,11 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
if (position + count >= pblockheight) if (position + count >= pblockheight)
count = pblockheight - position; count = pblockheight - position;
dest = block + (position*blockmodulo); for (dest = block + (position*blockmodulo); count > 0; count--, dest += blockmodulo, yfrac -= yfracstep)
while (count > 0)
{ {
count--;
texel = source[yfrac>>FRACBITS]; texel = source[yfrac>>FRACBITS];
alpha = 0xFF; alpha = 0xFF;
// Make pixel transparent if chroma keyed // Make pixel transparent if chroma keyed
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00; alpha = 0x00;
@ -219,8 +221,15 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
switch (bpp) switch (bpp)
{ {
case 2: case 2:
texelu16 = *((UINT16*)dest);
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha); {
if (originPatch->style == AST_TRANSLUCENT && originPatch->alpha < ASTTextureBlendingThreshold[0])
continue;
if (!(texelu16 & 0xFF00) && originPatch->alpha <= ASTTextureBlendingThreshold[1])
continue;
texel = ASTBlendPaletteIndexes(texelu16 & 0xFF, texel, originPatch->style, originPatch->alpha);
}
texelu16 = (UINT16)((alpha<<8) | texel); texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16)); memcpy(dest, &texelu16, sizeof(UINT16));
break; break;
@ -253,9 +262,6 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
*dest = texel; *dest = texel;
break; break;
} }
dest += blockmodulo;
yfrac -= yfracstep;
} }
} }
} }
@ -433,7 +439,7 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
// Create a composite texture from patches, adapt the texture size to a power of 2 // Create a composite texture from patches, adapt the texture size to a power of 2
// height and width for the hardware texture cache. // height and width for the hardware texture cache.
// //
static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t *mipmap)
{ {
UINT8 *block; UINT8 *block;
texture_t *texture; texture_t *texture;
@ -441,57 +447,19 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
INT32 blockwidth, blockheight, blocksize; INT32 blockwidth, blockheight, blocksize;
INT32 i; INT32 i;
boolean skyspecial = false; //poor hack for Legacy large skies..
RGBA_t *palette;
palette = HWR_GetTexturePalette();
texture = textures[texnum]; texture = textures[texnum];
// hack the Legacy skies.. mipmap->flags = TF_WRAPXY;
if (texture->name[0] == 'S' && mipmap->width = (UINT16)texture->width;
texture->name[1] == 'K' && mipmap->height = (UINT16)texture->height;
texture->name[2] == 'Y' && mipmap->format = textureformat;
(texture->name[4] == 0 ||
texture->name[5] == 0)
)
{
skyspecial = true;
grtex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky
}
else
grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY;
grtex->mipmap.width = (UINT16)texture->width;
grtex->mipmap.height = (UINT16)texture->height;
if (skyspecial)
grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ...
else
grtex->mipmap.format = textureformat;
blockwidth = texture->width; blockwidth = texture->width;
blockheight = texture->height; blockheight = texture->height;
blocksize = (blockwidth * blockheight); blocksize = (blockwidth * blockheight);
block = MakeBlock(&grtex->mipmap); block = MakeBlock(&grtex->mipmap);
if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading)
{
INT32 j;
RGBA_t col;
col = palette[HWR_PATCHES_CHROMAKEY_COLORINDEX];
for (j = 0; j < blockheight; j++)
{
for (i = 0; i < blockwidth; i++)
{
block[4*(j*blockwidth+i)+0] = col.s.red;
block[4*(j*blockwidth+i)+1] = col.s.green;
block[4*(j*blockwidth+i)+2] = col.s.blue;
block[4*(j*blockwidth+i)+3] = 0xff;
}
}
}
// Composite the columns together. // Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{ {
@ -526,13 +494,13 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
Patch_Free(realpatch); Patch_Free(realpatch);
} }
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
if (format2bpp(grtex->mipmap.format)==4) if (format2bpp(mipmap->format)==4)
{ {
for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp
{ {
if (block[i] == 0) if (block[i] == 0)
{ {
grtex->mipmap.flags |= TF_TRANSPARENT; mipmap->flags |= TF_TRANSPARENT;
break; break;
} }
} }
@ -661,8 +629,6 @@ void HWR_FreeTextureColormaps(patch_t *patch)
Z_Free(next->data); Z_Free(next->data);
if (next->colormap) if (next->colormap)
Z_Free(next->colormap); Z_Free(next->colormap);
next->data = NULL;
next->colormap = NULL;
HWD.pfnDeleteTexture(next); HWD.pfnDeleteTexture(next);
// Free the old colormap mipmap from memory. // Free the old colormap mipmap from memory.
@ -714,12 +680,25 @@ void HWR_InitMapTextures(void)
gl_maptexturesloaded = false; gl_maptexturesloaded = false;
} }
static void DeleteTextureMipmap(GLMipmap_t *grMipmap)
{
HWD.pfnDeleteTexture(grMipmap);
// Chroma-keyed textures do not own their texture data, so do not free it
if (!(grMipmap->flags & TF_CHROMAKEYED))
Z_Free(grMipmap->data);
}
static void FreeMapTexture(GLMapTexture_t *tex) static void FreeMapTexture(GLMapTexture_t *tex)
{ {
HWD.pfnDeleteTexture(&tex->mipmap); if (tex->mipmap.nextcolormap)
if (tex->mipmap.data) {
Z_Free(tex->mipmap.data); DeleteTextureMipmap(tex->mipmap.nextcolormap);
tex->mipmap.data = NULL; free(tex->mipmap.nextcolormap);
tex->mipmap.nextcolormap = NULL;
}
DeleteTextureMipmap(&tex->mipmap);
} }
void HWR_FreeMapTextures(void) void HWR_FreeMapTextures(void)
@ -762,41 +741,47 @@ void HWR_LoadMapTextures(size_t pnumtextures)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Make sure texture is downloaded and set it as the source // Make sure texture is downloaded and set it as the source
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
GLMapTexture_t *HWR_GetTexture(INT32 tex) static void GetMapTexture(INT32 tex, GLMapTexture_t *grtex, GLMipmap_t *mipmap)
{ {
GLMapTexture_t *grtex;
#ifdef PARANOIA
if ((unsigned)tex >= gl_numtextures)
I_Error("HWR_GetTexture: tex >= numtextures\n");
#endif
// Every texture in memory, stored in the
// hardware renderer's bit depth format. Wow!
grtex = &gl_textures[tex];
// Generate texture if missing from the cache // Generate texture if missing from the cache
if (!grtex->mipmap.data && !grtex->mipmap.downloaded) if (!mipmap->data && !mipmap->downloaded)
HWR_GenerateTexture(tex, grtex); HWR_GenerateTexture(tex, grtex, mipmap);
// If hardware does not have the texture, then call pfnSetTexture to upload it // If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grtex->mipmap.downloaded) if (!mipmap->downloaded)
HWD.pfnSetTexture(&grtex->mipmap); HWD.pfnSetTexture(mipmap);
HWR_SetCurrentTexture(&grtex->mipmap); HWR_SetCurrentTexture(mipmap);
// The system-memory data can be purged now. // The system-memory data can be purged now.
Z_ChangeTag(grtex->mipmap.data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(mipmap->data, PU_HWRCACHE_UNLOCKED);
}
GLMapTexture_t *HWR_GetTexture(INT32 tex)
{
if (tex < 0 || tex >= (signed)gl_numtextures)
{
#ifdef PARANOIA
I_Error("HWR_GetTexture: Invalid texture ID %d", tex);
#else
tex = 0;
#endif
}
GLMapTexture_t *grtex = &gl_textures[tex];
GetMapTexture(tex, grtex, &grtex->mipmap);
return grtex; return grtex;
} }
static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) static void HWR_CacheRawFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
{ {
size_t size = W_LumpLength(flatlumpnum); size_t size = W_LumpLength(flatlumpnum);
UINT16 pflatsize = R_GetFlatSize(size); UINT16 pflatsize = R_GetFlatSize(size);
// setup the texture info // setup the texture info
grMipmap->format = GL_TEXFMT_P_8; grMipmap->format = GL_TEXFMT_P_8;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; grMipmap->flags = TF_WRAPXY;
grMipmap->width = pflatsize; grMipmap->width = pflatsize;
grMipmap->height = pflatsize; grMipmap->height = pflatsize;
@ -817,7 +802,7 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum)
patch = HWR_GetCachedGLPatch(flatlumpnum); patch = HWR_GetCachedGLPatch(flatlumpnum);
grmip = ((GLPatch_t *)Patch_AllocateHardwarePatch(patch))->mipmap; grmip = ((GLPatch_t *)Patch_AllocateHardwarePatch(patch))->mipmap;
if (!grmip->downloaded && !grmip->data) if (!grmip->downloaded && !grmip->data)
HWR_CacheFlat(grmip, flatlumpnum); HWR_CacheRawFlat(grmip, flatlumpnum);
// If hardware does not have the texture, then call pfnSetTexture to upload it // If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grmip->downloaded) if (!grmip->downloaded)
@ -828,7 +813,16 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum)
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
} }
void HWR_GetLevelFlat(levelflat_t *levelflat) static void MakeLevelFlatMipmap(GLMipmap_t *grMipmap, INT32 texturenum, UINT16 flags)
{
grMipmap->format = GL_TEXFMT_P_8;
grMipmap->flags = flags;
grMipmap->width = (UINT16)textures[texturenum]->width;
grMipmap->height = (UINT16)textures[texturenum]->height;
}
void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed)
{ {
if (levelflat->type == LEVELFLAT_NONE || levelflat->texture_id < 0) if (levelflat->type == LEVELFLAT_NONE || levelflat->texture_id < 0)
{ {
@ -839,24 +833,50 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
INT32 texturenum = texturetranslation[levelflat->texture_id]; INT32 texturenum = texturetranslation[levelflat->texture_id];
GLMapTexture_t *grtex = &gl_flats[texturenum]; GLMapTexture_t *grtex = &gl_flats[texturenum];
GLMipmap_t *grMipmap = &grtex->mipmap; GLMipmap_t *grMipmap = &grtex->mipmap;
GLMipmap_t *originalMipmap = grMipmap;
if (!grMipmap->data && !grMipmap->downloaded) if (!originalMipmap->downloaded)
MakeLevelFlatMipmap(originalMipmap, texturenum, TF_WRAPXY);
if (!originalMipmap->data)
{ {
grMipmap->format = GL_TEXFMT_P_8; size_t size = originalMipmap->width * originalMipmap->height;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; memcpy(Z_Malloc(size, PU_HWRCACHE, &originalMipmap->data), R_GetFlatForTexture(texturenum), size);
}
grMipmap->width = (UINT16)textures[texturenum]->width; // If chroma-keyed, create or use a different mipmap for the variant
grMipmap->height = (UINT16)textures[texturenum]->height; if (chromakeyed)
{
if (!originalMipmap->data)
{
HWR_SetCurrentTexture(NULL);
return;
}
size_t size = grMipmap->width * grMipmap->height; // Allocate it if it wasn't already
memcpy(Z_Malloc(size, PU_HWRCACHE, &grMipmap->data), R_GetFlatForTexture(texturenum), size); if (!originalMipmap->nextcolormap)
{
GLMipmap_t *newMipmap = calloc(1, sizeof (*grMipmap));
if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetLevelFlat");
MakeLevelFlatMipmap(newMipmap, texturenum, TF_WRAPXY | TF_CHROMAKEYED);
originalMipmap->nextcolormap = newMipmap;
}
// Upload and bind the variant texture instead of the original one
grMipmap = originalMipmap->nextcolormap;
// Use the original texture's pixel data
// It can just be a pointer to it, since the r_opengl backend deals with the pixels
// that are supposed to be transparent.
grMipmap->data = originalMipmap->data;
} }
if (!grMipmap->downloaded) if (!grMipmap->downloaded)
HWD.pfnSetTexture(&grtex->mipmap); HWD.pfnSetTexture(grMipmap);
HWR_SetCurrentTexture(grMipmap);
HWR_SetCurrentTexture(&grtex->mipmap);
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
} }

View file

@ -246,7 +246,7 @@ enum ETextureFlags
TF_WRAPX = 0x00000001, // wrap around X TF_WRAPX = 0x00000001, // wrap around X
TF_WRAPY = 0x00000002, // wrap around Y TF_WRAPY = 0x00000002, // wrap around Y
TF_WRAPXY = TF_WRAPY|TF_WRAPX, // very common so use alias is more easy TF_WRAPXY = TF_WRAPY|TF_WRAPX, // very common so use alias is more easy
TF_CHROMAKEYED = 0x00000010, TF_CHROMAKEYED = 0x00000010, // Used only for flats with pixels that have palette index 255
TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0 TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0
}; };

View file

@ -121,7 +121,7 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum); void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
GLMapTexture_t *HWR_GetTexture(INT32 tex); GLMapTexture_t *HWR_GetTexture(INT32 tex);
void HWR_GetLevelFlat(levelflat_t *levelflat); void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed);
void HWR_GetRawFlat(lumpnum_t flatlumpnum); void HWR_GetRawFlat(lumpnum_t flatlumpnum);
void HWR_FreeTexture(patch_t *patch); void HWR_FreeTexture(patch_t *patch);

View file

@ -59,7 +59,7 @@ static void HWR_ProjectSprite(mobj_t *thing);
static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
static void HWR_ProjectBoundingBox(mobj_t *thing); static void HWR_ProjectBoundingBox(mobj_t *thing);
void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, boolean chromakeyed, extracolormap_t *planecolormap);
void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
@ -339,6 +339,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
static FOutVector *planeVerts = NULL; static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0; static UINT16 numAllocedPlaneVerts = 0;
if (!r_renderfloors)
return;
// no convex poly were generated for this subsector // no convex poly were generated for this subsector
if (!xsub->planepoly) if (!xsub->planepoly)
return; return;
@ -483,9 +486,6 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
PolyFlags |= PF_ColorMapped; PolyFlags |= PF_ColorMapped;
} }
if (!cv_renderfloors.value)
return;
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false); HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false);
if (subsector) if (subsector)
@ -668,7 +668,7 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL
{ {
INT32 shader = SHADER_NONE; INT32 shader = SHADER_NONE;
if (!cv_renderwalls.value) if (!r_renderwalls)
return; return;
HWR_Lighting(pSurf, lightlevel, wallcolormap); HWR_Lighting(pSurf, lightlevel, wallcolormap);
@ -709,7 +709,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y); FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y);
extracolormap_t *colormap = NULL; extracolormap_t *colormap = NULL;
if (!cv_renderwalls.value) if (!r_renderwalls)
return; return;
realtop = top = wallVerts[3].y; realtop = top = wallVerts[3].y;
@ -914,6 +914,191 @@ static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
return true; return true;
} }
static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliphigh, fixed_t worldtop, fixed_t worldbottom, fixed_t worldhigh, fixed_t worldlow, fixed_t worldtopslope, fixed_t worldbottomslope, fixed_t worldhighslope, fixed_t worldlowslope, UINT32 lightnum, FOutVector *inWallVerts)
{
FOutVector wallVerts[4];
FSurfaceInfo Surf;
Surf.PolyColor.s.alpha = 255;
// Determine if it's visible
if (!HWR_BlendMidtextureSurface(&Surf))
return;
fixed_t texheight = FixedDiv(textureheight[gl_midtexture], abs(gl_sidedef->scaley_mid));
INT32 repeats;
if (gl_sidedef->repeatcnt)
repeats = 1 + gl_sidedef->repeatcnt;
else if (gl_linedef->flags & ML_WRAPMIDTEX)
{
fixed_t high, low;
if (gl_frontsector->ceilingheight > gl_backsector->ceilingheight)
high = gl_backsector->ceilingheight;
else
high = gl_frontsector->ceilingheight;
if (gl_frontsector->floorheight > gl_backsector->floorheight)
low = gl_frontsector->floorheight;
else
low = gl_backsector->floorheight;
repeats = (high - low) / texheight;
if ((high - low) % texheight)
repeats++; // tile an extra time to fill the gap -- Monster Iestyn
}
else
repeats = 1;
GLMapTexture_t *grTex = HWR_GetTexture(gl_midtexture);
float xscale = FixedToFloat(gl_sidedef->scalex_mid);
float yscale = FixedToFloat(gl_sidedef->scaley_mid);
// SoM: a little note: popentop and popenbottom
// record the limits the texture can be displayed in.
// polytop and polybottom, are the ideal (i.e. unclipped)
// heights of the polygon, and h & l, are the final (clipped)
// poly coords.
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope;
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
// you must use the linedef's backsector to be correct
// From CB
if (gl_curline->polyseg)
{
// Change this when polyobjects support slopes
popentop = popentopslope = gl_curline->backsector->ceilingheight;
popenbottom = popenbottomslope = gl_curline->backsector->floorheight;
}
else
{
popentop = min(worldtop, worldhigh);
popenbottom = max(worldbottom, worldlow);
popentopslope = min(worldtopslope, worldhighslope);
popenbottomslope = max(worldbottomslope, worldlowslope);
}
// Find the wall's coordinates
fixed_t midtexheight = texheight * repeats;
fixed_t rowoffset = FixedDiv(gl_sidedef->rowoffset + gl_sidedef->offsety_mid, abs(gl_sidedef->scaley_mid));
// Texture is not skewed
if (gl_linedef->flags & ML_NOSKEW)
{
// Peg it to the floor
if (gl_linedef->flags & ML_MIDPEG)
{
polybottom = max(gl_frontsector->floorheight, gl_backsector->floorheight) + rowoffset;
polytop = polybottom + midtexheight;
}
// Peg it to the ceiling
else
{
polytop = min(gl_frontsector->ceilingheight, gl_backsector->ceilingheight) + rowoffset;
polybottom = polytop - midtexheight;
}
// The right side's coordinates are the the same as the left side
polytopslope = polytop;
polybottomslope = polybottom;
}
// Skew the texture, but peg it to the floor
else if (gl_linedef->flags & ML_MIDPEG)
{
polybottom = popenbottom + rowoffset;
polytop = polybottom + midtexheight;
polybottomslope = popenbottomslope + rowoffset;
polytopslope = polybottomslope + midtexheight;
}
// Skew it according to the ceiling's slope
else
{
polytop = popentop + rowoffset;
polybottom = polytop - midtexheight;
polytopslope = popentopslope + rowoffset;
polybottomslope = polytopslope - midtexheight;
}
// The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector
if (gl_curline->polyseg)
{
lowcut = polybottom;
highcut = polytop;
lowcutslope = polybottomslope;
highcutslope = polytopslope;
}
else
{
lowcut = popenbottom;
highcut = popentop;
lowcutslope = popenbottomslope;
highcutslope = popentopslope;
}
fixed_t h = min(highcut, polytop);
fixed_t l = max(polybottom, lowcut);
fixed_t hS = min(highcutslope, polytopslope);
fixed_t lS = max(polybottomslope, lowcutslope);
// PEGGING
fixed_t texturevpeg, texturevpegslope;
if (gl_linedef->flags & ML_MIDPEG)
{
texturevpeg = midtexheight - h + polybottom;
texturevpegslope = midtexheight - hS + polybottomslope;
}
else
{
texturevpeg = polytop - h;
texturevpegslope = polytopslope - hS;
}
memcpy(wallVerts, inWallVerts, sizeof(wallVerts));
// Left side
wallVerts[3].t = texturevpeg * yscale * grTex->scaleY;
wallVerts[0].t = (h - l + texturevpeg) * yscale * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX;
// Right side
wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY;
wallVerts[1].t = (hS - lS + texturevpegslope) * yscale * grTex->scaleY;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX;
// set top/bottom coords
// Take the texture peg into account, rather than changing the offsets past
// where the polygon might not be.
wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[0].y = FIXED_TO_FLOAT(l);
wallVerts[2].y = FIXED_TO_FLOAT(hS);
wallVerts[1].y = FIXED_TO_FLOAT(lS);
// TODO: Actually use the surface's flags so that I don't have to do this
FUINT blendmode = Surf.PolyFlags;
// Render midtextures on two-sided lines with a z-buffer offset.
// This will cause the midtexture appear on top, if a FOF overlaps with it.
blendmode |= PF_Decal;
extracolormap_t *colormap = gl_frontsector->extra_colormap;
if (gl_frontsector->numlights)
{
if (!(blendmode & PF_Masked))
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_TRANSLUCENT, NULL, blendmode);
else
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, blendmode);
}
else if (!(blendmode & PF_Masked))
HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
}
// Sort of like GLWall::Process in GZDoom // Sort of like GLWall::Process in GZDoom
static void HWR_ProcessSeg(void) static void HWR_ProcessSeg(void)
{ {
@ -979,9 +1164,8 @@ static void HWR_ProcessSeg(void)
wallVerts[2].z = wallVerts[1].z = ve.y; wallVerts[2].z = wallVerts[1].z = ve.y;
// x offset the texture // x offset the texture
fixed_t texturehpeg = gl_sidedef->textureoffset + gl_curline->offset; float cliplow = (float)gl_curline->offset;
float cliplow = (float)texturehpeg; float cliphigh = cliplow + (gl_curline->flength * FRACUNIT);
float cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT));
FUINT lightnum = gl_frontsector->lightlevel; FUINT lightnum = gl_frontsector->lightlevel;
extracolormap_t *colormap = gl_frontsector->extra_colormap; extracolormap_t *colormap = gl_frontsector->extra_colormap;
@ -997,6 +1181,7 @@ static void HWR_ProcessSeg(void)
if (gl_backsector) if (gl_backsector)
{ {
INT32 gl_toptexture = 0, gl_bottomtexture = 0; INT32 gl_toptexture = 0, gl_bottomtexture = 0;
fixed_t texturevpeg; fixed_t texturevpeg;
SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight) SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight)
@ -1026,30 +1211,46 @@ static void HWR_ProcessSeg(void)
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture) if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture)
{ {
grTex = HWR_GetTexture(gl_toptexture); grTex = HWR_GetTexture(gl_toptexture);
xscale = FixedToFloat(gl_sidedef->scalex_top); xscale = FixedToFloat(abs(gl_sidedef->scalex_top));
yscale = FixedToFloat(gl_sidedef->scaley_top); yscale = FixedToFloat(abs(gl_sidedef->scaley_top));
fixed_t texheight = FixedDiv(textureheight[gl_toptexture], gl_sidedef->scaley_top); fixed_t offsetx_top = gl_sidedef->textureoffset + gl_sidedef->offsetx_top;
float left = cliplow * xscale;
float right = cliphigh * xscale;
if (gl_sidedef->scalex_top < 0)
{
left = -left;
right = -right;
offsetx_top = -offsetx_top;
}
fixed_t texheight = textureheight[gl_toptexture];
fixed_t texheightscaled = FixedDiv(texheight, abs(gl_sidedef->scaley_top));
// PEGGING // PEGGING
// FIXME: This is probably not correct?
if (gl_linedef->flags & ML_DONTPEGTOP) if (gl_linedef->flags & ML_DONTPEGTOP)
texturevpeg = 0; texturevpeg = 0;
else if (gl_linedef->flags & ML_SKEWTD) else if (gl_linedef->flags & ML_SKEWTD)
texturevpeg = worldhigh + texheight - worldtop; texturevpeg = worldhigh + texheight - worldtop;
else else
texturevpeg = gl_backsector->ceilingheight + texheight - gl_frontsector->ceilingheight; texturevpeg = gl_backsector->ceilingheight + texheightscaled - gl_frontsector->ceilingheight;
texturevpeg *= yscale; texturevpeg *= yscale;
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top; if (gl_sidedef->scaley_top < 0)
texturevpeg -= gl_sidedef->rowoffset + gl_sidedef->offsety_top;
else
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top;
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
texturevpeg %= texheight; texturevpeg %= texheightscaled;
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * yscale) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * yscale) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_top) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = (left + offsetx_top) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_top) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = (right + offsetx_top) * grTex->scaleX;
// Adjust t value for sloped walls // Adjust t value for sloped walls
if (!(gl_linedef->flags & ML_SKEWTD)) if (!(gl_linedef->flags & ML_SKEWTD))
@ -1074,6 +1275,14 @@ static void HWR_ProcessSeg(void)
wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * yscale * grTex->scaleY; wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * yscale * grTex->scaleY;
} }
if (gl_sidedef->scaley_top < 0)
{
wallVerts[0].t = -wallVerts[0].t;
wallVerts[1].t = -wallVerts[1].t;
wallVerts[2].t = -wallVerts[2].t;
wallVerts[3].t = -wallVerts[3].t;
}
// set top/bottom coords // set top/bottom coords
wallVerts[3].y = FIXED_TO_FLOAT(worldtop); wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
wallVerts[0].y = FIXED_TO_FLOAT(worldhigh); wallVerts[0].y = FIXED_TO_FLOAT(worldhigh);
@ -1092,8 +1301,19 @@ static void HWR_ProcessSeg(void)
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture) if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture)
{ {
grTex = HWR_GetTexture(gl_bottomtexture); grTex = HWR_GetTexture(gl_bottomtexture);
xscale = FixedToFloat(gl_sidedef->scalex_bottom); xscale = FixedToFloat(abs(gl_sidedef->scalex_bottom));
yscale = FixedToFloat(gl_sidedef->scaley_bottom); yscale = FixedToFloat(abs(gl_sidedef->scaley_bottom));
fixed_t offsetx_bottom = gl_sidedef->textureoffset + gl_sidedef->offsetx_bottom;
float left = cliplow * xscale;
float right = cliphigh * xscale;
if (gl_sidedef->scalex_bottom < 0)
{
left = -left;
right = -right;
offsetx_bottom = -offsetx_bottom;
}
// PEGGING // PEGGING
if (!(gl_linedef->flags & ML_DONTPEGBOTTOM)) if (!(gl_linedef->flags & ML_DONTPEGBOTTOM))
@ -1105,15 +1325,18 @@ static void HWR_ProcessSeg(void)
texturevpeg *= yscale; texturevpeg *= yscale;
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bottom; if (gl_sidedef->scaley_bottom < 0)
texturevpeg -= gl_sidedef->rowoffset + gl_sidedef->offsety_bottom;
else
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bottom;
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], gl_sidedef->scaley_bottom); texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], abs(gl_sidedef->scaley_bottom));
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_backsector->floorheight - gl_frontsector->floorheight) * yscale) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_backsector->floorheight - gl_frontsector->floorheight) * yscale) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_bottom) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = (left + offsetx_bottom) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_bottom) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = (right + offsetx_bottom) * grTex->scaleX;
// Adjust t value for sloped walls // Adjust t value for sloped walls
if (!(gl_linedef->flags & ML_SKEWTD)) if (!(gl_linedef->flags & ML_SKEWTD))
@ -1137,6 +1360,14 @@ static void HWR_ProcessSeg(void)
wallVerts[1].t = (texturevpeg + (worldlowslope - worldbottomslope) * yscale) * grTex->scaleY; wallVerts[1].t = (texturevpeg + (worldlowslope - worldbottomslope) * yscale) * grTex->scaleY;
} }
if (gl_sidedef->scaley_bottom < 0)
{
wallVerts[0].t = -wallVerts[0].t;
wallVerts[1].t = -wallVerts[1].t;
wallVerts[2].t = -wallVerts[2].t;
wallVerts[3].t = -wallVerts[3].t;
}
// set top/bottom coords // set top/bottom coords
wallVerts[3].y = FIXED_TO_FLOAT(worldlow); wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
wallVerts[0].y = FIXED_TO_FLOAT(worldbottom); wallVerts[0].y = FIXED_TO_FLOAT(worldbottom);
@ -1151,196 +1382,14 @@ static void HWR_ProcessSeg(void)
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
} }
// Render midtexture if there's one. Determine if it's visible first, though // Render midtexture if there's one
if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf)) if (gl_midtexture)
{ HWR_RenderMidtexture(gl_midtexture, cliplow, cliphigh, worldtop, worldbottom, worldhigh, worldlow, worldtopslope, worldbottomslope, worldhighslope, worldlowslope, lightnum, wallVerts);
sector_t *front, *back;
fixed_t texheight = FixedDiv(textureheight[gl_midtexture], gl_sidedef->scaley_mid);
INT32 repeats;
if (gl_linedef->frontsector->heightsec != -1)
front = &sectors[gl_linedef->frontsector->heightsec];
else
front = gl_linedef->frontsector;
if (gl_linedef->backsector->heightsec != -1)
back = &sectors[gl_linedef->backsector->heightsec];
else
back = gl_linedef->backsector;
if (gl_sidedef->repeatcnt)
repeats = 1 + gl_sidedef->repeatcnt;
else if (gl_linedef->flags & ML_WRAPMIDTEX)
{
fixed_t high, low;
if (front->ceilingheight > back->ceilingheight)
high = back->ceilingheight;
else
high = front->ceilingheight;
if (front->floorheight > back->floorheight)
low = front->floorheight;
else
low = back->floorheight;
repeats = (high - low) / texheight;
if ((high - low) % texheight)
repeats++; // tile an extra time to fill the gap -- Monster Iestyn
}
else
repeats = 1;
grTex = HWR_GetTexture(gl_midtexture);
xscale = FixedToFloat(gl_sidedef->scalex_mid);
yscale = FixedToFloat(gl_sidedef->scaley_mid);
// SoM: a little note: popentop and popenbottom
// record the limits the texture can be displayed in.
// polytop and polybottom, are the ideal (i.e. unclipped)
// heights of the polygon, and h & l, are the final (clipped)
// poly coords.
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope;
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
// you must use the linedef's backsector to be correct
// From CB
if (gl_curline->polyseg)
{
popentop = popentopslope = back->ceilingheight;
popenbottom = popenbottomslope = back->floorheight;
}
else
{
popentop = min(worldtop, worldhigh);
popenbottom = max(worldbottom, worldlow);
popentopslope = min(worldtopslope, worldhighslope);
popenbottomslope = max(worldbottomslope, worldlowslope);
}
// Find the wall's coordinates
fixed_t midtexheight = texheight * repeats;
fixed_t rowoffset = FixedDiv(gl_sidedef->rowoffset + gl_sidedef->offsety_mid, gl_sidedef->scaley_mid);
// Texture is not skewed
if (gl_linedef->flags & ML_NOSKEW)
{
// Peg it to the floor
if (gl_linedef->flags & ML_MIDPEG)
{
polybottom = max(front->floorheight, back->floorheight) + rowoffset;
polytop = polybottom + midtexheight;
}
// Peg it to the ceiling
else
{
polytop = min(front->ceilingheight, back->ceilingheight) + rowoffset;
polybottom = polytop - midtexheight;
}
// The right side's coordinates are the the same as the left side
polytopslope = polytop;
polybottomslope = polybottom;
}
// Skew the texture, but peg it to the floor
else if (gl_linedef->flags & ML_MIDPEG)
{
polybottom = popenbottom + rowoffset;
polytop = polybottom + midtexheight;
polybottomslope = popenbottomslope + rowoffset;
polytopslope = polybottomslope + midtexheight;
}
// Skew it according to the ceiling's slope
else
{
polytop = popentop + rowoffset;
polybottom = polytop - midtexheight;
polytopslope = popentopslope + rowoffset;
polybottomslope = polytopslope - midtexheight;
}
// CB
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
// you must use the linedef's backsector to be correct
if (gl_curline->polyseg)
{
lowcut = polybottom;
highcut = polytop;
lowcutslope = polybottomslope;
highcutslope = polytopslope;
}
else
{
// The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector
lowcut = popenbottom;
highcut = popentop;
lowcutslope = popenbottomslope;
highcutslope = popentopslope;
}
h = min(highcut, polytop);
l = max(polybottom, lowcut);
hS = min(highcutslope, polytopslope);
lS = max(polybottomslope, lowcutslope);
// PEGGING
fixed_t texturevpegslope;
if (gl_linedef->flags & ML_MIDPEG)
{
texturevpeg = midtexheight - h + polybottom;
texturevpegslope = midtexheight - hS + polybottomslope;
}
else
{
texturevpeg = polytop - h;
texturevpegslope = polytopslope - hS;
}
// Left side
wallVerts[3].t = texturevpeg * yscale * grTex->scaleY;
wallVerts[0].t = (h - l + texturevpeg) * yscale * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX;
// Right side
wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY;
wallVerts[1].t = (hS - lS + texturevpegslope) * yscale * grTex->scaleY;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX;
// set top/bottom coords
// Take the texture peg into account, rather than changing the offsets past
// where the polygon might not be.
wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[0].y = FIXED_TO_FLOAT(l);
wallVerts[2].y = FIXED_TO_FLOAT(hS);
wallVerts[1].y = FIXED_TO_FLOAT(lS);
// TODO: Actually use the surface's flags so that I don't have to do this
FUINT blendmode = Surf.PolyFlags;
// Render midtextures on two-sided lines with a z-buffer offset.
// This will cause the midtexture appear on top, if a FOF overlaps with it.
blendmode |= PF_Decal;
if (gl_frontsector->numlights)
{
if (!(blendmode & PF_Masked))
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_TRANSLUCENT, NULL, blendmode);
else
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, blendmode);
}
else if (!(blendmode & PF_Masked))
HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
}
// Sky culling
// No longer so much a mess as before!
if (!gl_curline->polyseg) // Don't do it for polyobjects if (!gl_curline->polyseg) // Don't do it for polyobjects
{ {
// Sky culling
// No longer so much a mess as before!
if (gl_frontsector->ceilingpic == skyflatnum if (gl_frontsector->ceilingpic == skyflatnum
&& gl_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky && gl_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky
{ {
@ -1384,8 +1433,8 @@ static void HWR_ProcessSeg(void)
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->textureoffset + gl_sidedef->offsetx_mid) * grTex->scaleX;
// Texture correction for slopes // Texture correction for slopes
if (gl_linedef->flags & ML_NOSKEW) { if (gl_linedef->flags & ML_NOSKEW) {
@ -1448,8 +1497,9 @@ static void HWR_ProcessSeg(void)
// Used for height comparisons and etc across FOFs and slopes // Used for height comparisons and etc across FOFs and slopes
fixed_t high1, highslope1, low1, lowslope1; fixed_t high1, highslope1, low1, lowslope1;
fixed_t texturehpeg = gl_sidedef->textureoffset + gl_sidedef->offsetx_mid;
INT32 texnum; INT32 texnum;
line_t * newline = NULL; // Multi-Property FOF
lowcut = max(worldbottom, worldlow); lowcut = max(worldbottom, worldlow);
highcut = min(worldtop, worldhigh); highcut = min(worldtop, worldhigh);
@ -1483,16 +1533,14 @@ static void HWR_ProcessSeg(void)
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
continue; continue;
side_t *side = &sides[rover->master->sidenum[0]]; side_t *side = R_GetFFloorSide(gl_curline, rover);
boolean do_texture_skew; boolean do_texture_skew;
boolean dont_peg_bottom; boolean dont_peg_bottom;
if (rover->master->flags & ML_TFERLINE) if (rover->master->flags & ML_TFERLINE)
{ {
size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; line_t *newline = R_GetFFloorLine(gl_curline, rover);
newline = rover->master->frontsector->lines[0] + linenum;
side = &sides[newline->sidenum[0]];
do_texture_skew = newline->flags & ML_SKEWTD; do_texture_skew = newline->flags & ML_SKEWTD;
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM; dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
} }
@ -1570,14 +1618,14 @@ static void HWR_ProcessSeg(void)
} }
} }
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + side->offsetx_mid) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
} }
FBITFIELD blendmode;
if (rover->fofflags & FOF_FOG) if (rover->fofflags & FOF_FOG)
{ {
FBITFIELD blendmode;
blendmode = PF_Fog|PF_NoTexture; blendmode = PF_Fog|PF_NoTexture;
lightnum = rover->master->frontsector->lightlevel; lightnum = rover->master->frontsector->lightlevel;
@ -1593,7 +1641,7 @@ static void HWR_ProcessSeg(void)
} }
else else
{ {
FBITFIELD blendmode = PF_Masked; blendmode = PF_Masked;
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
{ {
@ -1641,13 +1689,21 @@ static void HWR_ProcessSeg(void)
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
continue; continue;
side_t *side = &sides[rover->master->sidenum[0]]; side_t *side = R_GetFFloorSide(gl_curline, rover);
boolean do_texture_skew;
boolean dont_peg_bottom;
if (rover->master->flags & ML_TFERLINE) if (rover->master->flags & ML_TFERLINE)
{ {
size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; line_t *newline = R_GetFFloorLine(gl_curline, rover);
newline = rover->master->frontsector->lines[0] + linenum; do_texture_skew = newline->flags & ML_SKEWTD;
side = &sides[newline->sidenum[0]]; dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
}
else
{
do_texture_skew = rover->master->flags & ML_SKEWTD;
dont_peg_bottom = gl_curline->linedef->flags & ML_DONTPEGBOTTOM;
} }
texnum = R_GetTextureNum(side->midtexture); texnum = R_GetTextureNum(side->midtexture);
@ -1684,23 +1740,49 @@ static void HWR_ProcessSeg(void)
} }
else else
{ {
// Wow, how was this missing from OpenGL for so long?
// ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software
// -- Monster Iestyn 26/06/18
fixed_t texturevpeg = side->rowoffset + side->offsety_mid;
grTex = HWR_GetTexture(texnum); grTex = HWR_GetTexture(texnum);
xscale = FixedToFloat(side->scalex_mid); xscale = FixedToFloat(side->scalex_mid);
yscale = FixedToFloat(side->scaley_mid); yscale = FixedToFloat(side->scaley_mid);
fixed_t diff = (*rover->topheight - h) * yscale; if (!do_texture_skew) // no skewing
{
if (dont_peg_bottom)
texturevpeg -= (*rover->topheight - *rover->bottomheight) * yscale;
wallVerts[3].t = wallVerts[2].t = (diff + side->rowoffset + side->offsety_mid) * grTex->scaleY; wallVerts[3].t = (((*rover->topheight - h) * yscale) + texturevpeg) * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (((h - l) * yscale) + (diff + side->rowoffset + side->offsety_mid)) * grTex->scaleY; wallVerts[2].t = (((*rover->topheight - hS) * yscale) + texturevpeg) * grTex->scaleY;
wallVerts[0].t = (((*rover->topheight - l) * yscale) + texturevpeg) * grTex->scaleY;
wallVerts[1].t = (((*rover->topheight - lS) * yscale) + texturevpeg) * grTex->scaleY;
}
else
{
if (!dont_peg_bottom) // skew by top
{
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = (((h - l) * yscale) + texturevpeg) * grTex->scaleY;
wallVerts[1].t = (((hS - lS) * yscale) + texturevpeg) * grTex->scaleY;
}
else // skew by bottom
{
wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY;
wallVerts[3].t = wallVerts[0].t - ((h - l) * yscale) * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t - ((hS - lS) * yscale) * grTex->scaleY;
}
}
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + side->offsetx_mid) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + texturehpeg + side->offsetx_mid) * grTex->scaleX;
} }
FBITFIELD blendmode;
if (rover->fofflags & FOF_FOG) if (rover->fofflags & FOF_FOG)
{ {
FBITFIELD blendmode;
blendmode = PF_Fog|PF_NoTexture; blendmode = PF_Fog|PF_NoTexture;
lightnum = rover->master->frontsector->lightlevel; lightnum = rover->master->frontsector->lightlevel;
@ -1716,7 +1798,7 @@ static void HWR_ProcessSeg(void)
} }
else else
{ {
FBITFIELD blendmode = PF_Masked; blendmode = PF_Masked;
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
{ {
@ -1994,36 +2076,14 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
static inline void HWR_AddPolyObjectSegs(void) static inline void HWR_AddPolyObjectSegs(void)
{ {
size_t i, j; size_t i, j;
seg_t *gl_fakeline = Z_Calloc(sizeof(seg_t), PU_STATIC, NULL);
polyvertex_t *pv1 = Z_Calloc(sizeof(polyvertex_t), PU_STATIC, NULL);
polyvertex_t *pv2 = Z_Calloc(sizeof(polyvertex_t), PU_STATIC, NULL);
// Sort through all the polyobjects // Sort through all the polyobjects
for (i = 0; i < numpolys; ++i) for (i = 0; i < numpolys; ++i)
{ {
// Render the polyobject's lines // Render the polyobject's lines
for (j = 0; j < po_ptrs[i]->segCount; ++j) for (j = 0; j < po_ptrs[i]->segCount; ++j)
{ HWR_AddLine(po_ptrs[i]->segs[j]);
// Copy the info of a polyobject's seg, then convert it to OpenGL floating point
M_Memcpy(gl_fakeline, po_ptrs[i]->segs[j], sizeof(seg_t));
// Now convert the line to float and add it to be rendered
pv1->x = FIXED_TO_FLOAT(gl_fakeline->v1->x);
pv1->y = FIXED_TO_FLOAT(gl_fakeline->v1->y);
pv2->x = FIXED_TO_FLOAT(gl_fakeline->v2->x);
pv2->y = FIXED_TO_FLOAT(gl_fakeline->v2->y);
gl_fakeline->pv1 = pv1;
gl_fakeline->pv2 = pv2;
HWR_AddLine(gl_fakeline);
}
} }
// Free temporary data no longer needed
Z_Free(pv2);
Z_Free(pv1);
Z_Free(gl_fakeline);
} }
static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
@ -2048,13 +2108,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
static FOutVector *planeVerts = NULL; static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0; static UINT16 numAllocedPlaneVerts = 0;
if (nrPlaneVerts < 3) // Not even a triangle? if (!r_renderfloors || nrPlaneVerts < 3) // Not even a triangle?
return; return;
else if (nrPlaneVerts > (size_t)UINT16_MAX) // FIXME: exceeds plVerts size
{
CONS_Debug(DBG_RENDER, "polygon size of %s exceeds max value of %d vertices\n", sizeu1(nrPlaneVerts), UINT16_MAX);
return;
}
// Allocate plane-vertex buffer if we need to // Allocate plane-vertex buffer if we need to
if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts) if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts)
@ -2197,7 +2252,7 @@ static void HWR_AddPolyObjectPlanes(void)
} }
else else
{ {
HWR_GetLevelFlat(&levelflats[polyobjsector->floorpic]); HWR_GetLevelFlat(&levelflats[polyobjsector->floorpic], false);
HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude, HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude,
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->floorpic], (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->floorpic],
polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : *gl_frontsector->lightlist[light].extra_colormap)); polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : *gl_frontsector->lightlist[light].extra_colormap));
@ -2220,7 +2275,7 @@ static void HWR_AddPolyObjectPlanes(void)
} }
else else
{ {
HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic]); HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic], false);
HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude,
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->ceilingpic], (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->ceilingpic],
polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : *gl_frontsector->lightlist[light].extra_colormap)); polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : *gl_frontsector->lightlist[light].extra_colormap));
@ -2350,7 +2405,7 @@ static void HWR_Subsector(size_t num)
{ {
if (sub->validcount != validcount) if (sub->validcount != validcount)
{ {
HWR_GetLevelFlat(&levelflats[gl_frontsector->floorpic]); HWR_GetLevelFlat(&levelflats[gl_frontsector->floorpic], false);
HWR_RenderPlane(sub, &extrasubsectors[num], false, HWR_RenderPlane(sub, &extrasubsectors[num], false,
// Hack to make things continue to work around slopes. // Hack to make things continue to work around slopes.
locFloorHeight == cullFloorHeight ? locFloorHeight : gl_frontsector->floorheight, locFloorHeight == cullFloorHeight ? locFloorHeight : gl_frontsector->floorheight,
@ -2366,7 +2421,7 @@ static void HWR_Subsector(size_t num)
{ {
if (sub->validcount != validcount) if (sub->validcount != validcount)
{ {
HWR_GetLevelFlat(&levelflats[gl_frontsector->ceilingpic]); HWR_GetLevelFlat(&levelflats[gl_frontsector->ceilingpic], false);
HWR_RenderPlane(sub, &extrasubsectors[num], true, HWR_RenderPlane(sub, &extrasubsectors[num], true,
// Hack to make things continue to work around slopes. // Hack to make things continue to work around slopes.
locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gl_frontsector->ceilingheight, locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gl_frontsector->ceilingheight,
@ -2424,7 +2479,7 @@ static void HWR_Subsector(size_t num)
*rover->bottomheight, *rover->bottomheight,
*gl_frontsector->lightlist[light].lightlevel, *gl_frontsector->lightlist[light].lightlevel,
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
true, rover->master->frontsector->extra_colormap); true, false, rover->master->frontsector->extra_colormap);
} }
else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) // SoM: Flags are more efficient else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) // SoM: Flags are more efficient
{ {
@ -2437,11 +2492,11 @@ static void HWR_Subsector(size_t num)
*gl_frontsector->lightlist[light].lightlevel, *gl_frontsector->lightlist[light].lightlevel,
max(0, min(rover->alpha, 255)), rover->master->frontsector, max(0, min(rover->alpha, 255)), rover->master->frontsector,
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent), HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
false, *gl_frontsector->lightlist[light].extra_colormap); false, rover->fofflags & FOF_SPLAT, *gl_frontsector->lightlist[light].extra_colormap);
} }
else else
{ {
HWR_GetLevelFlat(&levelflats[*rover->bottompic]); HWR_GetLevelFlat(&levelflats[*rover->bottompic], rover->fofflags & FOF_SPLAT);
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false); light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false);
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic], HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap); rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
@ -2469,7 +2524,7 @@ static void HWR_Subsector(size_t num)
*rover->topheight, *rover->topheight,
*gl_frontsector->lightlist[light].lightlevel, *gl_frontsector->lightlist[light].lightlevel,
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
true, rover->master->frontsector->extra_colormap); true, false, rover->master->frontsector->extra_colormap);
} }
else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
{ {
@ -2482,11 +2537,11 @@ static void HWR_Subsector(size_t num)
*gl_frontsector->lightlist[light].lightlevel, *gl_frontsector->lightlist[light].lightlevel,
max(0, min(rover->alpha, 255)), rover->master->frontsector, max(0, min(rover->alpha, 255)), rover->master->frontsector,
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent), HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
false, *gl_frontsector->lightlist[light].extra_colormap); false, rover->fofflags & FOF_SPLAT, *gl_frontsector->lightlist[light].extra_colormap);
} }
else else
{ {
HWR_GetLevelFlat(&levelflats[*rover->toppic]); HWR_GetLevelFlat(&levelflats[*rover->toppic], rover->fofflags & FOF_SPLAT);
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false); light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false);
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic], HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap); rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
@ -3793,6 +3848,7 @@ typedef struct
sector_t *FOFSector; sector_t *FOFSector;
FBITFIELD blend; FBITFIELD blend;
boolean fogplane; boolean fogplane;
boolean chromakeyed;
extracolormap_t *planecolormap; extracolormap_t *planecolormap;
INT32 drawcount; INT32 drawcount;
} planeinfo_t; } planeinfo_t;
@ -3834,7 +3890,7 @@ static INT32 drawcount = 0;
#define MAX_TRANSPARENTFLOOR 512 #define MAX_TRANSPARENTFLOOR 512
// This will likely turn into a copy of HWR_Add3DWater and replace it. // This will likely turn into a copy of HWR_Add3DWater and replace it.
void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, boolean chromakeyed, extracolormap_t *planecolormap)
{ {
static size_t allocedplanes = 0; static size_t allocedplanes = 0;
@ -3857,6 +3913,7 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo
planeinfo[numplanes].FOFSector = FOFSector; planeinfo[numplanes].FOFSector = FOFSector;
planeinfo[numplanes].blend = blend; planeinfo[numplanes].blend = blend;
planeinfo[numplanes].fogplane = fogplane; planeinfo[numplanes].fogplane = fogplane;
planeinfo[numplanes].chromakeyed = chromakeyed;
planeinfo[numplanes].planecolormap = planecolormap; planeinfo[numplanes].planecolormap = planecolormap;
planeinfo[numplanes].drawcount = drawcount++; planeinfo[numplanes].drawcount = drawcount++;
@ -4023,7 +4080,7 @@ static void HWR_CreateDrawNodes(void)
gl_frontsector = NULL; gl_frontsector = NULL;
if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture)) if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture))
HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat); HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->chromakeyed);
HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel,
sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->planecolormap); sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->planecolormap);
} }
@ -4032,9 +4089,11 @@ static void HWR_CreateDrawNodes(void)
// We aren't traversing the BSP tree, so make gl_frontsector null to avoid crashes. // We aren't traversing the BSP tree, so make gl_frontsector null to avoid crashes.
gl_frontsector = NULL; gl_frontsector = NULL;
polyobj_t *po = sortnode[sortindex[i]].polyplane->polysector;
if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture)) if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture))
HWR_GetLevelFlat(sortnode[sortindex[i]].polyplane->levelflat); HWR_GetLevelFlat(sortnode[sortindex[i]].polyplane->levelflat, po->flags & POF_SPLAT);
HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel, HWR_RenderPolyObjectPlane(po, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel,
sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap); sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap);
} }
else if (sortnode[sortindex[i]].wall) else if (sortnode[sortindex[i]].wall)
@ -4239,7 +4298,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
// uncapped/interpolation // uncapped/interpolation
interpmobjstate_t interp = {0}; interpmobjstate_t interp = {0};
if (!cv_renderthings.value) if (!r_renderthings)
return; return;
if (!thing) if (!thing)
@ -5513,7 +5572,7 @@ static void HWR_TogglePaletteRendering(void)
// The textures will still be converted to RGBA by r_opengl. // The textures will still be converted to RGBA by r_opengl.
// This however makes hw_cache use paletted blending for composite textures! // This however makes hw_cache use paletted blending for composite textures!
// (patchformat is not touched) // (patchformat is not touched)
textureformat = GL_TEXFMT_P_8; textureformat = GL_TEXFMT_AP_88;
HWR_SetMapPalette(); HWR_SetMapPalette();
HWR_SetPalette(pLocalPalette); HWR_SetPalette(pLocalPalette);
@ -5784,7 +5843,7 @@ void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 te
{ {
static size_t allocedwalls = 0; static size_t allocedwalls = 0;
if (!cv_renderwalls.value) if (!r_renderwalls)
return; return;
// Force realloc if buffer has been freed // Force realloc if buffer has been freed
@ -5815,7 +5874,7 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
INT32 shader = SHADER_NONE; INT32 shader = SHADER_NONE;
if (!cv_renderwalls.value) if (!r_renderwalls)
return; return;
// Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting // Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting

View file

@ -44,6 +44,21 @@ return luaL_error(L, "HUD rendering code should not call this function!");\
else if (hook_cmd_running)\ else if (hook_cmd_running)\
return luaL_error(L, "CMD building code should not call this function!"); return luaL_error(L, "CMD building code should not call this function!");
#define NOSPAWNNULL if (type >= NUMMOBJTYPES)\
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);\
else if (type == MT_NULL)\
{\
if (!nospawnnull_seen) {\
nospawnnull_seen = true;\
CONS_Alert(CONS_WARNING,"Spawning an \"MT_NULL\" mobj is deprecated and will be removed.\nUse \"MT_RAY\" instead.\n");\
}\
type = MT_RAY;\
}
static boolean nospawnnull_seen = false; // TODO: 2.3: Delete
// TODO: 2.3: Use the below NOSPAWNNULL define instead. P_SpawnMobj used to say "if MT_NULL, use MT_RAY instead", so the above define maintains Lua script compatibility until v2.3
/*#define NOSPAWNNULL if (type <= MT_NULL || type >= NUMMOBJTYPES)\
return luaL_error(L, "mobj type %d out of range (1 - %d)", type, NUMMOBJTYPES-1);*/
boolean luaL_checkboolean(lua_State *L, int narg) { boolean luaL_checkboolean(lua_State *L, int narg) {
luaL_checktype(L, narg, LUA_TBOOLEAN); luaL_checktype(L, narg, LUA_TBOOLEAN);
return lua_toboolean(L, narg); return lua_toboolean(L, narg);
@ -625,8 +640,7 @@ static int lib_pSpawnMobj(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 4); mobjtype_t type = luaL_checkinteger(L, 4);
NOHUD NOHUD
INLEVEL INLEVEL
if (type >= NUMMOBJTYPES) NOSPAWNNULL
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ); LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ);
return 1; return 1;
} }
@ -640,10 +654,9 @@ static int lib_pSpawnMobjFromMobj(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 5); mobjtype_t type = luaL_checkinteger(L, 5);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!actor) if (!actor)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ); LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ);
return 1; return 1;
} }
@ -708,10 +721,9 @@ static int lib_pSpawnMissile(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 3); mobjtype_t type = luaL_checkinteger(L, 3);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source || !dest) if (!source || !dest)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnMissile(source, dest, type), META_MOBJ); LUA_PushUserdata(L, P_SpawnMissile(source, dest, type), META_MOBJ);
return 1; return 1;
} }
@ -726,10 +738,9 @@ static int lib_pSpawnXYZMissile(lua_State *L)
fixed_t z = luaL_checkfixed(L, 6); fixed_t z = luaL_checkfixed(L, 6);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source || !dest) if (!source || !dest)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnXYZMissile(source, dest, type, x, y, z), META_MOBJ); LUA_PushUserdata(L, P_SpawnXYZMissile(source, dest, type, x, y, z), META_MOBJ);
return 1; return 1;
} }
@ -746,10 +757,9 @@ static int lib_pSpawnPointMissile(lua_State *L)
fixed_t z = luaL_checkfixed(L, 8); fixed_t z = luaL_checkfixed(L, 8);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnPointMissile(source, xa, ya, za, type, x, y, z), META_MOBJ); LUA_PushUserdata(L, P_SpawnPointMissile(source, xa, ya, za, type, x, y, z), META_MOBJ);
return 1; return 1;
} }
@ -764,10 +774,9 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L)
INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5); INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnAlteredDirectionMissile(source, type, x, y, z, shiftingAngle), META_MOBJ); LUA_PushUserdata(L, P_SpawnAlteredDirectionMissile(source, type, x, y, z, shiftingAngle), META_MOBJ);
return 1; return 1;
} }
@ -795,10 +804,9 @@ static int lib_pSPMAngle(lua_State *L)
UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0); UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SPMAngle(source, type, angle, allowaim, flags2), META_MOBJ); LUA_PushUserdata(L, P_SPMAngle(source, type, angle, allowaim, flags2), META_MOBJ);
return 1; return 1;
} }
@ -810,10 +818,9 @@ static int lib_pSpawnPlayerMissile(lua_State *L)
UINT32 flags2 = (UINT32)luaL_optinteger(L, 3, 0); UINT32 flags2 = (UINT32)luaL_optinteger(L, 3, 0);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnPlayerMissile(source, type, flags2), META_MOBJ); LUA_PushUserdata(L, P_SpawnPlayerMissile(source, type, flags2), META_MOBJ);
return 1; return 1;
} }
@ -844,8 +851,7 @@ static int lib_pWeaponOrPanel(lua_State *L)
{ {
mobjtype_t type = luaL_checkinteger(L, 1); mobjtype_t type = luaL_checkinteger(L, 1);
//HUDSAFE //HUDSAFE
if (type >= NUMMOBJTYPES) NOSPAWNNULL
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
lua_pushboolean(L, P_WeaponOrPanel(type)); lua_pushboolean(L, P_WeaponOrPanel(type));
return 1; return 1;
} }
@ -888,8 +894,7 @@ static int lib_pSpawnParaloop(lua_State *L)
boolean spawncenter = lua_optboolean(L, 9); boolean spawncenter = lua_optboolean(L, 9);
NOHUD NOHUD
INLEVEL INLEVEL
if (type >= NUMMOBJTYPES) NOSPAWNNULL
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
if (nstate >= NUMSTATES) if (nstate >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", nstate, NUMSTATES-1); return luaL_error(L, "state %d out of range (0 - %d)", nstate, NUMSTATES-1);
P_SpawnParaloop(x, y, z, radius, number, type, nstate, rotangle, spawncenter); P_SpawnParaloop(x, y, z, radius, number, type, nstate, rotangle, spawncenter);
@ -924,13 +929,14 @@ static int lib_pSetScale(lua_State *L)
{ {
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t newscale = luaL_checkfixed(L, 2); fixed_t newscale = luaL_checkfixed(L, 2);
boolean instant = lua_optboolean(L, 3);
NOHUD NOHUD
INLEVEL INLEVEL
if (!mobj) if (!mobj)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (newscale < FRACUNIT/100) if (newscale < FRACUNIT/100)
newscale = FRACUNIT/100; newscale = FRACUNIT/100;
P_SetScale(mobj, newscale); P_SetScale(mobj, newscale, instant);
return 0; return 0;
} }
@ -1762,10 +1768,9 @@ static int lib_pSpawnSpinMobj(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 2); mobjtype_t type = luaL_checkinteger(L, 2);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
P_SpawnSpinMobj(player, type); P_SpawnSpinMobj(player, type);
return 0; return 0;
} }
@ -2497,6 +2502,17 @@ static int lib_pDoSuperTransformation(lua_State *L)
return 0; return 0;
} }
static int lib_pDoSuperDetransformation(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
P_DoSuperDetransformation(player);
return 0;
}
static int lib_pExplodeMissile(lua_State *L) static int lib_pExplodeMissile(lua_State *L)
{ {
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -2711,12 +2727,11 @@ static int lib_pFadeLight(lua_State *L)
static int lib_pIsFlagAtBase(lua_State *L) static int lib_pIsFlagAtBase(lua_State *L)
{ {
mobjtype_t flag = luaL_checkinteger(L, 1); mobjtype_t type = luaL_checkinteger(L, 1);
//HUDSAFE //HUDSAFE
INLEVEL INLEVEL
if (flag >= NUMMOBJTYPES) NOSPAWNNULL
return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1); lua_pushboolean(L, P_IsFlagAtBase(type));
lua_pushboolean(L, P_IsFlagAtBase(flag));
return 1; return 1;
} }
@ -4450,6 +4465,7 @@ static luaL_Reg lib[] = {
{"P_VectorInstaThrust",lib_pVectorInstaThrust}, {"P_VectorInstaThrust",lib_pVectorInstaThrust},
{"P_SetMobjStateNF",lib_pSetMobjStateNF}, {"P_SetMobjStateNF",lib_pSetMobjStateNF},
{"P_DoSuperTransformation",lib_pDoSuperTransformation}, {"P_DoSuperTransformation",lib_pDoSuperTransformation},
{"P_DoSuperDetransformation",lib_pDoSuperDetransformation},
{"P_ExplodeMissile",lib_pExplodeMissile}, {"P_ExplodeMissile",lib_pExplodeMissile},
{"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial}, {"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial},
{"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor}, {"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor},

View file

@ -47,6 +47,7 @@ static const char *const hud_disable_options[] = {
"time", "time",
"rings", "rings",
"lives", "lives",
"input",
"weaponrings", "weaponrings",
"powerstones", "powerstones",
@ -70,6 +71,10 @@ static const char *const hud_disable_options[] = {
"intermissionemeralds", "intermissionemeralds",
NULL}; NULL};
// you know, let's actually make sure that the table is synced.
// because fuck knows how many times this has happened at this point. :v
I_StaticAssert(sizeof(hud_disable_options) / sizeof(*hud_disable_options) == hud_MAX+1);
enum hudinfo { enum hudinfo {
hudinfo_x = 0, hudinfo_x = 0,
hudinfo_y, hudinfo_y,

View file

@ -777,7 +777,7 @@ static int mobj_set(lua_State *L)
return luaL_error(L, "mobj.type %d out of range (0 - %d).", newtype, NUMMOBJTYPES-1); return luaL_error(L, "mobj.type %d out of range (0 - %d).", newtype, NUMMOBJTYPES-1);
mo->type = newtype; mo->type = newtype;
mo->info = &mobjinfo[newtype]; mo->info = &mobjinfo[newtype];
P_SetScale(mo, mo->scale); P_SetScale(mo, mo->scale, false);
break; break;
} }
case mobj_info: case mobj_info:
@ -851,9 +851,7 @@ static int mobj_set(lua_State *L)
fixed_t scale = luaL_checkfixed(L, 3); fixed_t scale = luaL_checkfixed(L, 3);
if (scale < FRACUNIT/100) if (scale < FRACUNIT/100)
scale = FRACUNIT/100; scale = FRACUNIT/100;
mo->destscale = scale; P_SetScale(mo, scale, true);
P_SetScale(mo, scale);
mo->old_scale = scale;
break; break;
} }
case mobj_destscale: case mobj_destscale:

View file

@ -1068,9 +1068,9 @@ static menuitem_t OP_ChangeControlsMenu[] =
{IT_CALL | IT_STRING2, NULL, "Move Backward", M_ChangeControl, GC_BACKWARD }, {IT_CALL | IT_STRING2, NULL, "Move Backward", M_ChangeControl, GC_BACKWARD },
{IT_CALL | IT_STRING2, NULL, "Move Left", M_ChangeControl, GC_STRAFELEFT }, {IT_CALL | IT_STRING2, NULL, "Move Left", M_ChangeControl, GC_STRAFELEFT },
{IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, GC_STRAFERIGHT }, {IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, GC_STRAFERIGHT },
{IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP }, {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP },
{IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN }, {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN },
{IT_CALL | IT_STRING2, NULL, "Shield", M_ChangeControl, GC_SHIELD }, {IT_CALL | IT_STRING2, NULL, "Shield Ability", M_ChangeControl, GC_SHIELD },
{IT_HEADER, NULL, "Camera", NULL, 0}, {IT_HEADER, NULL, "Camera", NULL, 0},
{IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_SPACE, NULL, NULL, NULL, 0}, // padding
{IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, GC_LOOKUP }, {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, GC_LOOKUP },
@ -1119,13 +1119,15 @@ static menuitem_t OP_ChangeControlsMenu[] =
static menuitem_t OP_Joystick1Menu[] = static menuitem_t OP_Joystick1Menu[] =
{ {
{IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup1PJoystickMenu, 10}, {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup1PJoystickMenu, 0},
{IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis , 30},
{IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis , 40}, {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis , 20},
{IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis , 50}, {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis , 30},
{IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis , 60}, {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis , 40},
{IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis , 70}, {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis , 50},
{IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis , 80}, {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis , 60},
{IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis , 70},
{IT_STRING | IT_CVAR, NULL, "Shield Axis" , &cv_shieldaxis , 80},
{IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis , 90}, {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis , 90},
{IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis ,100}, {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis ,100},
@ -1137,13 +1139,15 @@ static menuitem_t OP_Joystick1Menu[] =
static menuitem_t OP_Joystick2Menu[] = static menuitem_t OP_Joystick2Menu[] =
{ {
{IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup2PJoystickMenu, 10}, {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup2PJoystickMenu, 0},
{IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis2 , 30},
{IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis2 , 40}, {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis2 , 20},
{IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis2 , 50}, {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis2 , 30},
{IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis2 , 60}, {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis2 , 40},
{IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis2 , 70}, {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis2 , 50},
{IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis2 , 80}, {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis2 , 60},
{IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis2 , 70},
{IT_STRING | IT_CVAR, NULL, "Shield Axis" , &cv_shieldaxis2 , 80},
{IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis2 , 90}, {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis2 , 90},
{IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis2 ,100}, {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis2 ,100},
@ -3426,7 +3430,7 @@ boolean M_Responder(event_t *ev)
// ignore ev_keydown events if the key maps to a character, since // ignore ev_keydown events if the key maps to a character, since
// the ev_text event will follow immediately after in that case. // the ev_text event will follow immediately after in that case.
if (ev->type == ev_keydown && ch >= 32 && ch <= 127) if (ev->type == ev_keydown && ch >= 32 && ch <= 127)
return false; return true;
if (M_ChangeStringCvar(ch)) if (M_ChangeStringCvar(ch))
return true; return true;

View file

@ -671,6 +671,13 @@ void D_RegisterClientCommands(void)
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
sprintf(player_names[i], "Player %d", 1 + i); sprintf(player_names[i], "Player %d", 1 + i);
CV_RegisterVar(&cv_gravity);
CV_RegisterVar(&cv_tailspickup);
CV_RegisterVar(&cv_allowmlook);
CV_RegisterVar(&cv_flipcam);
CV_RegisterVar(&cv_flipcam2);
CV_RegisterVar(&cv_movebob);
if (dedicated) if (dedicated)
return; return;
@ -815,6 +822,8 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_jumpaxis2); CV_RegisterVar(&cv_jumpaxis2);
CV_RegisterVar(&cv_spinaxis); CV_RegisterVar(&cv_spinaxis);
CV_RegisterVar(&cv_spinaxis2); CV_RegisterVar(&cv_spinaxis2);
CV_RegisterVar(&cv_shieldaxis);
CV_RegisterVar(&cv_shieldaxis2);
CV_RegisterVar(&cv_fireaxis); CV_RegisterVar(&cv_fireaxis);
CV_RegisterVar(&cv_fireaxis2); CV_RegisterVar(&cv_fireaxis2);
CV_RegisterVar(&cv_firenaxis); CV_RegisterVar(&cv_firenaxis);
@ -899,13 +908,6 @@ void D_RegisterClientCommands(void)
// screen.c // screen.c
CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_fullscreen);
CV_RegisterVar(&cv_renderview);
CV_RegisterVar(&cv_renderhitboxinterpolation);
CV_RegisterVar(&cv_renderhitboxgldepth);
CV_RegisterVar(&cv_renderhitbox);
CV_RegisterVar(&cv_renderwalls);
CV_RegisterVar(&cv_renderfloors);
CV_RegisterVar(&cv_renderthings);
CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_renderer);
CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_depth);
CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_width);
@ -926,8 +928,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_opflags); CV_RegisterVar(&cv_opflags);
CV_RegisterVar(&cv_ophoopflags); CV_RegisterVar(&cv_ophoopflags);
CV_RegisterVar(&cv_mapthingnum); CV_RegisterVar(&cv_mapthingnum);
// CV_RegisterVar(&cv_grid);
// CV_RegisterVar(&cv_snapto);
CV_RegisterVar(&cv_freedemocamera); CV_RegisterVar(&cv_freedemocamera);

View file

@ -94,7 +94,10 @@ extern consvar_t cv_inttime, cv_coopstarposts, cv_cooplives, cv_advancemap, cv_p
extern consvar_t cv_overtime; extern consvar_t cv_overtime;
extern consvar_t cv_startinglives; extern consvar_t cv_startinglives;
// for F_finale.c extern consvar_t cv_gravity, cv_movebob;
extern consvar_t cv_tailspickup;
// for f_finale.c
extern consvar_t cv_rollingdemos; extern consvar_t cv_rollingdemos;
extern consvar_t cv_ringslinger, cv_soundtest; extern consvar_t cv_ringslinger, cv_soundtest;
@ -105,7 +108,6 @@ extern consvar_t cv_maxping;
extern consvar_t cv_pingtimeout; extern consvar_t cv_pingtimeout;
extern consvar_t cv_showping; extern consvar_t cv_showping;
extern consvar_t cv_skipmapcheck; extern consvar_t cv_skipmapcheck;
extern consvar_t cv_sleep; extern consvar_t cv_sleep;

View file

@ -1222,8 +1222,7 @@ static void P_FaceStabFlume(mobj_t *actor)
if (P_MobjWasRemoved(flume)) if (P_MobjWasRemoved(flume))
return; return;
flume->destscale = actor->scale*3; P_SetScale(flume, 3*actor->scale, true);
P_SetScale(flume, flume->destscale);
P_SetTarget(&flume->target, actor); P_SetTarget(&flume->target, actor);
flume->sprite = SPR_JETF; flume->sprite = SPR_JETF;
flume->frame = FF_FULLBRIGHT; flume->frame = FF_FULLBRIGHT;
@ -1342,8 +1341,7 @@ void A_FaceStabHurl(mobj_t *actor)
{ {
hwork = hwork->hnext; hwork = hwork->hnext;
hwork->angle = actor->angle + ANGLE_90; hwork->angle = actor->angle + ANGLE_90;
hwork->destscale = FixedSqrt(step*basesize); P_SetScale(hwork, FixedSqrt(step*basesize), true);
P_SetScale(hwork, hwork->destscale);
hwork->fuse = 2; hwork->fuse = 2;
P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS))); P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS)));
if (P_MobjWasRemoved(hwork)) if (P_MobjWasRemoved(hwork))
@ -2486,7 +2484,7 @@ void A_VultureBlast(mobj_t *actor)
if (P_MobjWasRemoved(dust)) if (P_MobjWasRemoved(dust))
continue; continue;
P_SetScale(dust, 4*FRACUNIT); P_SetScale(dust, 4*FRACUNIT, true);
dust->destscale = FRACUNIT; dust->destscale = FRACUNIT;
dust->scalespeed = 4*FRACUNIT/TICRATE; dust->scalespeed = 4*FRACUNIT/TICRATE;
dust->fuse = TICRATE; dust->fuse = TICRATE;
@ -2556,7 +2554,7 @@ void A_VultureFly(mobj_t *actor)
dust = P_SpawnMobj(actor->x + P_RandomFixed() - FRACUNIT/2, actor->y + P_RandomFixed() - FRACUNIT/2, actor->z + actor->height/2 + P_RandomFixed() - FRACUNIT/2, MT_PARTICLE); dust = P_SpawnMobj(actor->x + P_RandomFixed() - FRACUNIT/2, actor->y + P_RandomFixed() - FRACUNIT/2, actor->z + actor->height/2 + P_RandomFixed() - FRACUNIT/2, MT_PARTICLE);
if (!P_MobjWasRemoved(dust)) if (!P_MobjWasRemoved(dust))
{ {
P_SetScale(dust, 2*FRACUNIT); P_SetScale(dust, 2*FRACUNIT, true);
dust->destscale = FRACUNIT/3; dust->destscale = FRACUNIT/3;
dust->scalespeed = FRACUNIT/40; dust->scalespeed = FRACUNIT/40;
dust->fuse = TICRATE*2; dust->fuse = TICRATE*2;
@ -2765,15 +2763,9 @@ void A_LobShot(mobj_t *actor)
return; return;
if (actor->type == MT_BLACKEGGMAN) if (actor->type == MT_BLACKEGGMAN)
{ P_SetScale(shot, actor->scale/2, true);
shot->destscale = actor->scale/2;
P_SetScale(shot, actor->scale/2);
}
else else
{ P_SetScale(shot, actor->scale, true);
shot->destscale = actor->scale;
P_SetScale(shot, actor->scale);
}
P_SetTarget(&shot->target, actor); // where it came from P_SetTarget(&shot->target, actor); // where it came from
@ -3218,8 +3210,7 @@ void A_Boss1Laser(mobj_t *actor)
if (!P_MobjWasRemoved(point)) if (!P_MobjWasRemoved(point))
{ {
point->angle = actor->angle; point->angle = actor->angle;
point->destscale = actor->scale; P_SetScale(point, actor->scale, true);
P_SetScale(point, point->destscale);
P_SetTarget(&point->target, actor); P_SetTarget(&point->target, actor);
P_MobjCheckWater(point); P_MobjCheckWater(point);
if (point->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) if (point->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))
@ -3230,7 +3221,8 @@ void A_Boss1Laser(mobj_t *actor)
mobj_t *steam = P_SpawnMobj(x, y, point->watertop - size*mobjinfo[MT_DUST].height, MT_DUST); mobj_t *steam = P_SpawnMobj(x, y, point->watertop - size*mobjinfo[MT_DUST].height, MT_DUST);
if (P_MobjWasRemoved(steam)) if (P_MobjWasRemoved(steam))
continue; continue;
P_SetScale(steam, size*actor->scale); P_SetScale(steam, size*actor->scale, false);
steam->old_scale = steam->scale;
P_SetObjectMomZ(steam, FRACUNIT + 2*P_RandomFixed(), true); P_SetObjectMomZ(steam, FRACUNIT + 2*P_RandomFixed(), true);
P_InstaThrust(steam, FixedAngle(P_RandomKey(360)*FRACUNIT), 2*P_RandomFixed()); P_InstaThrust(steam, FixedAngle(P_RandomKey(360)*FRACUNIT), 2*P_RandomFixed());
if (point->info->painsound) if (point->info->painsound)
@ -3603,8 +3595,7 @@ void A_BossScream(mobj_t *actor)
return; return;
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
mo->flags2 |= MF2_OBJECTFLIP; mo->flags2 |= MF2_OBJECTFLIP;
mo->destscale = actor->scale; P_SetScale(mo, actor->scale, true);
P_SetScale(mo, mo->destscale);
if (actor->info->deathsound) if (actor->info->deathsound)
S_StartSound(mo, actor->info->deathsound); S_StartSound(mo, actor->info->deathsound);
} }
@ -4197,7 +4188,7 @@ static void P_DoBoss5Death(mobj_t *mo)
MT_FSGNB); MT_FSGNB);
if (!P_MobjWasRemoved(pole)) if (!P_MobjWasRemoved(pole))
{ {
P_SetScale(pole, (pole->destscale = 2*FRACUNIT)); P_SetScale(pole, 2*FRACUNIT, true);
pole->momx = P_ReturnThrustX(pole, pole->angle, speed); pole->momx = P_ReturnThrustX(pole, pole->angle, speed);
pole->momy = P_ReturnThrustY(pole, pole->angle, speed); pole->momy = P_ReturnThrustY(pole, pole->angle, speed);
P_SetTarget(&pole->tracer, P_SpawnMobj( P_SetTarget(&pole->tracer, P_SpawnMobj(
@ -4207,7 +4198,7 @@ static void P_DoBoss5Death(mobj_t *mo)
if (!P_MobjWasRemoved(pole->tracer)) if (!P_MobjWasRemoved(pole->tracer))
{ {
pole->tracer->flags |= MF_NOCLIPTHING; pole->tracer->flags |= MF_NOCLIPTHING;
P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT)); P_SetScale(pole->tracer, 2*FRACUNIT, true);
pole->angle = pole->tracer->angle = mo->tracer->angle; pole->angle = pole->tracer->angle = mo->tracer->angle;
pole->tracer->momx = pole->momx; pole->tracer->momx = pole->momx;
pole->tracer->momy = pole->momy; pole->tracer->momy = pole->momy;
@ -4746,10 +4737,7 @@ void A_BubbleSpawn(mobj_t *actor)
bubble = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2), MT_MEDIUMBUBBLE); bubble = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2), MT_MEDIUMBUBBLE);
if (bubble) if (bubble)
{ P_SetScale(bubble, actor->scale, true);
bubble->destscale = actor->scale;
P_SetScale(bubble, actor->scale);
}
} }
// Function: A_FanBubbleSpawn // Function: A_FanBubbleSpawn
@ -4792,10 +4780,7 @@ void A_FanBubbleSpawn(mobj_t *actor)
bubble = P_SpawnMobj(actor->x, actor->y, hz, MT_MEDIUMBUBBLE); bubble = P_SpawnMobj(actor->x, actor->y, hz, MT_MEDIUMBUBBLE);
if (bubble) if (bubble)
{ P_SetScale(bubble, actor->scale, true);
bubble->destscale = actor->scale;
P_SetScale(bubble, actor->scale);
}
} }
// Function: A_BubbleRise // Function: A_BubbleRise
@ -5072,8 +5057,7 @@ void A_ThrownRing(mobj_t *actor)
P_SetTarget(&ring->target, actor); P_SetTarget(&ring->target, actor);
ring->color = actor->color; //copy color ring->color = actor->color; //copy color
*/ */
ring->destscale = actor->scale; P_SetScale(ring, actor->scale, true);
P_SetScale(ring, actor->scale);
} }
} }
@ -5652,8 +5636,7 @@ void A_JetbThink(mobj_t *actor)
if (!P_MobjWasRemoved(bomb)) if (!P_MobjWasRemoved(bomb))
{ {
P_SetTarget(&bomb->target, actor); P_SetTarget(&bomb->target, actor);
bomb->destscale = actor->scale; P_SetScale(bomb, actor->scale, true);
P_SetScale(bomb, actor->scale);
actor->reactiontime = TICRATE; // one second actor->reactiontime = TICRATE; // one second
S_StartSound(actor, actor->info->attacksound); S_StartSound(actor, actor->info->attacksound);
} }
@ -5833,7 +5816,8 @@ void A_MinusDigging(mobj_t *actor)
P_SetMobjState(par, actor->info->raisestate); P_SetMobjState(par, actor->info->raisestate);
if (P_MobjWasRemoved(par)) if (P_MobjWasRemoved(par))
return; return;
P_SetScale(par, actor->scale*2); P_SetScale(par, actor->scale*2, false);
par->old_scale = par->scale;
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
par->eflags |= MFE_VERTICALFLIP; par->eflags |= MFE_VERTICALFLIP;
return; return;
@ -5905,7 +5889,8 @@ void A_MinusPopup(mobj_t *actor)
continue; continue;
P_Thrust(rock, ani*i, FRACUNIT); P_Thrust(rock, ani*i, FRACUNIT);
P_SetObjectMomZ(rock, 3*FRACUNIT, false); P_SetObjectMomZ(rock, 3*FRACUNIT, false);
P_SetScale(rock, rock->scale/3); P_SetScale(rock, rock->scale/3, false);
rock->old_scale = rock->scale;
} }
P_RadiusAttack(actor, actor, 2*actor->radius, 0, true); P_RadiusAttack(actor, actor, 2*actor->radius, 0, true);
if (actor->tracer) if (actor->tracer)
@ -5944,7 +5929,8 @@ void A_MinusCheck(mobj_t *actor)
continue; continue;
P_Thrust(rock, ani*i, FRACUNIT); P_Thrust(rock, ani*i, FRACUNIT);
P_SetObjectMomZ(rock, 3*FRACUNIT, false); P_SetObjectMomZ(rock, 3*FRACUNIT, false);
P_SetScale(rock, rock->scale/3); P_SetScale(rock, rock->scale/3, false);
rock->old_scale = rock->scale;
} }
} }
} }
@ -8273,8 +8259,9 @@ void A_EggShield(mobj_t *actor)
else else
actor->z = actor->target->z; actor->z = actor->target->z;
P_SetScale(actor, actor->target->scale, false);
actor->destscale = actor->target->destscale; actor->destscale = actor->target->destscale;
P_SetScale(actor, actor->target->scale); actor->old_scale = actor->target->old_scale;
actor->floorz = actor->target->floorz; actor->floorz = actor->target->floorz;
actor->ceilingz = actor->target->ceilingz; actor->ceilingz = actor->target->ceilingz;
@ -8555,7 +8542,7 @@ void A_Boss3ShockThink(mobj_t *actor)
P_SetTarget(&snew->target, actor->target); P_SetTarget(&snew->target, actor->target);
snew->fuse = actor->fuse; snew->fuse = actor->fuse;
P_SetScale(snew, actor->scale); P_SetScale(snew, actor->scale, true);
snew->destscale = actor->destscale; snew->destscale = actor->destscale;
snew->scalespeed = actor->scalespeed; snew->scalespeed = actor->scalespeed;
@ -8757,8 +8744,7 @@ void A_SmokeTrailer(mobj_t *actor)
if (P_MobjWasRemoved(th)) if (P_MobjWasRemoved(th))
return; return;
P_SetObjectMomZ(th, FRACUNIT, false); P_SetObjectMomZ(th, FRACUNIT, false);
th->destscale = actor->scale; P_SetScale(th, actor->scale, true);
P_SetScale(th, actor->scale);
th->tics -= P_RandomByte() & 3; th->tics -= P_RandomByte() & 3;
if (th->tics < 1) if (th->tics < 1)
th->tics = 1; th->tics = 1;
@ -9522,8 +9508,7 @@ void A_BossJetFume(mobj_t *actor)
if (!P_MobjWasRemoved(filler)) if (!P_MobjWasRemoved(filler))
{ {
P_SetTarget(&filler->target, actor); P_SetTarget(&filler->target, actor);
filler->destscale = actor->scale; P_SetScale(filler, actor->scale, true);
P_SetScale(filler, filler->destscale);
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
filler->flags2 |= MF2_OBJECTFLIP; filler->flags2 |= MF2_OBJECTFLIP;
filler->fuse = 56; filler->fuse = 56;
@ -9540,8 +9525,7 @@ void A_BossJetFume(mobj_t *actor)
if (!P_MobjWasRemoved(filler)) if (!P_MobjWasRemoved(filler))
{ {
P_SetTarget(&filler->target, actor); P_SetTarget(&filler->target, actor);
filler->destscale = actor->scale; P_SetScale(filler, actor->scale, true);
P_SetScale(filler, filler->destscale);
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
filler->flags2 |= MF2_OBJECTFLIP; filler->flags2 |= MF2_OBJECTFLIP;
filler->fuse = 57; filler->fuse = 57;
@ -9554,7 +9538,7 @@ void A_BossJetFume(mobj_t *actor)
{ {
P_SetTarget(&filler->target, actor); P_SetTarget(&filler->target, actor);
filler->destscale = actor->scale; filler->destscale = actor->scale;
P_SetScale(filler, filler->destscale); P_SetScale(filler, actor->scale, true);
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
filler->flags2 |= MF2_OBJECTFLIP; filler->flags2 |= MF2_OBJECTFLIP;
filler->fuse = 58; filler->fuse = 58;
@ -9575,8 +9559,7 @@ void A_BossJetFume(mobj_t *actor)
filler = P_SpawnMobj(jetx, jety, jetz, MT_PROPELLER); filler = P_SpawnMobj(jetx, jety, jetz, MT_PROPELLER);
P_SetTarget(&filler->target, actor); P_SetTarget(&filler->target, actor);
filler->destscale = actor->scale; P_SetScale(filler, actor->scale, true);
P_SetScale(filler, filler->destscale);
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
filler->flags2 |= MF2_OBJECTFLIP; filler->flags2 |= MF2_OBJECTFLIP;
filler->angle = actor->angle - ANGLE_180; filler->angle = actor->angle - ANGLE_180;
@ -9591,7 +9574,7 @@ void A_BossJetFume(mobj_t *actor)
P_SetTarget(&filler->target, actor); P_SetTarget(&filler->target, actor);
filler->fuse = 59; filler->fuse = 59;
P_SetTarget(&actor->tracer, filler); P_SetTarget(&actor->tracer, filler);
P_SetScale(filler, (filler->destscale = actor->scale/3)); P_SetScale(filler, actor->scale/3, true);
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
filler->flags2 |= MF2_OBJECTFLIP; filler->flags2 |= MF2_OBJECTFLIP;
filler->color = SKINCOLOR_ICY; filler->color = SKINCOLOR_ICY;
@ -9610,8 +9593,7 @@ void A_BossJetFume(mobj_t *actor)
{ {
P_SetTarget(&filler->target, actor); P_SetTarget(&filler->target, actor);
// Boss 4 already uses its tracer for other things // Boss 4 already uses its tracer for other things
filler->destscale = actor->scale; P_SetScale(filler, actor->scale, true);
P_SetScale(filler, filler->destscale);
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
filler->flags2 |= MF2_OBJECTFLIP; filler->flags2 |= MF2_OBJECTFLIP;
} }
@ -9633,8 +9615,7 @@ void A_BossJetFume(mobj_t *actor)
{ {
filler->movefactor = movefactor; filler->movefactor = movefactor;
P_SetTarget(&filler->target, actor); P_SetTarget(&filler->target, actor);
filler->destscale = actor->scale; P_SetScale(filler, actor->scale, true);
P_SetScale(filler, filler->destscale);
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
filler->flags2 |= MF2_OBJECTFLIP; filler->flags2 |= MF2_OBJECTFLIP;
} }
@ -9880,12 +9861,13 @@ void A_ToggleFlameJet(mobj_t* actor)
// var1 = Angle adjustment (aka orbit speed) // var1 = Angle adjustment (aka orbit speed)
// var2: // var2:
// Bits 1-10: height offset, max 1023 // Bits 1-10: height offset, max 1023
// Bits 11-16: X radius factor (max 63, default 20) // Bits 11-16: X radius factor (max 63, default 32)
// Bit 17: set if object is Nightopian Helper // Bit 17: set if object is Nightopian Helper
// Bit 18: set to define X/Y/Z rotation factor // Bit 18: set to define X/Y/Z rotation factor
// Bits 19-20: Unused // Bit 19: set to not sync scale to player
// Bit 20: Unused
// Bits 21-26: Y radius factor (max 63, default 32) // Bits 21-26: Y radius factor (max 63, default 32)
// Bits 27-32: Z radius factor (max 63, default 32) // Bits 27-32: Z radius factor (max 63, default 20)
// //
// If MF_GRENADEBOUNCE is flagged on mobj, use actor->threshold to define X/Y/Z radius factor, max 1023 each: // If MF_GRENADEBOUNCE is flagged on mobj, use actor->threshold to define X/Y/Z radius factor, max 1023 each:
// Bits 1-10: X factor // Bits 1-10: X factor
@ -9926,6 +9908,12 @@ void A_OrbitNights(mobj_t* actor)
} }
else else
{ {
if (!donotrescale)
{
P_SetScale(actor, actor->target->scale, true);
actor->old_scale = actor->target->old_scale;
}
actor->extravalue1 += var1; actor->extravalue1 += var1;
P_UnsetThingPosition(actor); P_UnsetThingPosition(actor);
{ {
@ -9953,9 +9941,6 @@ void A_OrbitNights(mobj_t* actor)
else else
actor->flags2 &= ~MF2_DONTDRAW; actor->flags2 &= ~MF2_DONTDRAW;
} }
if (!donotrescale && actor->destscale != actor->target->destscale)
actor->destscale = actor->target->destscale;
} }
} }
@ -11204,9 +11189,10 @@ void A_SetScale(mobj_t *actor)
return; return;
} }
target->destscale = locvar1; // destination scale if ((locvar2 & 65535) == 0)
if (!(locvar2 & 65535)) P_SetScale(target, locvar1, true); // this instantly changes current scale to var1 if used, if not destscale will alter scale to var1 over time
P_SetScale(target, locvar1); // this instantly changes current scale to var1 if used, if not destscale will alter scale to var1 anyway else
target->destscale = locvar1; // destination scale
} }
// Function: A_RemoteDamage // Function: A_RemoteDamage
@ -11350,8 +11336,7 @@ void A_TrapShot(mobj_t *actor)
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
missile->flags2 |= MF2_OBJECTFLIP; missile->flags2 |= MF2_OBJECTFLIP;
missile->destscale = actor->scale; P_SetScale(missile, actor->scale, true);
P_SetScale(missile, actor->scale);
if (missile->info->seesound) if (missile->info->seesound)
S_StartSound(missile, missile->info->seesound); S_StartSound(missile, missile->info->seesound);
@ -11425,8 +11410,7 @@ void A_VileTarget(mobj_t *actor)
fog->eflags |= MFE_VERTICALFLIP; fog->eflags |= MFE_VERTICALFLIP;
fog->flags2 |= MF2_OBJECTFLIP; fog->flags2 |= MF2_OBJECTFLIP;
} }
fog->destscale = actor->target->scale; P_SetScale(fog, actor->target->scale, true);
P_SetScale(fog, fog->destscale);
P_SetTarget(&actor->tracer, fog); P_SetTarget(&actor->tracer, fog);
P_SetTarget(&fog->target, actor); P_SetTarget(&fog->target, actor);
@ -11459,8 +11443,7 @@ void A_VileTarget(mobj_t *actor)
fog->eflags |= MFE_VERTICALFLIP; fog->eflags |= MFE_VERTICALFLIP;
fog->flags2 |= MF2_OBJECTFLIP; fog->flags2 |= MF2_OBJECTFLIP;
} }
fog->destscale = players[i].mo->scale; P_SetScale(fog, players[i].mo->scale, true);
P_SetScale(fog, fog->destscale);
if (players[i].mo == actor->target) // We only care to track the fog targeting who we REALLY hate right now if (players[i].mo == actor->target) // We only care to track the fog targeting who we REALLY hate right now
P_SetTarget(&actor->tracer, fog); P_SetTarget(&actor->tracer, fog);
@ -11617,8 +11600,8 @@ void A_VileFire(mobj_t *actor)
return; return;
// keep to same scale and gravity as tracer ALWAYS // keep to same scale and gravity as tracer ALWAYS
actor->destscale = dest->scale; P_SetScale(actor, dest->scale, true);
P_SetScale(actor, actor->destscale); actor->old_scale = dest->old_scale;
if (dest->eflags & MFE_VERTICALFLIP) if (dest->eflags & MFE_VERTICALFLIP)
{ {
actor->eflags |= MFE_VERTICALFLIP; actor->eflags |= MFE_VERTICALFLIP;
@ -12804,8 +12787,7 @@ void A_LightBeamReset(mobj_t *actor)
if (LUA_CallAction(A_LIGHTBEAMRESET, actor)) if (LUA_CallAction(A_LIGHTBEAMRESET, actor))
return; return;
actor->destscale = FRACUNIT + P_SignedRandom()*FRACUNIT/256; P_SetScale(actor, FRACUNIT + P_SignedRandom()*FRACUNIT/256, true);
P_SetScale(actor, actor->destscale);
if (!actor->spawnpoint) if (!actor->spawnpoint)
return; // this can't work properly welp return; // this can't work properly welp
@ -13392,7 +13374,7 @@ void A_DoNPCSkid(mobj_t *actor)
{ {
particle->tics = 10; particle->tics = 10;
P_SetScale(particle, 2*actor->scale/3); P_SetScale(particle, 2*actor->scale/3, true);
particle->destscale = actor->scale; particle->destscale = actor->scale;
P_SetObjectMomZ(particle, FRACUNIT, false); P_SetObjectMomZ(particle, FRACUNIT, false);
} }
@ -13815,7 +13797,7 @@ static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fi
continue; continue;
dust->angle = ang*i + ANGLE_90; dust->angle = ang*i + ANGLE_90;
P_SetScale(dust, FixedMul(initscale, scale)); P_SetScale(dust, FixedMul(initscale, scale), true);
dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(), scale); dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(), scale);
dust->scalespeed = scale/24; dust->scalespeed = scale/24;
P_Thrust(dust, ang*i, speed + FixedMul(P_RandomFixed(), scale)); P_Thrust(dust, ang*i, speed + FixedMul(P_RandomFixed(), scale));
@ -13956,7 +13938,8 @@ void A_DustDevilThink(mobj_t *actor)
while (layer && !P_MobjWasRemoved(layer)) { while (layer && !P_MobjWasRemoved(layer)) {
angle_t fa = layer->angle >> ANGLETOFINESHIFT; angle_t fa = layer->angle >> ANGLETOFINESHIFT;
P_MoveOrigin(layer, layer->x + 5 * FixedMul(scale, FINECOSINE(fa)), layer->y + 5 * FixedMul(scale, FINESINE(fa)), layer->z); P_MoveOrigin(layer, layer->x + 5 * FixedMul(scale, FINECOSINE(fa)), layer->y + 5 * FixedMul(scale, FINESINE(fa)), layer->z);
layer->scale = scale; P_SetScale(layer, scale, true);
layer->old_scale = actor->old_scale;
layer->angle += ANG10 / 2; layer->angle += ANG10 / 2;
layer->momx = actor->momx; layer->momx = actor->momx;
layer->momy = actor->momy; layer->momy = actor->momy;
@ -13970,8 +13953,7 @@ void A_DustDevilThink(mobj_t *actor)
if (!P_MobjWasRemoved(dust)) if (!P_MobjWasRemoved(dust))
{ {
P_SetMobjState(dust, dust->info->spawnstate + P_RandomRange(0, 2)); P_SetMobjState(dust, dust->info->spawnstate + P_RandomRange(0, 2));
dust->destscale = scale * 3; P_SetScale(dust, 3 * scale, true);
P_SetScale(dust, dust->destscale);
} }
} }
@ -13990,6 +13972,7 @@ void A_DustDevilThink(mobj_t *actor)
layer = P_SpawnMobj(px, py, pz, MT_DUSTLAYER); layer = P_SpawnMobj(px, py, pz, MT_DUSTLAYER);
if (P_MobjWasRemoved(layer)) if (P_MobjWasRemoved(layer))
continue; continue;
P_SetScale(layer, scale, true);
layer->momz = 5 * scale; layer->momz = 5 * scale;
layer->angle = ANGLE_90 + ANGLE_90*i; layer->angle = ANGLE_90 + ANGLE_90*i;
layer->extravalue1 = TICRATE * 3; layer->extravalue1 = TICRATE * 3;
@ -14610,8 +14593,7 @@ void A_MinecartSparkThink(mobj_t *actor)
continue; continue;
trail->tics = 2; trail->tics = 2;
trail->sprite = actor->sprite; trail->sprite = actor->sprite;
P_SetScale(trail, trail->scale/4); P_SetScale(trail, trail->scale/4, true);
trail->destscale = trail->scale;
} }
} }
@ -14734,8 +14716,16 @@ void A_FireShrink(mobj_t *actor)
if (LUA_CallAction(A_FIRESHRINK, actor)) if (LUA_CallAction(A_FIRESHRINK, actor))
return; return;
actor->destscale = locvar1; if (locvar2 == 0)
actor->scalespeed = FRACUNIT/locvar2; {
P_SetScale(actor, locvar1, true);
actor->scalespeed = FRACUNIT/12; // Reset scalespeed to the default
}
else
{
actor->destscale = locvar1;
actor->scalespeed = FRACUNIT/locvar2;
}
} }
// Function: A_SpawnPterabytes // Function: A_SpawnPterabytes

View file

@ -2774,8 +2774,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
mo = P_SpawnMobj(target->x, target->y, target->z, MT_EXTRALARGEBUBBLE); mo = P_SpawnMobj(target->x, target->y, target->z, MT_EXTRALARGEBUBBLE);
if (P_MobjWasRemoved(mo)) if (P_MobjWasRemoved(mo))
break; break;
mo->destscale = target->scale; P_SetScale(mo, target->scale, true);
P_SetScale(mo, mo->destscale);
P_SetMobjState(mo, mo->info->raisestate); P_SetMobjState(mo, mo->info->raisestate);
break; break;
@ -3966,8 +3965,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
mo->fuse = 8*TICRATE; mo->fuse = 8*TICRATE;
P_SetTarget(&mo->target, player->mo); P_SetTarget(&mo->target, player->mo);
mo->destscale = player->mo->scale; P_SetScale(mo, player->mo->scale, true);
P_SetScale(mo, player->mo->scale);
// Angle offset by player angle, then slightly offset by amount of rings // Angle offset by player angle, then slightly offset by amount of rings
fa = ((i*FINEANGLES/16) + va - ((num_rings-1)*FINEANGLES/32)) & FINEMASK; fa = ((i*FINEANGLES/16) + va - ((num_rings-1)*FINEANGLES/32)) & FINEMASK;
@ -4103,8 +4101,7 @@ void P_PlayerWeaponPanelBurst(player_t *player)
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
P_SetTarget(&mo->target, player->mo); P_SetTarget(&mo->target, player->mo);
mo->fuse = 12*TICRATE; mo->fuse = 12*TICRATE;
mo->destscale = player->mo->scale; P_SetScale(mo, player->mo->scale, true);
P_SetScale(mo, player->mo->scale);
// Angle offset by player angle // Angle offset by player angle
fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK;
@ -4192,8 +4189,7 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
player->powers[power] = 0; player->powers[power] = 0;
mo->fuse = 12*TICRATE; mo->fuse = 12*TICRATE;
mo->destscale = player->mo->scale; P_SetScale(mo, player->mo->scale, true);
P_SetScale(mo, player->mo->scale);
// Angle offset by player angle // Angle offset by player angle
fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK;
@ -4240,8 +4236,7 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player)
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \
P_SetTarget(&mo->target, player->mo); \ P_SetTarget(&mo->target, player->mo); \
mo->fuse = 12*TICRATE; \ mo->fuse = 12*TICRATE; \
mo->destscale = player->mo->scale; \ P_SetScale(mo, player->mo->scale, true); \
P_SetScale(mo, player->mo->scale); \
mo->momx = FixedMul(FINECOSINE(fa),ns); \ mo->momx = FixedMul(FINECOSINE(fa),ns); \
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \
mo->momy = FixedMul(FINESINE(fa),ns); \ mo->momy = FixedMul(FINESINE(fa),ns); \
@ -4263,8 +4258,7 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player)
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \
P_SetTarget(&mo->target, player->mo); \ P_SetTarget(&mo->target, player->mo); \
mo->fuse = 12*TICRATE; \ mo->fuse = 12*TICRATE; \
mo->destscale = player->mo->scale; \ P_SetScale(mo, player->mo->scale, true); \
P_SetScale(mo, player->mo->scale); \
mo->momx = FixedMul(FINECOSINE(fa),ns); \ mo->momx = FixedMul(FINECOSINE(fa),ns); \
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \
mo->momy = FixedMul(FINESINE(fa),ns); \ mo->momy = FixedMul(FINESINE(fa),ns); \

View file

@ -283,7 +283,6 @@ void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, b
extern mapthing_t *itemrespawnque[ITEMQUESIZE]; extern mapthing_t *itemrespawnque[ITEMQUESIZE];
extern tic_t itemrespawntime[ITEMQUESIZE]; extern tic_t itemrespawntime[ITEMQUESIZE];
extern size_t iquehead, iquetail; extern size_t iquehead, iquetail;
extern consvar_t cv_gravity, cv_movebob;
mobjtype_t P_GetMobjtype(UINT16 mthingtype); mobjtype_t P_GetMobjtype(UINT16 mthingtype);
@ -552,6 +551,7 @@ void P_ThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move);
void P_VectorInstaThrust(fixed_t xa, fixed_t xb, fixed_t xc, fixed_t ya, fixed_t yb, fixed_t yc, void P_VectorInstaThrust(fixed_t xa, fixed_t xb, fixed_t xc, fixed_t ya, fixed_t yb, fixed_t yc,
fixed_t za, fixed_t zb, fixed_t zc, fixed_t momentum, mobj_t *mo); fixed_t za, fixed_t zb, fixed_t zc, fixed_t momentum, mobj_t *mo);
void P_DoSuperTransformation(player_t *player, boolean giverings); void P_DoSuperTransformation(player_t *player, boolean giverings);
void P_DoSuperDetransformation(player_t *player);
void P_ExplodeMissile(mobj_t *mo); void P_ExplodeMissile(mobj_t *mo);
void P_CheckGravity(mobj_t *mo, boolean affect); void P_CheckGravity(mobj_t *mo, boolean affect);
void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope); void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope);

View file

@ -917,7 +917,7 @@ void P_ExplodeMissile(mobj_t *mo)
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo)) if (!P_MobjWasRemoved(explodemo))
{ {
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale, true);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
@ -926,7 +926,7 @@ void P_ExplodeMissile(mobj_t *mo)
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo)) if (!P_MobjWasRemoved(explodemo))
{ {
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale, true);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
@ -935,7 +935,7 @@ void P_ExplodeMissile(mobj_t *mo)
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo)) if (!P_MobjWasRemoved(explodemo))
{ {
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale, true);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
@ -944,7 +944,7 @@ void P_ExplodeMissile(mobj_t *mo)
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo)) if (!P_MobjWasRemoved(explodemo))
{ {
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale, true);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
@ -3113,8 +3113,7 @@ boolean P_SceneryZMovement(mobj_t *mo)
continue; continue;
explodemo->momx += ((prandom & 0x0F) << (FRACBITS-2)) * (i & 2 ? -1 : 1); explodemo->momx += ((prandom & 0x0F) << (FRACBITS-2)) * (i & 2 ? -1 : 1);
explodemo->momy += ((prandom & 0xF0) << (FRACBITS-6)) * (i & 1 ? -1 : 1); explodemo->momy += ((prandom & 0xF0) << (FRACBITS-6)) * (i & 1 ? -1 : 1);
explodemo->destscale = mo->scale; P_SetScale(explodemo, mo->scale, true);
P_SetScale(explodemo, mo->scale);
} }
if (mo->threshold != 42) // Don't make pop sound if threshold is 42. if (mo->threshold != 42) // Don't make pop sound if threshold is 42.
@ -3140,7 +3139,7 @@ boolean P_SceneryZMovement(mobj_t *mo)
mobj_t *flower = P_SpawnMobjFromMobj(mo, 0, 0, 0, flowertype); mobj_t *flower = P_SpawnMobjFromMobj(mo, 0, 0, 0, flowertype);
if (flower) if (flower)
{ {
P_SetScale(flower, mo->scale/16); P_SetScale(flower, mo->scale/16, true);
flower->destscale = mo->scale; flower->destscale = mo->scale;
flower->scalespeed = mo->scale/8; flower->scalespeed = mo->scale/8;
} }
@ -3380,10 +3379,7 @@ void P_MobjCheckWater(mobj_t *mobj)
else else
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype); splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype);
if (!P_MobjWasRemoved(splish)) if (!P_MobjWasRemoved(splish))
{ P_SetScale(splish, mobj->scale, true);
splish->destscale = mobj->scale;
P_SetScale(splish, mobj->scale);
}
} }
// skipping stone! // skipping stone!
@ -3422,10 +3418,7 @@ void P_MobjCheckWater(mobj_t *mobj)
else else
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype); splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype);
if (!P_MobjWasRemoved(splish)) if (!P_MobjWasRemoved(splish))
{ P_SetScale(splish, mobj->scale, true);
splish->destscale = mobj->scale;
P_SetScale(splish, mobj->scale);
}
} }
} }
@ -3476,8 +3469,7 @@ void P_MobjCheckWater(mobj_t *mobj)
else else
bubble->momz = 0; bubble->momz = 0;
bubble->destscale = mobj->scale; P_SetScale(bubble, mobj->scale, true);
P_SetScale(bubble, mobj->scale);
} }
} }
} }
@ -5147,8 +5139,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
mobj_t *smoke = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height, MT_SMOKE); mobj_t *smoke = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height, MT_SMOKE);
if (!P_MobjWasRemoved(smoke)) if (!P_MobjWasRemoved(smoke))
{ {
smoke->destscale = mobj->destscale; P_SetScale(smoke, mobj->destscale, true);
P_SetScale(smoke, smoke->destscale);
smoke->momz = FixedMul(FRACUNIT, smoke->scale); smoke->momz = FixedMul(FRACUNIT, smoke->scale);
} }
} }
@ -5599,7 +5590,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
if (mobj->hprev) if (mobj->hprev)
{ {
mobj->hprev->destscale = FRACUNIT + (2*TICRATE - mobj->fuse)*(FRACUNIT/2)/TICRATE + FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT),FRACUNIT/2); mobj->hprev->destscale = FRACUNIT + (2*TICRATE - mobj->fuse)*(FRACUNIT/2)/TICRATE + FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT),FRACUNIT/2);
P_SetScale(mobj->hprev, mobj->hprev->destscale); P_SetScale(mobj->hprev, mobj->hprev->destscale, false);
P_MoveOrigin(mobj->hprev, mobj->x, mobj->y, mobj->z + mobj->height/2 - mobj->hprev->height/2); P_MoveOrigin(mobj->hprev, mobj->x, mobj->y, mobj->z + mobj->height/2 - mobj->hprev->height/2);
mobj->hprev->momx = mobj->momx; mobj->hprev->momx = mobj->momx;
@ -5625,8 +5616,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
{ {
S_StopSound(missile); S_StopSound(missile);
if (mobj->extravalue1 >= 2) if (mobj->extravalue1 >= 2)
P_SetScale(missile, FRACUNIT>>1); P_SetScale(missile, FRACUNIT/2, true);
missile->destscale = missile->scale>>1; missile->destscale = missile->scale/2;
missile->fuse = TICRATE/2; missile->fuse = TICRATE/2;
missile->scalespeed = abs(missile->destscale - missile->scale)/missile->fuse; missile->scalespeed = abs(missile->destscale - missile->scale)/missile->fuse;
missile->z -= missile->height/2; missile->z -= missile->height/2;
@ -5649,7 +5640,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
spread->angle = missile->angle+(ANGLE_11hh/2)*(i-2); spread->angle = missile->angle+(ANGLE_11hh/2)*(i-2);
P_InstaThrust(spread,spread->angle,-spread->info->speed); P_InstaThrust(spread,spread->angle,-spread->info->speed);
spread->momz = missile->momz; spread->momz = missile->momz;
P_SetScale(spread, missile->scale); P_SetScale(spread, missile->scale, true);
spread->destscale = missile->destscale; spread->destscale = missile->destscale;
spread->scalespeed = missile->scalespeed; spread->scalespeed = missile->scalespeed;
spread->fuse = missile->fuse; spread->fuse = missile->fuse;
@ -5673,7 +5664,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
spread = P_SpawnMissile(mobj, mobj->target, missile->type); spread = P_SpawnMissile(mobj, mobj->target, missile->type);
if (P_MobjWasRemoved(spread)) if (P_MobjWasRemoved(spread))
continue; continue;
P_SetScale(spread, missile->scale); P_SetScale(spread, missile->scale, true);
spread->destscale = missile->destscale; spread->destscale = missile->destscale;
spread->fuse = missile->fuse; spread->fuse = missile->fuse;
spread->z -= spread->height/2; spread->z -= spread->height/2;
@ -5730,12 +5721,12 @@ static void P_Boss9Thinker(mobj_t *mobj)
{ {
if (mobj->health > mobj->info->damage) if (mobj->health > mobj->info->damage)
{ {
P_SetScale(missile, FRACUNIT/3); P_SetScale(missile, FRACUNIT/3, true);
missile->color = SKINCOLOR_MAGENTA; // sonic OVA/4 purple power missile->color = SKINCOLOR_MAGENTA; // sonic OVA/4 purple power
} }
else else
{ {
P_SetScale(missile, FRACUNIT/5); P_SetScale(missile, FRACUNIT/5, true);
missile->color = SKINCOLOR_SUNSET; // sonic cd electric power missile->color = SKINCOLOR_SUNSET; // sonic cd electric power
} }
missile->destscale = missile->scale*2; missile->destscale = missile->scale*2;
@ -5798,10 +5789,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
if (!P_MobjWasRemoved(missile)) if (!P_MobjWasRemoved(missile))
{ {
if (mobj->extravalue1 >= 2) if (mobj->extravalue1 >= 2)
{ P_SetScale(missile, FRACUNIT/2, true);
missile->destscale = FRACUNIT>>1;
P_SetScale(missile, missile->destscale);
}
missile->fuse = 3*TICRATE; missile->fuse = 3*TICRATE;
missile->z -= missile->height/2; missile->z -= missile->height/2;
@ -5820,8 +5808,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
spread->angle = missile->angle+(ANGLE_11hh/2)*(i-2); spread->angle = missile->angle+(ANGLE_11hh/2)*(i-2);
P_InstaThrust(spread,spread->angle,spread->info->speed); P_InstaThrust(spread,spread->angle,spread->info->speed);
spread->momz = missile->momz; spread->momz = missile->momz;
spread->destscale = FRACUNIT>>1; P_SetScale(spread, FRACUNIT/2, true);
P_SetScale(spread, spread->destscale);
spread->fuse = missile->fuse; spread->fuse = missile->fuse;
} }
P_InstaThrust(missile,missile->angle,missile->info->speed); P_InstaThrust(missile,missile->angle,missile->info->speed);
@ -5838,8 +5825,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
spread = P_SpawnMissile(mobj, mobj->target, missile->type); spread = P_SpawnMissile(mobj, mobj->target, missile->type);
if (!P_MobjWasRemoved(spread)) if (!P_MobjWasRemoved(spread))
{ {
spread->destscale = FRACUNIT>>1; P_SetScale(spread, FRACUNIT/2, true);
P_SetScale(spread, spread->destscale);
spread->fuse = missile->fuse; spread->fuse = missile->fuse;
spread->z -= spread->height/2; spread->z -= spread->height/2;
} }
@ -6103,8 +6089,12 @@ static void P_Boss9Thinker(mobj_t *mobj)
whoosh->flags |= MF_NOCLIPHEIGHT; whoosh->flags |= MF_NOCLIPHEIGHT;
#endif #endif
P_SetMobjState(mobj->tracer, S_JETFUMEFLASH); if (!P_MobjWasRemoved(mobj->tracer))
P_SetScale(mobj->tracer, mobj->scale << 1); {
P_SetMobjState(mobj->tracer, S_JETFUMEFLASH);
P_SetScale(mobj->tracer, 2*mobj->scale, false);
mobj->tracer->old_scale = mobj->tracer->scale;
}
} }
else else
{ {
@ -6439,28 +6429,24 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb
// //
// Sets the sprite scaling // Sets the sprite scaling
// //
void P_SetScale(mobj_t *mobj, fixed_t newscale) void P_SetScale(mobj_t *mobj, fixed_t newscale, boolean instant)
{ {
player_t *player;
fixed_t oldscale;
if (!mobj) if (!mobj)
return; return;
oldscale = mobj->scale; //keep for adjusting stuff below if (mobj->player)
mobj->scale = newscale;
mobj->radius = FixedMul(FixedDiv(mobj->radius, oldscale), newscale);
mobj->height = FixedMul(FixedDiv(mobj->height, oldscale), newscale);
player = mobj->player;
if (player)
{ {
G_GhostAddScale(newscale); G_GhostAddScale(newscale);
player->viewheight = FixedMul(FixedDiv(player->viewheight, oldscale), newscale); // Nonono don't calculate viewheight elsewhere, this is the best place for it! // Nonono don't calculate viewheight elsewhere, this is the best place for it!
mobj->player->viewheight = FixedMul(FixedDiv(mobj->player->viewheight, mobj->scale), newscale);
} }
mobj->radius = FixedMul(FixedDiv(mobj->radius, mobj->scale), newscale);
mobj->height = FixedMul(FixedDiv(mobj->height, mobj->scale), newscale);
mobj->scale = newscale;
if (instant)
mobj->destscale = mobj->old_scale = newscale;
} }
void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on your target void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on your target
@ -6815,8 +6801,7 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
thing->flags |= MF_NOCLIPHEIGHT; thing->flags |= MF_NOCLIPHEIGHT;
thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP); thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP);
P_SetScale(thing, FixedMul(thing->target->scale, thing->target->player->shieldscale)); P_SetScale(thing, FixedMul(thing->target->scale, thing->target->player->shieldscale), true);
thing->destscale = thing->scale;
thing->old_scale = FixedMul(thing->target->old_scale, thing->target->player->shieldscale); thing->old_scale = FixedMul(thing->target->old_scale, thing->target->player->shieldscale);
#define NewMH(mobj) mobj->height // Ugly mobj-height and player-height defines, for the sake of prettier code #define NewMH(mobj) mobj->height // Ugly mobj-height and player-height defines, for the sake of prettier code
@ -7164,11 +7149,11 @@ static void P_MobjScaleThink(mobj_t *mobj)
correctionType = 2; // Correct Z position by moving down correctionType = 2; // Correct Z position by moving down
if (abs(mobj->scale - mobj->destscale) < mobj->scalespeed) if (abs(mobj->scale - mobj->destscale) < mobj->scalespeed)
P_SetScale(mobj, mobj->destscale); P_SetScale(mobj, mobj->destscale, false);
else if (mobj->scale < mobj->destscale) else if (mobj->scale < mobj->destscale)
P_SetScale(mobj, mobj->scale + mobj->scalespeed); P_SetScale(mobj, mobj->scale + mobj->scalespeed, false);
else if (mobj->scale > mobj->destscale) else if (mobj->scale > mobj->destscale)
P_SetScale(mobj, mobj->scale - mobj->scalespeed); P_SetScale(mobj, mobj->scale - mobj->scalespeed, false);
if (correctionType == 1) if (correctionType == 1)
mobj->z -= (mobj->height - oldheight)/2; mobj->z -= (mobj->height - oldheight)/2;
@ -7261,8 +7246,9 @@ static boolean P_DrownNumbersSceneryThink(mobj_t *mobj)
mobj->x = mobj->target->x; mobj->x = mobj->target->x;
mobj->y = mobj->target->y; mobj->y = mobj->target->y;
P_SetScale(mobj, mobj->target->scale, false);
mobj->destscale = mobj->target->destscale; mobj->destscale = mobj->target->destscale;
P_SetScale(mobj, mobj->target->scale); mobj->old_scale = mobj->target->old_scale;
if (mobj->target->eflags & MFE_VERTICALFLIP) if (mobj->target->eflags & MFE_VERTICALFLIP)
{ {
@ -7423,10 +7409,10 @@ static boolean P_ParticleGenSceneryThink(mobj_t *mobj)
(mobjtype_t)mobj->threshold); (mobjtype_t)mobj->threshold);
if (!P_MobjWasRemoved(spawn)) if (!P_MobjWasRemoved(spawn))
{ {
P_SetScale(spawn, mobj->scale); P_SetScale(spawn, mobj->scale, true);
spawn->momz = FixedMul(mobj->movefactor, spawn->scale);
spawn->destscale = spawn->scale/100; spawn->destscale = spawn->scale/100;
spawn->scalespeed = spawn->scale/mobj->health; spawn->scalespeed = spawn->scale/mobj->health;
spawn->momz = FixedMul(mobj->movefactor, spawn->scale);
spawn->tics = (tic_t)mobj->health; spawn->tics = (tic_t)mobj->health;
spawn->flags2 |= (mobj->flags2 & MF2_OBJECTFLIP); spawn->flags2 |= (mobj->flags2 & MF2_OBJECTFLIP);
spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
@ -7646,8 +7632,7 @@ static void P_RosySceneryThink(mobj_t *mobj)
mobj_t *cdlhrt = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_CDLHRT); mobj_t *cdlhrt = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_CDLHRT);
if (!P_MobjWasRemoved(cdlhrt)) if (!P_MobjWasRemoved(cdlhrt))
{ {
cdlhrt->destscale = (5*mobj->scale) >> 4; P_SetScale(cdlhrt, (5*mobj->scale) >> 4, true);
P_SetScale(cdlhrt, cdlhrt->destscale);
cdlhrt->fuse = (5*TICRATE) >> 1; cdlhrt->fuse = (5*TICRATE) >> 1;
cdlhrt->momz = mobj->scale; cdlhrt->momz = mobj->scale;
P_SetTarget(&cdlhrt->target, mobj); P_SetTarget(&cdlhrt->target, mobj);
@ -7901,8 +7886,9 @@ static void P_MobjSceneryThink(mobj_t *mobj)
mobj->eflags |= (mobj->target->eflags & MFE_VERTICALFLIP); mobj->eflags |= (mobj->target->eflags & MFE_VERTICALFLIP);
P_SetScale(mobj, mobj->target->scale, false);
mobj->destscale = mobj->target->destscale; mobj->destscale = mobj->target->destscale;
P_SetScale(mobj, mobj->target->scale); mobj->old_scale = mobj->target->old_scale;
if (!(mobj->eflags & MFE_VERTICALFLIP)) if (!(mobj->eflags & MFE_VERTICALFLIP))
mobj->z = mobj->target->z + mobj->target->height + FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale); mobj->z = mobj->target->z + mobj->target->height + FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale);
@ -8052,7 +8038,9 @@ static void P_MobjSceneryThink(mobj_t *mobj)
} }
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
P_SetScale(mobj, mobj->target->scale); P_SetScale(mobj, mobj->target->scale, false);
mobj->destscale = mobj->target->destscale;
mobj->old_scale = mobj->target->old_scale;
} }
break; break;
case MT_TUTORIALFLOWER: case MT_TUTORIALFLOWER:
@ -8494,8 +8482,8 @@ static void P_ArrowThink(mobj_t *mobj)
if (!P_MobjWasRemoved(dust)) if (!P_MobjWasRemoved(dust))
{ {
dust->tics = 18; dust->tics = 18;
dust->scalespeed = 4096;
dust->destscale = FRACUNIT/32; dust->destscale = FRACUNIT/32;
dust->scalespeed = FRACUNIT/16;
} }
} }
} }
@ -9906,9 +9894,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
traindust->frame = P_RandomRange(0, 8)|FF_TRANS90; traindust->frame = P_RandomRange(0, 8)|FF_TRANS90;
traindust->angle = mobj->angle; traindust->angle = mobj->angle;
traindust->tics = TICRATE*4; traindust->tics = TICRATE*4;
P_SetScale(traindust, FRACUNIT*6, true);
traindust->destscale = FRACUNIT*64; traindust->destscale = FRACUNIT*64;
traindust->scalespeed = FRACUNIT/24; traindust->scalespeed = FRACUNIT/24;
P_SetScale(traindust, FRACUNIT*6);
} }
break; break;
case MT_TRAINSTEAMSPAWNER: case MT_TRAINSTEAMSPAWNER:
@ -9919,9 +9907,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_SetMobjState(steam, S_TRAINSTEAM); P_SetMobjState(steam, S_TRAINSTEAM);
steam->frame = P_RandomRange(0, 1)|FF_TRANS90; steam->frame = P_RandomRange(0, 1)|FF_TRANS90;
steam->tics = TICRATE*8; steam->tics = TICRATE*8;
P_SetScale(steam, FRACUNIT*16, true);
steam->destscale = FRACUNIT*64; steam->destscale = FRACUNIT*64;
steam->scalespeed = FRACUNIT/8; steam->scalespeed = FRACUNIT/8;
P_SetScale(steam, FRACUNIT*16);
steam->momx = P_SignedRandom()*32; steam->momx = P_SignedRandom()*32;
steam->momy = -64*FRACUNIT; steam->momy = -64*FRACUNIT;
steam->momz = 2*FRACUNIT; steam->momz = 2*FRACUNIT;
@ -10929,7 +10917,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
if (titlemapinaction) mobj->flags &= ~MF_NOTHINK; if (titlemapinaction) mobj->flags &= ~MF_NOTHINK;
break; break;
case MT_LOCKONINF: case MT_LOCKONINF:
P_SetScale(mobj, (mobj->destscale = 3*mobj->scale)); P_SetScale(mobj, 3*mobj->scale, true);
break; break;
case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE:
mobj->fuse = mobj->info->painchance; mobj->fuse = mobj->info->painchance;
@ -10940,8 +10928,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
if (P_MobjWasRemoved(spawn)) if (P_MobjWasRemoved(spawn))
break; break;
spawn->destscale = mobj->scale; P_SetScale(spawn, mobj->scale, true);
P_SetScale(spawn, mobj->scale);
P_SetTarget(&spawn->target, mobj); P_SetTarget(&spawn->target, mobj);
} }
break; break;
@ -10958,8 +10945,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
if (P_MobjWasRemoved(spawn)) if (P_MobjWasRemoved(spawn))
break; break;
spawn->destscale = mobj->scale; P_SetScale(spawn, mobj->scale, true);
P_SetScale(spawn, mobj->scale);
P_SetTarget(&mobj->tracer, spawn); P_SetTarget(&mobj->tracer, spawn);
P_SetTarget(&spawn->target, mobj); P_SetTarget(&spawn->target, mobj);
} }
@ -10976,8 +10962,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
if (P_MobjWasRemoved(ball)) if (P_MobjWasRemoved(ball))
continue; continue;
ball->destscale = mobj->scale; P_SetScale(ball, mobj->scale, true);
P_SetScale(ball, mobj->scale);
P_SetTarget(&ball->target, mobj); P_SetTarget(&ball->target, mobj);
ball->movedir = FixedAngle(FixedMul(FixedDiv(i<<FRACBITS, mobj->info->damage<<FRACBITS), 360<<FRACBITS)); ball->movedir = FixedAngle(FixedMul(FixedDiv(i<<FRACBITS, mobj->info->damage<<FRACBITS), 360<<FRACBITS));
ball->threshold = ball->radius + mobj->radius + FixedMul(ball->info->painchance, ball->scale); ball->threshold = ball->radius + mobj->radius + FixedMul(ball->info->painchance, ball->scale);
@ -10998,8 +10983,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
if (P_MobjWasRemoved(ball)) if (P_MobjWasRemoved(ball))
continue; continue;
ball->destscale = mobj->scale; P_SetScale(ball, mobj->scale, true);
P_SetScale(ball, mobj->scale);
P_SetTarget(&lastball->tracer, ball); P_SetTarget(&lastball->tracer, ball);
P_SetTarget(&ball->target, mobj); P_SetTarget(&ball->target, mobj);
lastball = ball; lastball = ball;
@ -11858,7 +11842,7 @@ void P_SpawnPlayer(INT32 playernum)
p->awayviewtics = 0; p->awayviewtics = 0;
// set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't. // set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't.
P_SetScale(mobj, mobj->destscale); P_SetScale(mobj, mobj->destscale, true);
P_FlashPal(p, 0, 0); // Resets P_FlashPal(p, 0, 0); // Resets
// Set bounds accurately. // Set bounds accurately.
@ -12032,7 +12016,7 @@ void P_MovePlayerToStarpost(INT32 playernum)
z = p->starpostz << FRACBITS; z = p->starpostz << FRACBITS;
P_SetScale(mobj, (mobj->destscale = abs(p->starpostscale))); P_SetScale(mobj, abs(p->starpostscale), true);
if (p->starpostscale < 0) if (p->starpostscale < 0)
{ {
@ -13140,8 +13124,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
if (P_MobjWasRemoved(corona)) if (P_MobjWasRemoved(corona))
break; break;
P_SetScale(corona, (corona->destscale = mobj->scale*3));
P_SetTarget(&mobj->tracer, corona); P_SetTarget(&mobj->tracer, corona);
P_SetScale(corona, 3*mobj->scale, true);
} }
break; break;
case MT_FLAMEHOLDER: case MT_FLAMEHOLDER:
@ -13159,8 +13143,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
if (P_MobjWasRemoved(corona)) if (P_MobjWasRemoved(corona))
break; break;
P_SetScale(corona, (corona->destscale = flame->scale*3));
P_SetTarget(&flame->tracer, corona); P_SetTarget(&flame->tracer, corona);
P_SetScale(corona, 3*flame->scale, true);
} }
} }
break; break;
@ -13248,10 +13232,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
case MT_DSZSTALAGMITE: case MT_DSZSTALAGMITE:
case MT_DSZ2STALAGMITE: case MT_DSZ2STALAGMITE:
case MT_KELP: case MT_KELP:
if (mthing->args[0]) { // make mobj twice as big as normal if (mthing->args[0]) // make mobj twice as big as normal
P_SetScale(mobj, 2*mobj->scale); // not 2*FRACUNIT in case of something like the old ERZ3 mode P_SetScale(mobj, 2*mobj->scale, true); // not 2*FRACUNIT in case of something like the old ERZ3 mode
mobj->destscale = mobj->scale;
}
break; break;
case MT_THZTREE: case MT_THZTREE:
{ // Spawn the branches { // Spawn the branches
@ -13330,10 +13312,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
case MT_LAVAFALL: case MT_LAVAFALL:
mobj->fuse = 30 + mthing->args[0]; mobj->fuse = 30 + mthing->args[0];
if (mthing->args[1]) if (mthing->args[1])
{ P_SetScale(mobj, 2*mobj->scale, true);
P_SetScale(mobj, 2*mobj->scale);
mobj->destscale = mobj->scale;
}
break; break;
case MT_PYREFLY: case MT_PYREFLY:
//start on fire if args[0], otherwise behave normally //start on fire if args[0], otherwise behave normally
@ -13396,8 +13375,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
break; break;
P_SetTarget(&elecmobj->target, mobj); P_SetTarget(&elecmobj->target, mobj);
elecmobj->angle = FixedAngle(mthing->angle << FRACBITS); elecmobj->angle = FixedAngle(mthing->angle << FRACBITS);
elecmobj->destscale = mobj->scale*2; P_SetScale(elecmobj, 2*mobj->scale, true);
P_SetScale(elecmobj, elecmobj->destscale);
} }
break; break;
case MT_STARPOST: case MT_STARPOST:
@ -13455,8 +13433,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
return false; return false;
} }
base->angle = mobjangle + ANGLE_90; base->angle = mobjangle + ANGLE_90;
P_SetScale(base, mobj->scale, true);
base->destscale = mobj->destscale; base->destscale = mobj->destscale;
P_SetScale(base, mobj->scale);
P_SetTarget(&base->target, mobj); P_SetTarget(&base->target, mobj);
P_SetTarget(&mobj->tracer, base); P_SetTarget(&mobj->tracer, base);
} }
@ -13633,8 +13611,9 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
return NULL; return NULL;
mobj->spawnpoint = mthing; mobj->spawnpoint = mthing;
P_SetScale(mobj, FixedMul(mobj->scale, mthing->scale)); P_SetScale(mobj, FixedMul(mobj->scale, mthing->scale), false);
mobj->destscale = FixedMul(mobj->destscale, mthing->scale); mobj->destscale = FixedMul(mobj->destscale, mthing->scale);
mobj->old_scale = FixedMul(mobj->old_scale, mthing->scale);
mobj->spritexscale = mthing->spritexscale; mobj->spritexscale = mthing->spritexscale;
mobj->spriteyscale = mthing->spriteyscale; mobj->spriteyscale = mthing->spriteyscale;
@ -14088,8 +14067,7 @@ mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type,
if (source->eflags & MFE_VERTICALFLIP) if (source->eflags & MFE_VERTICALFLIP)
th->flags2 |= MF2_OBJECTFLIP; th->flags2 |= MF2_OBJECTFLIP;
th->destscale = source->scale; P_SetScale(th, source->scale, true);
P_SetScale(th, source->scale);
speed = FixedMul(th->info->speed, th->scale); speed = FixedMul(th->info->speed, th->scale);
@ -14152,8 +14130,7 @@ mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t
if (source->eflags & MFE_VERTICALFLIP) if (source->eflags & MFE_VERTICALFLIP)
th->flags2 |= MF2_OBJECTFLIP; th->flags2 |= MF2_OBJECTFLIP;
th->destscale = source->scale; P_SetScale(th, source->scale, true);
P_SetScale(th, source->scale);
speed = FixedMul(th->info->speed, th->scale); speed = FixedMul(th->info->speed, th->scale);
@ -14219,8 +14196,7 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za,
if (source->eflags & MFE_VERTICALFLIP) if (source->eflags & MFE_VERTICALFLIP)
th->flags2 |= MF2_OBJECTFLIP; th->flags2 |= MF2_OBJECTFLIP;
th->destscale = source->scale; P_SetScale(th, source->scale, true);
P_SetScale(th, source->scale);
speed = FixedMul(th->info->speed, th->scale); speed = FixedMul(th->info->speed, th->scale);
@ -14291,8 +14267,7 @@ mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type)
if (source->eflags & MFE_VERTICALFLIP) if (source->eflags & MFE_VERTICALFLIP)
th->flags2 |= MF2_OBJECTFLIP; th->flags2 |= MF2_OBJECTFLIP;
th->destscale = source->scale; P_SetScale(th, source->scale, true);
P_SetScale(th, source->scale);
if (source->type == MT_METALSONIC_BATTLE && source->health < 4) if (source->type == MT_METALSONIC_BATTLE && source->health < 4)
speed = FixedMul(FixedMul(th->info->speed, 3*FRACUNIT/2), th->scale); speed = FixedMul(FixedMul(th->info->speed, 3*FRACUNIT/2), th->scale);
@ -14394,8 +14369,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai
if (source->eflags & MFE_VERTICALFLIP) if (source->eflags & MFE_VERTICALFLIP)
th->flags2 |= MF2_OBJECTFLIP; th->flags2 |= MF2_OBJECTFLIP;
th->destscale = source->scale; P_SetScale(th, source->scale, true);
P_SetScale(th, source->scale);
th->flags2 |= flags2; th->flags2 |= flags2;
@ -14477,8 +14451,8 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
newmobj->old_z2 = mobj->old_z2 + zofs; newmobj->old_z2 = mobj->old_z2 + zofs;
} }
P_SetScale(newmobj, mobj->scale, false);
newmobj->destscale = mobj->destscale; newmobj->destscale = mobj->destscale;
P_SetScale(newmobj, mobj->scale);
newmobj->old_x2 = mobj->old_x2 + xofs; newmobj->old_x2 = mobj->old_x2 + xofs;
newmobj->old_y2 = mobj->old_y2 + yofs; newmobj->old_y2 = mobj->old_y2 + yofs;
@ -14507,9 +14481,13 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
newmobj->old_scale2 = mobj->old_scale2; newmobj->old_scale2 = mobj->old_scale2;
newmobj->old_scale = mobj->old_scale; newmobj->old_scale = mobj->old_scale;
newmobj->old_spritexscale2 = mobj->old_spritexscale2;
newmobj->old_spritexscale = mobj->old_spritexscale; newmobj->old_spritexscale = mobj->old_spritexscale;
newmobj->old_spriteyscale2 = mobj->old_spriteyscale2;
newmobj->old_spriteyscale = mobj->old_spriteyscale; newmobj->old_spriteyscale = mobj->old_spriteyscale;
newmobj->old_spritexoffset2 = mobj->old_spritexoffset2;
newmobj->old_spritexoffset = mobj->old_spritexoffset; newmobj->old_spritexoffset = mobj->old_spritexoffset;
newmobj->old_spriteyoffset2 = mobj->old_spriteyoffset2;
newmobj->old_spriteyoffset = mobj->old_spriteyoffset; newmobj->old_spriteyoffset = mobj->old_spriteyoffset;
return newmobj; return newmobj;

View file

@ -316,8 +316,8 @@ typedef struct mobj_s
fixed_t alpha; // alpha fixed_t alpha; // alpha
fixed_t spritexscale, spriteyscale; fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset; fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale; fixed_t old_spritexscale, old_spriteyscale, old_spritexscale2, old_spriteyscale2;
fixed_t old_spritexoffset, old_spriteyoffset; fixed_t old_spritexoffset, old_spriteyoffset, old_spritexoffset2, old_spriteyoffset2;
struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by
struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
@ -460,8 +460,8 @@ typedef struct precipmobj_s
fixed_t alpha; // alpha fixed_t alpha; // alpha
fixed_t spritexscale, spriteyscale; fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset; fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale; fixed_t old_spritexscale, old_spriteyscale, old_spritexscale2, old_spriteyscale2;
fixed_t old_spritexoffset, old_spriteyoffset; fixed_t old_spritexoffset, old_spriteyoffset, old_spritexoffset2, old_spriteyoffset2;
struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by
struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
@ -529,7 +529,7 @@ void P_SnowThinker(precipmobj_t *mobj);
void P_RainThinker(precipmobj_t *mobj); void P_RainThinker(precipmobj_t *mobj);
void P_NullPrecipThinker(precipmobj_t *mobj); void P_NullPrecipThinker(precipmobj_t *mobj);
void P_RemovePrecipMobj(precipmobj_t *mobj); void P_RemovePrecipMobj(precipmobj_t *mobj);
void P_SetScale(mobj_t *mobj, fixed_t newscale); void P_SetScale(mobj_t *mobj, fixed_t newscale, boolean instant);
void P_XYMovement(mobj_t *mo); void P_XYMovement(mobj_t *mo);
void P_RingXYMovement(mobj_t *mo); void P_RingXYMovement(mobj_t *mo);
void P_SceneryXYMovement(mobj_t *mo); void P_SceneryXYMovement(mobj_t *mo);

View file

@ -3328,8 +3328,6 @@ static void P_InitializeSeg(seg_t *seg)
seg->lightmaps = NULL; // list of static lightmap for this seg seg->lightmaps = NULL; // list of static lightmap for this seg
#endif #endif
seg->numlights = 0;
seg->rlights = NULL;
seg->polyseg = NULL; seg->polyseg = NULL;
seg->dontrenderme = false; seg->dontrenderme = false;
} }

View file

@ -1378,7 +1378,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
// P_DoSuperDetransformation // P_DoSuperDetransformation
// //
// Detransform into regular Sonic! // Detransform into regular Sonic!
static void P_DoSuperDetransformation(player_t *player) void P_DoSuperDetransformation(player_t *player)
{ {
player->powers[pw_emeralds] = 0; // lost the power stones player->powers[pw_emeralds] = 0; // lost the power stones
P_SpawnGhostMobj(player->mo); P_SpawnGhostMobj(player->mo);
@ -2038,8 +2038,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
P_SetTarget(&ghost->target, mobj); P_SetTarget(&ghost->target, mobj);
P_SetTarget(&ghost->dontdrawforviewmobj, mobj); // Hide the ghost in first-person P_SetTarget(&ghost->dontdrawforviewmobj, mobj); // Hide the ghost in first-person
P_SetScale(ghost, mobj->scale); P_SetScale(ghost, mobj->scale, true);
ghost->destscale = mobj->scale;
if (mobj->eflags & MFE_VERTICALFLIP) if (mobj->eflags & MFE_VERTICALFLIP)
{ {
@ -2099,6 +2098,11 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->old_pitch = mobj->old_pitch2; ghost->old_pitch = mobj->old_pitch2;
ghost->old_roll = mobj->old_roll2; ghost->old_roll = mobj->old_roll2;
ghost->old_spriteroll = mobj->old_spriteroll2; ghost->old_spriteroll = mobj->old_spriteroll2;
ghost->old_spritexscale = mobj->old_spritexscale2;
ghost->old_spriteyscale = mobj->old_spriteyscale2;
ghost->old_spritexoffset = mobj->old_spritexoffset2;
ghost->old_spriteyoffset = mobj->old_spriteyoffset2;
ghost->old_scale = mobj->old_scale2;
return ghost; return ghost;
} }
@ -2154,7 +2158,7 @@ void P_SpawnThokMobj(player_t *player)
mobj->eflags |= (player->mo->eflags & MFE_VERTICALFLIP); mobj->eflags |= (player->mo->eflags & MFE_VERTICALFLIP);
// scale // scale
P_SetScale(mobj, (mobj->destscale = player->mo->scale)); P_SetScale(mobj, player->mo->scale, true);
if (type == MT_THOK) // spintrail-specific modification for MT_THOK if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{ {
@ -2218,8 +2222,7 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type)
mobj->eflags |= (player->mo->eflags & MFE_VERTICALFLIP); mobj->eflags |= (player->mo->eflags & MFE_VERTICALFLIP);
// scale // scale
P_SetScale(mobj, player->mo->scale); P_SetScale(mobj, player->mo->scale, true);
mobj->destscale = player->mo->scale;
if (type == MT_THOK) // spintrail-specific modification for MT_THOK if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{ {
@ -3042,9 +3045,8 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft); P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft);
P_SetTarget(&numbermobj->target, player->mo); P_SetTarget(&numbermobj->target, player->mo);
P_SetScale(numbermobj, player->mo->scale, true);
numbermobj->threshold = 40; numbermobj->threshold = 40;
numbermobj->destscale = player->mo->scale;
P_SetScale(numbermobj, player->mo->scale);
} }
} }
} }
@ -3106,10 +3108,7 @@ static void P_CheckInvincibilityTimer(player_t *player)
{ {
mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP);
if (!P_MobjWasRemoved(sparkle)) if (!P_MobjWasRemoved(sparkle))
{ P_SetScale(sparkle, player->mo->scale, true);
sparkle->destscale = player->mo->scale;
P_SetScale(sparkle, player->mo->scale);
}
} }
// Resume normal music stuff. // Resume normal music stuff.
@ -3184,8 +3183,7 @@ static void P_DoBubbleBreath(player_t *player)
if (bubble) if (bubble)
{ {
bubble->threshold = 42; bubble->threshold = 42;
bubble->destscale = player->mo->scale; P_SetScale(bubble, player->mo->scale, true);
P_SetScale(bubble, bubble->destscale);
} }
// Tails stirs up the water while flying in it // Tails stirs up the water while flying in it
@ -3207,20 +3205,14 @@ static void P_DoBubbleBreath(player_t *player)
player->mo->y + stirwatery, player->mo->y + stirwatery,
stirwaterz, MT_SMALLBUBBLE); stirwaterz, MT_SMALLBUBBLE);
if (!P_MobjWasRemoved(bubble)) if (!P_MobjWasRemoved(bubble))
{ P_SetScale(bubble, player->mo->scale, true);
bubble->destscale = player->mo->scale;
P_SetScale(bubble,bubble->destscale);
}
bubble = P_SpawnMobj( bubble = P_SpawnMobj(
player->mo->x - stirwaterx, player->mo->x - stirwaterx,
player->mo->y - stirwatery, player->mo->y - stirwatery,
stirwaterz, MT_SMALLBUBBLE); stirwaterz, MT_SMALLBUBBLE);
if (!P_MobjWasRemoved(bubble)) if (!P_MobjWasRemoved(bubble))
{ P_SetScale(bubble, player->mo->scale, true);
bubble->destscale = player->mo->scale;
P_SetScale(bubble,bubble->destscale);
}
} }
} }
@ -4190,16 +4182,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
I_Assert(player != NULL); I_Assert(player != NULL);
I_Assert(!P_MobjWasRemoved(player->mo)); I_Assert(!P_MobjWasRemoved(player->mo));
// Toss a flag
if (cmd->buttons & BT_TOSSFLAG && G_GametypeHasTeams()
&& !(player->powers[pw_super]) && !(player->tossdelay))
{
if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
P_PlayerEmeraldBurst(player, true); // Toss emeralds
else
P_PlayerFlagBurst(player, true);
}
if (!(cmd->buttons & (BT_ATTACK|BT_FIRENORMAL))) if (!(cmd->buttons & (BT_ATTACK|BT_FIRENORMAL)))
{ {
@ -4209,7 +4191,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
return; return;
} }
if (player->pflags & PF_ATTACKDOWN || player->climbing) if (player->pflags & PF_ATTACKDOWN || player->climbing || (G_TagGametype() && !(player->pflags & PF_TAGIT)))
return; return;
// Fire a fireball if we have the Fire Flower powerup! // Fire a fireball if we have the Fire Flower powerup!
@ -4225,7 +4207,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
} }
// No ringslinging outside of ringslinger! // No ringslinging outside of ringslinger!
if (!G_RingSlingerGametype() || player->weapondelay || (G_TagGametype() && !(player->pflags & PF_TAGIT))) if (!G_RingSlingerGametype() || player->weapondelay)
return; return;
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
@ -4425,10 +4407,7 @@ static void P_DoSuperStuff(player_t *player)
{ {
spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK); spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK);
if (!P_MobjWasRemoved(spark)) if (!P_MobjWasRemoved(spark))
{ P_SetScale(spark, player->mo->scale, true);
spark->destscale = player->mo->scale;
P_SetScale(spark, player->mo->scale);
}
} }
// Ran out of rings while super! // Ran out of rings while super!
@ -4453,14 +4432,14 @@ boolean P_SuperReady(player_t *player, boolean transform)
|| !ALL7EMERALDS(emeralds) || !ALL7EMERALDS(emeralds)
|| !(player->rings >= 50))) || !(player->rings >= 50)))
return false; return false;
if (player->mo if (player->mo
&& !player->powers[pw_tailsfly] && !player->powers[pw_tailsfly]
&& !player->powers[pw_carry] && !player->powers[pw_carry]
&& (player->charflags & SF_SUPER) && (player->charflags & SF_SUPER)
&& !P_PlayerInPain(player) && !P_PlayerInPain(player)
&& !player->climbing && !player->climbing
&& !(player->pflags & (PF_FULLSTASIS|PF_THOKKED|PF_STARTDASH|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) && !(player->pflags & (PF_JUMPSTASIS|PF_THOKKED|PF_STARTDASH|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY))
&& ((player->pflags & PF_JUMPED) || (P_IsObjectOnGround(player->mo) && (player->panim == PA_IDLE || player->panim == PA_EDGE && ((player->pflags & PF_JUMPED) || (P_IsObjectOnGround(player->mo) && (player->panim == PA_IDLE || player->panim == PA_EDGE
|| player->panim == PA_WALK || player->panim == PA_RUN || (player->charflags & SF_DASHMODE && player->panim == PA_DASH)))) || player->panim == PA_WALK || player->panim == PA_RUN || (player->charflags & SF_DASHMODE && player->panim == PA_DASH))))
&& !(maptol & TOL_NIGHTS)) && !(maptol & TOL_NIGHTS))
@ -4678,8 +4657,7 @@ void P_DoSpinDashDust(player_t *player)
P_SetMobjState(particle, S_SPINDUST_FIRE1); P_SetMobjState(particle, S_SPINDUST_FIRE1);
P_SetTarget(&particle->target, player->mo); P_SetTarget(&particle->target, player->mo);
particle->destscale = (2*player->mo->scale)/3; P_SetScale(particle, (2*player->mo->scale)/3, true);
P_SetScale(particle, particle->destscale);
if (player->mo->eflags & MFE_VERTICALFLIP) // readjust z position if needed if (player->mo->eflags & MFE_VERTICALFLIP) // readjust z position if needed
particle->z = player->mo->z + player->mo->height - particle->height; particle->z = player->mo->z + player->mo->height - particle->height;
prandom[0] = P_RandomFixed()<<2; // P_RandomByte()<<10 prandom[0] = P_RandomFixed()<<2; // P_RandomByte()<<10
@ -5078,7 +5056,7 @@ void P_TwinSpinRejuvenate(player_t *player, mobjtype_t type)
if (!P_MobjWasRemoved(missile)) if (!P_MobjWasRemoved(missile))
{ {
P_SetTarget(&missile->target, player->mo); P_SetTarget(&missile->target, player->mo);
P_SetScale(missile, (missile->destscale >>= 1)); P_SetScale(missile, missile->destscale/2, true);
missile->angle = ang + movang; missile->angle = ang + movang;
missile->fuse = TICRATE/2; missile->fuse = TICRATE/2;
missile->extravalue2 = (99*FRACUNIT)/100; missile->extravalue2 = (99*FRACUNIT)/100;
@ -5282,7 +5260,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
// //
// Handles player jumping // Handles player jumping
// //
static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd, boolean spinshieldhack)
{ {
mobj_t *lockonthok = NULL, *visual = NULL; mobj_t *lockonthok = NULL, *visual = NULL;
@ -5315,45 +5293,53 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
; ;
else if (P_PlayerShieldThink(player, cmd, lockonthok, visual)) else if (P_PlayerShieldThink(player, cmd, lockonthok, visual))
; ;
else if ((cmd->buttons & BT_SPIN) && !LUA_HookPlayer(player, HOOK(JumpSpinSpecial))) else if (cmd->buttons & BT_SPIN)
{ {
switch (player->charability) if (spinshieldhack && !(player->pflags & PF_SPINDOWN) && P_SuperReady(player, true)
&& !player->powers[pw_invulnerability] && !(player->powers[pw_shield] & SH_NOSTACK)) // These two checks are no longer in P_SuperReady
{ {
case CA_THOK: // If you're using two-button play, can turn Super and aren't already,
if (player->powers[pw_super]) // Super Sonic float // and you don't have a shield, then turn Super!
{ P_DoSuperTransformation(player, false);
if ((player->speed > 5*player->mo->scale) // FixedMul(5<<FRACBITS, player->mo->scale), but scale is FRACUNIT-based
&& (P_MobjFlip(player->mo)*player->mo->momz <= 0))
{
if (player->panim != PA_RUN && player->panim != PA_WALK)
{
if (player->speed >= FixedMul(player->runspeed, player->mo->scale))
P_SetMobjState(player->mo, S_PLAY_FLOAT_RUN);
else
P_SetMobjState(player->mo, S_PLAY_FLOAT);
}
player->mo->momz = 0;
player->pflags &= ~(PF_STARTJUMP|PF_SPINNING);
player->secondjump = 1;
}
}
break;
case CA_TELEKINESIS:
if (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || (player->charflags & SF_MULTIABILITY))
{
P_Telekinesis(player,
-FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player)
FixedMul(384*FRACUNIT, player->mo->scale));
}
break;
case CA_TWINSPIN:
if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || player->charflags & SF_MULTIABILITY))
P_DoTwinSpin(player);
break;
default:
break;
} }
else if (!LUA_HookPlayer(player, HOOK(JumpSpinSpecial)))
switch (player->charability)
{
case CA_THOK:
if (player->powers[pw_super]) // Super Sonic float
{
if ((player->speed > 5*player->mo->scale) // FixedMul(5<<FRACBITS, player->mo->scale), but scale is FRACUNIT-based
&& (P_MobjFlip(player->mo)*player->mo->momz <= 0))
{
if (player->panim != PA_RUN && player->panim != PA_WALK)
{
if (player->speed >= FixedMul(player->runspeed, player->mo->scale))
P_SetMobjState(player->mo, S_PLAY_FLOAT_RUN);
else
P_SetMobjState(player->mo, S_PLAY_FLOAT);
}
player->mo->momz = 0;
player->pflags &= ~(PF_STARTJUMP|PF_SPINNING);
player->secondjump = 1;
}
}
break;
case CA_TELEKINESIS:
if (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || (player->charflags & SF_MULTIABILITY))
{
P_Telekinesis(player,
-FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player)
FixedMul(384*FRACUNIT, player->mo->scale));
}
break;
case CA_TWINSPIN:
if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || player->charflags & SF_MULTIABILITY))
P_DoTwinSpin(player);
break;
default:
break;
}
} }
} }
@ -7418,9 +7404,8 @@ static void P_NiGHTSMovement(player_t *player)
firstmobj = P_SpawnMobj(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle+ANGLE_90, spawndist), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle+ANGLE_90, spawndist), z, MT_NIGHTSPARKLE); firstmobj = P_SpawnMobj(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle+ANGLE_90, spawndist), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle+ANGLE_90, spawndist), z, MT_NIGHTSPARKLE);
if (!P_MobjWasRemoved(firstmobj)) if (!P_MobjWasRemoved(firstmobj))
{ {
firstmobj->destscale = player->mo->scale;
P_SetTarget(&firstmobj->target, player->mo); P_SetTarget(&firstmobj->target, player->mo);
P_SetScale(firstmobj, player->mo->scale); P_SetScale(firstmobj, player->mo->scale, true);
// Superloop turns sparkles red // Superloop turns sparkles red
if (player->powers[pw_nights_superloop]) if (player->powers[pw_nights_superloop])
P_SetMobjState(firstmobj, mobjinfo[MT_NIGHTSPARKLE].seestate); P_SetMobjState(firstmobj, mobjinfo[MT_NIGHTSPARKLE].seestate);
@ -7428,10 +7413,8 @@ static void P_NiGHTSMovement(player_t *player)
secondmobj = P_SpawnMobj(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle-ANGLE_90, spawndist), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle-ANGLE_90, spawndist), z, MT_NIGHTSPARKLE); secondmobj = P_SpawnMobj(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle-ANGLE_90, spawndist), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle-ANGLE_90, spawndist), z, MT_NIGHTSPARKLE);
if (!P_MobjWasRemoved(secondmobj)) if (!P_MobjWasRemoved(secondmobj))
{ {
secondmobj->destscale = player->mo->scale;
P_SetTarget(&secondmobj->target, player->mo); P_SetTarget(&secondmobj->target, player->mo);
P_SetScale(secondmobj, player->mo->scale); P_SetScale(secondmobj, player->mo->scale, true);
// Superloop turns sparkles red // Superloop turns sparkles red
if (player->powers[pw_nights_superloop]) if (player->powers[pw_nights_superloop])
P_SetMobjState(secondmobj, mobjinfo[MT_NIGHTSPARKLE].seestate); P_SetMobjState(secondmobj, mobjinfo[MT_NIGHTSPARKLE].seestate);
@ -7446,7 +7429,7 @@ static void P_NiGHTSMovement(player_t *player)
{ {
helpermobj->fuse = player->mo->fuse = leveltime; helpermobj->fuse = player->mo->fuse = leveltime;
P_SetTarget(&helpermobj->target, player->mo); P_SetTarget(&helpermobj->target, player->mo);
P_SetScale(helpermobj, player->mo->scale); P_SetScale(helpermobj, player->mo->scale, false);
} }
} }
@ -7646,8 +7629,7 @@ static void P_NiGHTSMovement(player_t *player)
water->flags2 |= MF2_OBJECTFLIP; water->flags2 |= MF2_OBJECTFLIP;
water->eflags |= MFE_VERTICALFLIP; water->eflags |= MFE_VERTICALFLIP;
} }
water->destscale = player->mo->scale; P_SetScale(water, player->mo->scale, true);
P_SetScale(water, player->mo->scale);
} }
} }
@ -7890,8 +7872,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
P_SetTarget(&flame->target, player->mo); P_SetTarget(&flame->target, player->mo);
flame->angle = travelangle + i*(ANGLE_MAX/numangles); flame->angle = travelangle + i*(ANGLE_MAX/numangles);
flame->fuse = TICRATE*7; // takes about an extra second to hit the ground flame->fuse = TICRATE*7; // takes about an extra second to hit the ground
flame->destscale = player->mo->scale; P_SetScale(flame, player->mo->scale, true);
P_SetScale(flame, player->mo->scale);
if (!(player->mo->flags2 & MF2_OBJECTFLIP) != !(player->powers[pw_gravityboots])) // take gravity boots into account if (!(player->mo->flags2 & MF2_OBJECTFLIP) != !(player->powers[pw_gravityboots])) // take gravity boots into account
flame->flags2 |= MF2_OBJECTFLIP; flame->flags2 |= MF2_OBJECTFLIP;
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
@ -7928,8 +7909,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
P_SetTarget(&flame->target, player->mo); P_SetTarget(&flame->target, player->mo);
flame->angle = travelangle; flame->angle = travelangle;
flame->fuse = TICRATE*6; flame->fuse = TICRATE*6;
flame->destscale = player->mo->scale; P_SetScale(flame, player->mo->scale, true);
P_SetScale(flame, player->mo->scale);
if (!(player->mo->flags2 & MF2_OBJECTFLIP) != !(player->powers[pw_gravityboots])) // take gravity boots into account if (!(player->mo->flags2 & MF2_OBJECTFLIP) != !(player->powers[pw_gravityboots])) // take gravity boots into account
flame->flags2 |= MF2_OBJECTFLIP; flame->flags2 |= MF2_OBJECTFLIP;
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
@ -7977,8 +7957,7 @@ void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound)
} }
particle->tics = 10; particle->tics = 10;
particle->destscale = (2*mo->scale)/3; P_SetScale(particle, (2*mo->scale)/3, true);
P_SetScale(particle, particle->destscale);
P_SetObjectMomZ(particle, FRACUNIT, false); P_SetObjectMomZ(particle, FRACUNIT, false);
if (mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version if (mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version
@ -8075,6 +8054,7 @@ void P_MovePlayer(player_t *player)
{ {
ticcmd_t *cmd; ticcmd_t *cmd;
INT32 i; INT32 i;
boolean spinshieldhack = false; // Hack: Is Spin and Shield bound to the same button (pressed on the same tic)?
fixed_t runspd; fixed_t runspd;
@ -8567,8 +8547,7 @@ void P_MovePlayer(player_t *player)
water->flags2 |= MF2_OBJECTFLIP; water->flags2 |= MF2_OBJECTFLIP;
water->eflags |= MFE_VERTICALFLIP; water->eflags |= MFE_VERTICALFLIP;
} }
water->destscale = player->mo->scale; P_SetScale(water, player->mo->scale, true);
P_SetScale(water, player->mo->scale);
} }
} }
@ -8697,10 +8676,13 @@ void P_MovePlayer(player_t *player)
&& !(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) && !(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
P_ElementalFire(player, false); P_ElementalFire(player, false);
if ((cmd->buttons & (BT_SPIN|BT_SHIELD)) == (BT_SPIN|BT_SHIELD) && !(player->pflags & (PF_SPINDOWN|PF_SHIELDDOWN)))
spinshieldhack = true; // Spin and Shield is bound to the same button (pressed on the same tic), so enable two-button play (Jump and Spin+Shield)
P_DoSpinAbility(player, cmd); P_DoSpinAbility(player, cmd);
// jumping // jumping
P_DoJumpStuff(player, cmd); P_DoJumpStuff(player, cmd, spinshieldhack);
// If you're not spinning, you'd better not be spindashing! // If you're not spinning, you'd better not be spindashing!
if (!(player->pflags & PF_SPINNING) && player->powers[pw_carry] != CR_NIGHTSMODE) if (!(player->pflags & PF_SPINNING) && player->powers[pw_carry] != CR_NIGHTSMODE)
@ -8778,30 +8760,32 @@ void P_MovePlayer(player_t *player)
if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER) if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER)
&& player->panim == PA_IDLE && !(player->powers[pw_carry])) && player->panim == PA_IDLE && !(player->powers[pw_carry]))
P_DoTeeter(player); P_DoTeeter(player);
// Toss a flag
if (G_GametypeHasTeams() && (cmd->buttons & BT_TOSSFLAG) && !(player->powers[pw_super]) && !(player->tossdelay))
{
if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
P_PlayerEmeraldBurst(player, true); // Toss emeralds
else
P_PlayerFlagBurst(player, true);
}
// Check for fire and shield buttons // Check for fire and shield buttons
if (!player->exiting && !(player->pflags & PF_STASIS)) if (!player->exiting)
{ {
// Check for fire buttons
P_DoFiring(player, cmd); P_DoFiring(player, cmd);
// Release the shield button
if (!(cmd->buttons & BT_SHIELD))
player->pflags &= ~PF_SHIELDDOWN;
// Shield button behavior // Shield button behavior
// Check P_PlayerShieldThink for actual shields! // Check P_PlayerShieldThink for actual shields!
else if (!(player->pflags & PF_SHIELDDOWN)) if ((cmd->buttons & BT_SHIELD) && !(player->pflags & PF_SHIELDDOWN) && !spinshieldhack)
{ {
// Transform into super if we can! // Transform into super if we can!
if (P_SuperReady(player, true)) if (P_SuperReady(player, true))
P_DoSuperTransformation(player, false); P_DoSuperTransformation(player, false);
// Detransform from super if we can! // Detransform from super if we can!
else if (P_SuperReady(player, false)) else if (P_SuperReady(player, false))
P_DoSuperDetransformation(player); P_DoSuperDetransformation(player);
player->pflags |= PF_SHIELDDOWN;
} }
} }
@ -11000,8 +10984,7 @@ static void P_SpawnSparks(mobj_t *mo, angle_t maindir)
spark->momz = mo->momz + r3; spark->momz = mo->momz + r3;
P_Thrust(spark, R_PointToAngle2(mo->x, mo->y, spark->x, spark->y), 8*FRACUNIT); P_Thrust(spark, R_PointToAngle2(mo->x, mo->y, spark->x, spark->y), 8*FRACUNIT);
P_SetScale(spark, FRACUNIT/4); P_SetScale(spark, FRACUNIT/4, true);
spark->destscale = spark->scale;
spark->fuse = TICRATE/3; spark->fuse = TICRATE/3;
} }
@ -11473,8 +11456,9 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
tails->threshold = player->mo->z; tails->threshold = player->mo->z;
tails->movecount = player->panim; tails->movecount = player->panim;
tails->angle = horizangle; tails->angle = horizangle;
P_SetScale(tails, player->mo->scale); P_SetScale(tails, player->mo->scale, false);
tails->destscale = player->mo->destscale; tails->destscale = player->mo->destscale;
tails->old_scale = player->mo->old_scale;
tails->radius = player->mo->radius; tails->radius = player->mo->radius;
tails->height = player->mo->height; tails->height = player->mo->height;
zoffs = FixedMul(zoffs, tails->scale); zoffs = FixedMul(zoffs, tails->scale);
@ -11565,7 +11549,9 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume)
y = mo->y + radiusY + FixedMul(offsetH, factorY); y = mo->y + radiusY + FixedMul(offsetH, factorY);
z = mo->z + heightoffset + offsetV; z = mo->z + heightoffset + offsetV;
bubble = P_SpawnMobj(x, y, z, MT_SMALLBUBBLE); bubble = P_SpawnMobj(x, y, z, MT_SMALLBUBBLE);
bubble->scale = mo->scale >> 1; P_SetScale(bubble, mo->scale/2, true);
bubble->destscale = mo->scale;
bubble->scalespeed = FixedMul(bubble->scalespeed, mo->scale);
P_SetTarget(&bubble->dontdrawforviewmobj, mo); // Hide the bubble in first-person P_SetTarget(&bubble->dontdrawforviewmobj, mo); // Hide the bubble in first-person
} }
@ -11586,7 +11572,7 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume)
if (stat == fume->info->spawnstate) // If currently inivisble, activate! if (stat == fume->info->spawnstate) // If currently inivisble, activate!
{ {
P_SetMobjState(fume, (stat = fume->info->seestate)); P_SetMobjState(fume, (stat = fume->info->seestate));
P_SetScale(fume, mo->scale); P_SetScale(fume, mo->scale, false);
resetinterp = true; resetinterp = true;
} }
@ -11601,7 +11587,7 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume)
if (dashmode == DASHMODE_THRESHOLD && dashmode > (tic_t)fume->movecount) // If just about to enter dashmode, play the startup animation again if (dashmode == DASHMODE_THRESHOLD && dashmode > (tic_t)fume->movecount) // If just about to enter dashmode, play the startup animation again
{ {
P_SetMobjState(fume, (stat = fume->info->seestate)); P_SetMobjState(fume, (stat = fume->info->seestate));
P_SetScale(fume, mo->scale << 1); P_SetScale(fume, 2*mo->scale, true);
} }
fume->flags2 = (fume->flags2 & ~MF2_DONTDRAW) | (mo->flags2 & MF2_DONTDRAW); fume->flags2 = (fume->flags2 & ~MF2_DONTDRAW) | (mo->flags2 & MF2_DONTDRAW);
fume->destscale = (mo->scale + FixedDiv(player->speed, player->normalspeed)) / (underwater ? 6 : 3); fume->destscale = (mo->scale + FixedDiv(player->speed, player->normalspeed)) / (underwater ? 6 : 3);
@ -12055,7 +12041,7 @@ void P_PlayerThink(player_t *player)
ticmiss++; ticmiss++;
P_DoRopeHang(player); P_DoRopeHang(player);
P_DoJumpStuff(player, &player->cmd); P_DoJumpStuff(player, &player->cmd, false); // P_DoRopeHang would set PF_SPINDOWN, so no spinshieldhack here
} }
else //if (player->powers[pw_carry] == CR_ZOOMTUBE) else //if (player->powers[pw_carry] == CR_ZOOMTUBE)
{ {
@ -12325,6 +12311,12 @@ void P_PlayerThink(player_t *player)
player->pflags &= ~PF_SPINDOWN; player->pflags &= ~PF_SPINDOWN;
} }
// Check for Shield button
if (cmd->buttons & BT_SHIELD)
player->pflags |= PF_SHIELDDOWN;
else
player->pflags &= ~PF_SHIELDDOWN;
// IF PLAYER NOT HERE THEN FLASH END IF // IF PLAYER NOT HERE THEN FLASH END IF
if (player->quittime && player->powers[pw_flashing] < flashingtics - 1 if (player->quittime && player->powers[pw_flashing] < flashingtics - 1
&& !(G_TagGametype() && !(player->pflags & PF_TAGIT)) && !player->gotflag) && !(G_TagGametype() && !(player->pflags & PF_TAGIT)) && !player->gotflag)

View file

@ -1382,10 +1382,9 @@ void R_RenderPortalHorizonLine(sector_t *sector)
|| frontsector->ceilingpic == skyflatnum || frontsector->ceilingpic == skyflatnum
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum)) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))
{ {
ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic, ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel,
ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingxscale, frontsector->ceilingyscale, frontsector->ceilingxoffset, frontsector->ceilingyoffset, frontsector->ceilingxscale, frontsector->ceilingyscale,
frontsector->ceilingyoffset, frontsector->ceilingangle, frontsector->ceilingangle, ceilingcolormap, NULL, NULL, NULL, NULL);
ceilingcolormap, NULL, NULL, NULL, NULL);
} }
else else
ceilingplane = NULL; ceilingplane = NULL;

View file

@ -751,9 +751,6 @@ typedef struct seg_s
lightmap_t *lightmaps; // for static lightmap lightmap_t *lightmaps; // for static lightmap
#endif #endif
// Why slow things down by calculating lightlists for every thick side?
size_t numlights;
r_lightlist_t *rlights;
polyobj_t *polyseg; polyobj_t *polyseg;
boolean dontrenderme; boolean dontrenderme;
boolean glseg; boolean glseg;
@ -837,6 +834,7 @@ typedef struct drawseg_s
INT16 *sprtopclip; INT16 *sprtopclip;
INT16 *sprbottomclip; INT16 *sprbottomclip;
fixed_t *maskedtexturecol; fixed_t *maskedtexturecol;
fixed_t *maskedtextureheight; // For handling sloped midtextures
fixed_t *invscale; fixed_t *invscale;
struct visplane_s *ffloorplanes[MAXFFLOORS]; struct visplane_s *ffloorplanes[MAXFFLOORS];
@ -848,8 +846,6 @@ typedef struct drawseg_s
UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping
fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures
vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes
} drawseg_t; } drawseg_t;

View file

@ -817,6 +817,10 @@ void R_ResetMobjInterpolationState(mobj_t *mobj)
mobj->old_roll2 = mobj->old_roll; mobj->old_roll2 = mobj->old_roll;
mobj->old_spriteroll2 = mobj->old_spriteroll; mobj->old_spriteroll2 = mobj->old_spriteroll;
mobj->old_scale2 = mobj->old_scale; mobj->old_scale2 = mobj->old_scale;
mobj->old_spritexscale2 = mobj->old_spritexscale;
mobj->old_spriteyscale2 = mobj->old_spriteyscale;
mobj->old_spritexoffset2 = mobj->old_spritexoffset;
mobj->old_spriteyoffset2 = mobj->old_spriteyoffset;
mobj->old_x = mobj->x; mobj->old_x = mobj->x;
mobj->old_y = mobj->y; mobj->old_y = mobj->y;
mobj->old_z = mobj->z; mobj->old_z = mobj->z;
@ -853,6 +857,10 @@ void R_ResetPrecipitationMobjInterpolationState(precipmobj_t *mobj)
mobj->old_pitch2 = mobj->old_pitch; mobj->old_pitch2 = mobj->old_pitch;
mobj->old_roll2 = mobj->old_roll; mobj->old_roll2 = mobj->old_roll;
mobj->old_spriteroll2 = mobj->old_spriteroll; mobj->old_spriteroll2 = mobj->old_spriteroll;
mobj->old_spritexscale2 = mobj->old_spritexscale;
mobj->old_spriteyscale2 = mobj->old_spriteyscale;
mobj->old_spritexoffset2 = mobj->old_spritexoffset;
mobj->old_spriteyoffset2 = mobj->old_spriteyoffset;
mobj->old_x = mobj->x; mobj->old_x = mobj->x;
mobj->old_y = mobj->y; mobj->old_y = mobj->y;
mobj->old_z = mobj->z; mobj->old_z = mobj->z;

View file

@ -66,6 +66,10 @@ sector_t *viewsector;
player_t *viewplayer; player_t *viewplayer;
mobj_t *r_viewmobj; mobj_t *r_viewmobj;
boolean r_renderwalls;
boolean r_renderfloors;
boolean r_renderthings;
fixed_t rendertimefrac; fixed_t rendertimefrac;
fixed_t renderdeltatics; fixed_t renderdeltatics;
boolean renderisnewtic; boolean renderisnewtic;
@ -149,8 +153,6 @@ consvar_t cv_flipcam2 = CVAR_INIT ("flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT,
consvar_t cv_shadow = CVAR_INIT ("shadow", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_shadow = CVAR_INIT ("shadow", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_skybox = CVAR_INIT ("skybox", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_skybox = CVAR_INIT ("skybox", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_ffloorclip = CVAR_INIT ("r_ffloorclip", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_spriteclip = CVAR_INIT ("r_spriteclip", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_allowmlook = CVAR_INIT ("allowmlook", "Yes", CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); consvar_t cv_allowmlook = CVAR_INIT ("allowmlook", "Yes", CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL);
consvar_t cv_showhud = CVAR_INIT ("showhud", "Yes", CV_CALL|CV_ALLOWLUA, CV_YesNo, R_SetViewSize); consvar_t cv_showhud = CVAR_INIT ("showhud", "Yes", CV_CALL|CV_ALLOWLUA, CV_YesNo, R_SetViewSize);
consvar_t cv_translucenthud = CVAR_INIT ("translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL); consvar_t cv_translucenthud = CVAR_INIT ("translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL);
@ -161,12 +163,17 @@ consvar_t cv_drawdist_nights = CVAR_INIT ("drawdist_nights", "2048", CV_SAVE, dr
consvar_t cv_drawdist_precip = CVAR_INIT ("drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL); consvar_t cv_drawdist_precip = CVAR_INIT ("drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL);
consvar_t cv_fov = CVAR_INIT ("fov", "90", CV_SAVE|CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange); consvar_t cv_fov = CVAR_INIT ("fov", "90", CV_SAVE|CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange);
consvar_t cv_fovchange = CVAR_INIT ("fovchange", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_fovchange = CVAR_INIT ("fovchange", "Off", CV_SAVE, CV_OnOff, NULL);
// Okay, whoever said homremoval causes a performance hit should be shot.
consvar_t cv_homremoval = CVAR_INIT ("homremoval", "No", CV_SAVE, homremoval_cons_t, NULL);
consvar_t cv_maxportals = CVAR_INIT ("maxportals", "2", CV_SAVE, maxportals_cons_t, NULL); consvar_t cv_maxportals = CVAR_INIT ("maxportals", "2", CV_SAVE, maxportals_cons_t, NULL);
consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL);
consvar_t cv_renderwalls = CVAR_INIT ("r_renderwalls", "On", 0, CV_OnOff, NULL);
consvar_t cv_renderfloors = CVAR_INIT ("r_renderfloors", "On", 0, CV_OnOff, NULL);
consvar_t cv_renderthings = CVAR_INIT ("r_renderthings", "On", 0, CV_OnOff, NULL);
consvar_t cv_ffloorclip = CVAR_INIT ("r_ffloorclip", "On", 0, CV_OnOff, NULL);
consvar_t cv_spriteclip = CVAR_INIT ("r_spriteclip", "On", 0, CV_OnOff, NULL);
consvar_t cv_homremoval = CVAR_INIT ("homremoval", "No", CV_SAVE, homremoval_cons_t, NULL);
consvar_t cv_renderstats = CVAR_INIT ("renderstats", "Off", 0, CV_OnOff, NULL); consvar_t cv_renderstats = CVAR_INIT ("renderstats", "Off", 0, CV_OnOff, NULL);
void SplitScreen_OnChange(void) void SplitScreen_OnChange(void)
@ -383,33 +390,26 @@ fixed_t R_PointToDist(fixed_t x, fixed_t y)
return R_PointToDist2(viewx, viewy, x, y); return R_PointToDist2(viewx, viewy, x, y);
} }
// line_t *R_GetFFloorLine(const seg_t *seg, const ffloor_t *pfloor)
// R_ScaleFromGlobalAngle
// Returns the texture mapping scale for the current line (horizontal span)
// at the given angle.
// rw_distance must be calculated first.
//
// killough 5/2/98: reformatted, cleaned up
//
// note: THIS IS USED ONLY FOR WALLS!
fixed_t R_ScaleFromGlobalAngle(angle_t visangle)
{ {
angle_t anglea = ANGLE_90 + (visangle-viewangle); if (pfloor->master->flags & ML_TFERLINE)
angle_t angleb = ANGLE_90 + (visangle-rw_normalangle);
fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT));
// proff 11/06/98: Changed for high-res
fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT));
if (den > num>>16)
{ {
num = FixedDiv(num, den); size_t linenum = seg->linedef - pfloor->target->lines[0];
if (num > 64*FRACUNIT) return pfloor->master->frontsector->lines[0] + linenum;
return 64*FRACUNIT;
if (num < 256)
return 256;
return num;
} }
return 64*FRACUNIT; else
return pfloor->master;
}
side_t *R_GetFFloorSide(const seg_t *seg, const ffloor_t *pfloor)
{
if (pfloor->master->flags & ML_TFERLINE)
{
line_t *newline = R_GetFFloorLine(seg, pfloor);
return &sides[newline->sidenum[0]];
}
else
return &sides[pfloor->master->sidenum[0]];
} }
// //
@ -1620,17 +1620,11 @@ void R_RenderPlayerView(player_t *player)
void R_RegisterEngineStuff(void) void R_RegisterEngineStuff(void)
{ {
CV_RegisterVar(&cv_gravity); // Do nothing for dedicated server
CV_RegisterVar(&cv_tailspickup);
CV_RegisterVar(&cv_allowmlook);
CV_RegisterVar(&cv_homremoval);
CV_RegisterVar(&cv_flipcam);
CV_RegisterVar(&cv_flipcam2);
// Enough for dedicated server
if (dedicated) if (dedicated)
return; return;
CV_RegisterVar(&cv_homremoval);
CV_RegisterVar(&cv_translucency); CV_RegisterVar(&cv_translucency);
CV_RegisterVar(&cv_drawdist); CV_RegisterVar(&cv_drawdist);
CV_RegisterVar(&cv_drawdist_nights); CV_RegisterVar(&cv_drawdist_nights);
@ -1643,6 +1637,13 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_shadow); CV_RegisterVar(&cv_shadow);
CV_RegisterVar(&cv_skybox); CV_RegisterVar(&cv_skybox);
CV_RegisterVar(&cv_renderview);
CV_RegisterVar(&cv_renderhitboxinterpolation);
CV_RegisterVar(&cv_renderhitboxgldepth);
CV_RegisterVar(&cv_renderhitbox);
CV_RegisterVar(&cv_renderwalls);
CV_RegisterVar(&cv_renderfloors);
CV_RegisterVar(&cv_renderthings);
CV_RegisterVar(&cv_ffloorclip); CV_RegisterVar(&cv_ffloorclip);
CV_RegisterVar(&cv_spriteclip); CV_RegisterVar(&cv_spriteclip);
@ -1681,8 +1682,6 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_maxportals); CV_RegisterVar(&cv_maxportals);
CV_RegisterVar(&cv_movebob);
// Frame interpolation/uncapped // Frame interpolation/uncapped
CV_RegisterVar(&cv_fpscap); CV_RegisterVar(&cv_fpscap);
} }

View file

@ -80,13 +80,15 @@ angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
fixed_t R_PointToDist(fixed_t x, fixed_t y); fixed_t R_PointToDist(fixed_t x, fixed_t y);
fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
fixed_t R_ScaleFromGlobalAngle(angle_t visangle);
boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y); boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y);
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y); subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);
subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y); subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y);
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph); boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);
line_t *R_GetFFloorLine(const seg_t *seg, const ffloor_t *pfloor);
side_t *R_GetFFloorSide(const seg_t *seg, const ffloor_t *pfloor);
// Render stats // Render stats
extern precise_t ps_prevframetime;// time when previous frame was rendered extern precise_t ps_prevframetime;// time when previous frame was rendered
@ -117,12 +119,18 @@ extern consvar_t cv_chasecam, cv_chasecam2;
extern consvar_t cv_flipcam, cv_flipcam2; extern consvar_t cv_flipcam, cv_flipcam2;
extern consvar_t cv_shadow; extern consvar_t cv_shadow;
extern consvar_t cv_ffloorclip, cv_spriteclip;
extern consvar_t cv_translucency; extern consvar_t cv_translucency;
extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip;
extern consvar_t cv_fov, cv_fovchange; extern consvar_t cv_fov, cv_fovchange;
extern consvar_t cv_skybox; extern consvar_t cv_skybox;
extern consvar_t cv_tailspickup; extern consvar_t cv_renderview;
extern consvar_t cv_renderhitbox, cv_renderhitboxinterpolation, cv_renderhitboxgldepth;
extern consvar_t cv_renderwalls, cv_renderfloors, cv_renderthings;
extern consvar_t cv_ffloorclip, cv_spriteclip;
extern boolean r_renderwalls;
extern boolean r_renderfloors;
extern boolean r_renderthings;
// Called by startup code. // Called by startup code.
void R_Init(void); void R_Init(void);

View file

@ -603,6 +603,9 @@ void R_DrawPlanes(void)
visplane_t *pl; visplane_t *pl;
INT32 i; INT32 i;
if (!r_renderfloors)
return;
R_UpdatePlaneRipple(); R_UpdatePlaneRipple();
for (i = 0; i < MAXVISPLANES; i++, pl++) for (i = 0; i < MAXVISPLANES; i++, pl++)
@ -881,9 +884,6 @@ void R_DrawSinglePlane(visplane_t *pl)
if (!(pl->minx <= pl->maxx)) if (!(pl->minx <= pl->maxx))
return; return;
if (!cv_renderfloors.value)
return;
// sky flat // sky flat
if (pl->picnum == skyflatnum) if (pl->picnum == skyflatnum)
{ {

View file

@ -16,7 +16,6 @@
#include "r_sky.h" #include "r_sky.h"
#include "r_portal.h" #include "r_portal.h"
#include "r_splats.h"
#include "w_wad.h" #include "w_wad.h"
#include "z_zone.h" #include "z_zone.h"
@ -75,6 +74,8 @@ static fixed_t *maskedtextureheight = NULL;
static fixed_t *thicksidecol = NULL; static fixed_t *thicksidecol = NULL;
static fixed_t *invscale = NULL; static fixed_t *invscale = NULL;
static boolean texcoltables;
//SoM: 3/23/2000: Use boom opening limit removal //SoM: 3/23/2000: Use boom opening limit removal
static size_t numopenings; static size_t numopenings;
static INT16 *openings, *lastopening; static INT16 *openings, *lastopening;
@ -88,10 +89,6 @@ void R_ClearSegTables(void)
curtexturecolumntable = texturecolumntable; curtexturecolumntable = texturecolumntable;
} }
// ==========================================================================
// R_RenderMaskedSegRange
// ==========================================================================
transnum_t R_GetLinedefTransTable(fixed_t alpha) transnum_t R_GetLinedefTransTable(fixed_t alpha)
{ {
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1); return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
@ -111,10 +108,12 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
INT32 times, repeats; INT32 times, repeats;
INT64 overflow_test; INT64 overflow_test;
INT32 range; INT32 range;
UINT8 vertflip;
unsigned lengthcol; unsigned lengthcol;
if (!cv_renderwalls.value) fixed_t wall_scaley;
return; fixed_t scalestep;
fixed_t scale1;
// Calculate light table. // Calculate light table.
// Use different light tables // Use different light tables
@ -163,9 +162,17 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
colfunc = colfuncs[COLDRAWFUNC_FUZZY]; colfunc = colfuncs[COLDRAWFUNC_FUZZY];
} }
fixed_t wall_scaley = sidedef->scaley_mid; vertflip = textures[texnum]->flip & 2;
fixed_t scalestep = FixedDiv(ds->scalestep, wall_scaley);
fixed_t scale1 = FixedDiv(ds->scale1, wall_scaley); wall_scaley = sidedef->scaley_mid;
if (wall_scaley < 0)
{
wall_scaley = -wall_scaley;
vertflip = !vertflip;
}
scalestep = FixedDiv(ds->scalestep, wall_scaley);
scale1 = FixedDiv(ds->scale1, wall_scaley);
range = max(ds->x2-ds->x1, 1); range = max(ds->x2-ds->x1, 1);
rw_scalestep = scalestep; rw_scalestep = scalestep;
@ -174,7 +181,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
// Texture must be cached // Texture must be cached
R_CheckTextureCache(texnum); R_CheckTextureCache(texnum);
if (textures[texnum]->flip & 2) // vertically flipped? if (vertflip) // vertically flipped?
colfunc_2s = R_DrawFlippedMaskedColumn; colfunc_2s = R_DrawFlippedMaskedColumn;
else else
colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
@ -470,6 +477,11 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor)
return false; return false;
} }
static fixed_t R_GetSlopeTextureSlide(pslope_t *slope, angle_t lineangle)
{
return FixedMul(slope->zdelta, FINECOSINE((lineangle-slope->xydirection)>>ANGLETOFINESHIFT));
}
// //
// R_RenderThickSideRange // R_RenderThickSideRange
// Renders all the thick sides in the given range. // Renders all the thick sides in the given range.
@ -494,19 +506,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
INT64 top_frac, top_step, bottom_frac, bottom_step; INT64 top_frac, top_step, bottom_frac, bottom_step;
// skew FOF walls with slopes? // skew FOF walls with slopes?
fixed_t ffloortextureslide = 0; fixed_t ffloortextureslide = 0;
INT32 oldx = -1; fixed_t oldtexturecolumn = -1;
fixed_t left_top, left_bottom; // needed here for slope skewing fixed_t left_top, left_bottom; // needed here for slope skewing
pslope_t *skewslope = NULL; pslope_t *skewslope = NULL;
boolean do_texture_skew; boolean do_texture_skew;
boolean dont_peg_bottom; boolean dont_peg_bottom;
fixed_t wall_offsetx;
fixed_t wall_scalex, wall_scaley; fixed_t wall_scalex, wall_scaley;
UINT8 vertflip;
unsigned lengthcol; unsigned lengthcol;
void (*colfunc_2s) (column_t *, unsigned); void (*colfunc_2s) (column_t *, unsigned);
if (!cv_renderwalls.value)
return;
// Calculate light table. // Calculate light table.
// Use different light tables // Use different light tables
// for horizontal / vertical / diagonal. Diagonal? // for horizontal / vertical / diagonal. Diagonal?
@ -515,15 +526,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
curline = ds->curline; curline = ds->curline;
backsector = pfloor->target; backsector = pfloor->target;
frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector;
sidedef = &sides[pfloor->master->sidenum[0]]; sidedef = R_GetFFloorSide(curline, pfloor);
colfunc = colfuncs[BASEDRAWFUNC]; colfunc = colfuncs[BASEDRAWFUNC];
if (pfloor->master->flags & ML_TFERLINE) if (pfloor->master->flags & ML_TFERLINE)
{ {
size_t linenum = curline->linedef-backsector->lines[0]; line_t *newline = R_GetFFloorLine(curline, pfloor);
line_t *newline = pfloor->master->frontsector->lines[0] + linenum;
sidedef = &sides[newline->sidenum[0]];
do_texture_skew = newline->flags & ML_SKEWTD; do_texture_skew = newline->flags & ML_SKEWTD;
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM; dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
} }
@ -534,6 +543,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
} }
texnum = R_GetTextureNum(sidedef->midtexture); texnum = R_GetTextureNum(sidedef->midtexture);
vertflip = textures[texnum]->flip & 2;
if (pfloor->fofflags & FOF_TRANSLUCENT) if (pfloor->fofflags & FOF_TRANSLUCENT)
{ {
@ -687,18 +697,25 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
wall_scalex = FixedDiv(FRACUNIT, sidedef->scalex_mid); wall_scalex = FixedDiv(FRACUNIT, sidedef->scalex_mid);
wall_scaley = sidedef->scaley_mid; wall_scaley = sidedef->scaley_mid;
if (wall_scaley < 0)
{
wall_scaley = -wall_scaley;
vertflip = !vertflip;
}
thicksidecol = ffloortexturecolumn; thicksidecol = ffloortexturecolumn;
wall_offsetx = ds->offsetx + sidedef->offsetx_mid;
if (wall_scalex == FRACUNIT) if (wall_scalex == FRACUNIT)
{ {
for (INT32 x = x1; x <= x2; x++) for (INT32 x = x1; x <= x2; x++)
thicksidecol[x] = ds->thicksidecol[x] + ds->offsetx; thicksidecol[x] = ds->thicksidecol[x];
} }
else else
{ {
for (INT32 x = x1; x <= x2; x++) for (INT32 x = x1; x <= x2; x++)
thicksidecol[x] = FixedDiv(ds->thicksidecol[x], wall_scalex) + ds->offsetx; thicksidecol[x] = FixedDiv(ds->thicksidecol[x], wall_scalex);
} }
mfloorclip = ds->sprbottomclip; mfloorclip = ds->sprbottomclip;
@ -733,7 +750,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (skewslope) if (skewslope)
{ {
angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); ffloortextureslide = FixedMul(R_GetSlopeTextureSlide(skewslope, lineangle), wall_scaley);
} }
dc_texturemid += offsetvalue; dc_texturemid += offsetvalue;
@ -741,7 +758,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// Texture must be cached // Texture must be cached
R_CheckTextureCache(texnum); R_CheckTextureCache(texnum);
if (textures[texnum]->flip & 2) // vertically flipped? if (vertflip) // vertically flipped?
colfunc_2s = R_DrawRepeatFlippedMaskedColumn; colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
else else
colfunc_2s = R_DrawRepeatMaskedColumn; colfunc_2s = R_DrawRepeatMaskedColumn;
@ -775,9 +792,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// skew FOF walls // skew FOF walls
if (ffloortextureslide) if (ffloortextureslide)
{ {
if (oldx != -1) if (oldtexturecolumn != -1)
dc_texturemid += FixedMul(ffloortextureslide, thicksidecol[oldx]-thicksidecol[dc_x]); dc_texturemid += FixedMul(ffloortextureslide, oldtexturecolumn-ds->thicksidecol[dc_x]);
oldx = dc_x; oldtexturecolumn = ds->thicksidecol[dc_x];
} }
// Calculate bounds // Calculate bounds
@ -814,7 +831,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley); dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley);
// Get data for the column // Get data for the column
col = R_GetColumn(texnum, (thicksidecol[dc_x] >> FRACBITS)); col = R_GetColumn(texnum, ((thicksidecol[dc_x] + wall_offsetx) >> FRACBITS));
// SoM: New code does not rely on R_DrawColumnShadowed_8 which // SoM: New code does not rely on R_DrawColumnShadowed_8 which
// will (hopefully) put less strain on the stack. // will (hopefully) put less strain on the stack.
@ -988,36 +1005,77 @@ static boolean R_FFloorCanClip(visffloor_t *pfloor)
#define HEIGHTBITS 12 #define HEIGHTBITS 12
#define HEIGHTUNIT (1<<HEIGHTBITS) #define HEIGHTUNIT (1<<HEIGHTBITS)
static void R_DrawRegularWall(UINT8 *source, INT32 height)
{
dc_source = source;
dc_texheight = height;
colfunc();
}
//profile stuff --------------------------------------------------------- static void R_DrawFlippedWall(UINT8 *source, INT32 height)
//#define TIMING {
#ifdef TIMING dc_texheight = height;
#include "p5prof.h" R_DrawFlippedPost(source, (unsigned)height, colfunc);
INT64 mycount; }
INT64 mytotal = 0;
UINT32 nombre = 100000; static void R_DrawNoWall(UINT8 *source, INT32 height)
//static char runtest[10][80]; {
#endif (void)source;
//profile stuff --------------------------------------------------------- (void)height;
}
static void R_RenderSegLoop (void) static void R_RenderSegLoop (void)
{ {
angle_t angle; angle_t angle;
fixed_t textureoffset; fixed_t textureoffset;
size_t pindex; size_t pindex;
INT32 yl; INT32 yl;
INT32 yh; INT32 yh;
INT32 mid; INT32 mid;
fixed_t texturecolumn = 0; fixed_t texturecolumn = 0;
fixed_t toptexturecolumn = 0; fixed_t toptexturecolumn = 0;
fixed_t bottomtexturecolumn = 0; fixed_t bottomtexturecolumn = 0;
fixed_t oldtexturecolumn = -1; fixed_t oldtexturecolumn = -1;
fixed_t oldtexturecolumn_top = -1; fixed_t oldtexturecolumn_top = -1;
fixed_t oldtexturecolumn_bottom = -1; fixed_t oldtexturecolumn_bottom = -1;
INT32 top; INT32 top;
INT32 bottom; INT32 bottom;
INT32 i; INT32 i;
fixed_t topscaley = rw_toptexturescaley;
fixed_t midscaley = rw_midtexturescaley;
fixed_t bottomscaley = rw_bottomtexturescaley;
void (*drawtop)(UINT8 *, INT32) = R_DrawRegularWall;
void (*drawmiddle)(UINT8 *, INT32) = R_DrawRegularWall;
void (*drawbottom)(UINT8 *, INT32) = R_DrawRegularWall;
if (dc_numlights)
colfunc = colfuncs[COLDRAWFUNC_SHADOWED];
if (toptexture && topscaley < 0)
{
topscaley = -topscaley;
drawtop = R_DrawFlippedWall;
}
if (midtexture && midscaley < 0)
{
midscaley = -midscaley;
drawmiddle = R_DrawFlippedWall;
}
if (bottomtexture && bottomscaley < 0)
{
bottomscaley = -bottomscaley;
drawbottom = R_DrawFlippedWall;
}
if (!r_renderwalls)
{
drawtop = R_DrawNoWall;
drawmiddle = R_DrawNoWall;
drawbottom = R_DrawNoWall;
}
if (midtexture) if (midtexture)
R_CheckTextureCache(midtexture); R_CheckTextureCache(midtexture);
@ -1252,32 +1310,14 @@ static void R_RenderSegLoop (void)
// single sided line // single sided line
if (yl <= yh && yh >= 0 && yl < viewheight) if (yl <= yh && yh >= 0 && yl < viewheight)
{ {
if (cv_renderwalls.value) fixed_t offset = texturecolumn + rw_offsetx;
{
fixed_t offset = texturecolumn + rw_offsetx;
dc_yl = yl; dc_yl = yl;
dc_yh = yh; dc_yh = yh;
dc_texturemid = rw_midtexturemid; dc_texturemid = rw_midtexturemid;
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_midtexturescaley); dc_texheight = textureheight[midtexture]>>FRACBITS;
dc_source = R_GetColumn(midtexture, offset >> FRACBITS)->pixels; dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, midscaley);
dc_texheight = textureheight[midtexture]>>FRACBITS; drawmiddle(R_GetColumn(midtexture, offset >> FRACBITS)->pixels, dc_texheight);
//profile stuff ---------------------------------------------------------
#ifdef TIMING
ProfZeroTimer();
#endif
colfunc();
#ifdef TIMING
RDMSR(0x10,&mycount);
mytotal += mycount; //64bit add
if (nombre--==0)
I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1),
(INT32)mytotal);
#endif
//profile stuff ---------------------------------------------------------
}
// dont draw anything more for this column, since // dont draw anything more for this column, since
// a midtexture blocks the view // a midtexture blocks the view
@ -1321,21 +1361,17 @@ static void R_RenderSegLoop (void)
} }
else if (mid >= 0) // safe to draw top texture else if (mid >= 0) // safe to draw top texture
{ {
if (cv_renderwalls.value) fixed_t offset = rw_offset_top;
{ if (rw_toptexturescalex < 0)
fixed_t offset = rw_offset_top; offset = -offset;
if (rw_toptexturescalex < 0) offset = toptexturecolumn + offset;
offset = -offset;
offset = toptexturecolumn + offset;
dc_yl = yl; dc_yl = yl;
dc_yh = mid; dc_yh = mid;
dc_texturemid = rw_toptexturemid; dc_texturemid = rw_toptexturemid;
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_toptexturescaley); dc_texheight = textureheight[toptexture]>>FRACBITS;
dc_source = R_GetColumn(toptexture, offset >> FRACBITS)->pixels; dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, topscaley);
dc_texheight = textureheight[toptexture]>>FRACBITS; drawtop(R_GetColumn(toptexture, offset >> FRACBITS)->pixels, dc_texheight);
colfunc();
}
ceilingclip[rw_x] = (INT16)mid; ceilingclip[rw_x] = (INT16)mid;
} }
else if (!rw_ceilingmarked) // entirely off top of screen else if (!rw_ceilingmarked) // entirely off top of screen
@ -1345,8 +1381,8 @@ static void R_RenderSegLoop (void)
ceilingclip[rw_x] = topclip; ceilingclip[rw_x] = topclip;
if (oldtexturecolumn_top != -1) if (oldtexturecolumn_top != -1)
rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn_top-toptexturecolumn); rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn_top-textureoffset);
oldtexturecolumn_top = toptexturecolumn; oldtexturecolumn_top = textureoffset;
} }
else if (markceiling && (!rw_ceilingmarked)) // no top wall else if (markceiling && (!rw_ceilingmarked)) // no top wall
ceilingclip[rw_x] = topclip; ceilingclip[rw_x] = topclip;
@ -1372,21 +1408,17 @@ static void R_RenderSegLoop (void)
} }
else if (mid < viewheight) // safe to draw bottom texture else if (mid < viewheight) // safe to draw bottom texture
{ {
if (cv_renderwalls.value) fixed_t offset = rw_offset_bottom;
{ if (rw_bottomtexturescalex < 0)
fixed_t offset = rw_offset_bottom; offset = -offset;
if (rw_bottomtexturescalex < 0) offset = bottomtexturecolumn + offset;
offset = -offset;
offset = bottomtexturecolumn + offset;
dc_yl = mid; dc_yl = mid;
dc_yh = yh; dc_yh = yh;
dc_texturemid = rw_bottomtexturemid; dc_texturemid = rw_bottomtexturemid;
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_bottomtexturescaley); dc_texheight = textureheight[bottomtexture]>>FRACBITS;
dc_source = R_GetColumn(bottomtexture, offset >> FRACBITS)->pixels; dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, bottomscaley);
dc_texheight = textureheight[bottomtexture]>>FRACBITS; drawbottom(R_GetColumn(bottomtexture, offset >> FRACBITS)->pixels, dc_texheight);
colfunc();
}
floorclip[rw_x] = (INT16)mid; floorclip[rw_x] = (INT16)mid;
} }
else if (!rw_floormarked) // entirely off bottom of screen else if (!rw_floormarked) // entirely off bottom of screen
@ -1396,8 +1428,8 @@ static void R_RenderSegLoop (void)
floorclip[rw_x] = bottomclip; floorclip[rw_x] = bottomclip;
if (oldtexturecolumn_bottom != -1) if (oldtexturecolumn_bottom != -1)
rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn_bottom-bottomtexturecolumn); rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn_bottom-textureoffset);
oldtexturecolumn_bottom = bottomtexturecolumn; oldtexturecolumn_bottom = textureoffset;
} }
else if (markfloor && (!rw_floormarked)) // no bottom wall else if (markfloor && (!rw_floormarked)) // no bottom wall
floorclip[rw_x] = bottomclip; floorclip[rw_x] = bottomclip;
@ -1421,11 +1453,14 @@ static void R_RenderSegLoop (void)
{ {
if (oldtexturecolumn != -1) if (oldtexturecolumn != -1)
{ {
rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); INT32 diff = oldtexturecolumn-textureoffset;
rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); if (rw_invmidtexturescalex < 0)
diff = -diff;
rw_midtexturemid += FixedMul(rw_midtextureslide, diff);
rw_midtextureback += FixedMul(rw_midtexturebackslide, diff);
} }
oldtexturecolumn = texturecolumn; oldtexturecolumn = textureoffset;
} }
if (invscale) if (invscale)
@ -1519,7 +1554,7 @@ static void R_AllocClippingTables(size_t range)
static void R_AllocTextureColumnTables(size_t range) static void R_AllocTextureColumnTables(size_t range)
{ {
size_t pos = curtexturecolumntable - texturecolumntable; size_t pos = curtexturecolumntable - texturecolumntable;
size_t need = range * 3; size_t need = range * 4;
if (pos + need < texturecolumntablesize) if (pos + need < texturecolumntablesize)
return; return;
@ -1540,15 +1575,48 @@ static void R_AllocTextureColumnTables(size_t range)
for (drawseg_t *ds = drawsegs; ds < ds_p; ds++) for (drawseg_t *ds = drawsegs; ds < ds_p; ds++)
{ {
// Check if it's in range of the tables // Check if it's in range of the tables
if (ds->maskedtexturecol + ds->x1 >= oldtable && ds->maskedtexturecol + ds->x1 <= oldlast) #define CHECK(which) \
ds->maskedtexturecol = (ds->maskedtexturecol - oldtable) + texturecolumntable; if (which + ds->x1 >= oldtable && which + ds->x1 <= oldlast) \
if (ds->thicksidecol + ds->x1 >= oldtable && ds->thicksidecol + ds->x1 <= oldlast) which = (which - oldtable) + texturecolumntable
ds->thicksidecol = (ds->thicksidecol - oldtable) + texturecolumntable;
if (ds->invscale + ds->x1 >= oldtable && ds->invscale + ds->x1 <= oldlast) CHECK(ds->maskedtexturecol);
ds->invscale = (ds->invscale - oldtable) + texturecolumntable; CHECK(ds->maskedtextureheight);
CHECK(ds->thicksidecol);
CHECK(ds->invscale);
#undef CHECK
} }
} }
//
// R_ScaleFromGlobalAngle
// Returns the texture mapping scale for the current line (horizontal span)
// at the given angle.
// rw_distance must be calculated first.
//
// killough 5/2/98: reformatted, cleaned up
//
// note: THIS IS USED ONLY FOR WALLS!
static fixed_t R_ScaleFromGlobalAngle(angle_t visangle)
{
angle_t anglea = ANGLE_90 + (visangle-viewangle);
angle_t angleb = ANGLE_90 + (visangle-rw_normalangle);
fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT));
// proff 11/06/98: Changed for high-res
fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT));
if (den > num>>16)
{
num = FixedDiv(num, den);
if (num > 64*FRACUNIT)
return 64*FRACUNIT;
if (num < 256)
return 256;
return num;
}
return 64*FRACUNIT;
}
// //
// R_StoreWallRange // R_StoreWallRange
// A wall segment will be drawn // A wall segment will be drawn
@ -1720,11 +1788,14 @@ void R_StoreWallRange(INT32 start, INT32 stop)
midtexture = toptexture = bottomtexture = maskedtexture = 0; midtexture = toptexture = bottomtexture = maskedtexture = 0;
ds_p->maskedtexturecol = NULL; ds_p->maskedtexturecol = NULL;
ds_p->maskedtextureheight = NULL;
ds_p->numthicksides = numthicksides = 0; ds_p->numthicksides = numthicksides = 0;
ds_p->thicksidecol = NULL; ds_p->thicksidecol = NULL;
ds_p->invscale = NULL; ds_p->invscale = NULL;
ds_p->tsilheight = 0; ds_p->tsilheight = 0;
texcoltables = false;
numbackffloors = 0; numbackffloors = 0;
for (i = 0; i < MAXFFLOORS; i++) for (i = 0; i < MAXFFLOORS; i++)
@ -1750,16 +1821,19 @@ void R_StoreWallRange(INT32 start, INT32 stop)
angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
if (frontsector->f_slope) if (frontsector->f_slope)
floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); floorfrontslide = R_GetSlopeTextureSlide(frontsector->f_slope, lineangle);
if (frontsector->c_slope) if (frontsector->c_slope)
ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); ceilingfrontslide = R_GetSlopeTextureSlide(frontsector->c_slope, lineangle);
if (backsector && backsector->f_slope) if (backsector)
floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); {
if (backsector->f_slope)
floorbackslide = R_GetSlopeTextureSlide(backsector->f_slope, lineangle);
if (backsector && backsector->c_slope) if (backsector->c_slope)
ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); ceilingbackslide = R_GetSlopeTextureSlide(backsector->c_slope, lineangle);
}
} }
rw_midtexturescalex = sidedef->scalex_mid; rw_midtexturescalex = sidedef->scalex_mid;
@ -1775,26 +1849,27 @@ void R_StoreWallRange(INT32 start, INT32 stop)
fixed_t rowoffset = sidedef->rowoffset + sidedef->offsety_mid; fixed_t rowoffset = sidedef->rowoffset + sidedef->offsety_mid;
fixed_t texheight = textureheight[midtexture]; fixed_t texheight = textureheight[midtexture];
fixed_t scaley = abs(rw_midtexturescaley);
if (rw_midtexturescaley > 0) if (rw_midtexturescaley > 0)
{ {
if (linedef->flags & ML_NOSKEW) if (linedef->flags & ML_NOSKEW)
{ {
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_DONTPEGBOTTOM)
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley) + texheight; rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, scaley) + texheight;
else else
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley); rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, scaley);
} }
else if (linedef->flags & ML_DONTPEGBOTTOM) else if (linedef->flags & ML_DONTPEGBOTTOM)
{ {
rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley) + texheight; rw_midtexturemid = FixedMul(worldbottom, scaley) + texheight;
rw_midtextureslide = floorfrontslide; rw_midtextureslide = FixedMul(floorfrontslide, scaley);
} }
else else
{ {
// top of texture at top // top of texture at top
rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley); rw_midtexturemid = FixedMul(worldtop, scaley);
rw_midtextureslide = ceilingfrontslide; rw_midtextureslide = FixedMul(ceilingfrontslide, scaley);
} }
} }
else else
@ -1805,20 +1880,20 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (linedef->flags & ML_NOSKEW) if (linedef->flags & ML_NOSKEW)
{ {
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_DONTPEGBOTTOM)
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley); rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, scaley);
else else
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley) + texheight; rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, scaley) + texheight;
} }
else if (linedef->flags & ML_DONTPEGBOTTOM) else if (linedef->flags & ML_DONTPEGBOTTOM)
{ {
rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley); rw_midtexturemid = FixedMul(worldbottom, scaley);
rw_midtextureslide = floorfrontslide; rw_midtextureslide = FixedMul(floorfrontslide, scaley);
} }
else else
{ {
// top of texture at top // top of texture at top
rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley) + texheight; rw_midtexturemid = FixedMul(worldtop, scaley) + texheight;
rw_midtextureslide = ceilingfrontslide; rw_midtextureslide = FixedMul(ceilingfrontslide, scaley);
} }
} }
@ -2027,15 +2102,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{ {
// top of texture at top // top of texture at top
rw_toptexturemid = worldtop; rw_toptexturemid = worldtop;
rw_toptextureslide = ceilingfrontslide; rw_toptextureslide = FixedMul(ceilingfrontslide, abs(rw_toptexturescaley));
} }
else else
{ {
rw_toptexturemid = worldhigh + texheight; rw_toptexturemid = worldhigh + texheight;
rw_toptextureslide = ceilingbackslide; rw_toptextureslide = FixedMul(ceilingbackslide, abs(rw_toptexturescaley));
} }
rw_toptexturemid = FixedMul(rw_toptexturemid, rw_toptexturescaley); rw_toptexturemid = FixedMul(rw_toptexturemid, abs(rw_toptexturescaley));
rw_toptexturemid += toprowoffset;
} }
// check BOTTOM TEXTURE // check BOTTOM TEXTURE
@ -2066,24 +2142,24 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// bottom of texture at bottom // bottom of texture at bottom
// top of texture at top // top of texture at top
rw_bottomtexturemid = worldbottom; rw_bottomtexturemid = worldbottom;
rw_bottomtextureslide = floorfrontslide; rw_bottomtextureslide = FixedMul(floorfrontslide, abs(rw_bottomtexturescaley));
} }
else else
{ {
// top of texture at top // top of texture at top
rw_bottomtexturemid = worldlow; rw_bottomtexturemid = worldlow;
rw_bottomtextureslide = floorbackslide; rw_bottomtextureslide = FixedMul(floorbackslide, abs(rw_bottomtexturescaley));
} }
rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, rw_bottomtexturescaley); rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, abs(rw_bottomtexturescaley));
rw_bottomtexturemid += botrowoffset;
} }
rw_toptexturemid += toprowoffset;
rw_bottomtexturemid += botrowoffset;
// allocate space for masked texture tables // allocate space for masked texture tables
R_AllocTextureColumnTables(rw_stopx - start); R_AllocTextureColumnTables(rw_stopx - start);
texcoltables = true;
if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors)) if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors))
{ {
ffloor_t *rover; ffloor_t *rover;
@ -2282,7 +2358,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x; ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x; curtexturecolumntable += rw_stopx - rw_x;
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) ds_p->maskedtextureheight = maskedtextureheight = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x;
maskedtexture = true; maskedtexture = true;
@ -2324,13 +2401,14 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} }
} }
rw_midtexturemid = FixedMul(rw_midtexturemid, rw_midtexturescaley); rw_midtexturemid = FixedMul(rw_midtexturemid, abs(rw_midtexturescaley));
rw_midtextureback = FixedMul(rw_midtextureback, rw_midtexturescaley); rw_midtextureback = FixedMul(rw_midtextureback, abs(rw_midtexturescaley));
rw_midtextureslide = FixedMul(rw_midtextureslide, abs(rw_midtexturescaley));
rw_midtexturebackslide = FixedMul(rw_midtexturebackslide, abs(rw_midtexturescaley));
rw_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid; rw_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid;
rw_midtextureback += sidedef->rowoffset + sidedef->offsety_mid; rw_midtextureback += sidedef->rowoffset + sidedef->offsety_mid;
maskedtexture = true;
} }
} }

View file

@ -376,7 +376,7 @@ static void SetSkin(player_t *player, INT32 skinnum)
player->mo->skin = skin; player->mo->skin = skin;
if (newcolor) if (newcolor)
player->mo->color = newcolor; player->mo->color = newcolor;
P_SetScale(player->mo, player->mo->scale); P_SetScale(player->mo, player->mo->scale, false);
player->mo->radius = radius; player->mo->radius = radius;
P_SetMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames P_SetMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames

View file

@ -658,12 +658,31 @@ void R_DrawMaskedColumn(column_t *column, unsigned lengthcol)
static UINT8 *flippedcol = NULL; static UINT8 *flippedcol = NULL;
static size_t flippedcolsize = 0; static size_t flippedcolsize = 0;
void R_DrawFlippedPost(UINT8 *source, unsigned length, void (*drawcolfunc)(void))
{
if (!length)
return;
if (!flippedcolsize || length > flippedcolsize)
{
flippedcolsize = length;
flippedcol = Z_Realloc(flippedcol, length, PU_STATIC, NULL);
}
dc_source = flippedcol;
for (UINT8 *s = (UINT8 *)source, *d = flippedcol+length-1; d >= flippedcol; s++)
*d-- = *s;
drawcolfunc();
}
void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol) void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol)
{ {
INT32 topscreen; INT32 topscreen;
INT32 bottomscreen; INT32 bottomscreen;
fixed_t basetexturemid = dc_texturemid; fixed_t basetexturemid = dc_texturemid;
UINT8 *d,*s; INT32 topdelta;
for (unsigned i = 0; i < column->num_posts; i++) for (unsigned i = 0; i < column->num_posts; i++)
{ {
@ -671,7 +690,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol)
if (!post->length) if (!post->length)
continue; continue;
INT32 topdelta = lengthcol-post->length-post->topdelta; topdelta = lengthcol-post->length-post->topdelta;
topscreen = sprtopscreen + spryscale*topdelta; topscreen = sprtopscreen + spryscale*topdelta;
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*post->length bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*post->length
: sprbotscreen + spryscale*post->length; : sprbotscreen + spryscale*post->length;
@ -698,18 +717,9 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol)
if (dc_yl <= dc_yh && dc_yh > 0) if (dc_yl <= dc_yh && dc_yh > 0)
{ {
if (post->length > flippedcolsize)
{
flippedcolsize = post->length;
flippedcol = Z_Realloc(flippedcol, flippedcolsize, PU_STATIC, NULL);
}
for (s = column->pixels+post->data_offset+post->length, d = flippedcol; d < flippedcol+post->length; --s)
*d++ = *s;
dc_source = flippedcol;
dc_texturemid = basetexturemid - (topdelta<<FRACBITS); dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
colfunc(); R_DrawFlippedPost(column->pixels + post->data_offset, post->length, colfunc);
} }
} }
@ -1536,7 +1546,7 @@ static void R_ProjectSprite(mobj_t *thing)
// uncapped/interpolation // uncapped/interpolation
interpmobjstate_t interp = {0}; interpmobjstate_t interp = {0};
if (!cv_renderthings.value) if (!r_renderthings)
return; return;
// do interpolation // do interpolation
@ -2698,7 +2708,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
// Add the 3D floors, thicksides, and masked textures... // Add the 3D floors, thicksides, and masked textures...
for (ds = drawsegs + mask->drawsegs[1]; ds-- > drawsegs + mask->drawsegs[0];) for (ds = drawsegs + mask->drawsegs[1]; ds-- > drawsegs + mask->drawsegs[0];)
{ {
if (ds->numthicksides) if (ds->numthicksides && r_renderwalls)
{ {
for (i = 0; i < ds->numthicksides; i++) for (i = 0; i < ds->numthicksides; i++)
{ {
@ -2717,17 +2727,19 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
else { else {
// Put it in! // Put it in!
entry = R_CreateDrawNode(head); entry = R_CreateDrawNode(head);
entry->plane = plane; if (r_renderwalls)
entry->seg = ds; entry->seg = ds;
if (r_renderfloors)
entry->plane = plane;
} }
ds->curline->polyseg->visplane = NULL; ds->curline->polyseg->visplane = NULL;
} }
if (ds->maskedtexturecol) if (ds->maskedtexturecol && r_renderwalls)
{ {
entry = R_CreateDrawNode(head); entry = R_CreateDrawNode(head);
entry->seg = ds; entry->seg = ds;
} }
if (ds->numffloorplanes) if (ds->numffloorplanes && r_renderfloors)
{ {
for (i = 0; i < ds->numffloorplanes; i++) for (i = 0; i < ds->numffloorplanes; i++)
{ {
@ -3194,9 +3206,6 @@ static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* port
(lowscale < spr->sortscale && (lowscale < spr->sortscale &&
!R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) !R_PointOnSegSide (spr->gx, spr->gy, ds->curline)))
{ {
// masked mid texture?
/*if (ds->maskedtexturecol)
R_RenderMaskedSegRange (ds, r1, r2);*/
// seg is behind sprite // seg is behind sprite
continue; continue;
} }

View file

@ -48,6 +48,7 @@ extern fixed_t windowbottom;
void R_DrawMaskedColumn(column_t *column, unsigned lengthcol); void R_DrawMaskedColumn(column_t *column, unsigned lengthcol);
void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol); void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol);
void R_DrawFlippedPost(UINT8 *source, unsigned length, void (*drawcolfunc)(void));
// ---------------- // ----------------
// SPRITE RENDERING // SPRITE RENDERING

View file

@ -72,11 +72,6 @@ consvar_t cv_scr_width_w = CVAR_INIT ("scr_width_w", "640", CV_SAVE, CV_Unsigned
consvar_t cv_scr_height_w = CVAR_INIT ("scr_height_w", "400", CV_SAVE, CV_Unsigned, NULL); consvar_t cv_scr_height_w = CVAR_INIT ("scr_height_w", "400", CV_SAVE, CV_Unsigned, NULL);
consvar_t cv_scr_depth = CVAR_INIT ("scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL); consvar_t cv_scr_depth = CVAR_INIT ("scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL);
consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL);
consvar_t cv_renderwalls = CVAR_INIT ("renderwalls", "On", CV_NOTINNET|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_renderfloors = CVAR_INIT ("renderfloors", "On", CV_NOTINNET|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_renderthings = CVAR_INIT ("renderthings", "On", CV_NOTINNET|CV_CHEAT, CV_OnOff, NULL);
CV_PossibleValue_t cv_renderer_t[] = { CV_PossibleValue_t cv_renderer_t[] = {
{1, "Software"}, {1, "Software"},
#ifdef HWRENDER #ifdef HWRENDER

View file

@ -157,9 +157,7 @@ extern CV_PossibleValue_t cv_renderer_t[];
extern INT32 scr_bpp; extern INT32 scr_bpp;
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_width_w, cv_scr_height_w, cv_scr_depth, cv_fullscreen; extern consvar_t cv_scr_width, cv_scr_height, cv_scr_width_w, cv_scr_height_w, cv_scr_depth, cv_fullscreen;
extern consvar_t cv_renderwalls, cv_renderfloors, cv_renderthings; extern consvar_t cv_renderer;
extern consvar_t cv_renderview, cv_renderer;
extern consvar_t cv_renderhitbox, cv_renderhitboxinterpolation, cv_renderhitboxgldepth;
// wait for page flipping to end or not // wait for page flipping to end or not
extern consvar_t cv_vidwait; extern consvar_t cv_vidwait;
extern consvar_t cv_timescale; extern consvar_t cv_timescale;

View file

@ -1171,8 +1171,10 @@ static void ST_drawInput(void)
V_DrawFill(x+16+(xoffs), y+(yoffs)-offs, 10, 10, col);\ V_DrawFill(x+16+(xoffs), y+(yoffs)-offs, 10, 10, col);\
V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, hudinfo[HUD_INPUT].f|symb, false) V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, hudinfo[HUD_INPUT].f|symb, false)
drawbutt( 4,-3, BT_JUMP, 'J'); drawbutt( 4,-3, BT_JUMP, 'J' );
drawbutt(15,-3, BT_SPIN, 'S'); drawbutt(15,-3, BT_SPIN, 'S' );
drawbutt(26,-3, BT_SHIELD, '\0'); // Instead of a wide 'J' or 'S', we'll draw a thin "SH" for Shield
V_DrawThinString(x+16+26, y+2+(-3)-offs, hudinfo[HUD_LIVES].f, "SH");
V_DrawFill(x+16+4, y+8, 21, 10, hudinfo[HUD_INPUT].f|20); // sundial backing V_DrawFill(x+16+4, y+8, 21, 10, hudinfo[HUD_INPUT].f|20); // sundial backing
if (stplyr->mo) if (stplyr->mo)

View file

@ -579,9 +579,9 @@ void Y_IntermissionDrawer(void)
{ {
if (LUA_HudEnabled(hud_intermissiontitletext)) if (LUA_HudEnabled(hud_intermissiontitletext))
{ {
const char *ringtext = "\x82" "get 50 rings then"; const char *ringtext = "\x82" "get 50 rings, then";
const char *tut1text = "\x82" "press " "\x80" "shield"; const char *tut1text = "\x82" "press " "\x80" "shield";
const char *tut2text = "\x82" "to " "\x80" "transform"; const char *tut2text = "\x82" "to transform";
ttheight = 8; ttheight = 8;
V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
ttheight += V_LevelNameHeight(data.spec.passed3) + 2; ttheight += V_LevelNameHeight(data.spec.passed3) + 2;