Merge branch 'next' into sector-portals

This commit is contained in:
Lactozilla 2023-12-27 23:46:16 -03:00
commit fd64fdfa34
70 changed files with 3854 additions and 2705 deletions

1
.gitattributes vendored
View file

@ -10,6 +10,7 @@
/src/Make*.cfg text=auto /src/Make*.cfg text=auto
/src/CMakeLists.txt text=auto /src/CMakeLists.txt text=auto
*.mk -whitespace text=auto *.mk -whitespace text=auto
/comptime.sh text eol=lf
# Windows EOL # Windows EOL
*.cs -crlf -whitespace *.cs -crlf -whitespace
*.bat -crlf -whitespace *.bat -crlf -whitespace

View file

@ -3,7 +3,7 @@ variables:
GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_PATH GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_PATH
default: default:
image: debian:stable-slim image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:stable
cache: cache:
- key: ccache-$CI_PROJECT_PATH_SLUG-$CI_JOB_NAME_SLUG - key: ccache-$CI_PROJECT_PATH_SLUG-$CI_JOB_NAME_SLUG
@ -19,6 +19,11 @@ default:
- apt-cache - apt-cache
unprotect: true unprotect: true
- key: apk-$CI_JOB_IMAGE
paths:
- apk-cache
unprotect: true
before_script: before_script:
- - | - - |
# debconf # debconf
@ -167,6 +172,10 @@ Debian testing GCC:
allow_failure: true allow_failure: true
artifacts: artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "testing-gcc"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-gcc" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-gcc"
variables: variables:
@ -401,6 +410,10 @@ Debian stable Clang:
allow_failure: true allow_failure: true
artifacts: artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "clang"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
variables: variables:
@ -442,6 +455,10 @@ Debian stable musl:
allow_failure: true allow_failure: true
artifacts: artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "musl"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-musl" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-musl"
variables: variables:
@ -481,6 +498,10 @@ Debian testing Clang:
image: debian:testing-slim image: debian:testing-slim
artifacts: artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "testing-clang"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-clang" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-clang"
variables: variables:
@ -497,9 +518,143 @@ Debian testing musl:
image: debian:testing-slim image: debian:testing-slim
artifacts: artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "testing-musl"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-musl" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-musl"
variables: variables:
CC: musl-gcc CC: musl-gcc
LDD: musl-ldd LDD: musl-ldd
LDFLAGS: -Wl,-fuse-ld=gold LDFLAGS: -Wl,-fuse-ld=gold
Alpine 3 GCC:
stage: build
when: on_success
image: alpine:3
allow_failure: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Apline-3"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3"
before_script:
- - |
# apk_cache
echo -e "\e[0Ksection_start:`date +%s`:apk_cache[collapsed=true]\r\e[0KUpdating APK listing"
- export APK_CACHE_DIR=`pwd`/apk-cache
- mkdir --parents --verbose $APK_CACHE_DIR/
- ln -sf /etc/apk/cache $APK_CACHE_DIR
- |
# apk_cache
echo -e "\e[0Ksection_end:`date +%s`:apk_cache\r\e[0K"
- - |
# apk_update
echo -e "\e[0Ksection_start:`date +%s`:apk_update[collapsed=true]\r\e[0KUpdating APK listing"
- apk update
- |
# apk_update
echo -e "\e[0Ksection_end:`date +%s`:apk_update\r\e[0K"
- - |
# apk_upgrade
echo -e "\e[0Ksection_start:`date +%s`:apk_upgrade[collapsed=true]\r\e[0KUpdating existing packages"
- apk upgrade
- |
# apk_update
echo -e "\e[0Ksection_end:`date +%s`:apk_upgrade\r\e[0K"
- - |
# apk_common
echo -e "\e[0Ksection_start:`date +%s`:apk_common[collapsed=true]\r\e[0KInstalling common packages"
- apk add make git ccache nasm
- |
# apk_common
echo -e "\e[0Ksection_end:`date +%s`:apk_common\r\e[0K"
- - |
# ccache_config
echo -e "\e[0Ksection_start:`date +%s`:ccache_config[collapsed=true]\r\e[0KSetting up ccache config"
- mkdir --parents --verbose ~/.ccache/
- touch ~/.ccache/ccache.conf
- |
# cache.conf
echo Adding ccache configution option
- |
# base_dir
echo base_dir = $PWD | tee -a ~/.ccache/ccache.conf
- |
# cache_dir
echo cache_dir = $PWD/ccache | tee -a ~/.ccache/ccache.conf
- |
# compiler_check
echo compiler_check = content | tee -a ~/.ccache/ccache.conf
- |
# stats_log
echo stats_log = $PWD/ccache_statslog | tee -a ~/.ccache/ccache.conf
- |
# max_size
echo max_size = 50M | tee -a ~/.ccache/ccache.conf
- |
# ccache_config
echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K"
- - |
# cache_reset
echo -e "\e[0Ksection_start:`date +%s`:ccache_reset[collapsed=true]\r\e[0KResetting ccache statistics"
- ccache --zero-stats
- ccache --show-stats
- |
# ccache_reset
echo -e "\e[0Ksection_end:`date +%s`:ccache_reset\r\e[0K"
script:
- - |
# apk_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apk_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apk add gcc
- |
# apk_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apk_toolchain\r\e[0K"
- - |
# apk_development
echo -e "\e[0Ksection_start:`date +%s`:apk_development[collapsed=true]\r\e[0KInstalling development packages"
- apk add musl-dev sdl2_mixer-dev libpng-dev curl-dev libgme-dev libopenmpt-dev
- |
# apk_development
echo -e "\e[0Ksection_end:`date +%s`:apk_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
after_script:
- - |
# apk_clean
echo -e "\e[0Ksection_start:`date +%s`:apk_clean[collapsed=true]\r\e[0KCleaning of unneeded APK packages"
- apk cache clean
- |
# apk_clean
echo -e "\e[0Ksection_end:`date +%s`:apk_clean\r\e[0K"
- - |
# ccache_stats
echo -e "\e[0Ksection_start:`date +%s`:ccache_stats[collapsed=true]\r\e[0Kccache statistics:"
- ccache --show-stats --verbose
- ccache --show-log-stats --verbose
- |
# ccahe_stats
echo -e "\e[0Ksection_end:`date +%s`:ccache_stats\r\e[0K"

View file

@ -1,6 +1,7 @@
@echo off @echo off
set BRA=Unknown set BRA=Unknown
set REV=illegal set REV=illegal
set GL1=Dummy
copy nul: /b +%1\comptime.c tmp.$$$ > nul copy nul: /b +%1\comptime.c tmp.$$$ > nul
move tmp.$$$ %1\comptime.c > nul move tmp.$$$ %1\comptime.c > nul
@ -13,8 +14,9 @@ goto filwri
:gitrev :gitrev
set GIT=%2 set GIT=%2
if "%GIT%"=="" set GIT=git if "%GIT%"=="" set GIT=git
for /f "usebackq" %%s in (`%GIT% rev-parse --abbrev-ref HEAD`) do @set BRA=%%s for /f "tokens=* usebackq" %%s in (`%GIT% rev-parse --abbrev-ref HEAD`) do @set BRA=%%s
for /f "usebackq" %%s in (`%GIT% rev-parse HEAD`) do @set REV=%%s for /f "tokens=* usebackq" %%s in (`%GIT% rev-parse HEAD`) do @set REV=%%s
for /f "tokens=* usebackq" %%s in (`%GIT% log -1 --format^=%%s`) do @set GL1=%%s
set REV=%REV:~0,8% set REV=%REV:~0,8%
goto filwri goto filwri
@ -30,3 +32,4 @@ echo // by the %0 batch file >> %1\comptime.h
echo // >> %1\comptime.h echo // >> %1\comptime.h
echo const char* compbranch = "%BRA%"; >> %1\comptime.h echo const char* compbranch = "%BRA%"; >> %1\comptime.h
echo const char* comprevision = "%REV%"; >> %1\comptime.h echo const char* comprevision = "%REV%"; >> %1\comptime.h
echo const char* compnote = "%GL1%"; >> %1\comptime.h

View file

@ -12,24 +12,26 @@ version() {
// //
const char* compbranch = "$1"; const char* compbranch = "$1";
const char* comprevision = "$2"; const char* comprevision = "$2";
const char* compnote = "$3";
EOF EOF
} }
versiongit() { versiongit() {
gitbranch="$(git rev-parse --abbrev-ref HEAD)" gitbranch="$(git rev-parse --abbrev-ref HEAD)"
gitversion="$(git rev-parse HEAD | cut -c -8)" gitversion="$(git rev-parse HEAD | cut -c -8)"
version "$gitbranch" "$gitversion"; gitsubject="$(git log -1 --format=%s)"
version "$gitbranch" "$gitversion" "$gitsubject";
exit 0 exit 0
} }
versionsvn() { versionsvn() {
svnrevision="$(svnversion -n "$1")" svnrevision="$(svnversion -n "$1")"
version "Subversion" "r$svnrevision"; version "Subversion" "r$svnrevision" "dummy";
exit 0 exit 0
} }
versionfake() { versionfake() {
version "Unknown" "illegal"; version "Unknown" "illegal" "dummy";
} }
compversion() { compversion() {

View file

@ -254,6 +254,7 @@ target_compile_options(SRB2SDL2 PRIVATE
-Winline -Winline
-Wformat-y2k -Wformat-y2k
-Wformat-security -Wformat-security
-fwrapv
$<$<VERSION_LESS:$<C_COMPILER_VERSION>,2.9.5>: $<$<VERSION_LESS:$<C_COMPILER_VERSION>,2.9.5>:
-Wno-div-by-zero -Wno-div-by-zero
@ -323,6 +324,7 @@ target_compile_options(SRB2SDL2 PRIVATE
-Wno-error=non-literal-null-conversion -Wno-error=non-literal-null-conversion
-Wno-error=constant-conversion -Wno-error=constant-conversion
-Wno-error=unused-but-set-variable -Wno-error=unused-but-set-variable
-fwrapv
> >
# C, MSVC # C, MSVC

View file

@ -164,7 +164,7 @@ sources:=
makedir:=../make makedir:=../make
# -DCOMPVERSION: flag to use comptime.h # -DCOMPVERSION: flag to use comptime.h
opts:=-DCOMPVERSION -g opts:=-DCOMPVERSION -g -fwrapv
libs:= libs:=
# This is a list of variables names, of which if defined, # This is a list of variables names, of which if defined,

View file

@ -5,7 +5,7 @@
passthru_opts+=\ passthru_opts+=\
NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\ NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
MOBJCONSISTANCY PACKETDROP ZDEBUG\ MOBJCONSISTANCY PACKETDROP ZDEBUG\
HAVE_MINIUPNPC\ HAVE_MINIUPNPC NOEXECINFO\
# build with debugging information # build with debugging information
ifdef DEBUGMODE ifdef DEBUGMODE

View file

@ -584,11 +584,11 @@ void B_RespawnBot(INT32 playernum)
P_SetOrigin(tails, x, y, z); P_SetOrigin(tails, x, y, z);
if (player->charability == CA_FLY) if (player->charability == CA_FLY)
{ {
P_SetPlayerMobjState(tails, S_PLAY_FLY); P_SetMobjState(tails, S_PLAY_FLY);
tails->player->powers[pw_tailsfly] = (UINT16)-1; tails->player->powers[pw_tailsfly] = (UINT16)-1;
} }
else else
P_SetPlayerMobjState(tails, S_PLAY_FALL); P_SetMobjState(tails, S_PLAY_FALL);
P_SetScale(tails, sonic->scale); P_SetScale(tails, sonic->scale);
tails->destscale = sonic->destscale; tails->destscale = sonic->destscale;
} }
@ -614,6 +614,9 @@ void B_HandleFlightIndicator(player_t *player)
// otherwise, spawn it // otherwise, spawn it
P_SetTarget(&tails->hnext, P_SpawnMobjFromMobj(tails, 0, 0, 0, MT_OVERLAY)); P_SetTarget(&tails->hnext, P_SpawnMobjFromMobj(tails, 0, 0, 0, MT_OVERLAY));
if (P_MobjWasRemoved(tails->hnext))
return; // we can't spawn one, so it can't exist
P_SetTarget(&tails->hnext->target, tails); P_SetTarget(&tails->hnext->target, tails);
P_SetTarget(&tails->hnext->hprev, tails); P_SetTarget(&tails->hnext->hprev, tails);
P_SetMobjState(tails->hnext, S_FLIGHTINDICATOR); P_SetMobjState(tails->hnext, S_FLIGHTINDICATOR);

View file

@ -937,7 +937,7 @@ boolean CON_Responder(event_t *ev)
return false; return false;
// let go keyup events, don't eat them // let go keyup events, don't eat them
if (ev->type != ev_keydown && ev->type != ev_console) if (ev->type != ev_keydown && ev->type != ev_text && ev->type != ev_console)
{ {
if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1]) if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1])
consdown = false; consdown = false;
@ -952,7 +952,7 @@ boolean CON_Responder(event_t *ev)
if (modeattacking || metalrecording || marathonmode) if (modeattacking || metalrecording || marathonmode)
return false; return false;
if (key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) if ((key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) && !shiftdown)
{ {
if (consdown) // ignore repeat if (consdown) // ignore repeat
return true; return true;
@ -964,7 +964,7 @@ boolean CON_Responder(event_t *ev)
// check other keys only if console prompt is active // check other keys only if console prompt is active
if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!!
{ {
if (! menuactive && bindtable[key]) if (ev->type == ev_keydown && !menuactive && bindtable[key])
{ {
COM_BufAddText(bindtable[key]); COM_BufAddText(bindtable[key]);
COM_BufAddText("\n"); COM_BufAddText("\n");
@ -981,6 +981,13 @@ boolean CON_Responder(event_t *ev)
} }
} }
if (ev->type == ev_text)
{
if (!consoletoggle)
CON_InputAddChar(key);
return true;
}
// Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas // Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas
if (key == KEY_LSHIFT || key == KEY_RSHIFT if (key == KEY_LSHIFT || key == KEY_RSHIFT
|| key == KEY_LCTRL || key == KEY_RCTRL || key == KEY_LCTRL || key == KEY_RCTRL
@ -1295,21 +1302,12 @@ boolean CON_Responder(event_t *ev)
else if (key == KEY_KPADSLASH) else if (key == KEY_KPADSLASH)
key = '/'; key = '/';
if (key >= 'a' && key <= 'z')
{
if (capslock ^ shiftdown)
key = shiftxform[key];
}
else if (shiftdown)
key = shiftxform[key];
// enter a char into the command prompt // enter a char into the command prompt
if (key < 32 || key > 127) if (key < 32 || key > 127)
return true; return true;
if (input_sel != input_cur) if (input_sel != input_cur)
CON_InputDelSelection(); CON_InputDelSelection();
CON_InputAddChar(key);
return true; return true;
} }

View file

@ -22,6 +22,7 @@ typedef enum
{ {
ev_keydown, ev_keydown,
ev_keyup, ev_keyup,
ev_text,
ev_console, ev_console,
ev_mouse, ev_mouse,
ev_joystick, ev_joystick,

View file

@ -192,19 +192,19 @@ void D_ProcessEvents(void)
ev = &events[eventtail]; ev = &events[eventtail];
// Set mouse buttons early in case event is eaten later // Set mouse buttons early in case event is eaten later
if (ev->type == ev_keydown || ev->type == ev_keyup) if (ev->type == ev_keydown || ev->type == ev_keyup || ev->type == ev_text)
{ {
// Mouse buttons // Mouse buttons
if ((UINT32)(ev->key - KEY_MOUSE1) < MOUSEBUTTONS) if ((UINT32)(ev->key - KEY_MOUSE1) < MOUSEBUTTONS)
{ {
if (ev->type == ev_keydown) if (ev->type == ev_keydown || ev->type == ev_text)
mouse.buttons |= 1 << (ev->key - KEY_MOUSE1); mouse.buttons |= 1 << (ev->key - KEY_MOUSE1);
else else
mouse.buttons &= ~(1 << (ev->key - KEY_MOUSE1)); mouse.buttons &= ~(1 << (ev->key - KEY_MOUSE1));
} }
else if ((UINT32)(ev->key - KEY_2MOUSE1) < MOUSEBUTTONS) else if ((UINT32)(ev->key - KEY_2MOUSE1) < MOUSEBUTTONS)
{ {
if (ev->type == ev_keydown) if (ev->type == ev_keydown || ev->type == ev_text)
mouse2.buttons |= 1 << (ev->key - KEY_2MOUSE1); mouse2.buttons |= 1 << (ev->key - KEY_2MOUSE1);
else else
mouse2.buttons &= ~(1 << (ev->key - KEY_2MOUSE1)); mouse2.buttons &= ~(1 << (ev->key - KEY_2MOUSE1));

View file

@ -51,6 +51,7 @@ typedef struct thinker_s
// killough 11/98: count of how many other objects reference // killough 11/98: count of how many other objects reference
// this one using pointers. Used for garbage collection. // this one using pointers. Used for garbage collection.
INT32 references; INT32 references;
boolean cachable;
#ifdef PARANOIA #ifdef PARANOIA
INT32 debug_mobjtype; INT32 debug_mobjtype;

View file

@ -533,7 +533,7 @@ extern char liveeventbackup[256];
#define M_GetText(x) (x) #define M_GetText(x) (x)
#endif #endif
void M_StartupLocale(void); void M_StartupLocale(void);
extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL; void *M_Memcpy(void* dest, const void* src, size_t n);
char *va(const char *format, ...) FUNCPRINTF; char *va(const char *format, ...) FUNCPRINTF;
char *M_GetToken(const char *inputString); char *M_GetToken(const char *inputString);
void M_UnGetToken(void); void M_UnGetToken(void);

View file

@ -4524,7 +4524,7 @@ void F_TextPromptDrawer(void)
if (players[j].mo->state == states+S_PLAY_STND && players[j].mo->tics != -1)\ if (players[j].mo->state == states+S_PLAY_STND && players[j].mo->tics != -1)\
players[j].mo->tics++;\ players[j].mo->tics++;\
else if (players[j].mo->state == states+S_PLAY_WAIT)\ else if (players[j].mo->state == states+S_PLAY_WAIT)\
P_SetPlayerMobjState(players[j].mo, S_PLAY_STND);\ P_SetMobjState(players[j].mo, S_PLAY_STND);\
}\ }\
} }

View file

@ -798,32 +798,40 @@ void G_GhostTicker(void)
if (type == MT_GHOST) if (type == MT_GHOST)
{ {
mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<<FF_TRANSSHIFT; // P_SpawnGhostMobj sets trans50, we want trans60 if (!P_MobjWasRemoved(mobj))
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<<FF_TRANSSHIFT; // P_SpawnGhostMobj sets trans50, we want trans60
} }
else else
{ {
mobj = P_SpawnMobjFromMobj(g->mo, 0, 0, -FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK); mobj = P_SpawnMobjFromMobj(g->mo, 0, 0, -FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK);
mobj->sprite = states[mobjinfo[type].spawnstate].sprite; if (!P_MobjWasRemoved(mobj))
mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
mobj->color = g->mo->color;
mobj->skin = g->mo->skin;
P_SetScale(mobj, (mobj->destscale = g->mo->scale));
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{ {
mobj->frame = FF_TRANS80; mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
mobj->fuse = mobj->tics; mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
mobj->color = g->mo->color;
mobj->skin = g->mo->skin;
P_SetScale(mobj, (mobj->destscale = g->mo->scale));
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{
mobj->frame = FF_TRANS80;
mobj->fuse = mobj->tics;
}
mobj->tics = -1; // nope.
} }
mobj->tics = -1; // nope.
} }
mobj->floorz = mobj->z;
mobj->ceilingz = mobj->z+mobj->height; if (!P_MobjWasRemoved(mobj))
P_UnsetThingPosition(mobj); {
mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... mobj->floorz = mobj->z;
P_SetThingPosition(mobj); mobj->ceilingz = mobj->z+mobj->height;
if (!mobj->fuse) P_UnsetThingPosition(mobj);
mobj->fuse = 8; mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
P_SetTarget(&mobj->target, g->mo); P_SetThingPosition(mobj);
if (!mobj->fuse)
mobj->fuse = 8;
P_SetTarget(&mobj->target, g->mo);
}
} }
} }
if (xziptic & EZT_HIT) if (xziptic & EZT_HIT)
@ -847,6 +855,8 @@ void G_GhostTicker(void)
|| health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad. || health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad.
continue; continue;
poof = P_SpawnMobj(x, y, z, MT_GHOST); poof = P_SpawnMobj(x, y, z, MT_GHOST);
if (P_MobjWasRemoved(poof))
continue;
poof->angle = angle; poof->angle = angle;
poof->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... poof->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
poof->health = 0; poof->health = 0;
@ -892,19 +902,22 @@ void G_GhostTicker(void)
if (follow) if (follow)
P_RemoveMobj(follow); P_RemoveMobj(follow);
P_SetTarget(&follow, P_SpawnMobjFromMobj(g->mo, 0, 0, 0, MT_GHOST)); P_SetTarget(&follow, P_SpawnMobjFromMobj(g->mo, 0, 0, 0, MT_GHOST));
P_SetTarget(&follow->tracer, g->mo); if (!P_MobjWasRemoved(follow))
follow->tics = -1; {
temp = READINT16(g->p)<<FRACBITS; P_SetTarget(&follow->tracer, g->mo);
follow->height = FixedMul(follow->scale, temp); follow->tics = -1;
temp = READINT16(g->p)<<FRACBITS;
follow->height = FixedMul(follow->scale, temp);
if (followtic & FZT_LINKDRAW) if (followtic & FZT_LINKDRAW)
follow->flags2 |= MF2_LINKDRAW; follow->flags2 |= MF2_LINKDRAW;
if (followtic & FZT_COLORIZED) if (followtic & FZT_COLORIZED)
follow->colorized = true; follow->colorized = true;
if (followtic & FZT_SKIN) if (followtic & FZT_SKIN)
follow->skin = &skins[READUINT8(g->p)]; follow->skin = &skins[READUINT8(g->p)];
}
} }
if (follow) if (follow)
{ {
@ -1097,28 +1110,35 @@ void G_ReadMetalTic(mobj_t *metal)
else else
{ {
mobj = P_SpawnMobjFromMobj(metal, 0, 0, -FixedDiv(FixedMul(metal->info->height, metal->scale) - metal->height,3*FRACUNIT), MT_THOK); mobj = P_SpawnMobjFromMobj(metal, 0, 0, -FixedDiv(FixedMul(metal->info->height, metal->scale) - metal->height,3*FRACUNIT), MT_THOK);
mobj->sprite = states[mobjinfo[type].spawnstate].sprite; if (!P_MobjWasRemoved(mobj))
mobj->frame = states[mobjinfo[type].spawnstate].frame;
mobj->angle = metal->angle;
mobj->color = metal->color;
mobj->skin = metal->skin;
P_SetScale(mobj, (mobj->destscale = metal->scale));
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{ {
mobj->frame = FF_TRANS70; mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
mobj->fuse = mobj->tics; mobj->frame = states[mobjinfo[type].spawnstate].frame;
mobj->angle = metal->angle;
mobj->color = metal->color;
mobj->skin = metal->skin;
P_SetScale(mobj, (mobj->destscale = metal->scale));
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{
mobj->frame = FF_TRANS70;
mobj->fuse = mobj->tics;
}
mobj->tics = -1; // nope.
} }
mobj->tics = -1; // nope.
} }
mobj->floorz = mobj->z;
mobj->ceilingz = mobj->z+mobj->height; if (!P_MobjWasRemoved(mobj))
P_UnsetThingPosition(mobj); {
mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... mobj->floorz = mobj->z;
P_SetThingPosition(mobj); mobj->ceilingz = mobj->z+mobj->height;
if (!mobj->fuse) P_UnsetThingPosition(mobj);
mobj->fuse = 8; mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
P_SetTarget(&mobj->target, metal); P_SetThingPosition(mobj);
if (!mobj->fuse)
mobj->fuse = 8;
P_SetTarget(&mobj->target, metal);
}
} }
} }
if (xziptic & EZT_SPRITE) if (xziptic & EZT_SPRITE)
@ -1140,19 +1160,22 @@ void G_ReadMetalTic(mobj_t *metal)
if (follow) if (follow)
P_RemoveMobj(follow); P_RemoveMobj(follow);
P_SetTarget(&follow, P_SpawnMobjFromMobj(metal, 0, 0, 0, MT_GHOST)); P_SetTarget(&follow, P_SpawnMobjFromMobj(metal, 0, 0, 0, MT_GHOST));
P_SetTarget(&follow->tracer, metal); if (!P_MobjWasRemoved(follow))
follow->tics = -1; {
temp = READINT16(metal_p)<<FRACBITS; P_SetTarget(&follow->tracer, metal);
follow->height = FixedMul(follow->scale, temp); follow->tics = -1;
temp = READINT16(metal_p)<<FRACBITS;
follow->height = FixedMul(follow->scale, temp);
if (followtic & FZT_LINKDRAW) if (followtic & FZT_LINKDRAW)
follow->flags2 |= MF2_LINKDRAW; follow->flags2 |= MF2_LINKDRAW;
if (followtic & FZT_COLORIZED) if (followtic & FZT_COLORIZED)
follow->colorized = true; follow->colorized = true;
if (followtic & FZT_SKIN) if (followtic & FZT_SKIN)
follow->skin = &skins[READUINT8(metal_p)]; follow->skin = &skins[READUINT8(metal_p)];
}
} }
if (follow) if (follow)
{ {
@ -2535,7 +2558,9 @@ void G_AddGhost(char *defdemoname)
{ // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling. { // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling.
fixed_t z,f,c; fixed_t z,f,c;
fixed_t offset = mthing->z << FRACBITS; fixed_t offset = mthing->z << FRACBITS;
gh->mo = P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST); P_SetTarget(&gh->mo, P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST));
if (P_MobjWasRemoved(gh->mo))
return;
gh->mo->angle = FixedAngle(mthing->angle << FRACBITS); gh->mo->angle = FixedAngle(mthing->angle << FRACBITS);
f = gh->mo->floorz; f = gh->mo->floorz;
c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height; c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height;

View file

@ -308,7 +308,9 @@ consvar_t cv_chatheight= CVAR_INIT ("chatheight", "8", CV_SAVE, chatheight_cons_
consvar_t cv_chatnotifications= CVAR_INIT ("chatnotifications", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_chatnotifications= CVAR_INIT ("chatnotifications", "On", CV_SAVE, CV_OnOff, NULL);
// chat spam protection (why would you want to disable that???) // chat spam protection (why would you want to disable that???)
consvar_t cv_chatspamprotection= CVAR_INIT ("chatspamprotection", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_chatspamprotection= CVAR_INIT ("chatspamprotection", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_chatspamspeed= CVAR_INIT ("chatspamspeed", "35", CV_SAVE|CV_NETVAR, CV_Unsigned, NULL);
consvar_t cv_chatspamburst= CVAR_INIT ("chatspamburst", "3", CV_SAVE|CV_NETVAR, CV_Unsigned, NULL);
// minichat text background // minichat text background
consvar_t cv_chatbacktint = CVAR_INIT ("chatbacktint", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_chatbacktint = CVAR_INIT ("chatbacktint", "On", CV_SAVE, CV_OnOff, NULL);
@ -5380,16 +5382,29 @@ void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc)
INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
{ {
boolean usemapcode = false; boolean usemapcode = false;
INT32 newmapnum; INT32 newmapnum;
size_t mapnamelen = strlen(mapname);
size_t mapnamelen;
char *p; char *p;
mapnamelen = strlen(mapname); if (mapnamelen == 1)
{
if (mapnamelen == 2)/* maybe two digit code */ if (mapname[0] == '*') // current map
{
usemapcode = true;
newmapnum = gamemap;
}
else if (mapname[0] == '+' && mapheaderinfo[gamemap-1]) // next map
{
usemapcode = true;
newmapnum = mapheaderinfo[gamemap-1]->nextlevel;
if (newmapnum < 1 || newmapnum > NUMMAPS)
{
CONS_Alert(CONS_ERROR, M_GetText("NextLevel (%d) is not a valid map.\n"), newmapnum);
return 0;
}
}
}
else if (mapnamelen == 2)/* maybe two digit code */
{ {
if (( newmapnum = M_MapNumber(mapname[0], mapname[1]) )) if (( newmapnum = M_MapNumber(mapname[0], mapname[1]) ))
usemapcode = true; usemapcode = true;

View file

@ -53,7 +53,7 @@ extern consvar_t cv_instantretry;
// used in game menu // used in game menu
extern consvar_t cv_tutorialprompt; extern consvar_t cv_tutorialprompt;
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard; extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_chatspamspeed, cv_chatspamburst, cv_compactscoreboard;
extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_crosshair, cv_crosshair2;
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove;
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2; extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2;

View file

@ -372,11 +372,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
INT32 i; INT32 i;
float height; // constant y for all points on the convex flat polygon float height; // constant y for all points on the convex flat polygon
float flatxref, flatyref, anglef = 0.0f; float anglef = 0.0f;
float fflatwidth = 64.0f, fflatheight = 64.0f; float fflatwidth = 64.0f, fflatheight = 64.0f;
UINT16 flatflag = 63; float xscale = 1.0f, yscale = 1.0f;
boolean texflat = false;
float tempxsow, tempytow; float tempxsow, tempytow;
float scrollx = 0.0f, scrolly = 0.0f; float scrollx = 0.0f, scrolly = 0.0f;
@ -411,11 +409,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
slope = gl_frontsector->c_slope; slope = gl_frontsector->c_slope;
} }
// Set fixedheight to the slope's height from our viewpoint, if we have a slope height = FixedToFloat(fixedheight);
if (slope)
fixedheight = P_GetSlopeZAt(slope, viewx, viewy);
height = FIXED_TO_FLOAT(fixedheight);
// Allocate plane-vertex buffer if we need to // Allocate plane-vertex buffer if we need to
if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts) if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts)
@ -431,8 +425,8 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
if (levelflat->type == LEVELFLAT_FLAT) if (levelflat->type == LEVELFLAT_FLAT)
{ {
size_t len = W_LumpLength(levelflat->u.flat.lumpnum); size_t len = W_LumpLength(levelflat->u.flat.lumpnum);
flatflag = R_GetFlatSize(len) - 1; unsigned flatflag = R_GetFlatSize(len);
fflatwidth = fflatheight = (float)(flatflag + 1); fflatwidth = fflatheight = (float)flatflag;
} }
else else
{ {
@ -446,29 +440,28 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
fflatwidth = levelflat->width; fflatwidth = levelflat->width;
fflatheight = levelflat->height; fflatheight = levelflat->height;
} }
texflat = true;
} }
} }
else // set no texture else // set no texture
HWR_SetCurrentTexture(NULL); HWR_SetCurrentTexture(NULL);
// reference point for flat texture coord for each vertex around the polygon
flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatwidth);
flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatheight);
// transform // transform
if (FOFsector != NULL) if (FOFsector != NULL)
{ {
if (!isceiling) // it's a floor if (!isceiling) // it's a floor
{ {
scrollx = FIXED_TO_FLOAT(FOFsector->floorxoffset)/fflatwidth; xscale = FixedToFloat(FOFsector->floorxscale);
scrolly = FIXED_TO_FLOAT(FOFsector->flooryoffset)/fflatheight; yscale = FixedToFloat(FOFsector->flooryscale);
scrollx = FixedToFloat(FOFsector->floorxoffset) / fflatwidth;
scrolly = FixedToFloat(FOFsector->flooryoffset) / fflatheight;
angle = FOFsector->floorangle; angle = FOFsector->floorangle;
} }
else // it's a ceiling else // it's a ceiling
{ {
scrollx = FIXED_TO_FLOAT(FOFsector->ceilingxoffset)/fflatwidth; xscale = FixedToFloat(FOFsector->ceilingxscale);
scrolly = FIXED_TO_FLOAT(FOFsector->ceilingyoffset)/fflatheight; yscale = FixedToFloat(FOFsector->ceilingyscale);
scrollx = FixedToFloat(FOFsector->ceilingxoffset) / fflatwidth;
scrolly = FixedToFloat(FOFsector->ceilingyoffset) / fflatheight;
angle = FOFsector->ceilingangle; angle = FOFsector->ceilingangle;
} }
} }
@ -476,41 +469,28 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
{ {
if (!isceiling) // it's a floor if (!isceiling) // it's a floor
{ {
scrollx = FIXED_TO_FLOAT(gl_frontsector->floorxoffset)/fflatwidth; xscale = FixedToFloat(gl_frontsector->floorxscale);
scrolly = FIXED_TO_FLOAT(gl_frontsector->flooryoffset)/fflatheight; yscale = FixedToFloat(gl_frontsector->flooryscale);
scrollx = FixedToFloat(gl_frontsector->floorxoffset) / fflatwidth;
scrolly = FixedToFloat(gl_frontsector->flooryoffset) / fflatheight;
angle = gl_frontsector->floorangle; angle = gl_frontsector->floorangle;
} }
else // it's a ceiling else // it's a ceiling
{ {
scrollx = FIXED_TO_FLOAT(gl_frontsector->ceilingxoffset)/fflatwidth; xscale = FixedToFloat(gl_frontsector->ceilingxscale);
scrolly = FIXED_TO_FLOAT(gl_frontsector->ceilingyoffset)/fflatheight; yscale = FixedToFloat(gl_frontsector->ceilingyscale);
scrollx = FixedToFloat(gl_frontsector->ceilingxoffset) / fflatwidth;
scrolly = FixedToFloat(gl_frontsector->ceilingyoffset) / fflatheight;
angle = gl_frontsector->ceilingangle; angle = gl_frontsector->ceilingangle;
} }
} }
if (angle) // Only needs to be done if there's an altered angle anglef = ANG2RAD(InvAngle(angle));
{
tempxsow = flatxref;
tempytow = flatyref;
anglef = ANG2RAD(InvAngle(angle));
flatxref = (tempxsow * cos(anglef)) - (tempytow * sin(anglef));
flatyref = (tempxsow * sin(anglef)) + (tempytow * cos(anglef));
}
#define SETUP3DVERT(vert, vx, vy) {\ #define SETUP3DVERT(vert, vx, vy) {\
/* Hurdler: add scrolling texture on floor/ceiling */\ /* Hurdler: add scrolling texture on floor/ceiling */\
if (texflat)\ vert->s = ((vx) / fflatwidth) + (scrollx / xscale);\
{\ vert->t = -((vy) / fflatheight) + (scrolly / yscale);\
vert->s = (float)((vx) / fflatwidth) + scrollx;\
vert->t = -(float)((vy) / fflatheight) + scrolly;\
}\
else\
{\
vert->s = (float)(((vx) / fflatwidth) - flatxref + scrollx);\
vert->t = (float)(flatyref - ((vy) / fflatheight) + scrolly);\
}\
\ \
/* Need to rotate before translate */\ /* Need to rotate before translate */\
if (angle) /* Only needs to be done if there's an altered angle */\ if (angle) /* Only needs to be done if there's an altered angle */\
@ -521,15 +501,18 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
vert->t = (tempxsow * sin(anglef)) + (tempytow * cos(anglef));\ vert->t = (tempxsow * sin(anglef)) + (tempytow * cos(anglef));\
}\ }\
\ \
vert->x = (vx);\ vert->s *= xscale;\
vert->y = height;\ vert->t *= yscale;\
vert->z = (vy);\
\ \
if (slope)\ if (slope)\
{\ {\
fixedheight = P_GetSlopeZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\ fixedheight = P_GetSlopeZAt(slope, FloatToFixed((vx)), FloatToFixed((vy)));\
vert->y = FIXED_TO_FLOAT(fixedheight);\ height = FixedToFloat(fixedheight);\
}\ }\
\
vert->x = (vx);\
vert->y = height;\
vert->z = (vy);\
} }
for (i = 0, v3d = planeVerts; i < (INT32)nrPlaneVerts; i++,v3d++,pv++) for (i = 0, v3d = planeVerts; i < (INT32)nrPlaneVerts; i++,v3d++,pv++)
@ -1081,6 +1064,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
fixed_t h, l; // 3D sides and 2s middle textures fixed_t h, l; // 3D sides and 2s middle textures
fixed_t hS, lS; fixed_t hS, lS;
float xscale, yscale;
gl_sidedef = gl_curline->sidedef; gl_sidedef = gl_curline->sidedef;
gl_linedef = gl_curline->linedef; gl_linedef = gl_curline->linedef;
@ -1176,47 +1160,53 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// check TOP TEXTURE // check TOP TEXTURE
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture) if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture)
{ {
grTex = HWR_GetTexture(gl_toptexture);
xscale = FixedToFloat(gl_sidedef->scalex_top);
yscale = FixedToFloat(gl_sidedef->scaley_top);
fixed_t texheight = FixedDiv(textureheight[gl_toptexture], gl_sidedef->scaley_top);
// PEGGING // PEGGING
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 + textureheight[gl_toptexture] - worldtop; texturevpeg = worldhigh + texheight - worldtop;
else else
texturevpeg = gl_backsector->ceilingheight + textureheight[gl_toptexture] - gl_frontsector->ceilingheight; texturevpeg = gl_backsector->ceilingheight + texheight - gl_frontsector->ceilingheight;
texturevpeg *= yscale;
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top; 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 %= textureheight[gl_toptexture]; texturevpeg %= texheight;
grTex = HWR_GetTexture(gl_toptexture);
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) * 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 + gl_sidedef->offsetx_top) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_top) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_top) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->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))
{ {
// Unskewed // Unskewed
wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * grTex->scaleY; wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * yscale * grTex->scaleY;
wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * grTex->scaleY; wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * yscale * grTex->scaleY;
wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * grTex->scaleY; wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * yscale * grTex->scaleY;
wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * grTex->scaleY; wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * yscale * grTex->scaleY;
} }
else if (gl_linedef->flags & ML_DONTPEGTOP) else if (gl_linedef->flags & ML_DONTPEGTOP)
{ {
// Skewed by top // Skewed by top
wallVerts[0].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY; wallVerts[0].t = (texturevpeg + (worldtop - worldhigh) * yscale) * grTex->scaleY;
wallVerts[1].t = (texturevpeg + worldtopslope - worldhighslope) * grTex->scaleY; wallVerts[1].t = (texturevpeg + (worldtopslope - worldhighslope) * yscale) * grTex->scaleY;
} }
else else
{ {
// Skewed by bottom // Skewed by bottom
wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + (worldtop - worldhigh) * yscale) * grTex->scaleY;
wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY; wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * yscale * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY; wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * yscale * grTex->scaleY;
} }
// set top/bottom coords // set top/bottom coords
@ -1236,6 +1226,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// check BOTTOM TEXTURE // check BOTTOM TEXTURE
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture) if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture)
{ {
grTex = HWR_GetTexture(gl_bottomtexture);
xscale = FixedToFloat(gl_sidedef->scalex_bottom);
yscale = FixedToFloat(gl_sidedef->scaley_bottom);
// PEGGING // PEGGING
if (!(gl_linedef->flags & ML_DONTPEGBOTTOM)) if (!(gl_linedef->flags & ML_DONTPEGBOTTOM))
texturevpeg = 0; texturevpeg = 0;
@ -1244,38 +1238,38 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
else else
texturevpeg = gl_frontsector->floorheight - gl_backsector->floorheight; texturevpeg = gl_frontsector->floorheight - gl_backsector->floorheight;
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bot; texturevpeg *= yscale;
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 %= textureheight[gl_bottomtexture]; texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], gl_sidedef->scaley_bottom);
grTex = HWR_GetTexture(gl_bottomtexture);
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) * 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 + gl_sidedef->offsetx_bot) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_bottom) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_bot) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->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))
{ {
// Unskewed // Unskewed
wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * grTex->scaleY; wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * yscale * grTex->scaleY;
wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * grTex->scaleY; wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * yscale * grTex->scaleY;
wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * grTex->scaleY; wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * yscale * grTex->scaleY;
wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * grTex->scaleY; wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * yscale * grTex->scaleY;
} }
else if (gl_linedef->flags & ML_DONTPEGBOTTOM) else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
{ {
// Skewed by bottom // Skewed by bottom
wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + (worldlow - worldbottom) * yscale) * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY; wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * yscale * grTex->scaleY;
} }
else else
{ {
// Skewed by top // Skewed by top
wallVerts[0].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY; wallVerts[0].t = (texturevpeg + (worldlow - worldbottom) * yscale) * grTex->scaleY;
wallVerts[1].t = (texturevpeg + worldlowslope - worldbottomslope) * grTex->scaleY; wallVerts[1].t = (texturevpeg + (worldlowslope - worldbottomslope) * yscale) * grTex->scaleY;
} }
// set top/bottom coords // set top/bottom coords
@ -1296,6 +1290,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf)) if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf))
{ {
sector_t *front, *back; sector_t *front, *back;
fixed_t texheight = FixedDiv(textureheight[gl_midtexture], gl_sidedef->scaley_mid);
INT32 repeats; INT32 repeats;
if (gl_linedef->frontsector->heightsec != -1) if (gl_linedef->frontsector->heightsec != -1)
@ -1324,13 +1319,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
else else
low = back->floorheight; low = back->floorheight;
repeats = (high - low) / textureheight[gl_midtexture]; repeats = (high - low) / texheight;
if ((high - low) % textureheight[gl_midtexture]) if ((high - low) % texheight)
repeats++; // tile an extra time to fill the gap -- Monster Iestyn repeats++; // tile an extra time to fill the gap -- Monster Iestyn
} }
else else
repeats = 1; 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 // SoM: a little note: popentop and popenbottom
// record the limits the texture can be displayed in. // record the limits the texture can be displayed in.
// polytop and polybottom, are the ideal (i.e. unclipped) // polytop and polybottom, are the ideal (i.e. unclipped)
@ -1348,7 +1347,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
popenbottom = popenbottomslope = back->floorheight; popenbottom = popenbottomslope = back->floorheight;
} }
else else
{ {
popentop = min(worldtop, worldhigh); popentop = min(worldtop, worldhigh);
popenbottom = max(worldbottom, worldlow); popenbottom = max(worldbottom, worldlow);
popentopslope = min(worldtopslope, worldhighslope); popentopslope = min(worldtopslope, worldhighslope);
@ -1356,7 +1355,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
} }
// Find the wall's coordinates // Find the wall's coordinates
fixed_t midtexheight = textureheight[gl_midtexture] * repeats; fixed_t midtexheight = texheight * repeats;
fixed_t rowoffset = FixedDiv(gl_sidedef->rowoffset + gl_sidedef->offsety_mid, gl_sidedef->scaley_mid);
// Texture is not skewed // Texture is not skewed
if (gl_linedef->flags & ML_NOSKEW) if (gl_linedef->flags & ML_NOSKEW)
@ -1364,13 +1365,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// Peg it to the floor // Peg it to the floor
if (gl_linedef->flags & ML_MIDPEG) if (gl_linedef->flags & ML_MIDPEG)
{ {
polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; polybottom = max(front->floorheight, back->floorheight) + rowoffset;
polytop = polybottom + midtexheight; polytop = polybottom + midtexheight;
} }
// Peg it to the ceiling // Peg it to the ceiling
else else
{ {
polytop = min(front->ceilingheight, back->ceilingheight) + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; polytop = min(front->ceilingheight, back->ceilingheight) + rowoffset;
polybottom = polytop - midtexheight; polybottom = polytop - midtexheight;
} }
@ -1381,17 +1382,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// Skew the texture, but peg it to the floor // Skew the texture, but peg it to the floor
else if (gl_linedef->flags & ML_MIDPEG) else if (gl_linedef->flags & ML_MIDPEG)
{ {
polybottom = popenbottom + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; polybottom = popenbottom + rowoffset;
polytop = polybottom + midtexheight; polytop = polybottom + midtexheight;
polybottomslope = popenbottomslope + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; polybottomslope = popenbottomslope + rowoffset;
polytopslope = polybottomslope + midtexheight; polytopslope = polybottomslope + midtexheight;
} }
// Skew it according to the ceiling's slope // Skew it according to the ceiling's slope
else else
{ {
polytop = popentop + gl_sidedef->rowoffset; polytop = popentop + rowoffset;
polybottom = polytop - midtexheight; polybottom = polytop - midtexheight;
polytopslope = popentopslope + gl_sidedef->rowoffset; polytopslope = popentopslope + rowoffset;
polybottomslope = polytopslope - midtexheight; polybottomslope = polytopslope - midtexheight;
} }
@ -1433,17 +1434,15 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
texturevpegslope = polytopslope - hS; texturevpegslope = polytopslope - hS;
} }
grTex = HWR_GetTexture(gl_midtexture);
// Left side // Left side
wallVerts[3].t = texturevpeg * grTex->scaleY; wallVerts[3].t = texturevpeg * yscale * grTex->scaleY;
wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; wallVerts[0].t = (h - l + texturevpeg) * yscale * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX;
// Right side // Right side
wallVerts[2].t = texturevpegslope * grTex->scaleY; wallVerts[2].t = texturevpegslope * yscale * grTex->scaleY;
wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY; wallVerts[1].t = (hS - lS + texturevpegslope) * yscale * grTex->scaleY;
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX;
// set top/bottom coords // set top/bottom coords
// Take the texture peg into account, rather than changing the offsets past // Take the texture peg into account, rather than changing the offsets past
@ -1501,36 +1500,40 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// Single sided line... Deal only with the middletexture (if one exists) // Single sided line... Deal only with the middletexture (if one exists)
if (gl_midtexture && gl_linedef->special != SPECIAL_HORIZON_LINE) // (Ignore horizon line for OGL) if (gl_midtexture && gl_linedef->special != SPECIAL_HORIZON_LINE) // (Ignore horizon line for OGL)
{ {
grTex = HWR_GetTexture(gl_midtexture);
xscale = FixedToFloat(gl_sidedef->scalex_mid);
yscale = FixedToFloat(gl_sidedef->scaley_mid);
fixed_t texturevpeg; fixed_t texturevpeg;
// PEGGING // PEGGING
if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW)) if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW))
texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; texturevpeg = (gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight) * yscale;
else if (gl_linedef->flags & ML_DONTPEGBOTTOM) else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; texturevpeg = (worldbottom + textureheight[gl_sidedef->midtexture] - worldtop) * yscale;
else else
// top of texture at top // top of texture at top
texturevpeg = gl_sidedef->rowoffset + gl_sidedef->offsety_mid; texturevpeg = 0;
grTex = HWR_GetTexture(gl_midtexture); texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_mid;
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 + gl_sidedef->offsetx_mid) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_mid) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + 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) {
wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * grTex->scaleY; wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * yscale * grTex->scaleY;
wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * grTex->scaleY; wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * yscale * grTex->scaleY;
wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * grTex->scaleY; wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * yscale * grTex->scaleY;
wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * grTex->scaleY; wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * yscale * yscale;
} else if (gl_linedef->flags & ML_DONTPEGBOTTOM) { } else if (gl_linedef->flags & ML_DONTPEGBOTTOM) {
wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * grTex->scaleY; wallVerts[3].t = wallVerts[0].t + ((worldbottom - worldtop) * yscale) * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * grTex->scaleY; wallVerts[2].t = wallVerts[1].t + ((worldbottomslope - worldtopslope) * yscale) * grTex->scaleY;
} else { } else {
wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * grTex->scaleY; wallVerts[0].t = wallVerts[3].t - ((worldbottom - worldtop) * yscale) * grTex->scaleY;
wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * grTex->scaleY; wallVerts[1].t = wallVerts[2].t - ((worldbottomslope - worldtopslope) * yscale) * grTex->scaleY;
} }
//Set textures properly on single sided walls that are sloped //Set textures properly on single sided walls that are sloped
@ -1615,15 +1618,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
continue; continue;
texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture); side_t *side = &sides[rover->master->sidenum[0]];
if (rover->master->flags & ML_TFERLINE) if (rover->master->flags & ML_TFERLINE)
{ {
size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; size_t linenum = gl_curline->linedef-gl_backsector->lines[0];
newline = rover->master->frontsector->lines[0] + linenum; newline = rover->master->frontsector->lines[0] + linenum;
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); side = &sides[newline->sidenum[0]];
} }
texnum = R_GetTextureNum(side->midtexture);
h = P_GetFFloorTopZAt (rover, v1x, v1y); h = P_GetFFloorTopZAt (rover, v1x, v1y);
hS = P_GetFFloorTopZAt (rover, v2x, v2y); hS = P_GetFFloorTopZAt (rover, v2x, v2y);
l = P_GetFFloorBottomZAt(rover, v1x, v1y); l = P_GetFFloorBottomZAt(rover, v1x, v1y);
@ -1639,14 +1644,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
l = lowcut; l = lowcut;
lS = lowcutslope; lS = lowcutslope;
} }
//Hurdler: HW code starts here
//FIXME: check if peging is correct
// set top/bottom coords
// set top/bottom coords
wallVerts[3].y = FIXED_TO_FLOAT(h); wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[2].y = FIXED_TO_FLOAT(hS); wallVerts[2].y = FIXED_TO_FLOAT(hS);
wallVerts[0].y = FIXED_TO_FLOAT(l); wallVerts[0].y = FIXED_TO_FLOAT(l);
wallVerts[1].y = FIXED_TO_FLOAT(lS); wallVerts[1].y = FIXED_TO_FLOAT(lS);
if (rover->fofflags & FOF_FOG) if (rover->fofflags & FOF_FOG)
{ {
wallVerts[3].t = wallVerts[2].t = 0; wallVerts[3].t = wallVerts[2].t = 0;
@ -1656,56 +1660,46 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
} }
else else
{ {
fixed_t texturevpeg;
boolean attachtobottom = false;
boolean slopeskew = false; // skew FOF walls with slopes?
// Wow, how was this missing from OpenGL for so long? // Wow, how was this missing from OpenGL for so long?
// ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software // ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software
// -- Monster Iestyn 26/06/18 // -- Monster Iestyn 26/06/18
if (newline) fixed_t texturevpeg = side->rowoffset + side->offsety_mid;
{ boolean attachtobottom = !!(rover->master->flags & ML_DONTPEGBOTTOM);
texturevpeg = sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid;
attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM);
slopeskew = !!(newline->flags & ML_SKEWTD);
}
else
{
texturevpeg = sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid;
attachtobottom = !!(gl_linedef->flags & ML_DONTPEGBOTTOM);
slopeskew = !!(rover->master->flags & ML_SKEWTD);
}
grTex = HWR_GetTexture(texnum); grTex = HWR_GetTexture(texnum);
xscale = FixedToFloat(side->scalex_mid);
yscale = FixedToFloat(side->scaley_mid);
if (!slopeskew) // no skewing if (!(rover->master->flags & ML_SKEWTD)) // no skewing
{ {
if (attachtobottom) if (attachtobottom)
texturevpeg -= *rover->topheight - *rover->bottomheight; texturevpeg -= (*rover->topheight - *rover->bottomheight) * yscale;
wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY; wallVerts[3].t = (((*rover->topheight - h) * yscale) + texturevpeg) * grTex->scaleY;
wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY; wallVerts[2].t = (((*rover->topheight - hS) * yscale) + texturevpeg) * grTex->scaleY;
wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY; wallVerts[0].t = (((*rover->topheight - l) * yscale) + texturevpeg) * grTex->scaleY;
wallVerts[1].t = (((*rover->topheight - lS) * yscale) + texturevpeg) * grTex->scaleY;
} }
else else
{ {
if (!attachtobottom) // skew by top if (!attachtobottom) // skew by top
{ {
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; wallVerts[0].t = (((h - l) * yscale) + texturevpeg) * grTex->scaleY;
wallVerts[1].t = (hS - lS + texturevpeg) * grTex->scaleY; wallVerts[1].t = (((hS - lS) * yscale) + texturevpeg) * grTex->scaleY;
} }
else // skew by bottom else // skew by bottom
{ {
wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY;
wallVerts[3].t = wallVerts[0].t - (h - l) * grTex->scaleY; wallVerts[3].t = wallVerts[0].t - ((h - l) * yscale) * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t - (hS - lS) * grTex->scaleY; wallVerts[2].t = wallVerts[1].t - ((hS - lS) * yscale) * grTex->scaleY;
} }
} }
wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + side->offsetx_mid) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX;
} }
if (rover->fofflags & FOF_FOG) if (rover->fofflags & FOF_FOG)
{ {
FBITFIELD blendmode; FBITFIELD blendmode;
@ -1772,14 +1766,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
continue; continue;
texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture); side_t *side = &sides[rover->master->sidenum[0]];
if (rover->master->flags & ML_TFERLINE) if (rover->master->flags & ML_TFERLINE)
{ {
size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; size_t linenum = gl_curline->linedef-gl_backsector->lines[0];
newline = rover->master->frontsector->lines[0] + linenum; newline = rover->master->frontsector->lines[0] + linenum;
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); side = &sides[newline->sidenum[0]];
} }
texnum = R_GetTextureNum(side->midtexture);
h = P_GetFFloorTopZAt (rover, v1x, v1y); h = P_GetFFloorTopZAt (rover, v1x, v1y);
hS = P_GetFFloorTopZAt (rover, v2x, v2y); hS = P_GetFFloorTopZAt (rover, v2x, v2y);
l = P_GetFFloorBottomZAt(rover, v1x, v1y); l = P_GetFFloorBottomZAt(rover, v1x, v1y);
@ -1813,20 +1810,16 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
else else
{ {
grTex = HWR_GetTexture(texnum); grTex = HWR_GetTexture(texnum);
xscale = FixedToFloat(side->scalex_mid);
yscale = FixedToFloat(side->scaley_mid);
if (newline) fixed_t diff = (*rover->topheight - h) * yscale;
{
wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid) * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset) + sides[newline->sidenum[0]].offsety_mid) * grTex->scaleY;
}
else
{
wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid) * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid)) * grTex->scaleY;
}
wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; wallVerts[3].t = wallVerts[2].t = (diff + side->rowoffset + side->offsety_mid) * grTex->scaleY;
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; wallVerts[0].t = wallVerts[1].t = (((h - l) * yscale) + (diff + side->rowoffset + side->offsety_mid)) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + side->offsetx_mid) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + side->offsetx_mid) * grTex->scaleX;
} }
if (rover->fofflags & FOF_FOG) if (rover->fofflags & FOF_FOG)
@ -2708,11 +2701,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
INT32 i; INT32 i;
float height = FIXED_TO_FLOAT(fixedheight); // constant y for all points on the convex flat polygon float height = FIXED_TO_FLOAT(fixedheight); // constant y for all points on the convex flat polygon
float flatxref, flatyref;
float fflatwidth = 64.0f, fflatheight = 64.0f; float fflatwidth = 64.0f, fflatheight = 64.0f;
UINT16 flatflag = 63; float xscale = 1.0f, yscale = 1.0f;
boolean texflat = false;
float scrollx = 0.0f, scrolly = 0.0f; float scrollx = 0.0f, scrolly = 0.0f;
float tempxsow, tempytow, anglef = 0.0f; float tempxsow, tempytow, anglef = 0.0f;
@ -2743,8 +2733,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
if (levelflat->type == LEVELFLAT_FLAT) if (levelflat->type == LEVELFLAT_FLAT)
{ {
size_t len = W_LumpLength(levelflat->u.flat.lumpnum); size_t len = W_LumpLength(levelflat->u.flat.lumpnum);
flatflag = R_GetFlatSize(len) - 1; unsigned flatflag = R_GetFlatSize(len);
fflatwidth = fflatheight = (float)(flatflag + 1); fflatwidth = fflatheight = (float)flatflag;
} }
else else
{ {
@ -2758,19 +2748,11 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
fflatwidth = levelflat->width; fflatwidth = levelflat->width;
fflatheight = levelflat->height; fflatheight = levelflat->height;
} }
texflat = true;
} }
} }
else // set no texture else // set no texture
HWR_SetCurrentTexture(NULL); HWR_SetCurrentTexture(NULL);
// reference point for flat texture coord for each vertex around the polygon
flatxref = FIXED_TO_FLOAT(polysector->origVerts[0].x);
flatyref = FIXED_TO_FLOAT(polysector->origVerts[0].y);
flatxref = (float)(((fixed_t)flatxref & (~flatflag)) / fflatwidth);
flatyref = (float)(((fixed_t)flatyref & (~flatflag)) / fflatheight);
// transform // transform
v3d = planeVerts; v3d = planeVerts;
@ -2778,14 +2760,18 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
{ {
if (!isceiling) // it's a floor if (!isceiling) // it's a floor
{ {
scrollx = FIXED_TO_FLOAT(FOFsector->floorxoffset)/fflatwidth; xscale = FixedToFloat(FOFsector->floorxscale);
scrolly = FIXED_TO_FLOAT(FOFsector->flooryoffset)/fflatheight; yscale = FixedToFloat(FOFsector->flooryscale);
scrollx = FixedToFloat(FOFsector->floorxoffset) / fflatwidth;
scrolly = FixedToFloat(FOFsector->flooryoffset) / fflatheight;
angle = FOFsector->floorangle; angle = FOFsector->floorangle;
} }
else // it's a ceiling else // it's a ceiling
{ {
scrollx = FIXED_TO_FLOAT(FOFsector->ceilingxoffset)/fflatwidth; xscale = FixedToFloat(FOFsector->ceilingxscale);
scrolly = FIXED_TO_FLOAT(FOFsector->ceilingyoffset)/fflatheight; yscale = FixedToFloat(FOFsector->ceilingyscale);
scrollx = FixedToFloat(FOFsector->ceilingxoffset) / fflatwidth;
scrolly = FixedToFloat(FOFsector->ceilingyoffset) / fflatheight;
angle = FOFsector->ceilingangle; angle = FOFsector->ceilingangle;
} }
} }
@ -2793,43 +2779,30 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
{ {
if (!isceiling) // it's a floor if (!isceiling) // it's a floor
{ {
scrollx = FIXED_TO_FLOAT(gl_frontsector->floorxoffset)/fflatwidth; xscale = FixedToFloat(gl_frontsector->floorxscale);
scrolly = FIXED_TO_FLOAT(gl_frontsector->flooryoffset)/fflatheight; yscale = FixedToFloat(gl_frontsector->flooryscale);
scrollx = FixedToFloat(gl_frontsector->floorxoffset) / fflatwidth;
scrolly = FixedToFloat(gl_frontsector->flooryoffset) / fflatheight;
angle = gl_frontsector->floorangle; angle = gl_frontsector->floorangle;
} }
else // it's a ceiling else // it's a ceiling
{ {
scrollx = FIXED_TO_FLOAT(gl_frontsector->ceilingxoffset)/fflatwidth; xscale = FixedToFloat(gl_frontsector->ceilingxscale);
scrolly = FIXED_TO_FLOAT(gl_frontsector->ceilingyoffset)/fflatheight; yscale = FixedToFloat(gl_frontsector->ceilingyscale);
scrollx = FixedToFloat(gl_frontsector->ceilingxoffset) / fflatwidth;
scrolly = FixedToFloat(gl_frontsector->ceilingyoffset) / fflatheight;
angle = gl_frontsector->ceilingangle; angle = gl_frontsector->ceilingangle;
} }
} }
if (angle) // Only needs to be done if there's an altered angle anglef = ANG2RAD(InvAngle(angle));
{
tempxsow = flatxref;
tempytow = flatyref;
anglef = ANG2RAD(InvAngle(angle));
flatxref = (tempxsow * cos(anglef)) - (tempytow * sin(anglef));
flatyref = (tempxsow * sin(anglef)) + (tempytow * cos(anglef));
}
for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++) for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++)
{ {
// Go from the polysector's original vertex locations // Go from the polysector's original vertex locations
// Means the flat is offset based on the original vertex locations // Means the flat is offset based on the original vertex locations
if (texflat) v3d->s = (FixedToFloat(polysector->origVerts[i].x) / fflatwidth) + (scrollx / xscale);
{ v3d->t = -(FixedToFloat(polysector->origVerts[i].y) / fflatheight) + (scrolly / yscale);
v3d->s = (float)(FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) + scrollx;
v3d->t = -(float)(FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly;
}
else
{
v3d->s = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx);
v3d->t = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly);
}
// Need to rotate before translate // Need to rotate before translate
if (angle) // Only needs to be done if there's an altered angle if (angle) // Only needs to be done if there's an altered angle
@ -2841,6 +2814,9 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
v3d->t = (tempxsow * sin(anglef)) + (tempytow * cos(anglef)); v3d->t = (tempxsow * sin(anglef)) + (tempytow * cos(anglef));
} }
v3d->s *= xscale;
v3d->t *= yscale;
v3d->x = FIXED_TO_FLOAT(polysector->vertices[i]->x); v3d->x = FIXED_TO_FLOAT(polysector->vertices[i]->x);
v3d->y = height; v3d->y = height;
v3d->z = FIXED_TO_FLOAT(polysector->vertices[i]->y); v3d->z = FIXED_TO_FLOAT(polysector->vertices[i]->y);

View file

@ -79,6 +79,7 @@ patch_t *nto_font[NT_FONTSIZE];
static player_t *plr; static player_t *plr;
boolean chat_on; // entering a chat message? boolean chat_on; // entering a chat message?
boolean chat_on_first_event; // blocker for first chat input event
static char w_chat[HU_MAXMSGLEN + 1]; static char w_chat[HU_MAXMSGLEN + 1];
static size_t c_input = 0; // let's try to make the chat input less shitty. static size_t c_input = 0; // let's try to make the chat input less shitty.
static boolean headsupactive = false; static boolean headsupactive = false;
@ -618,7 +619,9 @@ static void Command_CSay_f(void)
DoSayCommand(0, 1, HU_CSAY); DoSayCommand(0, 1, HU_CSAY);
} }
static tic_t stop_spamming[MAXPLAYERS];
static tic_t spam_tokens[MAXPLAYERS];
static tic_t spam_tics[MAXPLAYERS];
/** Receives a message, processing an ::XD_SAY command. /** Receives a message, processing an ::XD_SAY command.
* \sa DoSayCommand * \sa DoSayCommand
@ -670,14 +673,14 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
// before we do anything, let's verify the guy isn't spamming, get this easier on us. // before we do anything, let's verify the guy isn't spamming, get this easier on us.
//if (stop_spamming[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY)) //if (stop_spamming[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY))
if (stop_spamming[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & HU_CSAY)) if (spam_tokens[playernum] <= 0 && cv_chatspamprotection.value && !(flags & HU_CSAY))
{ {
CONS_Debug(DBG_NETPLAY,"Received SAY cmd too quickly from Player %d (%s), assuming as spam and blocking message.\n", playernum+1, player_names[playernum]); CONS_Debug(DBG_NETPLAY,"Received SAY cmd too quickly from Player %d (%s), assuming as spam and blocking message.\n", playernum+1, player_names[playernum]);
stop_spamming[playernum] = 4; spam_tics[playernum] = 0;
spam_eatmsg = 1; spam_eatmsg = 1;
} }
else else
stop_spamming[playernum] = 4; // you can hold off for 4 tics, can you? spam_tokens[playernum] -= 1;
// run the lua hook even if we were supposed to eat the msg, netgame consistency goes first. // run the lua hook even if we were supposed to eat the msg, netgame consistency goes first.
@ -857,6 +860,25 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
// //
void HU_Ticker(void) void HU_Ticker(void)
{ {
// do this server-side, too
if (netgame)
{
size_t i = 0;
// handle spam while we're at it:
for(; (i<MAXPLAYERS); i++)
{
if (spam_tokens[i] < (tic_t)cv_chatspamburst.value)
{
if (++spam_tics[i] >= (tic_t)cv_chatspamspeed.value)
{
spam_tokens[i]++;
spam_tics[i] = 0;
}
}
}
}
if (dedicated) if (dedicated)
return; return;
@ -879,13 +901,6 @@ void HU_Ticker(void)
{ {
size_t i = 0; size_t i = 0;
// handle spam while we're at it:
for(; (i<MAXPLAYERS); i++)
{
if (stop_spamming[i] > 0)
stop_spamming[i]--;
}
// handle chat timers // handle chat timers
for (i=0; (i<chat_nummsg_min); i++) for (i=0; (i<chat_nummsg_min); i++)
{ {
@ -1025,7 +1040,7 @@ boolean HU_Responder(event_t *ev)
{ {
INT32 c=0; INT32 c=0;
if (ev->type != ev_keydown) if (ev->type != ev_keydown && ev->type != ev_text)
return false; return false;
// only KeyDown events now... // only KeyDown events now...
@ -1054,11 +1069,15 @@ boolean HU_Responder(event_t *ev)
if (!chat_on) if (!chat_on)
{ {
if (ev->type == ev_text)
return false;
// enter chat mode // enter chat mode
if ((ev->key == gamecontrol[GC_TALKKEY][0] || ev->key == gamecontrol[GC_TALKKEY][1]) if ((ev->key == gamecontrol[GC_TALKKEY][0] || ev->key == gamecontrol[GC_TALKKEY][1])
&& netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise. && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise.
{ {
chat_on = true; chat_on = true;
chat_on_first_event = false;
w_chat[0] = 0; w_chat[0] = 0;
teamtalk = false; teamtalk = false;
chat_scrollmedown = true; chat_scrollmedown = true;
@ -1069,6 +1088,7 @@ boolean HU_Responder(event_t *ev)
&& netgame && !OLD_MUTE) && netgame && !OLD_MUTE)
{ {
chat_on = true; chat_on = true;
chat_on_first_event = false;
w_chat[0] = 0; w_chat[0] = 0;
teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams. teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams.
chat_scrollmedown = true; chat_scrollmedown = true;
@ -1078,6 +1098,31 @@ boolean HU_Responder(event_t *ev)
} }
else // if chat_on else // if chat_on
{ {
if (!chat_on_first_event)
{
// since the text event is sent immediately after the keydown event,
// we need to make sure that nothing is displayed once the chat
// opens, otherwise a 't' would be outputted.
chat_on_first_event = true;
return true;
}
if (ev->type == ev_text)
{
if ((c < HU_FONTSTART || c > HU_FONTEND || !hu_font[c-HU_FONTSTART])
&& c != ' ') // Allow spaces, of course
{
return false;
}
if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN)
return true;
memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1);
w_chat[c_input] = c;
c_input++;
return true;
}
// Ignore modifier keys // Ignore modifier keys
// Note that we do this here so users can still set // Note that we do this here so users can still set
@ -1087,23 +1132,8 @@ boolean HU_Responder(event_t *ev)
|| ev->key == KEY_LALT || ev->key == KEY_RALT) || ev->key == KEY_LALT || ev->key == KEY_RALT)
return true; return true;
c = (INT32)ev->key;
// I know this looks very messy but this works. If it ain't broke, don't fix it!
// shift LETTERS to uppercase if we have capslock or are holding shift
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
if (shiftdown ^ capslock)
c = shiftxform[c];
}
else // if we're holding shift we should still shift non letter symbols
{
if (shiftdown)
c = shiftxform[c];
}
// pasting. pasting is cool. chat is a bit limited, though :( // pasting. pasting is cool. chat is a bit limited, though :(
if ((c == 'v' || c == 'V') && ctrldown) if (c == 'v' && ctrldown)
{ {
const char *paste; const char *paste;
size_t chatlen; size_t chatlen;
@ -1171,16 +1201,6 @@ boolean HU_Responder(event_t *ev)
else else
c_input++; c_input++;
} }
else if ((c >= HU_FONTSTART && c <= HU_FONTEND && hu_font[c-HU_FONTSTART])
|| c == ' ') // Allow spaces, of course
{
if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN)
return true;
memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1);
w_chat[c_input] = c;
c_input++;
}
else if (c == KEY_BACKSPACE) else if (c == KEY_BACKSPACE)
{ {
if (CHAT_MUTE || c_input <= 0) if (CHAT_MUTE || c_input <= 0)

View file

@ -30,12 +30,6 @@ static precise_t enterprecise, oldenterprecise;
static fixed_t entertic, oldentertics; static fixed_t entertic, oldentertics;
static double tictimer; static double tictimer;
// A little more than the minimum sleep duration on Windows.
// May be incorrect for other platforms, but we don't currently have a way to
// query the scheduler granularity. SDL will do what's needed to make this as
// low as possible though.
#define MIN_SLEEP_DURATION_MS 2.1
tic_t I_GetTime(void) tic_t I_GetTime(void)
{ {
return g_time.time; return g_time.time;
@ -88,38 +82,3 @@ void I_UpdateTime(fixed_t timescale)
g_time.timefrac = FLOAT_TO_FIXED(fractional); g_time.timefrac = FLOAT_TO_FIXED(fractional);
} }
} }
void I_SleepDuration(precise_t duration)
{
UINT64 precision = I_GetPrecisePrecision();
INT32 sleepvalue = cv_sleep.value;
UINT64 delaygranularity;
precise_t cur;
precise_t dest;
{
double gran = round(((double)(precision / 1000) * sleepvalue * MIN_SLEEP_DURATION_MS));
delaygranularity = (UINT64)gran;
}
cur = I_GetPreciseTime();
dest = cur + duration;
// the reason this is not dest > cur is because the precise counter may wrap
// two's complement arithmetic is our friend here, though!
// e.g. cur 0xFFFFFFFFFFFFFFFE = -2, dest 0x0000000000000001 = 1
// 0x0000000000000001 - 0xFFFFFFFFFFFFFFFE = 3
while ((INT64)(dest - cur) > 0)
{
// If our cv_sleep value exceeds the remaining sleep duration, use the
// hard sleep function.
if (sleepvalue > 0 && (dest - cur) > delaygranularity)
{
I_Sleep(sleepvalue);
}
// Otherwise, this is a spinloop.
cur = I_GetPreciseTime();
}
}

View file

@ -76,12 +76,12 @@ static boolean mobj_hook_available(int hook_type, mobjtype_t mobj_type)
); );
} }
static int hook_in_list static unsigned hook_in_list
( (
const char * const name, const char * const name,
const char * const * const list const char * const * const list
){ ){
int type; unsigned type;
for (type = 0; list[type] != NULL; ++type) for (type = 0; list[type] != NULL; ++type)
{ {
@ -200,7 +200,7 @@ static void add_hook_ref(lua_State *L, int idx)
static int lib_addHook(lua_State *L) static int lib_addHook(lua_State *L)
{ {
const char * name; const char * name;
int type; unsigned type;
if (!lua_lumploading) if (!lua_lumploading)
return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); return luaL_error(L, "This function cannot be called from within a hook or coroutine!");

View file

@ -35,10 +35,14 @@ enum sector_e {
sector_floorpic, sector_floorpic,
sector_floorxoffset, sector_floorxoffset,
sector_flooryoffset, sector_flooryoffset,
sector_floorxscale,
sector_flooryscale,
sector_floorangle, sector_floorangle,
sector_ceilingpic, sector_ceilingpic,
sector_ceilingxoffset, sector_ceilingxoffset,
sector_ceilingyoffset, sector_ceilingyoffset,
sector_ceilingxscale,
sector_ceilingyscale,
sector_ceilingangle, sector_ceilingangle,
sector_lightlevel, sector_lightlevel,
sector_floorlightlevel, sector_floorlightlevel,
@ -74,10 +78,14 @@ static const char *const sector_opt[] = {
"floorpic", "floorpic",
"floorxoffset", "floorxoffset",
"flooryoffset", "flooryoffset",
"floorxscale",
"flooryscale",
"floorangle", "floorangle",
"ceilingpic", "ceilingpic",
"ceilingxoffset", "ceilingxoffset",
"ceilingyoffset", "ceilingyoffset",
"ceilingxscale",
"ceilingyscale",
"ceilingangle", "ceilingangle",
"lightlevel", "lightlevel",
"floorlightlevel", "floorlightlevel",
@ -188,8 +196,16 @@ enum side_e {
side_offsety_top, side_offsety_top,
side_offsetx_mid, side_offsetx_mid,
side_offsety_mid, side_offsety_mid,
side_offsetx_bottom,
side_offsetx_bot, side_offsetx_bot,
side_offsety_bottom,
side_offsety_bot, side_offsety_bot,
side_scalex_top,
side_scaley_top,
side_scalex_mid,
side_scaley_mid,
side_scalex_bottom,
side_scaley_bottom,
side_toptexture, side_toptexture,
side_bottomtexture, side_bottomtexture,
side_midtexture, side_midtexture,
@ -208,8 +224,16 @@ static const char *const side_opt[] = {
"offsety_top", "offsety_top",
"offsetx_mid", "offsetx_mid",
"offsety_mid", "offsety_mid",
"offsetx_bottom",
"offsetx_bot", "offsetx_bot",
"offsety_bottom",
"offsety_bot", "offsety_bot",
"scalex_top",
"scaley_top",
"scalex_mid",
"scaley_mid",
"scalex_bottom",
"scaley_bottom",
"toptexture", "toptexture",
"bottomtexture", "bottomtexture",
"midtexture", "midtexture",
@ -249,8 +273,16 @@ enum ffloor_e {
ffloor_topheight, ffloor_topheight,
ffloor_toppic, ffloor_toppic,
ffloor_toplightlevel, ffloor_toplightlevel,
ffloor_topxoffs,
ffloor_topyoffs,
ffloor_topxscale,
ffloor_topyscale,
ffloor_bottomheight, ffloor_bottomheight,
ffloor_bottompic, ffloor_bottompic,
ffloor_bottomxoffs,
ffloor_bottomyoffs,
ffloor_bottomxscale,
ffloor_bottomyscale,
ffloor_tslope, ffloor_tslope,
ffloor_bslope, ffloor_bslope,
ffloor_sector, ffloor_sector,
@ -275,8 +307,16 @@ static const char *const ffloor_opt[] = {
"topheight", "topheight",
"toppic", "toppic",
"toplightlevel", "toplightlevel",
"topxoffs",
"topyoffs",
"topxscale",
"topyscale",
"bottomheight", "bottomheight",
"bottompic", "bottompic",
"bottomxoffs",
"bottomyoffs",
"bottomxscale",
"bottomyscale",
"t_slope", "t_slope",
"b_slope", "b_slope",
"sector", // secnum pushed as control sector userdata "sector", // secnum pushed as control sector userdata
@ -656,20 +696,20 @@ static int sector_get(lua_State *L)
return 1; return 1;
} }
case sector_floorxoffset: case sector_floorxoffset:
{
lua_pushfixed(L, sector->floorxoffset); lua_pushfixed(L, sector->floorxoffset);
return 1; return 1;
}
case sector_flooryoffset: case sector_flooryoffset:
{
lua_pushfixed(L, sector->flooryoffset); lua_pushfixed(L, sector->flooryoffset);
return 1; return 1;
} case sector_floorxscale:
lua_pushfixed(L, sector->floorxscale);
return 1;
case sector_flooryscale:
lua_pushfixed(L, sector->flooryscale);
return 1;
case sector_floorangle: case sector_floorangle:
{
lua_pushangle(L, sector->floorangle); lua_pushangle(L, sector->floorangle);
return 1; return 1;
}
case sector_ceilingpic: // ceilingpic case sector_ceilingpic: // ceilingpic
{ {
levelflat_t *levelflat = &levelflats[sector->ceilingpic]; levelflat_t *levelflat = &levelflats[sector->ceilingpic];
@ -680,20 +720,20 @@ static int sector_get(lua_State *L)
return 1; return 1;
} }
case sector_ceilingxoffset: case sector_ceilingxoffset:
{
lua_pushfixed(L, sector->ceilingxoffset); lua_pushfixed(L, sector->ceilingxoffset);
return 1; return 1;
}
case sector_ceilingyoffset: case sector_ceilingyoffset:
{
lua_pushfixed(L, sector->ceilingyoffset); lua_pushfixed(L, sector->ceilingyoffset);
return 1; return 1;
} case sector_ceilingxscale:
lua_pushfixed(L, sector->ceilingxscale);
return 1;
case sector_ceilingyscale:
lua_pushfixed(L, sector->ceilingyscale);
return 1;
case sector_ceilingangle: case sector_ceilingangle:
{
lua_pushangle(L, sector->ceilingangle); lua_pushangle(L, sector->ceilingangle);
return 1; return 1;
}
case sector_lightlevel: case sector_lightlevel:
lua_pushinteger(L, sector->lightlevel); lua_pushinteger(L, sector->lightlevel);
return 1; return 1;
@ -845,6 +885,12 @@ static int sector_set(lua_State *L)
case sector_flooryoffset: case sector_flooryoffset:
sector->flooryoffset = luaL_checkfixed(L, 3); sector->flooryoffset = luaL_checkfixed(L, 3);
break; break;
case sector_floorxscale:
sector->floorxscale = luaL_checkfixed(L, 3);
break;
case sector_flooryscale:
sector->flooryscale = luaL_checkfixed(L, 3);
break;
case sector_floorangle: case sector_floorangle:
sector->floorangle = luaL_checkangle(L, 3); sector->floorangle = luaL_checkangle(L, 3);
break; break;
@ -857,6 +903,12 @@ static int sector_set(lua_State *L)
case sector_ceilingyoffset: case sector_ceilingyoffset:
sector->ceilingyoffset = luaL_checkfixed(L, 3); sector->ceilingyoffset = luaL_checkfixed(L, 3);
break; break;
case sector_ceilingxscale:
sector->ceilingxscale = luaL_checkfixed(L, 3);
break;
case sector_ceilingyscale:
sector->ceilingyscale = luaL_checkfixed(L, 3);
break;
case sector_ceilingangle: case sector_ceilingangle:
sector->ceilingangle = luaL_checkangle(L, 3); sector->ceilingangle = luaL_checkangle(L, 3);
break; break;
@ -1210,11 +1262,31 @@ static int side_get(lua_State *L)
case side_offsety_mid: case side_offsety_mid:
lua_pushfixed(L, side->offsety_mid); lua_pushfixed(L, side->offsety_mid);
return 1; return 1;
case side_offsetx_bottom:
case side_offsetx_bot: case side_offsetx_bot:
lua_pushfixed(L, side->offsetx_bot); lua_pushfixed(L, side->offsetx_bottom);
return 1; return 1;
case side_offsety_bottom:
case side_offsety_bot: case side_offsety_bot:
lua_pushfixed(L, side->offsety_bot); lua_pushfixed(L, side->offsety_bottom);
return 1;
case side_scalex_top:
lua_pushfixed(L, side->scalex_top);
return 1;
case side_scaley_top:
lua_pushfixed(L, side->scaley_top);
return 1;
case side_scalex_mid:
lua_pushfixed(L, side->scalex_mid);
return 1;
case side_scaley_mid:
lua_pushfixed(L, side->scaley_mid);
return 1;
case side_scalex_bottom:
lua_pushfixed(L, side->scalex_bottom);
return 1;
case side_scaley_bottom:
lua_pushfixed(L, side->scaley_bottom);
return 1; return 1;
case side_toptexture: case side_toptexture:
lua_pushinteger(L, side->toptexture); lua_pushinteger(L, side->toptexture);
@ -1302,10 +1374,30 @@ static int side_set(lua_State *L)
side->offsety_mid = luaL_checkfixed(L, 3); side->offsety_mid = luaL_checkfixed(L, 3);
break; break;
case side_offsetx_bot: case side_offsetx_bot:
side->offsetx_bot = luaL_checkfixed(L, 3); case side_offsetx_bottom:
side->offsetx_bottom = luaL_checkfixed(L, 3);
break; break;
case side_offsety_bot: case side_offsety_bot:
side->offsety_bot = luaL_checkfixed(L, 3); case side_offsety_bottom:
side->offsety_bottom = luaL_checkfixed(L, 3);
break;
case side_scalex_top:
side->scalex_top = luaL_checkfixed(L, 3);
break;
case side_scaley_top:
side->scaley_top = luaL_checkfixed(L, 3);
break;
case side_scalex_mid:
side->scalex_mid = luaL_checkfixed(L, 3);
break;
case side_scaley_mid:
side->scaley_mid = luaL_checkfixed(L, 3);
break;
case side_scalex_bottom:
side->scalex_bottom = luaL_checkfixed(L, 3);
break;
case side_scaley_bottom:
side->scaley_bottom = luaL_checkfixed(L, 3);
break; break;
case side_toptexture: case side_toptexture:
side->toptexture = luaL_checkinteger(L, 3); side->toptexture = luaL_checkinteger(L, 3);
@ -2122,6 +2214,18 @@ static int ffloor_get(lua_State *L)
case ffloor_toplightlevel: case ffloor_toplightlevel:
lua_pushinteger(L, *ffloor->toplightlevel); lua_pushinteger(L, *ffloor->toplightlevel);
return 1; return 1;
case ffloor_topxoffs:
lua_pushfixed(L, *ffloor->topxoffs);
return 1;
case ffloor_topyoffs:
lua_pushfixed(L, *ffloor->topyoffs);
return 1;
case ffloor_topxscale:
lua_pushfixed(L, *ffloor->topxscale);
return 1;
case ffloor_topyscale:
lua_pushfixed(L, *ffloor->topyscale);
return 1;
case ffloor_bottomheight: case ffloor_bottomheight:
lua_pushfixed(L, *ffloor->bottomheight); lua_pushfixed(L, *ffloor->bottomheight);
return 1; return 1;
@ -2133,6 +2237,18 @@ static int ffloor_get(lua_State *L)
lua_pushlstring(L, levelflat->name, i); lua_pushlstring(L, levelflat->name, i);
return 1; return 1;
} }
case ffloor_bottomxoffs:
lua_pushfixed(L, *ffloor->bottomxoffs);
return 1;
case ffloor_bottomyoffs:
lua_pushfixed(L, *ffloor->bottomyoffs);
return 1;
case ffloor_bottomxscale:
lua_pushfixed(L, *ffloor->bottomxscale);
return 1;
case ffloor_bottomyscale:
lua_pushfixed(L, *ffloor->bottomyscale);
return 1;
case ffloor_tslope: case ffloor_tslope:
LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE); LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE);
return 1; return 1;
@ -2317,6 +2433,18 @@ static int ffloor_set(lua_State *L)
case ffloor_toplightlevel: case ffloor_toplightlevel:
*ffloor->toplightlevel = (INT16)luaL_checkinteger(L, 3); *ffloor->toplightlevel = (INT16)luaL_checkinteger(L, 3);
break; break;
case ffloor_topxoffs:
*ffloor->topxoffs = luaL_checkfixed(L, 3);
break;
case ffloor_topyoffs:
*ffloor->topyoffs = luaL_checkfixed(L, 3);
break;
case ffloor_topxscale:
*ffloor->topxscale = luaL_checkfixed(L, 3);
break;
case ffloor_topyscale:
*ffloor->topyscale = luaL_checkfixed(L, 3);
break;
case ffloor_bottomheight: { // bottomheight case ffloor_bottomheight: { // bottomheight
boolean flag; boolean flag;
fixed_t lastpos = *ffloor->bottomheight; fixed_t lastpos = *ffloor->bottomheight;
@ -2335,6 +2463,18 @@ static int ffloor_set(lua_State *L)
case ffloor_bottompic: case ffloor_bottompic:
*ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); *ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3));
break; break;
case ffloor_bottomxoffs:
*ffloor->bottomxoffs = luaL_checkfixed(L, 3);
break;
case ffloor_bottomyoffs:
*ffloor->bottomyoffs = luaL_checkfixed(L, 3);
break;
case ffloor_bottomxscale:
*ffloor->bottomxscale = luaL_checkfixed(L, 3);
break;
case ffloor_bottomyscale:
*ffloor->bottomyscale = luaL_checkfixed(L, 3);
break;
case ffloor_fofflags: { case ffloor_fofflags: {
ffloortype_e oldflags = ffloor->fofflags; // store FOF's old flags ffloortype_e oldflags = ffloor->fofflags; // store FOF's old flags
ffloor->fofflags = luaL_checkinteger(L, 3); ffloor->fofflags = luaL_checkinteger(L, 3);

View file

@ -641,10 +641,7 @@ static int mobj_set(lua_State *L)
mo->tics = luaL_checkinteger(L, 3); mo->tics = luaL_checkinteger(L, 3);
break; break;
case mobj_state: // set state by enum case mobj_state: // set state by enum
if (mo->player) P_SetMobjState(mo, luaL_checkinteger(L, 3));
P_SetPlayerMobjState(mo, luaL_checkinteger(L, 3));
else
P_SetMobjState(mo, luaL_checkinteger(L, 3));
break; break;
case mobj_flags: // special handling for MF_NOBLOCKMAP and MF_NOSECTOR case mobj_flags: // special handling for MF_NOBLOCKMAP and MF_NOSECTOR
{ {

View file

@ -1019,7 +1019,7 @@ static void OP_CycleThings(INT32 amt)
if (players[0].mo->eflags & MFE_VERTICALFLIP) // correct z when flipped if (players[0].mo->eflags & MFE_VERTICALFLIP) // correct z when flipped
players[0].mo->z += players[0].mo->height - FixedMul(mobjinfo[op_currentthing].height, players[0].mo->scale); players[0].mo->z += players[0].mo->height - FixedMul(mobjinfo[op_currentthing].height, players[0].mo->scale);
players[0].mo->height = FixedMul(mobjinfo[op_currentthing].height, players[0].mo->scale); players[0].mo->height = FixedMul(mobjinfo[op_currentthing].height, players[0].mo->scale);
P_SetPlayerMobjState(players[0].mo, S_OBJPLACE_DUMMY); P_SetMobjState(players[0].mo, S_OBJPLACE_DUMMY);
op_currentdoomednum = mobjinfo[op_currentthing].doomednum; op_currentdoomednum = mobjinfo[op_currentthing].doomednum;
} }
@ -1528,7 +1528,7 @@ void Command_ObjectPlace_f(void)
else else
OP_CycleThings(0); // sets all necessary height values without cycling op_currentthing OP_CycleThings(0); // sets all necessary height values without cycling op_currentthing
P_SetPlayerMobjState(players[0].mo, S_OBJPLACE_DUMMY); P_SetMobjState(players[0].mo, S_OBJPLACE_DUMMY);
} }
// Or are we leaving it instead? // Or are we leaving it instead?
else else
@ -1542,7 +1542,7 @@ void Command_ObjectPlace_f(void)
// If still in dummy state, get out of it. // If still in dummy state, get out of it.
if (players[0].mo->state == &states[S_OBJPLACE_DUMMY]) if (players[0].mo->state == &states[S_OBJPLACE_DUMMY])
P_SetPlayerMobjState(players[0].mo, op_oldstate); P_SetMobjState(players[0].mo, op_oldstate);
// Reset everything back to how it was before we entered objectplace. // Reset everything back to how it was before we entered objectplace.
P_UnsetThingPosition(players[0].mo); P_UnsetThingPosition(players[0].mo);

View file

@ -34,6 +34,7 @@
*/ */
typedef INT32 fixed_t; typedef INT32 fixed_t;
typedef UINT32 ufixed_t;
/*! /*!
\brief convert fixed_t into floating number \brief convert fixed_t into floating number
@ -106,7 +107,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedInt(fixed_t a)
*/ */
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedDiv(fixed_t a, fixed_t b) FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedDiv(fixed_t a, fixed_t b)
{ {
if ((abs(a) >> (FRACBITS-2)) >= abs(b)) if (((ufixed_t)abs(a) >> (FRACBITS-2)) >= (ufixed_t)abs(b))
return (a^b) < 0 ? INT32_MIN : INT32_MAX; return (a^b) < 0 ? INT32_MIN : INT32_MAX;
return FixedDiv2(a, b); return FixedDiv2(a, b);

View file

@ -3177,40 +3177,42 @@ boolean M_Responder(event_t *ev)
} }
else if (menuactive) else if (menuactive)
{ {
if (ev->type == ev_keydown) if (ev->type == ev_keydown || ev->type == ev_text)
{ {
keydown++;
ch = ev->key; ch = ev->key;
if (ev->type == ev_keydown)
// added 5-2-98 remap virtual keys (mouse & joystick buttons)
switch (ch)
{ {
case KEY_MOUSE1: keydown++;
case KEY_JOY1: // added 5-2-98 remap virtual keys (mouse & joystick buttons)
ch = KEY_ENTER; switch (ch)
break; {
case KEY_JOY1 + 3: case KEY_MOUSE1:
ch = 'n'; case KEY_JOY1:
break; ch = KEY_ENTER;
case KEY_MOUSE1 + 1: break;
case KEY_JOY1 + 1: case KEY_JOY1 + 3:
ch = KEY_ESCAPE; ch = 'n';
break; break;
case KEY_JOY1 + 2: case KEY_MOUSE1 + 1:
ch = KEY_BACKSPACE; case KEY_JOY1 + 1:
break; ch = KEY_ESCAPE;
case KEY_HAT1: break;
ch = KEY_UPARROW; case KEY_JOY1 + 2:
break; ch = KEY_BACKSPACE;
case KEY_HAT1 + 1: break;
ch = KEY_DOWNARROW; case KEY_HAT1:
break; ch = KEY_UPARROW;
case KEY_HAT1 + 2: break;
ch = KEY_LEFTARROW; case KEY_HAT1 + 1:
break; ch = KEY_DOWNARROW;
case KEY_HAT1 + 3: break;
ch = KEY_RIGHTARROW; case KEY_HAT1 + 2:
break; ch = KEY_LEFTARROW;
break;
case KEY_HAT1 + 3:
ch = KEY_RIGHTARROW;
break;
}
} }
} }
else if (ev->type == ev_joystick && ev->key == 0 && joywait < I_GetTime()) else if (ev->type == ev_joystick && ev->key == 0 && joywait < I_GetTime())
@ -3372,8 +3374,11 @@ boolean M_Responder(event_t *ev)
// Handle menuitems which need a specific key handling // Handle menuitems which need a specific key handling
if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER) if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER)
{ {
if (shiftdown && ch >= 32 && ch <= 127) // ignore ev_keydown events if the key maps to a character, since
ch = shiftxform[ch]; // the ev_text event will follow immediately after in that case.
if (ev->type == ev_keydown && ch >= 32 && ch <= 127)
return true;
routine(ch); routine(ch);
return true; return true;
} }
@ -3415,6 +3420,11 @@ boolean M_Responder(event_t *ev)
{ {
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING) if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
{ {
// ignore ev_keydown events if the key maps to a character, since
// the ev_text event will follow immediately after in that case.
if (ev->type == ev_keydown && ch >= 32 && ch <= 127)
return false;
if (M_ChangeStringCvar(ch)) if (M_ChangeStringCvar(ch))
return true; return true;
else else
@ -11255,6 +11265,8 @@ static void M_DrawConnectMenu(void)
V_DrawSmallString(currentMenu->x+202, S_LINEY(i)+8, globalflags, "\x85" "Mod"); V_DrawSmallString(currentMenu->x+202, S_LINEY(i)+8, globalflags, "\x85" "Mod");
if (serverlist[slindex].info.cheatsenabled) if (serverlist[slindex].info.cheatsenabled)
V_DrawSmallString(currentMenu->x+222, S_LINEY(i)+8, globalflags, "\x83" "Cheats"); V_DrawSmallString(currentMenu->x+222, S_LINEY(i)+8, globalflags, "\x83" "Cheats");
if (Net_IsNodeIPv6(serverlist[slindex].node))
V_DrawSmallString(currentMenu->x+252, S_LINEY(i)+8, globalflags, "\x84" "IPv6");
V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags, V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags,
va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time))); va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time)));
@ -11948,7 +11960,7 @@ static void M_HandleConnectIP(INT32 choice)
// Rudimentary number and period enforcing - also allows letters so hostnames can be used instead // Rudimentary number and period enforcing - also allows letters so hostnames can be used instead
// and square brackets for RFC 2732 IPv6 addresses // and square brackets for RFC 2732 IPv6 addresses
if ((choice >= '-' && choice <= ':') || if ((choice >= '-' && choice <= ':') ||
(choice == '[' || choice == ']') || (choice == '[' || choice == ']' || choice == '%') ||
(choice >= 'A' && choice <= 'Z') || (choice >= 'A' && choice <= 'Z') ||
(choice >= 'a' && choice <= 'z')) (choice >= 'a' && choice <= 'z'))
{ {

View file

@ -2207,430 +2207,11 @@ char *sizeu5(size_t num)
return sizeu5_buf; return sizeu5_buf;
} }
#if defined (__GNUC__) && defined (__i386__) // from libkwave, under GPL void *M_Memcpy(void *dest, const void *src, size_t n)
// Alam: note libkwave memcpy code comes from mplayer's libvo/aclib_template.c, r699
/* for small memory blocks (<256 bytes) this version is faster */
#define small_memcpy(dest,src,n)\
{\
register unsigned long int dummy;\
__asm__ __volatile__(\
"cld\n\t"\
"rep; movsb"\
:"=&D"(dest), "=&S"(src), "=&c"(dummy)\
:"0" (dest), "1" (src),"2" (n)\
: "memory", "cc");\
}
/* linux kernel __memcpy (from: /include/asm/string.h) */
ATTRINLINE static FUNCINLINE void *__memcpy (void *dest, const void * src, size_t n)
{ {
int d0, d1, d2;
if ( n < 4 )
{
small_memcpy(dest, src, n);
}
else
{
__asm__ __volatile__ (
"rep ; movsl;"
"testb $2,%b4;"
"je 1f;"
"movsw;"
"1:\ttestb $1,%b4;"
"je 2f;"
"movsb;"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
:"0" (n/4), "q" (n),"1" ((long) dest),"2" ((long) src)
: "memory");
}
return dest;
}
#define SSE_MMREG_SIZE 16
#define MMX_MMREG_SIZE 8
#define MMX1_MIN_LEN 0x800 /* 2K blocks */
#define MIN_LEN 0x40 /* 64-byte blocks */
/* SSE note: i tried to move 128 bytes a time instead of 64 but it
didn't make any measureable difference. i'm using 64 for the sake of
simplicity. [MF] */
static /*FUNCTARGET("sse2")*/ void *sse_cpy(void * dest, const void * src, size_t n)
{
void *retval = dest;
size_t i;
/* PREFETCH has effect even for MOVSB instruction ;) */
__asm__ __volatile__ (
"prefetchnta (%0);"
"prefetchnta 32(%0);"
"prefetchnta 64(%0);"
"prefetchnta 96(%0);"
"prefetchnta 128(%0);"
"prefetchnta 160(%0);"
"prefetchnta 192(%0);"
"prefetchnta 224(%0);"
"prefetchnta 256(%0);"
"prefetchnta 288(%0);"
: : "r" (src) );
if (n >= MIN_LEN)
{
register unsigned long int delta;
/* Align destinition to MMREG_SIZE -boundary */
delta = ((unsigned long int)dest)&(SSE_MMREG_SIZE-1);
if (delta)
{
delta=SSE_MMREG_SIZE-delta;
n -= delta;
small_memcpy(dest, src, delta);
}
i = n >> 6; /* n/64 */
n&=63;
if (((unsigned long)src) & 15)
/* if SRC is misaligned */
for (; i>0; i--)
{
__asm__ __volatile__ (
"prefetchnta 320(%0);"
"prefetchnta 352(%0);"
"movups (%0), %%xmm0;"
"movups 16(%0), %%xmm1;"
"movups 32(%0), %%xmm2;"
"movups 48(%0), %%xmm3;"
"movntps %%xmm0, (%1);"
"movntps %%xmm1, 16(%1);"
"movntps %%xmm2, 32(%1);"
"movntps %%xmm3, 48(%1);"
:: "r" (src), "r" (dest) : "memory");
src = (const unsigned char *)src + 64;
dest = (unsigned char *)dest + 64;
}
else
/*
Only if SRC is aligned on 16-byte boundary.
It allows to use movaps instead of movups, which required data
to be aligned or a general-protection exception (#GP) is generated.
*/
for (; i>0; i--)
{
__asm__ __volatile__ (
"prefetchnta 320(%0);"
"prefetchnta 352(%0);"
"movaps (%0), %%xmm0;"
"movaps 16(%0), %%xmm1;"
"movaps 32(%0), %%xmm2;"
"movaps 48(%0), %%xmm3;"
"movntps %%xmm0, (%1);"
"movntps %%xmm1, 16(%1);"
"movntps %%xmm2, 32(%1);"
"movntps %%xmm3, 48(%1);"
:: "r" (src), "r" (dest) : "memory");
src = ((const unsigned char *)src) + 64;
dest = ((unsigned char *)dest) + 64;
}
/* since movntq is weakly-ordered, a "sfence"
* is needed to become ordered again. */
__asm__ __volatile__ ("sfence":::"memory");
/* enables to use FPU */
__asm__ __volatile__ ("emms":::"memory");
}
/*
* Now do the tail of the block
*/
if (n) __memcpy(dest, src, n);
return retval;
}
static FUNCTARGET("mmx") void *mmx2_cpy(void *dest, const void *src, size_t n)
{
void *retval = dest;
size_t i;
/* PREFETCH has effect even for MOVSB instruction ;) */
__asm__ __volatile__ (
"prefetchnta (%0);"
"prefetchnta 32(%0);"
"prefetchnta 64(%0);"
"prefetchnta 96(%0);"
"prefetchnta 128(%0);"
"prefetchnta 160(%0);"
"prefetchnta 192(%0);"
"prefetchnta 224(%0);"
"prefetchnta 256(%0);"
"prefetchnta 288(%0);"
: : "r" (src));
if (n >= MIN_LEN)
{
register unsigned long int delta;
/* Align destinition to MMREG_SIZE -boundary */
delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1);
if (delta)
{
delta=MMX_MMREG_SIZE-delta;
n -= delta;
small_memcpy(dest, src, delta);
}
i = n >> 6; /* n/64 */
n&=63;
for (; i>0; i--)
{
__asm__ __volatile__ (
"prefetchnta 320(%0);"
"prefetchnta 352(%0);"
"movq (%0), %%mm0;"
"movq 8(%0), %%mm1;"
"movq 16(%0), %%mm2;"
"movq 24(%0), %%mm3;"
"movq 32(%0), %%mm4;"
"movq 40(%0), %%mm5;"
"movq 48(%0), %%mm6;"
"movq 56(%0), %%mm7;"
"movntq %%mm0, (%1);"
"movntq %%mm1, 8(%1);"
"movntq %%mm2, 16(%1);"
"movntq %%mm3, 24(%1);"
"movntq %%mm4, 32(%1);"
"movntq %%mm5, 40(%1);"
"movntq %%mm6, 48(%1);"
"movntq %%mm7, 56(%1);"
:: "r" (src), "r" (dest) : "memory");
src = ((const unsigned char *)src) + 64;
dest = ((unsigned char *)dest) + 64;
}
/* since movntq is weakly-ordered, a "sfence"
* is needed to become ordered again. */
__asm__ __volatile__ ("sfence":::"memory");
__asm__ __volatile__ ("emms":::"memory");
}
/*
* Now do the tail of the block
*/
if (n) __memcpy(dest, src, n);
return retval;
}
static FUNCTARGET("mmx") void *mmx1_cpy(void *dest, const void *src, size_t n) //3DNOW
{
void *retval = dest;
size_t i;
/* PREFETCH has effect even for MOVSB instruction ;) */
__asm__ __volatile__ (
"prefetch (%0);"
"prefetch 32(%0);"
"prefetch 64(%0);"
"prefetch 96(%0);"
"prefetch 128(%0);"
"prefetch 160(%0);"
"prefetch 192(%0);"
"prefetch 224(%0);"
"prefetch 256(%0);"
"prefetch 288(%0);"
: : "r" (src));
if (n >= MMX1_MIN_LEN)
{
register unsigned long int delta;
/* Align destinition to MMREG_SIZE -boundary */
delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1);
if (delta)
{
delta=MMX_MMREG_SIZE-delta;
n -= delta;
small_memcpy(dest, src, delta);
}
i = n >> 6; /* n/64 */
n&=63;
for (; i>0; i--)
{
__asm__ __volatile__ (
"prefetch 320(%0);"
"prefetch 352(%0);"
"movq (%0), %%mm0;"
"movq 8(%0), %%mm1;"
"movq 16(%0), %%mm2;"
"movq 24(%0), %%mm3;"
"movq 32(%0), %%mm4;"
"movq 40(%0), %%mm5;"
"movq 48(%0), %%mm6;"
"movq 56(%0), %%mm7;"
"movq %%mm0, (%1);"
"movq %%mm1, 8(%1);"
"movq %%mm2, 16(%1);"
"movq %%mm3, 24(%1);"
"movq %%mm4, 32(%1);"
"movq %%mm5, 40(%1);"
"movq %%mm6, 48(%1);"
"movq %%mm7, 56(%1);"
:: "r" (src), "r" (dest) : "memory");
src = ((const unsigned char *)src) + 64;
dest = ((unsigned char *)dest) + 64;
}
__asm__ __volatile__ ("femms":::"memory"); // same as mmx_cpy() but with a femms
}
/*
* Now do the tail of the block
*/
if (n) __memcpy(dest, src, n);
return retval;
}
#endif
// Alam: why? memcpy may be __cdecl/_System and our code may be not the same type
static void *cpu_cpy(void *dest, const void *src, size_t n)
{
if (src == NULL)
{
CONS_Debug(DBG_MEMORY, "Memcpy from 0x0?!: %p %p %s\n", dest, src, sizeu1(n));
return dest;
}
if(dest == NULL)
{
CONS_Debug(DBG_MEMORY, "Memcpy to 0x0?!: %p %p %s\n", dest, src, sizeu1(n));
return dest;
}
return memcpy(dest, src, n); return memcpy(dest, src, n);
} }
static /*FUNCTARGET("mmx")*/ void *mmx_cpy(void *dest, const void *src, size_t n)
{
#if defined (_MSC_VER) && defined (_X86_)
_asm
{
mov ecx, [n]
mov esi, [src]
mov edi, [dest]
shr ecx, 6 // mit mmx: 64bytes per iteration
jz lower_64 // if lower than 64 bytes
loop_64: // MMX transfers multiples of 64bytes
movq mm0, 0[ESI] // read sources
movq mm1, 8[ESI]
movq mm2, 16[ESI]
movq mm3, 24[ESI]
movq mm4, 32[ESI]
movq mm5, 40[ESI]
movq mm6, 48[ESI]
movq mm7, 56[ESI]
movq 0[EDI], mm0 // write destination
movq 8[EDI], mm1
movq 16[EDI], mm2
movq 24[EDI], mm3
movq 32[EDI], mm4
movq 40[EDI], mm5
movq 48[EDI], mm6
movq 56[EDI], mm7
add esi, 64
add edi, 64
dec ecx
jnz loop_64
emms // close mmx operation
lower_64:// transfer rest of buffer
mov ebx,esi
sub ebx,src
mov ecx,[n]
sub ecx,ebx
shr ecx, 3 // multiples of 8 bytes
jz lower_8
loop_8:
movq mm0, [esi] // read source
movq [edi], mm0 // write destination
add esi, 8
add edi, 8
dec ecx
jnz loop_8
emms // close mmx operation
lower_8:
mov ebx,esi
sub ebx,src
mov ecx,[n]
sub ecx,ebx
rep movsb
mov eax, [dest] // return dest
}
#elif defined (__GNUC__) && defined (__i386__)
void *retval = dest;
size_t i;
if (n >= MMX1_MIN_LEN)
{
register unsigned long int delta;
/* Align destinition to MMREG_SIZE -boundary */
delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1);
if (delta)
{
delta=MMX_MMREG_SIZE-delta;
n -= delta;
small_memcpy(dest, src, delta);
}
i = n >> 6; /* n/64 */
n&=63;
for (; i>0; i--)
{
__asm__ __volatile__ (
"movq (%0), %%mm0;"
"movq 8(%0), %%mm1;"
"movq 16(%0), %%mm2;"
"movq 24(%0), %%mm3;"
"movq 32(%0), %%mm4;"
"movq 40(%0), %%mm5;"
"movq 48(%0), %%mm6;"
"movq 56(%0), %%mm7;"
"movq %%mm0, (%1);"
"movq %%mm1, 8(%1);"
"movq %%mm2, 16(%1);"
"movq %%mm3, 24(%1);"
"movq %%mm4, 32(%1);"
"movq %%mm5, 40(%1);"
"movq %%mm6, 48(%1);"
"movq %%mm7, 56(%1);"
:: "r" (src), "r" (dest) : "memory");
src = ((const unsigned char *)src) + 64;
dest = ((unsigned char *)dest) + 64;
}
__asm__ __volatile__ ("emms":::"memory");
}
/*
* Now do the tail of the block
*/
if (n) __memcpy(dest, src, n);
return retval;
#else
return cpu_cpy(dest, src, n);
#endif
}
void *(*M_Memcpy)(void* dest, const void* src, size_t n) = cpu_cpy;
/** Memcpy that uses MMX, 3DNow, MMXExt or even SSE
* Do not use on overlapped memory, use memmove for that
*/
void M_SetupMemcpy(void)
{
#if defined (__GNUC__) && defined (__i386__)
if (R_SSE2)
M_Memcpy = sse_cpy;
else if (R_MMXExt)
M_Memcpy = mmx2_cpy;
else if (R_3DNow)
M_Memcpy = mmx1_cpy;
else
#endif
if (R_MMX)
M_Memcpy = mmx_cpy;
#if 0
M_Memcpy = cpu_cpy;
#endif
}
/** Return the appropriate message for a file error or end of file. /** Return the appropriate message for a file error or end of file.
*/ */
const char *M_FileError(FILE *fp) const char *M_FileError(FILE *fp)

View file

@ -79,7 +79,7 @@ static void Ban_Clear(void)
void Ban_Load_File(boolean warning) void Ban_Load_File(boolean warning)
{ {
FILE *f; FILE *f;
const char *address, *mask; char *address, *mask;
char buffer[MAX_WADPATH]; char buffer[MAX_WADPATH];
if (!I_ClearBans) if (!I_ClearBans)
@ -100,6 +100,14 @@ void Ban_Load_File(boolean warning)
{ {
address = strtok(buffer, " \t\r\n"); address = strtok(buffer, " \t\r\n");
mask = strtok(NULL, " \t\r\n"); mask = strtok(NULL, " \t\r\n");
if (address[0] == '[')
{
size_t len;
address++;
len = strlen(address);
if (address[len-1] == ']')
address[len-1] = '\0';
}
I_SetBanAddress(address, mask); I_SetBanAddress(address, mask);

View file

@ -90,8 +90,8 @@ INT16 consistancy[BACKUPTICS];
// true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks // true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks
boolean hu_stopped = false; boolean hu_stopped = false;
UINT8 adminpassmd5[16]; UINT8 (*adminpassmd5)[16];
boolean adminpasswordset = false; UINT32 adminpasscount = 0;
tic_t neededtic; tic_t neededtic;
SINT8 servernode = 0; // the number of the server node SINT8 servernode = 0; // the number of the server node
@ -862,26 +862,31 @@ static void PT_Login(SINT8 node, INT32 netconsole)
#ifndef NOMD5 #ifndef NOMD5
UINT8 finalmd5[16];/* Well, it's the cool thing to do? */ UINT8 finalmd5[16];/* Well, it's the cool thing to do? */
UINT32 i;
if (doomcom->datalength < 16)/* ignore partial sends */ if (doomcom->datalength < 16)/* ignore partial sends */
return; return;
if (!adminpasswordset) if (adminpasscount == 0)
{ {
CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]); CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]);
return; return;
} }
// Do the final pass to compare with the sent md5 for (i = 0; i < adminpasscount; i++)
D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", netconsole), &finalmd5);
if (!memcmp(netbuffer->u.md5sum, finalmd5, 16))
{ {
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); // Do the final pass to compare with the sent md5
COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately D_MD5PasswordPass(adminpassmd5[i], 16, va("PNUM%02d", netconsole), &finalmd5);
if (!memcmp(netbuffer->u.md5sum, finalmd5, 16))
{
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]);
COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately
return;
}
} }
else
CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]);
#else #else
(void)netconsole; (void)netconsole;
#endif #endif
@ -1618,6 +1623,17 @@ INT32 D_NumPlayers(void)
return num; return num;
} }
/** Returns the number of nodes on the server.
*/
INT32 D_NumNodes(void)
{
INT32 num = 0;
for (INT32 ix = 0; ix < MAXNETNODES; ix++)
if (netnodes[ix].ingame)
num++;
return num;
}
/** Similar to the above, but counts only bots. /** Similar to the above, but counts only bots.
* Purpose is to remove bots from both the player count and the * Purpose is to remove bots from both the player count and the
* max player count on the server view * max player count on the server view

View file

@ -121,14 +121,15 @@ extern char motd[254], server_context[8];
extern UINT8 playernode[MAXPLAYERS]; extern UINT8 playernode[MAXPLAYERS];
INT32 D_NumPlayers(void); INT32 D_NumPlayers(void);
INT32 D_NumNodes(void);
INT32 D_NumBots(void); INT32 D_NumBots(void);
tic_t GetLag(INT32 node); tic_t GetLag(INT32 node);
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest); void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
extern UINT8 adminpassmd5[16]; extern UINT8 (*adminpassmd5)[16];
extern boolean adminpasswordset; extern UINT32 adminpasscount;
extern boolean hu_stopped; extern boolean hu_stopped;

View file

@ -313,9 +313,9 @@ static void RemoveAck(INT32 i)
} }
// We have got a packet, proceed the ack request and ack return // We have got a packet, proceed the ack request and ack return
static boolean Processackpak(void) static int Processackpak(void)
{ {
boolean goodpacket = true; int goodpacket = 0;
node_t *node = &nodes[doomcom->remotenode]; node_t *node = &nodes[doomcom->remotenode];
// Received an ack return, so remove the ack in the list // Received an ack return, so remove the ack in the list
@ -340,7 +340,7 @@ static boolean Processackpak(void)
{ {
DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack)); DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack));
duppacket++; duppacket++;
goodpacket = false; // Discard packet (duplicate) goodpacket = 1; // Discard packet (duplicate)
} }
else else
{ {
@ -350,10 +350,10 @@ static boolean Processackpak(void)
{ {
DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack)); DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack));
duppacket++; duppacket++;
goodpacket = false; // Discard packet (duplicate) goodpacket = 1; // Discard packet (duplicate)
break; break;
} }
if (goodpacket) if (goodpacket == 0)
{ {
// Is a good packet so increment the acknowledge number, // Is a good packet so increment the acknowledge number,
// Then search for a "hole" in the queue // Then search for a "hole" in the queue
@ -414,12 +414,13 @@ static boolean Processackpak(void)
else // Buffer full discard packet, sender will resend it else // Buffer full discard packet, sender will resend it
{ // We can admit the packet but we will not detect the duplication after :( { // We can admit the packet but we will not detect the duplication after :(
DEBFILE("no more freeackret\n"); DEBFILE("no more freeackret\n");
goodpacket = false; goodpacket = 2;
} }
} }
} }
} }
} }
// return values: 0 = ok, 1 = duplicate, 2 = out of order
return goodpacket; return goodpacket;
} }
@ -1069,6 +1070,7 @@ boolean HGetPacket(void)
while(true) while(true)
{ {
//nodejustjoined = I_NetGet(); //nodejustjoined = I_NetGet();
int goodpacket;
I_NetGet(); I_NetGet();
if (doomcom->remotenode == -1) // No packet received if (doomcom->remotenode == -1) // No packet received
@ -1114,8 +1116,15 @@ boolean HGetPacket(void)
}*/ }*/
// Proceed the ack and ackreturn field // Proceed the ack and ackreturn field
if (!Processackpak()) goodpacket = Processackpak();
if (goodpacket != 0)
{
// resend the ACK in case the previous ACK didn't reach the client.
// prevents the client's netbuffer from locking up.
if (goodpacket == 1)
Net_SendAcks(doomcom->remotenode);
continue; // discarded (duplicated) continue; // discarded (duplicated)
}
// A packet with just ackreturn // A packet with just ackreturn
if (netbuffer->packettype == PT_NOTHING) if (netbuffer->packettype == PT_NOTHING)

View file

@ -70,6 +70,7 @@ boolean HGetPacket(void);
void D_SetDoomcom(void); void D_SetDoomcom(void);
boolean D_CheckNetGame(void); boolean D_CheckNetGame(void);
void D_CloseConnection(void); void D_CloseConnection(void);
boolean Net_IsNodeIPv6(INT32 node);
void Net_UnAcknowledgePacket(INT32 node); void Net_UnAcknowledgePacket(INT32 node);
void Net_CloseConnection(INT32 node); void Net_CloseConnection(INT32 node);
void Net_ConnectionTimeout(INT32 node); void Net_ConnectionTimeout(INT32 node);

View file

@ -150,6 +150,7 @@ static void Command_Clearscores_f(void);
// Remote Administration // Remote Administration
static void Command_Changepassword_f(void); static void Command_Changepassword_f(void);
static void Command_Clearpassword_f(void);
static void Command_Login_f(void); static void Command_Login_f(void);
static void Got_Verification(UINT8 **cp, INT32 playernum); static void Got_Verification(UINT8 **cp, INT32 playernum);
static void Got_Removal(UINT8 **cp, INT32 playernum); static void Got_Removal(UINT8 **cp, INT32 playernum);
@ -468,6 +469,7 @@ void D_RegisterServerCommands(void)
// Remote Administration // Remote Administration
COM_AddCommand("password", Command_Changepassword_f, COM_LUA); COM_AddCommand("password", Command_Changepassword_f, COM_LUA);
COM_AddCommand("clearpassword", Command_Clearpassword_f, COM_LUA);
COM_AddCommand("login", Command_Login_f, COM_LUA); // useful in dedicated to kick off remote admin COM_AddCommand("login", Command_Login_f, COM_LUA); // useful in dedicated to kick off remote admin
COM_AddCommand("promote", Command_Verify_f, COM_LUA); COM_AddCommand("promote", Command_Verify_f, COM_LUA);
RegisterNetXCmd(XD_VERIFIED, Got_Verification); RegisterNetXCmd(XD_VERIFIED, Got_Verification);
@ -620,6 +622,10 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_addons_folder); CV_RegisterVar(&cv_addons_folder);
CV_RegisterVar(&cv_dummyconsvar); CV_RegisterVar(&cv_dummyconsvar);
CV_RegisterVar(&cv_chatspamprotection);
CV_RegisterVar(&cv_chatspamspeed);
CV_RegisterVar(&cv_chatspamburst);
} }
// ========================================================================= // =========================================================================
@ -763,7 +769,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_chatheight); CV_RegisterVar(&cv_chatheight);
CV_RegisterVar(&cv_chatwidth); CV_RegisterVar(&cv_chatwidth);
CV_RegisterVar(&cv_chattime); CV_RegisterVar(&cv_chattime);
CV_RegisterVar(&cv_chatspamprotection);
CV_RegisterVar(&cv_chatbacktint); CV_RegisterVar(&cv_chatbacktint);
CV_RegisterVar(&cv_consolechat); CV_RegisterVar(&cv_consolechat);
CV_RegisterVar(&cv_chatnotifications); CV_RegisterVar(&cv_chatnotifications);
@ -2841,8 +2846,15 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
void D_SetPassword(const char *pw) void D_SetPassword(const char *pw)
{ {
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5); adminpassmd5 = Z_Realloc(adminpassmd5, sizeof(*adminpassmd5) * ++adminpasscount, PU_STATIC, NULL);
adminpasswordset = true; D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5[adminpasscount-1]);
}
void D_ClearPassword(void)
{
Z_Free(adminpassmd5);
adminpassmd5 = NULL;
adminpasscount = 0;
} }
// Remote Administration // Remote Administration
@ -2860,12 +2872,30 @@ static void Command_Changepassword_f(void)
if (COM_Argc() != 2) if (COM_Argc() != 2)
{ {
CONS_Printf(M_GetText("password <password>: change remote admin password\n")); CONS_Printf(M_GetText("password <password>: add remote admin password\n"));
return; return;
} }
D_SetPassword(COM_Argv(1)); D_SetPassword(COM_Argv(1));
CONS_Printf(M_GetText("Password set.\n")); CONS_Printf(M_GetText("Password added.\n"));
#endif
}
// Remote Administration
static void Command_Clearpassword_f(void)
{
#ifdef NOMD5
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
#else
if (client) // cannot change remotely
{
CONS_Printf(M_GetText("Only the server can use this.\n"));
return;
}
D_ClearPassword();
CONS_Printf(M_GetText("Passwords cleared.\n"));
#endif #endif
} }

View file

@ -209,6 +209,7 @@ void ClearAdminPlayers(void);
void RemoveAdminPlayer(INT32 playernum); void RemoveAdminPlayer(INT32 playernum);
void ItemFinder_OnChange(void); void ItemFinder_OnChange(void);
void D_SetPassword(const char *pw); void D_SetPassword(const char *pw);
void D_ClearPassword(void);
// used for the player setup menu // used for the player setup menu
UINT8 CanChangeSkin(INT32 playernum); UINT8 CanChangeSkin(INT32 playernum);

View file

@ -35,6 +35,10 @@ Documentation available here.
#define Blame( ... ) \ #define Blame( ... ) \
CONS_Printf("\x85" __VA_ARGS__) CONS_Printf("\x85" __VA_ARGS__)
#define PROTO_ANY 0
#define PROTO_V4 1
#define PROTO_V6 2
static void MasterServer_Debug_OnChange (void); static void MasterServer_Debug_OnChange (void);
consvar_t cv_masterserver_timeout = CVAR_INIT consvar_t cv_masterserver_timeout = CVAR_INIT
@ -59,12 +63,17 @@ consvar_t cv_masterserver_token = CVAR_INIT
static int hms_started; static int hms_started;
static boolean hms_allow_ipv6;
static char *hms_api; static char *hms_api;
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
static I_mutex hms_api_mutex; static I_mutex hms_api_mutex;
#endif #endif
static char *hms_server_token; static char *hms_server_token;
#ifndef NO_IPV6
static char *hms_server_token_ipv6;
#endif
static char hms_useragent[512]; static char hms_useragent[512];
@ -126,7 +135,7 @@ HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
} }
static struct HMS_buffer * static struct HMS_buffer *
HMS_connect (const char *format, ...) HMS_connect (int proto, const char *format, ...)
{ {
va_list ap; va_list ap;
CURL *curl; CURL *curl;
@ -136,8 +145,14 @@ HMS_connect (const char *format, ...)
size_t token_length; size_t token_length;
struct HMS_buffer *buffer; struct HMS_buffer *buffer;
#ifdef NO_IPV6
if (proto == PROTO_V6)
return NULL;
#endif
if (! hms_started) if (! hms_started)
{ {
hms_allow_ipv6 = !M_CheckParm("-noipv6");
if (curl_global_init(CURL_GLOBAL_ALL) != 0) if (curl_global_init(CURL_GLOBAL_ALL) != 0)
{ {
Contact_error(); Contact_error();
@ -219,7 +234,9 @@ HMS_connect (const char *format, ...)
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
#ifndef NO_IPV6 #ifndef NO_IPV6
if (M_CheckParm("-noipv6")) if (proto == PROTO_V6)
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
if (proto == PROTO_V4)
#endif #endif
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
@ -309,7 +326,7 @@ HMS_fetch_rooms (int joining, int query_id)
(void)query_id; (void)query_id;
hms = HMS_connect("rooms"); hms = HMS_connect(PROTO_ANY, "rooms");
if (! hms) if (! hms)
return 0; return 0;
@ -409,7 +426,7 @@ HMS_register (void)
char *title; char *title;
hms = HMS_connect("rooms/%d/register", ms_RoomId); hms = HMS_connect(PROTO_V4, "rooms/%d/register", ms_RoomId);
if (! hms) if (! hms)
return 0; return 0;
@ -441,6 +458,27 @@ HMS_register (void)
HMS_end(hms); HMS_end(hms);
#ifndef NO_IPV6
if (!hms_allow_ipv6)
return ok;
hms = HMS_connect(PROTO_V6, "rooms/%d/register", ms_RoomId);
if (! hms)
return 0;
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
ok = HMS_do(hms);
if (ok)
{
hms_server_token_ipv6 = strdup(strtok(hms->buffer, "\n"));
}
HMS_end(hms);
#endif
return ok; return ok;
} }
@ -450,7 +488,7 @@ HMS_unlist (void)
struct HMS_buffer *hms; struct HMS_buffer *hms;
int ok; int ok;
hms = HMS_connect("servers/%s/unlist", hms_server_token); hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token);
if (! hms) if (! hms)
return 0; return 0;
@ -462,6 +500,23 @@ HMS_unlist (void)
free(hms_server_token); free(hms_server_token);
#ifndef NO_IPV6
if (hms_server_token_ipv6 && hms_allow_ipv6)
{
hms = HMS_connect(PROTO_V6, "servers/%s/unlist", hms_server_token_ipv6);
if (! hms)
return 0;
curl_easy_setopt(hms->curl, CURLOPT_CUSTOMREQUEST, "POST");
ok = HMS_do(hms);
HMS_end(hms);
free(hms_server_token_ipv6);
}
#endif
return ok; return ok;
} }
@ -475,7 +530,7 @@ HMS_update (void)
char *title; char *title;
hms = HMS_connect("servers/%s/update", hms_server_token); hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token);
if (! hms) if (! hms)
return 0; return 0;
@ -494,6 +549,21 @@ HMS_update (void)
ok = HMS_do(hms); ok = HMS_do(hms);
HMS_end(hms); HMS_end(hms);
#ifndef NO_IPV6
if (hms_server_token_ipv6 && hms_allow_ipv6)
{
hms = HMS_connect(PROTO_V6, "servers/%s/update", hms_server_token_ipv6);
if (! hms)
return ok;
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
ok = HMS_do(hms);
HMS_end(hms);
}
#endif
return ok; return ok;
} }
@ -505,7 +575,7 @@ HMS_list_servers (void)
char *list; char *list;
char *p; char *p;
hms = HMS_connect("servers"); hms = HMS_connect(PROTO_ANY, "servers");
if (! hms) if (! hms)
return; return;
@ -554,10 +624,10 @@ HMS_fetch_servers (msg_server_t *list, int room_number, int query_id)
if (room_number > 0) if (room_number > 0)
{ {
hms = HMS_connect("rooms/%d/servers", room_number); hms = HMS_connect(PROTO_ANY, "rooms/%d/servers", room_number);
} }
else else
hms = HMS_connect("servers"); hms = HMS_connect(PROTO_ANY, "servers");
if (! hms) if (! hms)
return NULL; return NULL;
@ -661,7 +731,7 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
char *version; char *version;
char *version_name; char *version_name;
hms = HMS_connect("versions/%d", MODID); hms = HMS_connect(PROTO_ANY, "versions/%d", MODID);
if (! hms) if (! hms)
return 0; return 0;

View file

@ -83,6 +83,10 @@
#undef ETIMEDOUT #undef ETIMEDOUT
#endif #endif
#define ETIMEDOUT WSAETIMEDOUT #define ETIMEDOUT WSAETIMEDOUT
#ifdef EHOSTUNREACH
#undef EHOSTUNREACH
#endif
#define EHOSTUNREACH WSAEHOSTUNREACH
#ifndef IOC_VENDOR #ifndef IOC_VENDOR
#define IOC_VENDOR 0x18000000 #define IOC_VENDOR 0x18000000
#endif #endif
@ -404,6 +408,20 @@ static const char *SOCK_GetBanMask(size_t ban)
return NULL; return NULL;
} }
#ifdef HAVE_IPV6
static boolean SOCK_cmpipv6(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
{
UINT8 bitmask;
I_Assert(mask <= 128);
if (memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, mask / 8) != 0)
return false;
if (mask % 8 == 0)
return true;
bitmask = 255 << (mask % 8);
return (a->ip6.sin6_addr.s6_addr[mask / 8] & bitmask) == (b->ip6.sin6_addr.s6_addr[mask / 8] & bitmask);
}
#endif
static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
{ {
UINT32 bitmask = INADDR_NONE; UINT32 bitmask = INADDR_NONE;
@ -416,7 +434,7 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
&& (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port)); && (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port));
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
else if (b->any.sa_family == AF_INET6) else if (b->any.sa_family == AF_INET6)
return !memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr)) return SOCK_cmpipv6(a, b, mask)
&& (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port)); && (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port));
#endif #endif
else else
@ -678,7 +696,7 @@ static void SOCK_Send(void)
if (c == ERRSOCKET) if (c == ERRSOCKET)
{ {
int e = errno; // save error code so it can't be modified later int e = errno; // save error code so it can't be modified later
if (e != ECONNREFUSED && e != EWOULDBLOCK) if (e != ECONNREFUSED && e != EWOULDBLOCK && e != EHOSTUNREACH)
I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode, I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode,
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e)); SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
} }
@ -1362,4 +1380,13 @@ boolean I_InitTcpNetwork(void)
return ret; return ret;
} }
boolean Net_IsNodeIPv6(INT32 node)
{
#ifdef NO_IPV6
return false;
#else
return clientaddress[node].any.sa_family == AF_INET6;
#endif
}
#include "i_addrinfo.c" #include "i_addrinfo.c"

View file

@ -60,7 +60,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
{0,NULL} {0,NULL}
}; };
consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://mb.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange); consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ds.ms.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange);
consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters); consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters);
consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters); consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters);
@ -539,6 +539,13 @@ static void MasterServer_OnChange(void)
CV_StealthSet(&cv_masterserver, cv_masterserver.defaultvalue); CV_StealthSet(&cv_masterserver, cv_masterserver.defaultvalue);
} }
if (
! cv_masterserver.changed &&
strcmp(cv_masterserver.string, "https://mb.srb2.org/MS/0") == 0
){
CV_StealthSet(&cv_masterserver, cv_masterserver.defaultvalue);
}
Set_api(cv_masterserver.string); Set_api(cv_masterserver.string);
if (Online()) if (Online())

View file

@ -109,7 +109,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime); netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime);
// Exclude bots from both counts // Exclude bots from both counts
netbuffer->u.serverinfo.numberofplayer = (UINT8)(D_NumPlayers() - D_NumBots()); netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumNodes();
netbuffer->u.serverinfo.maxplayer = (UINT8)(cv_maxplayers.value - D_NumBots()); netbuffer->u.serverinfo.maxplayer = (UINT8)(cv_maxplayers.value - D_NumBots());
netbuffer->u.serverinfo.refusereason = GetRefuseReason(node); netbuffer->u.serverinfo.refusereason = GetRefuseReason(node);
@ -164,7 +164,7 @@ static void SV_SendPlayerInfo(INT32 node)
for (UINT8 i = 0; i < MAXPLAYERS; i++) for (UINT8 i = 0; i < MAXPLAYERS; i++)
{ {
if (!playeringame[i]) if (playernode[i] == UINT8_MAX || !netnodes[playernode[i]].ingame)
{ {
netbuffer->u.playerinfo[i].num = 255; // This slot is empty. netbuffer->u.playerinfo[i].num = 255; // This slot is empty.
continue; continue;

File diff suppressed because it is too large Load diff

View file

@ -1921,6 +1921,9 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
for (c = topz; c > bottomz; c -= spacing) for (c = topz; c > bottomz; c -= spacing)
{ {
spawned = P_SpawnMobj(a, b, c, type); spawned = P_SpawnMobj(a, b, c, type);
if (P_MobjWasRemoved(spawned))
continue;
spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
if (fromcenter) if (fromcenter)

View file

@ -256,6 +256,9 @@ void P_DoNightsScore(player_t *player)
player->linktimer = nightslinktics; player->linktimer = nightslinktics;
} }
if (P_MobjWasRemoved(dummymo))
return;
// Award 10-100 score, doubled if bonus time is active // Award 10-100 score, doubled if bonus time is active
P_AddPlayerScore(player, min(player->linkcount,10)*(player->bonustime ? 20 : 10)); P_AddPlayerScore(player, min(player->linkcount,10)*(player->bonustime ? 20 : 10));
P_SetMobjState(dummymo, (player->bonustime ? dummymo->info->xdeathstate : dummymo->info->spawnstate) + min(player->linkcount,10)-1); P_SetMobjState(dummymo, (player->bonustime ? dummymo->info->xdeathstate : dummymo->info->spawnstate) + min(player->linkcount,10)-1);
@ -526,7 +529,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
else if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) else if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher))
{ {
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
P_SetPlayerMobjState(toucher, S_PLAY_FALL); P_SetMobjState(toucher, S_PLAY_FALL);
toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3);
toucher->momx = 7*toucher->momx>>3; toucher->momx = 7*toucher->momx>>3;
toucher->momy = 7*toucher->momy>>3; toucher->momy = 7*toucher->momy>>3;
@ -1246,7 +1249,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_ResetPlayer(player); P_ResetPlayer(player);
P_SetPlayerMobjState(toucher, S_PLAY_FALL); P_SetMobjState(toucher, S_PLAY_FALL);
} }
} }
return; return;
@ -1301,7 +1304,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
// A flicky orbits us now // A flicky orbits us now
mobj_t *flickyobj = P_SpawnMobj(toucher->x, toucher->y, toucher->z + toucher->info->height, MT_NIGHTOPIANHELPER); mobj_t *flickyobj = P_SpawnMobj(toucher->x, toucher->y, toucher->z + toucher->info->height, MT_NIGHTOPIANHELPER);
P_SetTarget(&flickyobj->target, toucher); if (!P_MobjWasRemoved(flickyobj))
P_SetTarget(&flickyobj->target, toucher);
player->powers[pw_nights_helper] = (UINT16)special->info->speed; player->powers[pw_nights_helper] = (UINT16)special->info->speed;
} }
@ -1312,7 +1316,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (playeringame[i] && players[i].mo && players[i].powers[pw_carry] == CR_NIGHTSMODE) { if (playeringame[i] && players[i].mo && players[i].powers[pw_carry] == CR_NIGHTSMODE) {
players[i].powers[pw_nights_helper] = (UINT16)special->info->speed; players[i].powers[pw_nights_helper] = (UINT16)special->info->speed;
flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER); flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER);
P_SetTarget(&flickyobj->target, players[i].mo); if (!P_MobjWasRemoved(flickyobj))
P_SetTarget(&flickyobj->target, players[i].mo);
} }
if (special->info->deathsound != sfx_None) if (special->info->deathsound != sfx_None)
S_StartSound(NULL, special->info->deathsound); S_StartSound(NULL, special->info->deathsound);
@ -1553,7 +1558,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher))
{ {
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
P_SetPlayerMobjState(toucher, S_PLAY_FALL); P_SetMobjState(toucher, S_PLAY_FALL);
toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3);
toucher->momx = 7*toucher->momx>>3; toucher->momx = 7*toucher->momx>>3;
toucher->momy = 7*toucher->momy>>3; toucher->momy = 7*toucher->momy>>3;
@ -1604,7 +1609,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher))
{ {
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
P_SetPlayerMobjState(toucher, S_PLAY_FALL); P_SetMobjState(toucher, S_PLAY_FALL);
toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3);
toucher->momx = 7*toucher->momx>>3; toucher->momx = 7*toucher->momx>>3;
toucher->momy = 7*toucher->momy>>3; toucher->momy = 7*toucher->momy>>3;
@ -1640,7 +1645,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->momx = special->momy = 0; special->momx = special->momy = 0;
// Buenos Dias Mandy // Buenos Dias Mandy
P_SetPlayerMobjState(toucher, S_PLAY_STUN); P_SetMobjState(toucher, S_PLAY_STUN);
player->pflags &= ~PF_APPLYAUTOBRAKE; player->pflags &= ~PF_APPLYAUTOBRAKE;
P_ResetPlayer(player); P_ResetPlayer(player);
player->drawangle = special->angle + ANGLE_180; player->drawangle = special->angle + ANGLE_180;
@ -1719,7 +1724,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
player->powers[pw_carry] = CR_MACESPIN; player->powers[pw_carry] = CR_MACESPIN;
S_StartSound(toucher, sfx_spin); S_StartSound(toucher, sfx_spin);
P_SetPlayerMobjState(toucher, S_PLAY_ROLL); P_SetMobjState(toucher, S_PLAY_ROLL);
} }
else else
player->powers[pw_carry] = CR_GENERIC; player->powers[pw_carry] = CR_GENERIC;
@ -1780,7 +1785,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
if (player->bot && player->bot != BOT_MPAI && toucher->state-states != S_PLAY_GASP) if (player->bot && player->bot != BOT_MPAI && toucher->state-states != S_PLAY_GASP)
S_StartSound(toucher, special->info->deathsound); // Force it to play a sound for bots S_StartSound(toucher, special->info->deathsound); // Force it to play a sound for bots
P_SetPlayerMobjState(toucher, S_PLAY_GASP); P_SetMobjState(toucher, S_PLAY_GASP);
P_ResetPlayer(player); P_ResetPlayer(player);
} }
@ -1821,9 +1826,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (!player->bot && player->bot != BOT_MPAI && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART && !(player->powers[pw_ignorelatch] & (1<<15))) if (!player->bot && player->bot != BOT_MPAI && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART && !(player->powers[pw_ignorelatch] & (1<<15)))
{ {
mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART);
P_SetTarget(&mcart->target, toucher); if (!P_MobjWasRemoved(mcart))
mcart->angle = toucher->angle = player->drawangle = special->angle; {
mcart->friction = FRACUNIT; P_SetTarget(&mcart->target, toucher);
mcart->angle = toucher->angle = player->drawangle = special->angle;
mcart->friction = FRACUNIT;
}
P_ResetPlayer(player); P_ResetPlayer(player);
player->pflags |= PF_JUMPDOWN; player->pflags |= PF_JUMPDOWN;
@ -1847,7 +1855,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
toucher->momz = toucher->tracer->momz + P_AproxDistance(toucher->tracer->momx, toucher->tracer->momy)/2; toucher->momz = toucher->tracer->momz + P_AproxDistance(toucher->tracer->momx, toucher->tracer->momy)/2;
P_ResetPlayer(player); P_ResetPlayer(player);
player->pflags &= ~PF_APPLYAUTOBRAKE; player->pflags &= ~PF_APPLYAUTOBRAKE;
P_SetPlayerMobjState(toucher, S_PLAY_FALL); P_SetMobjState(toucher, S_PLAY_FALL);
P_SetTarget(&toucher->tracer->target, NULL); P_SetTarget(&toucher->tracer->target, NULL);
P_KillMobj(toucher->tracer, toucher, special, 0); P_KillMobj(toucher->tracer, toucher, special, 0);
P_SetTarget(&toucher->tracer, NULL); P_SetTarget(&toucher->tracer, NULL);
@ -2593,7 +2601,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
break; break;
} }
P_SetMobjState(scoremobj, scorestate); if (!P_MobjWasRemoved(scoremobj))
P_SetMobjState(scoremobj, scorestate);
source->player->scoreadd = locscoreadd; source->player->scoreadd = locscoreadd;
} }
@ -2754,6 +2763,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
mo = P_SpawnMobj(inflictor->x + inflictor->momx, inflictor->y + inflictor->momy, inflictor->z + (inflictor->height / 2) + inflictor->momz, MT_EXTRALARGEBUBBLE); mo = P_SpawnMobj(inflictor->x + inflictor->momx, inflictor->y + inflictor->momy, inflictor->z + (inflictor->height / 2) + inflictor->momz, MT_EXTRALARGEBUBBLE);
else else
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))
break;
mo->destscale = target->scale; mo->destscale = target->scale;
P_SetScale(mo, mo->destscale); P_SetScale(mo, mo->destscale);
P_SetMobjState(mo, mo->info->raisestate); P_SetMobjState(mo, mo->info->raisestate);
@ -2832,8 +2843,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
mo->angle = FixedAngle((P_RandomKey(36)*10)<<FRACBITS); mo->angle = FixedAngle((P_RandomKey(36)*10)<<FRACBITS);
mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK); mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK);
mo2->angle = mo->angle; if (!P_MobjWasRemoved(mo2))
P_SetMobjState(mo2, S_BOSSSEBH2); {
mo2->angle = mo->angle;
P_SetMobjState(mo2, S_BOSSSEBH2);
}
if (++i == 2) // we've already removed 2 of these, let's stop now if (++i == 2) // we've already removed 2 of these, let's stop now
break; break;
@ -2932,7 +2946,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
if (flip) if (flip)
momz *= -1; momz *= -1;
#define makechunk(angtweak, xmov, ymov) \ #define makechunk(angtweak, xmov, ymov) \
do {\
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\ chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\
if (P_MobjWasRemoved(chunk))\
break;\
P_SetMobjState(chunk, target->info->xdeathstate);\ P_SetMobjState(chunk, target->info->xdeathstate);\
chunk->health = 0;\ chunk->health = 0;\
chunk->angle = angtweak;\ chunk->angle = angtweak;\
@ -2942,7 +2959,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
chunk->y += ymov;\ chunk->y += ymov;\
P_SetThingPosition(chunk);\ P_SetThingPosition(chunk);\
P_InstaThrust(chunk,chunk->angle, 4*scale);\ P_InstaThrust(chunk,chunk->angle, 4*scale);\
chunk->momz = momz chunk->momz = momz;\
} while (0)
makechunk(ang + ANGLE_180, -xoffs, -yoffs); makechunk(ang + ANGLE_180, -xoffs, -yoffs);
makechunk(ang, xoffs, yoffs); makechunk(ang, xoffs, yoffs);
@ -2955,20 +2973,23 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
momz *= -1; momz *= -1;
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE); chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);
P_SetMobjState(chunk, target->info->deathstate); if (!P_MobjWasRemoved(chunk))
chunk->health = 0; {
chunk->angle = ang + ANGLE_180; P_SetMobjState(chunk, target->info->deathstate);
P_UnsetThingPosition(chunk); chunk->health = 0;
chunk->flags = MF_NOCLIP; chunk->angle = ang + ANGLE_180;
chunk->x -= xoffs; P_UnsetThingPosition(chunk);
chunk->y -= yoffs; chunk->flags = MF_NOCLIP;
if (flip) chunk->x -= xoffs;
chunk->z -= 12*scale; chunk->y -= yoffs;
else if (flip)
chunk->z += 12*scale; chunk->z -= 12*scale;
P_SetThingPosition(chunk); else
P_InstaThrust(chunk, chunk->angle, 2*scale); chunk->z += 12*scale;
chunk->momz = momz; P_SetThingPosition(chunk);
P_InstaThrust(chunk, chunk->angle, 2*scale);
chunk->momz = momz;
}
P_SetMobjState(target, target->info->deathstate); P_SetMobjState(target, target->info->deathstate);
target->health = 0; target->health = 0;
@ -2977,7 +2998,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->flags = MF_NOCLIP; target->flags = MF_NOCLIP;
target->x += xoffs; target->x += xoffs;
target->y += yoffs; target->y += yoffs;
target->z = chunk->z; if (flip)
target->z -= 12*scale;
else
target->z += 12*scale;
P_SetThingPosition(target); P_SetThingPosition(target);
P_InstaThrust(target, target->angle, 2*scale); P_InstaThrust(target, target->angle, 2*scale);
target->momz = momz; target->momz = momz;
@ -3000,21 +3024,25 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
sprflip = P_RandomChance(FRACUNIT/2); sprflip = P_RandomChance(FRACUNIT/2);
#define makechunk(angtweak, xmov, ymov) \ #define makechunk(angtweak, xmov, ymov) \
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\ do {\
P_SetMobjState(chunk, target->info->xdeathstate);\ chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\
chunk->health = 0;\ if (P_MobjWasRemoved(chunk))\
chunk->angle = target->angle;\ break;\
P_UnsetThingPosition(chunk);\ P_SetMobjState(chunk, target->info->xdeathstate);\
chunk->flags = MF_NOCLIP;\ chunk->health = 0;\
chunk->x += xmov - forwardxoffs;\ chunk->angle = target->angle;\
chunk->y += ymov - forwardyoffs;\ P_UnsetThingPosition(chunk);\
P_SetThingPosition(chunk);\ chunk->flags = MF_NOCLIP;\
P_InstaThrust(chunk, angtweak, 4*scale);\ chunk->x += xmov - forwardxoffs;\
chunk->momz = P_RandomRange(5, 7)*scale;\ chunk->y += ymov - forwardyoffs;\
if (flip)\ P_SetThingPosition(chunk);\
chunk->momz *= -1;\ P_InstaThrust(chunk, angtweak, 4*scale);\
if (sprflip)\ chunk->momz = P_RandomRange(5, 7)*scale;\
chunk->frame |= FF_VERTICALFLIP if (flip)\
chunk->momz *= -1;\
if (sprflip)\
chunk->frame |= FF_VERTICALFLIP;\
} while (0)
makechunk(ang + ANGLE_180, -xoffs, -yoffs); makechunk(ang + ANGLE_180, -xoffs, -yoffs);
sprflip = !sprflip; sprflip = !sprflip;
@ -3026,21 +3054,23 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
sprflip = P_RandomChance(FRACUNIT/2); sprflip = P_RandomChance(FRACUNIT/2);
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE); chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);
if (!P_MobjWasRemoved(chunk))
P_SetMobjState(chunk, target->info->deathstate); {
chunk->health = 0; P_SetMobjState(chunk, target->info->deathstate);
chunk->angle = target->angle; chunk->health = 0;
P_UnsetThingPosition(chunk); chunk->angle = target->angle;
chunk->flags = MF_NOCLIP; P_UnsetThingPosition(chunk);
chunk->x += forwardxoffs - xoffs; chunk->flags = MF_NOCLIP;
chunk->y += forwardyoffs - yoffs; chunk->x += forwardxoffs - xoffs;
P_SetThingPosition(chunk); chunk->y += forwardyoffs - yoffs;
P_InstaThrust(chunk, ang + ANGLE_180, 2*scale); P_SetThingPosition(chunk);
chunk->momz = P_RandomRange(5, 7)*scale; P_InstaThrust(chunk, ang + ANGLE_180, 2*scale);
if (flip) chunk->momz = P_RandomRange(5, 7)*scale;
chunk->momz *= -1; if (flip)
if (sprflip) chunk->momz *= -1;
chunk->frame |= FF_VERTICALFLIP; if (sprflip)
chunk->frame |= FF_VERTICALFLIP;
}
P_SetMobjState(target, target->info->deathstate); P_SetMobjState(target, target->info->deathstate);
target->health = 0; target->health = 0;
@ -3059,9 +3089,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
else if (target->player) else if (target->player)
{ {
if (damagetype == DMG_DROWNED || damagetype == DMG_SPACEDROWN) if (damagetype == DMG_DROWNED || damagetype == DMG_SPACEDROWN)
P_SetPlayerMobjState(target, target->info->xdeathstate); P_SetMobjState(target, target->info->xdeathstate);
else else
P_SetPlayerMobjState(target, target->info->deathstate); P_SetMobjState(target, target->info->deathstate);
} }
else else
#ifdef DEBUG_NULL_DEATHSTATE #ifdef DEBUG_NULL_DEATHSTATE
@ -3115,7 +3145,7 @@ static void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
} }
player->powers[pw_flashing] = flashingtics; player->powers[pw_flashing] = flashingtics;
P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN); P_SetMobjState(target, S_PLAY_NIGHTS_STUN);
S_StartSound(target, sfx_nghurt); S_StartSound(target, sfx_nghurt);
player->mo->spriteroll = 0; player->mo->spriteroll = 0;
@ -3336,7 +3366,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
if (!player->spectator) if (!player->spectator)
player->mo->flags2 &= ~MF2_DONTDRAW; player->mo->flags2 &= ~MF2_DONTDRAW;
P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); P_SetMobjState(player->mo, player->mo->info->deathstate);
if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
{ {
P_PlayerFlagBurst(player, false); P_PlayerFlagBurst(player, false);
@ -3410,7 +3440,7 @@ static void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, I
P_InstaThrust(player->mo, ang, fallbackspeed); P_InstaThrust(player->mo, ang, fallbackspeed);
P_SetPlayerMobjState(player->mo, S_PLAY_STUN); P_SetMobjState(player->mo, S_PLAY_STUN);
P_ResetPlayer(player); P_ResetPlayer(player);
@ -3921,6 +3951,8 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
z += player->mo->height - mobjinfo[objType].height; z += player->mo->height - mobjinfo[objType].height;
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, objType); mo = P_SpawnMobj(player->mo->x, player->mo->y, z, objType);
if (P_MobjWasRemoved(mo))
continue;
mo->fuse = 8*TICRATE; mo->fuse = 8*TICRATE;
P_SetTarget(&mo->target, player->mo); P_SetTarget(&mo->target, player->mo);
@ -4054,6 +4086,9 @@ void P_PlayerWeaponPanelBurst(player_t *player)
z += player->mo->height - mobjinfo[weptype].height; z += player->mo->height - mobjinfo[weptype].height;
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype); mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype);
if (P_MobjWasRemoved(mo))
continue;
mo->reactiontime = ammoamt; mo->reactiontime = ammoamt;
mo->flags2 |= MF2_DONTRESPAWN; mo->flags2 |= MF2_DONTRESPAWN;
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
@ -4087,13 +4122,13 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
mobj_t *mo; mobj_t *mo;
angle_t fa; angle_t fa;
fixed_t ns; fixed_t ns;
INT32 i = 0; INT32 i;
fixed_t z; fixed_t z;
mobjtype_t weptype = 0; mobjtype_t weptype = 0;
powertype_t power = 0; powertype_t power = 0;
while (true) for (i = 0;; i++)
{ {
if (player->powers[pw_bouncering]) if (player->powers[pw_bouncering])
{ {
@ -4138,6 +4173,8 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
z += player->mo->height - mobjinfo[weptype].height; z += player->mo->height - mobjinfo[weptype].height;
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype); mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype);
if (P_MobjWasRemoved(mo))
continue;
mo->health = player->powers[power]; mo->health = player->powers[power];
mo->flags2 |= MF2_DONTRESPAWN; mo->flags2 |= MF2_DONTRESPAWN;
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
@ -4163,8 +4200,6 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
if (i & 1) if (i & 1)
P_SetObjectMomZ(mo, 3*FRACUNIT, true); P_SetObjectMomZ(mo, 3*FRACUNIT, true);
i++;
} }
} }
@ -4189,45 +4224,50 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player)
player->ringweapons &= ~rwflag; \ player->ringweapons &= ~rwflag; \
SETUP_DROP(pickup) \ SETUP_DROP(pickup) \
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, pickup); \ mo = P_SpawnMobj(player->mo->x, player->mo->y, z, pickup); \
mo->reactiontime = 0; \ if (!P_MobjWasRemoved(mo)) \
mo->flags2 |= MF2_DONTRESPAWN; \ { \
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ mo->reactiontime = 0; \
P_SetTarget(&mo->target, player->mo); \ mo->flags2 |= MF2_DONTRESPAWN; \
mo->fuse = 12*TICRATE; \ mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \
mo->destscale = player->mo->scale; \ P_SetTarget(&mo->target, player->mo); \
P_SetScale(mo, player->mo->scale); \ mo->fuse = 12*TICRATE; \
mo->momx = FixedMul(FINECOSINE(fa),ns); \ mo->destscale = player->mo->scale; \
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ P_SetScale(mo, player->mo->scale); \
mo->momy = FixedMul(FINESINE(fa),ns); \ mo->momx = FixedMul(FINECOSINE(fa),ns); \
P_SetObjectMomZ(mo, 4*FRACUNIT, false); \ if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \
if (i & 1) \ mo->momy = FixedMul(FINESINE(fa),ns); \
P_SetObjectMomZ(mo, 4*FRACUNIT, true); \ P_SetObjectMomZ(mo, 4*FRACUNIT, false); \
if (player->mo->eflags & MFE_VERTICALFLIP) \ if (i & 1) \
mo->flags2 |= MF2_OBJECTFLIP; \ P_SetObjectMomZ(mo, 4*FRACUNIT, true); \
++i; \ if (player->mo->eflags & MFE_VERTICALFLIP) \
mo->flags2 |= MF2_OBJECTFLIP; \
} \
} \ } \
else if (player->powers[power] > 0) \ else if (player->powers[power] > 0) \
{ \ { \
SETUP_DROP(ammo) \ SETUP_DROP(ammo) \
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, ammo); \ mo = P_SpawnMobj(player->mo->x, player->mo->y, z, ammo); \
mo->health = player->powers[power]; \ if (!P_MobjWasRemoved(mo)) \
mo->flags2 |= MF2_DONTRESPAWN; \ { \
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ mo->health = player->powers[power]; \
P_SetTarget(&mo->target, player->mo); \ mo->flags2 |= MF2_DONTRESPAWN; \
mo->fuse = 12*TICRATE; \ mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \
mo->destscale = player->mo->scale; \ P_SetTarget(&mo->target, player->mo); \
P_SetScale(mo, player->mo->scale); \ mo->fuse = 12*TICRATE; \
mo->momx = FixedMul(FINECOSINE(fa),ns); \ mo->destscale = player->mo->scale; \
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ P_SetScale(mo, player->mo->scale); \
mo->momy = FixedMul(FINESINE(fa),ns); \ mo->momx = FixedMul(FINECOSINE(fa),ns); \
P_SetObjectMomZ(mo, 3*FRACUNIT, false); \ if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \
if (i & 1) \ mo->momy = FixedMul(FINESINE(fa),ns); \
P_SetObjectMomZ(mo, 3*FRACUNIT, true); \ P_SetObjectMomZ(mo, 3*FRACUNIT, false); \
if (player->mo->eflags & MFE_VERTICALFLIP) \ if (i & 1) \
mo->flags2 |= MF2_OBJECTFLIP; \ P_SetObjectMomZ(mo, 3*FRACUNIT, true); \
player->powers[power] = 0; \ if (player->mo->eflags & MFE_VERTICALFLIP) \
++i; \ mo->flags2 |= MF2_OBJECTFLIP; \
} player->powers[power] = 0; \
} \
} \
++i
DROP_WEAPON(RW_BOUNCE, MT_BOUNCEPICKUP, MT_BOUNCERING, pw_bouncering); DROP_WEAPON(RW_BOUNCE, MT_BOUNCEPICKUP, MT_BOUNCERING, pw_bouncering);
DROP_WEAPON(RW_RAIL, MT_RAILPICKUP, MT_RAILRING, pw_railring); DROP_WEAPON(RW_RAIL, MT_RAILPICKUP, MT_RAILRING, pw_railring);
@ -4351,23 +4391,26 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss)
momy = 0; momy = 0;
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, MT_FLINGEMERALD); mo = P_SpawnMobj(player->mo->x, player->mo->y, z, MT_FLINGEMERALD);
mo->health = 1; if (!P_MobjWasRemoved(mo))
mo->threshold = stoneflag;
mo->flags2 |= (MF2_DONTRESPAWN|MF2_SLIDEPUSH);
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
P_SetTarget(&mo->target, player->mo);
mo->fuse = 12*TICRATE;
P_SetMobjState(mo, statenum);
mo->momx = momx;
mo->momy = momy;
P_SetObjectMomZ(mo, 3*FRACUNIT, false);
if (player->mo->eflags & MFE_VERTICALFLIP)
{ {
mo->momz = -mo->momz; mo->health = 1;
mo->flags2 |= MF2_OBJECTFLIP; mo->threshold = stoneflag;
mo->flags2 |= (MF2_DONTRESPAWN|MF2_SLIDEPUSH);
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
P_SetTarget(&mo->target, player->mo);
mo->fuse = 12*TICRATE;
P_SetMobjState(mo, statenum);
mo->momx = momx;
mo->momy = momy;
P_SetObjectMomZ(mo, 3*FRACUNIT, false);
if (player->mo->eflags & MFE_VERTICALFLIP)
{
mo->momz = -mo->momz;
mo->flags2 |= MF2_OBJECTFLIP;
}
} }
if (toss) if (toss)
@ -4395,6 +4438,8 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
type = MT_BLUEFLAG; type = MT_BLUEFLAG;
flag = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, type); flag = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, type);
if (P_MobjWasRemoved(flag))
return;
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{ {

View file

@ -71,6 +71,7 @@ typedef enum
NUM_THINKERLISTS NUM_THINKERLISTS
} thinklistnum_t; /**< Thinker lists. */ } thinklistnum_t; /**< Thinker lists. */
extern thinker_t thlist[]; extern thinker_t thlist[];
extern mobj_t *mobjcache;
void P_InitThinkers(void); void P_InitThinkers(void);
void P_AddThinker(const thinklistnum_t n, thinker_t *thinker); void P_AddThinker(const thinklistnum_t n, thinker_t *thinker);
@ -288,7 +289,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype);
void P_RespawnSpecials(void); void P_RespawnSpecials(void);
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...);
void P_RecalcPrecipInSector(sector_t *sector); void P_RecalcPrecipInSector(sector_t *sector);
void P_PrecipitationEffects(void); void P_PrecipitationEffects(void);
@ -296,7 +297,6 @@ void P_PrecipitationEffects(void);
void P_RemoveMobj(mobj_t *th); void P_RemoveMobj(mobj_t *th);
boolean P_MobjWasRemoved(mobj_t *th); boolean P_MobjWasRemoved(mobj_t *th);
void P_RemoveSavegameMobj(mobj_t *th); void P_RemoveSavegameMobj(mobj_t *th);
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
boolean P_SetMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
void P_RunShields(void); void P_RunShields(void);
void P_RunOverlays(void); void P_RunOverlays(void);

View file

@ -264,7 +264,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
UINT8 secondjump = object->player->secondjump; UINT8 secondjump = object->player->secondjump;
UINT16 tailsfly = object->player->powers[pw_tailsfly]; UINT16 tailsfly = object->player->powers[pw_tailsfly];
if (object->player->pflags & PF_GLIDING) if (object->player->pflags & PF_GLIDING)
P_SetPlayerMobjState(object, S_PLAY_FALL); P_SetMobjState(object, S_PLAY_FALL);
P_ResetPlayer(object->player); P_ResetPlayer(object->player);
object->player->pflags |= pflags; object->player->pflags |= pflags;
object->player->secondjump = secondjump; object->player->secondjump = secondjump;
@ -403,7 +403,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
} }
if (object->player->pflags & PF_GLIDING) if (object->player->pflags & PF_GLIDING)
P_SetPlayerMobjState(object, S_PLAY_FALL); P_SetMobjState(object, S_PLAY_FALL);
if ((spring->info->painchance == 3)) if ((spring->info->painchance == 3))
{ {
if (!(pflags = (object->player->pflags & PF_SPINNING)) && if (!(pflags = (object->player->pflags & PF_SPINNING)) &&
@ -411,11 +411,11 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|| (spring->flags2 & MF2_AMBUSH))) || (spring->flags2 & MF2_AMBUSH)))
{ {
pflags = PF_SPINNING; pflags = PF_SPINNING;
P_SetPlayerMobjState(object, S_PLAY_ROLL); P_SetMobjState(object, S_PLAY_ROLL);
S_StartSound(object, sfx_spin); S_StartSound(object, sfx_spin);
} }
else else
P_SetPlayerMobjState(object, S_PLAY_ROLL); P_SetMobjState(object, S_PLAY_ROLL);
} }
else else
{ {
@ -424,7 +424,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
pflags = object->player->pflags & (PF_STARTJUMP | PF_JUMPED | PF_NOJUMPDAMAGE | PF_SPINNING | PF_THOKKED | PF_BOUNCING); // I still need these. pflags = object->player->pflags & (PF_STARTJUMP | PF_JUMPED | PF_NOJUMPDAMAGE | PF_SPINNING | PF_THOKKED | PF_BOUNCING); // I still need these.
if (wasSpindashing) // Ensure we're in the rolling state, and not spindash. if (wasSpindashing) // Ensure we're in the rolling state, and not spindash.
P_SetPlayerMobjState(object, S_PLAY_ROLL); P_SetMobjState(object, S_PLAY_ROLL);
if (object->player->charability == CA_GLIDEANDCLIMB && object->player->skidtime && (pflags & PF_JUMPED)) if (object->player->charability == CA_GLIDEANDCLIMB && object->player->skidtime && (pflags & PF_JUMPED))
{ {
@ -439,7 +439,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (spring->info->painchance == 1) // For all those ancient, SOC'd abilities. if (spring->info->painchance == 1) // For all those ancient, SOC'd abilities.
{ {
object->player->pflags |= P_GetJumpFlags(object->player); object->player->pflags |= P_GetJumpFlags(object->player);
P_SetPlayerMobjState(object, S_PLAY_JUMP); P_SetMobjState(object, S_PLAY_JUMP);
} }
else if ((spring->info->painchance == 2) || ((spring->info->painchance != 3) && (pflags & PF_BOUNCING))) // Adding momentum only. else if ((spring->info->painchance == 2) || ((spring->info->painchance != 3) && (pflags & PF_BOUNCING))) // Adding momentum only.
{ {
@ -456,16 +456,16 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
object->player->secondjump = secondjump; object->player->secondjump = secondjump;
} }
else if (object->player->dashmode >= DASHMODE_THRESHOLD) else if (object->player->dashmode >= DASHMODE_THRESHOLD)
P_SetPlayerMobjState(object, S_PLAY_DASH); P_SetMobjState(object, S_PLAY_DASH);
else if (P_IsObjectOnGround(object)) else if (P_IsObjectOnGround(object))
P_SetPlayerMobjState(object, (horizspeed >= FixedMul(object->player->runspeed, object->scale)) ? S_PLAY_RUN : S_PLAY_WALK); P_SetMobjState(object, (horizspeed >= FixedMul(object->player->runspeed, object->scale)) ? S_PLAY_RUN : S_PLAY_WALK);
else else
P_SetPlayerMobjState(object, (object->momz > 0) ? S_PLAY_SPRING : S_PLAY_FALL); P_SetMobjState(object, (object->momz > 0) ? S_PLAY_SPRING : S_PLAY_FALL);
} }
else if (P_MobjFlip(object)*vertispeed > 0) else if (P_MobjFlip(object)*vertispeed > 0)
P_SetPlayerMobjState(object, S_PLAY_SPRING); P_SetMobjState(object, S_PLAY_SPRING);
else else
P_SetPlayerMobjState(object, S_PLAY_FALL); P_SetMobjState(object, S_PLAY_FALL);
} }
else if (horizspeed else if (horizspeed
&& object->tracer && object->tracer
@ -547,7 +547,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
if (p && !p->powers[pw_tailsfly] && !p->powers[pw_carry]) // doesn't reset anim for Tails' flight if (p && !p->powers[pw_tailsfly] && !p->powers[pw_carry]) // doesn't reset anim for Tails' flight
{ {
P_ResetPlayer(p); P_ResetPlayer(p);
P_SetPlayerMobjState(object, S_PLAY_FALL); P_SetMobjState(object, S_PLAY_FALL);
P_SetTarget(&object->tracer, spring); P_SetTarget(&object->tracer, spring);
p->powers[pw_carry] = CR_FAN; p->powers[pw_carry] = CR_FAN;
} }
@ -565,7 +565,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
{ {
P_ResetPlayer(p); P_ResetPlayer(p);
if (p->panim != PA_FALL) if (p->panim != PA_FALL)
P_SetPlayerMobjState(object, S_PLAY_FALL); P_SetMobjState(object, S_PLAY_FALL);
} }
break; break;
default: default:
@ -1047,7 +1047,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
thing->flags2 &= ~MF2_DONTDRAW; // don't leave the rock invisible if it was flashing prior to boarding thing->flags2 &= ~MF2_DONTDRAW; // don't leave the rock invisible if it was flashing prior to boarding
P_SetTarget(&thing->tracer, tmthing); P_SetTarget(&thing->tracer, tmthing);
P_ResetPlayer(tmthing->player); P_ResetPlayer(tmthing->player);
P_SetPlayerMobjState(tmthing, S_PLAY_WALK); P_SetMobjState(tmthing, S_PLAY_WALK);
tmthing->player->powers[pw_carry] = CR_ROLLOUT; tmthing->player->powers[pw_carry] = CR_ROLLOUT;
P_SetTarget(&tmthing->tracer, thing); P_SetTarget(&tmthing->tracer, thing);
if (!P_IsObjectOnGround(thing)) if (!P_IsObjectOnGround(thing))
@ -2865,6 +2865,8 @@ boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{ {
boolean moveok; boolean moveok;
mobj_t *hack = P_SpawnMobjFromMobj(thing, 0, 0, 0, MT_RAY); mobj_t *hack = P_SpawnMobjFromMobj(thing, 0, 0, 0, MT_RAY);
if (P_MobjWasRemoved(hack))
return false;
hack->radius = thing->radius; hack->radius = thing->radius;
hack->height = thing->height; hack->height = thing->height;

File diff suppressed because it is too large Load diff

View file

@ -1243,6 +1243,8 @@ boolean Polyobj_rotate(polyobj_t *po, angle_t delta, boolean turnplayers, boolea
// Returns NULL if no such polyobject exists. // Returns NULL if no such polyobject exists.
polyobj_t *Polyobj_GetForNum(INT32 id) polyobj_t *Polyobj_GetForNum(INT32 id)
{ {
if (numPolyObjects == 0)
return NULL;
INT32 curidx = PolyObjects[id % numPolyObjects].first; INT32 curidx = PolyObjects[id % numPolyObjects].first;
while (curidx != numPolyObjects && PolyObjects[curidx].id != id) while (curidx != numPolyObjects && PolyObjects[curidx].id != id)

View file

@ -861,32 +861,62 @@ static void P_NetUnArchiveWaypoints(void)
#define SD_SPECIALFLAG 0x40 #define SD_SPECIALFLAG 0x40
#define SD_DIFF4 0x80 #define SD_DIFF4 0x80
//diff4 flags // diff4 flags
#define SD_DAMAGETYPE 0x01 #define SD_DAMAGETYPE 0x01
#define SD_TRIGGERTAG 0x02 #define SD_TRIGGERTAG 0x02
#define SD_TRIGGERER 0x04 #define SD_TRIGGERER 0x04
#define SD_GRAVITY 0x08 #define SD_FXSCALE 0x08
#define SD_FLOORPORTAL 0x10 #define SD_FYSCALE 0x10
#define SD_CEILPORTAL 0x20 #define SD_CXSCALE 0x20
#define SD_CYSCALE 0x40
#define SD_DIFF5 0x80
#define LD_FLAG 0x01 // diff5 flags
#define LD_SPECIAL 0x02 #define SD_GRAVITY 0x01
#define LD_CLLCOUNT 0x04 #define SD_FLOORPORTAL 0x02
#define LD_S1TEXOFF 0x08 #define SD_CEILPORTAL 0x04
#define LD_S1TOPTEX 0x10
#define LD_S1BOTTEX 0x20 // diff1 flags
#define LD_S1MIDTEX 0x40 #define LD_FLAG 0x01
#define LD_DIFF2 0x80 #define LD_SPECIAL 0x02
#define LD_CLLCOUNT 0x04
#define LD_ARGS 0x08
#define LD_STRINGARGS 0x10
#define LD_SIDE1 0x20
#define LD_SIDE2 0x40
#define LD_DIFF2 0x80
// diff2 flags // diff2 flags
#define LD_S2TEXOFF 0x01 #define LD_EXECUTORDELAY 0x01
#define LD_S2TOPTEX 0x02 #define LD_TRANSFPORTAL 0x02
#define LD_S2BOTTEX 0x04
#define LD_S2MIDTEX 0x08 // sidedef flags
#define LD_ARGS 0x10 enum
#define LD_STRINGARGS 0x20 {
#define LD_EXECUTORDELAY 0x40 LD_SDTEXOFFX = 1,
#define LD_TRANSFPORTAL 0x80 LD_SDTEXOFFY = 1<<1,
LD_SDTOPTEX = 1<<2,
LD_SDBOTTEX = 1<<3,
LD_SDMIDTEX = 1<<4,
LD_SDTOPOFFX = 1<<5,
LD_SDTOPOFFY = 1<<6,
LD_SDMIDOFFX = 1<<7,
LD_SDMIDOFFY = 1<<8,
LD_SDBOTOFFX = 1<<9,
LD_SDBOTOFFY = 1<<10,
LD_SDTOPSCALEX = 1<<11,
LD_SDTOPSCALEY = 1<<12,
LD_SDMIDSCALEX = 1<<13,
LD_SDMIDSCALEY = 1<<14,
LD_SDBOTSCALEX = 1<<15,
LD_SDBOTSCALEY = 1<<16,
LD_SDLIGHT = 1<<17,
LD_SDTOPLIGHT = 1<<18,
LD_SDMIDLIGHT = 1<<19,
LD_SDBOTLIGHT = 1<<20,
LD_SDREPEATCNT = 1<<21,
LD_SDFLAGS = 1<<22
};
static boolean P_AreArgsEqual(const line_t *li, const line_t *spawnli) static boolean P_AreArgsEqual(const line_t *li, const line_t *spawnli)
{ {
@ -1007,11 +1037,11 @@ static void ArchiveSectors(void)
size_t i, j; size_t i, j;
const sector_t *ss = sectors; const sector_t *ss = sectors;
const sector_t *spawnss = spawnsectors; const sector_t *spawnss = spawnsectors;
UINT8 diff, diff2, diff3, diff4; UINT8 diff, diff2, diff3, diff4, diff5;
for (i = 0; i < numsectors; i++, ss++, spawnss++) for (i = 0; i < numsectors; i++, ss++, spawnss++)
{ {
diff = diff2 = diff3 = diff4 = 0; diff = diff2 = diff3 = diff4 = diff5 = 0;
if (ss->floorheight != spawnss->floorheight) if (ss->floorheight != spawnss->floorheight)
diff |= SD_FLOORHT; diff |= SD_FLOORHT;
if (ss->ceilingheight != spawnss->ceilingheight) if (ss->ceilingheight != spawnss->ceilingheight)
@ -1037,6 +1067,14 @@ static void ArchiveSectors(void)
diff2 |= SD_CXOFFS; diff2 |= SD_CXOFFS;
if (ss->ceilingyoffset != spawnss->ceilingyoffset) if (ss->ceilingyoffset != spawnss->ceilingyoffset)
diff2 |= SD_CYOFFS; diff2 |= SD_CYOFFS;
if (ss->floorxscale != spawnss->floorxscale)
diff2 |= SD_FXSCALE;
if (ss->flooryscale != spawnss->flooryscale)
diff2 |= SD_FYSCALE;
if (ss->ceilingxscale != spawnss->ceilingxscale)
diff2 |= SD_CXSCALE;
if (ss->ceilingyscale != spawnss->ceilingyscale)
diff2 |= SD_CYSCALE;
if (ss->floorangle != spawnss->floorangle) if (ss->floorangle != spawnss->floorangle)
diff2 |= SD_FLOORANG; diff2 |= SD_FLOORANG;
if (ss->ceilingangle != spawnss->ceilingangle) if (ss->ceilingangle != spawnss->ceilingangle)
@ -1065,15 +1103,18 @@ static void ArchiveSectors(void)
if (ss->triggerer != spawnss->triggerer) if (ss->triggerer != spawnss->triggerer)
diff4 |= SD_TRIGGERER; diff4 |= SD_TRIGGERER;
if (ss->gravity != spawnss->gravity) if (ss->gravity != spawnss->gravity)
diff4 |= SD_GRAVITY; diff5 |= SD_GRAVITY;
if (ss->portal_floor != spawnss->portal_floor) if (ss->portal_floor != spawnss->portal_floor)
diff4 |= SD_FLOORPORTAL; diff5 |= SD_FLOORPORTAL;
if (ss->portal_ceiling != spawnss->portal_ceiling) if (ss->portal_ceiling != spawnss->portal_ceiling)
diff4 |= SD_CEILPORTAL; diff5 |= SD_CEILPORTAL;
if (ss->ffloors && CheckFFloorDiff(ss)) if (ss->ffloors && CheckFFloorDiff(ss))
diff |= SD_FFLOORS; diff |= SD_FFLOORS;
if (diff5)
diff4 |= SD_DIFF5;
if (diff4) if (diff4)
diff3 |= SD_DIFF4; diff3 |= SD_DIFF4;
@ -1093,6 +1134,8 @@ static void ArchiveSectors(void)
WRITEUINT8(save_p, diff3); WRITEUINT8(save_p, diff3);
if (diff3 & SD_DIFF4) if (diff3 & SD_DIFF4)
WRITEUINT8(save_p, diff4); WRITEUINT8(save_p, diff4);
if (diff4 & SD_DIFF5)
WRITEUINT8(save_p, diff5);
if (diff & SD_FLOORHT) if (diff & SD_FLOORHT)
WRITEFIXED(save_p, ss->floorheight); WRITEFIXED(save_p, ss->floorheight);
if (diff & SD_CEILHT) if (diff & SD_CEILHT)
@ -1149,11 +1192,19 @@ static void ArchiveSectors(void)
WRITEINT16(save_p, ss->triggertag); WRITEINT16(save_p, ss->triggertag);
if (diff4 & SD_TRIGGERER) if (diff4 & SD_TRIGGERER)
WRITEUINT8(save_p, ss->triggerer); WRITEUINT8(save_p, ss->triggerer);
if (diff4 & SD_GRAVITY) if (diff4 & SD_FXSCALE)
WRITEFIXED(save_p, ss->floorxscale);
if (diff4 & SD_FYSCALE)
WRITEFIXED(save_p, ss->flooryscale);
if (diff4 & SD_CXSCALE)
WRITEFIXED(save_p, ss->ceilingxscale);
if (diff4 & SD_CYSCALE)
WRITEFIXED(save_p, ss->ceilingyscale);
if (diff5 & SD_GRAVITY)
WRITEFIXED(save_p, ss->gravity); WRITEFIXED(save_p, ss->gravity);
if (diff4 & SD_FLOORPORTAL) if (diff5 & SD_FLOORPORTAL)
WRITEUINT32(save_p, ss->portal_floor); WRITEUINT32(save_p, ss->portal_floor);
if (diff4 & SD_CEILPORTAL) if (diff5 & SD_CEILPORTAL)
WRITEUINT32(save_p, ss->portal_ceiling); WRITEUINT32(save_p, ss->portal_ceiling);
if (diff & SD_FFLOORS) if (diff & SD_FFLOORS)
ArchiveFFloors(ss); ArchiveFFloors(ss);
@ -1167,7 +1218,7 @@ static void UnArchiveSectors(void)
{ {
UINT32 i; UINT32 i;
UINT16 j; UINT16 j;
UINT8 diff, diff2, diff3, diff4; UINT8 diff, diff2, diff3, diff4, diff5;
for (;;) for (;;)
{ {
i = READUINT32(save_p); i = READUINT32(save_p);
@ -1191,6 +1242,10 @@ static void UnArchiveSectors(void)
diff4 = READUINT8(save_p); diff4 = READUINT8(save_p);
else else
diff4 = 0; diff4 = 0;
if (diff4 & SD_DIFF5)
diff5 = READUINT8(save_p);
else
diff5 = 0;
if (diff & SD_FLOORHT) if (diff & SD_FLOORHT)
sectors[i].floorheight = READFIXED(save_p); sectors[i].floorheight = READFIXED(save_p);
@ -1274,11 +1329,19 @@ static void UnArchiveSectors(void)
sectors[i].triggertag = READINT16(save_p); sectors[i].triggertag = READINT16(save_p);
if (diff4 & SD_TRIGGERER) if (diff4 & SD_TRIGGERER)
sectors[i].triggerer = READUINT8(save_p); sectors[i].triggerer = READUINT8(save_p);
if (diff4 & SD_GRAVITY) if (diff4 & SD_FXSCALE)
sectors[i].floorxscale = READFIXED(save_p);
if (diff4 & SD_FYSCALE)
sectors[i].flooryscale = READFIXED(save_p);
if (diff4 & SD_CXSCALE)
sectors[i].ceilingxscale = READFIXED(save_p);
if (diff4 & SD_CYSCALE)
sectors[i].ceilingyscale = READFIXED(save_p);
if (diff5 & SD_GRAVITY)
sectors[i].gravity = READFIXED(save_p); sectors[i].gravity = READFIXED(save_p);
if (diff4 & SD_FLOORPORTAL) if (diff5 & SD_FLOORPORTAL)
sectors[i].portal_floor = READUINT32(save_p); sectors[i].portal_floor = READUINT32(save_p);
if (diff4 & SD_CEILPORTAL) if (diff5 & SD_CEILPORTAL)
sectors[i].portal_ceiling = READUINT32(save_p); sectors[i].portal_ceiling = READUINT32(save_p);
if (diff & SD_FFLOORS) if (diff & SD_FFLOORS)
@ -1286,18 +1349,104 @@ static void UnArchiveSectors(void)
} }
} }
static UINT32 GetSideDiff(const side_t *si, const side_t *spawnsi)
{
UINT32 diff = 0;
if (si->textureoffset != spawnsi->textureoffset)
diff |= LD_SDTEXOFFX;
if (si->rowoffset != spawnsi->rowoffset)
diff |= LD_SDTEXOFFY;
//SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures.
if (si->toptexture != spawnsi->toptexture)
diff |= LD_SDTOPTEX;
if (si->bottomtexture != spawnsi->bottomtexture)
diff |= LD_SDBOTTEX;
if (si->midtexture != spawnsi->midtexture)
diff |= LD_SDMIDTEX;
if (si->offsetx_top != spawnsi->offsetx_top)
diff |= LD_SDTOPOFFX;
if (si->offsetx_mid != spawnsi->offsetx_mid)
diff |= LD_SDMIDOFFX;
if (si->offsetx_bottom != spawnsi->offsetx_bottom)
diff |= LD_SDBOTOFFX;
if (si->offsety_top != spawnsi->offsety_top)
diff |= LD_SDTOPOFFY;
if (si->offsety_mid != spawnsi->offsety_mid)
diff |= LD_SDMIDOFFY;
if (si->offsety_bottom != spawnsi->offsety_bottom)
diff |= LD_SDBOTOFFY;
if (si->scalex_top != spawnsi->scalex_top)
diff |= LD_SDTOPSCALEX;
if (si->scalex_mid != spawnsi->scalex_mid)
diff |= LD_SDMIDSCALEX;
if (si->scalex_bottom != spawnsi->scalex_bottom)
diff |= LD_SDBOTSCALEX;
if (si->scaley_top != spawnsi->scaley_top)
diff |= LD_SDTOPSCALEY;
if (si->scaley_mid != spawnsi->scaley_mid)
diff |= LD_SDMIDSCALEY;
if (si->scaley_bottom != spawnsi->scaley_bottom)
diff |= LD_SDBOTSCALEY;
if (si->repeatcnt != spawnsi->repeatcnt)
diff |= LD_SDREPEATCNT;
return diff;
}
static void ArchiveSide(const side_t *si, UINT32 diff)
{
WRITEUINT32(save_p, diff);
if (diff & LD_SDTEXOFFX)
WRITEFIXED(save_p, si->textureoffset);
if (diff & LD_SDTEXOFFY)
WRITEFIXED(save_p, si->rowoffset);
if (diff & LD_SDTOPTEX)
WRITEINT32(save_p, si->toptexture);
if (diff & LD_SDBOTTEX)
WRITEINT32(save_p, si->bottomtexture);
if (diff & LD_SDMIDTEX)
WRITEINT32(save_p, si->midtexture);
if (diff & LD_SDTOPOFFX)
WRITEFIXED(save_p, si->offsetx_top);
if (diff & LD_SDMIDOFFX)
WRITEFIXED(save_p, si->offsetx_mid);
if (diff & LD_SDBOTOFFX)
WRITEFIXED(save_p, si->offsetx_bottom);
if (diff & LD_SDTOPOFFY)
WRITEFIXED(save_p, si->offsety_top);
if (diff & LD_SDMIDOFFY)
WRITEFIXED(save_p, si->offsety_mid);
if (diff & LD_SDBOTOFFY)
WRITEFIXED(save_p, si->offsety_bottom);
if (diff & LD_SDTOPSCALEX)
WRITEFIXED(save_p, si->scalex_top);
if (diff & LD_SDMIDSCALEX)
WRITEFIXED(save_p, si->scalex_mid);
if (diff & LD_SDBOTSCALEX)
WRITEFIXED(save_p, si->scalex_bottom);
if (diff & LD_SDTOPSCALEY)
WRITEFIXED(save_p, si->scaley_top);
if (diff & LD_SDMIDSCALEY)
WRITEFIXED(save_p, si->scaley_mid);
if (diff & LD_SDBOTSCALEY)
WRITEFIXED(save_p, si->scaley_bottom);
if (diff & LD_SDREPEATCNT)
WRITEINT16(save_p, si->repeatcnt);
}
static void ArchiveLines(void) static void ArchiveLines(void)
{ {
size_t i; size_t i;
const line_t *li = lines; const line_t *li = lines;
const line_t *spawnli = spawnlines; const line_t *spawnli = spawnlines;
const side_t *si; UINT8 diff, diff2;
const side_t *spawnsi; UINT32 side1diff;
UINT8 diff, diff2; // no diff3 UINT32 side2diff;
for (i = 0; i < numlines; i++, spawnli++, li++) for (i = 0; i < numlines; i++, spawnli++, li++)
{ {
diff = diff2 = 0; diff = diff2 = 0;
side1diff = side2diff = 0;
if (li->special != spawnli->special) if (li->special != spawnli->special)
diff |= LD_SPECIAL; diff |= LD_SPECIAL;
@ -1306,10 +1455,10 @@ static void ArchiveLines(void)
diff |= LD_CLLCOUNT; diff |= LD_CLLCOUNT;
if (!P_AreArgsEqual(li, spawnli)) if (!P_AreArgsEqual(li, spawnli))
diff2 |= LD_ARGS; diff |= LD_ARGS;
if (!P_AreStringArgsEqual(li, spawnli)) if (!P_AreStringArgsEqual(li, spawnli))
diff2 |= LD_STRINGARGS; diff |= LD_STRINGARGS;
if (li->executordelay != spawnli->executordelay) if (li->executordelay != spawnli->executordelay)
diff2 |= LD_EXECUTORDELAY; diff2 |= LD_EXECUTORDELAY;
@ -1319,30 +1468,15 @@ static void ArchiveLines(void)
if (li->sidenum[0] != NO_SIDEDEF) if (li->sidenum[0] != NO_SIDEDEF)
{ {
si = &sides[li->sidenum[0]]; side1diff = GetSideDiff(&sides[li->sidenum[0]], &spawnsides[li->sidenum[0]]);
spawnsi = &spawnsides[li->sidenum[0]]; if (side1diff)
if (si->textureoffset != spawnsi->textureoffset) diff |= LD_SIDE1;
diff |= LD_S1TEXOFF;
//SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures.
if (si->toptexture != spawnsi->toptexture)
diff |= LD_S1TOPTEX;
if (si->bottomtexture != spawnsi->bottomtexture)
diff |= LD_S1BOTTEX;
if (si->midtexture != spawnsi->midtexture)
diff |= LD_S1MIDTEX;
} }
if (li->sidenum[1] != NO_SIDEDEF) if (li->sidenum[1] != NO_SIDEDEF)
{ {
si = &sides[li->sidenum[1]]; side2diff = GetSideDiff(&sides[li->sidenum[1]], &spawnsides[li->sidenum[1]]);
spawnsi = &spawnsides[li->sidenum[1]]; if (side2diff)
if (si->textureoffset != spawnsi->textureoffset) diff |= LD_SIDE2;
diff2 |= LD_S2TEXOFF;
if (si->toptexture != spawnsi->toptexture)
diff2 |= LD_S2TOPTEX;
if (si->bottomtexture != spawnsi->bottomtexture)
diff2 |= LD_S2BOTTEX;
if (si->midtexture != spawnsi->midtexture)
diff2 |= LD_S2MIDTEX;
} }
if (diff2) if (diff2)
@ -1360,33 +1494,13 @@ static void ArchiveLines(void)
WRITEINT16(save_p, li->special); WRITEINT16(save_p, li->special);
if (diff & LD_CLLCOUNT) if (diff & LD_CLLCOUNT)
WRITEINT16(save_p, li->callcount); WRITEINT16(save_p, li->callcount);
if (diff & LD_ARGS)
si = &sides[li->sidenum[0]];
if (diff & LD_S1TEXOFF)
WRITEFIXED(save_p, si->textureoffset);
if (diff & LD_S1TOPTEX)
WRITEINT32(save_p, si->toptexture);
if (diff & LD_S1BOTTEX)
WRITEINT32(save_p, si->bottomtexture);
if (diff & LD_S1MIDTEX)
WRITEINT32(save_p, si->midtexture);
si = &sides[li->sidenum[1]];
if (diff2 & LD_S2TEXOFF)
WRITEFIXED(save_p, si->textureoffset);
if (diff2 & LD_S2TOPTEX)
WRITEINT32(save_p, si->toptexture);
if (diff2 & LD_S2BOTTEX)
WRITEINT32(save_p, si->bottomtexture);
if (diff2 & LD_S2MIDTEX)
WRITEINT32(save_p, si->midtexture);
if (diff2 & LD_ARGS)
{ {
UINT8 j; UINT8 j;
for (j = 0; j < NUMLINEARGS; j++) for (j = 0; j < NUMLINEARGS; j++)
WRITEINT32(save_p, li->args[j]); WRITEINT32(save_p, li->args[j]);
} }
if (diff2 & LD_STRINGARGS) if (diff & LD_STRINGARGS)
{ {
UINT8 j; UINT8 j;
for (j = 0; j < NUMLINESTRINGARGS; j++) for (j = 0; j < NUMLINESTRINGARGS; j++)
@ -1405,6 +1519,10 @@ static void ArchiveLines(void)
WRITECHAR(save_p, li->stringargs[j][k]); WRITECHAR(save_p, li->stringargs[j][k]);
} }
} }
if (diff & LD_SIDE1)
ArchiveSide(&sides[li->sidenum[0]], side1diff);
if (diff & LD_SIDE2)
ArchiveSide(&sides[li->sidenum[1]], side2diff);
if (diff2 & LD_EXECUTORDELAY) if (diff2 & LD_EXECUTORDELAY)
WRITEINT32(save_p, li->executordelay); WRITEINT32(save_p, li->executordelay);
if (diff2 & LD_TRANSFPORTAL) if (diff2 & LD_TRANSFPORTAL)
@ -1414,12 +1532,53 @@ static void ArchiveLines(void)
WRITEUINT32(save_p, 0xffffffff); WRITEUINT32(save_p, 0xffffffff);
} }
static void UnArchiveSide(side_t *si)
{
UINT32 diff = READUINT32(save_p);
if (diff & LD_SDTEXOFFX)
si->textureoffset = READFIXED(save_p);
if (diff & LD_SDTEXOFFY)
si->rowoffset = READFIXED(save_p);
if (diff & LD_SDTOPTEX)
si->toptexture = READINT32(save_p);
if (diff & LD_SDBOTTEX)
si->bottomtexture = READINT32(save_p);
if (diff & LD_SDMIDTEX)
si->midtexture = READINT32(save_p);
if (diff & LD_SDTOPOFFX)
si->offsetx_top = READFIXED(save_p);
if (diff & LD_SDMIDOFFX)
si->offsetx_mid = READFIXED(save_p);
if (diff & LD_SDBOTOFFX)
si->offsetx_bottom = READFIXED(save_p);
if (diff & LD_SDTOPOFFY)
si->offsety_top = READFIXED(save_p);
if (diff & LD_SDMIDOFFY)
si->offsety_mid = READFIXED(save_p);
if (diff & LD_SDBOTOFFY)
si->offsety_bottom = READFIXED(save_p);
if (diff & LD_SDTOPSCALEX)
si->scalex_top = READFIXED(save_p);
if (diff & LD_SDMIDSCALEX)
si->scalex_mid = READFIXED(save_p);
if (diff & LD_SDBOTSCALEX)
si->scalex_bottom = READFIXED(save_p);
if (diff & LD_SDTOPSCALEY)
si->scaley_top = READFIXED(save_p);
if (diff & LD_SDMIDSCALEY)
si->scaley_mid = READFIXED(save_p);
if (diff & LD_SDBOTSCALEY)
si->scaley_bottom = READFIXED(save_p);
if (diff & LD_SDREPEATCNT)
si->repeatcnt = READINT16(save_p);
}
static void UnArchiveLines(void) static void UnArchiveLines(void)
{ {
UINT32 i; UINT32 i;
line_t *li; line_t *li;
side_t *si; UINT8 diff, diff2;
UINT8 diff, diff2; // no diff3
for (;;) for (;;)
{ {
@ -1431,12 +1590,11 @@ static void UnArchiveLines(void)
I_Error("Invalid line number %u from server", i); I_Error("Invalid line number %u from server", i);
diff = READUINT8(save_p); diff = READUINT8(save_p);
li = &lines[i];
if (diff & LD_DIFF2) if (diff & LD_DIFF2)
diff2 = READUINT8(save_p); diff2 = READUINT8(save_p);
else else
diff2 = 0; diff2 = 0;
li = &lines[i];
if (diff & LD_FLAG) if (diff & LD_FLAG)
li->flags = READINT16(save_p); li->flags = READINT16(save_p);
@ -1444,33 +1602,13 @@ static void UnArchiveLines(void)
li->special = READINT16(save_p); li->special = READINT16(save_p);
if (diff & LD_CLLCOUNT) if (diff & LD_CLLCOUNT)
li->callcount = READINT16(save_p); li->callcount = READINT16(save_p);
if (diff & LD_ARGS)
si = &sides[li->sidenum[0]];
if (diff & LD_S1TEXOFF)
si->textureoffset = READFIXED(save_p);
if (diff & LD_S1TOPTEX)
si->toptexture = READINT32(save_p);
if (diff & LD_S1BOTTEX)
si->bottomtexture = READINT32(save_p);
if (diff & LD_S1MIDTEX)
si->midtexture = READINT32(save_p);
si = &sides[li->sidenum[1]];
if (diff2 & LD_S2TEXOFF)
si->textureoffset = READFIXED(save_p);
if (diff2 & LD_S2TOPTEX)
si->toptexture = READINT32(save_p);
if (diff2 & LD_S2BOTTEX)
si->bottomtexture = READINT32(save_p);
if (diff2 & LD_S2MIDTEX)
si->midtexture = READINT32(save_p);
if (diff2 & LD_ARGS)
{ {
UINT8 j; UINT8 j;
for (j = 0; j < NUMLINEARGS; j++) for (j = 0; j < NUMLINEARGS; j++)
li->args[j] = READINT32(save_p); li->args[j] = READINT32(save_p);
} }
if (diff2 & LD_STRINGARGS) if (diff & LD_STRINGARGS)
{ {
UINT8 j; UINT8 j;
for (j = 0; j < NUMLINESTRINGARGS; j++) for (j = 0; j < NUMLINESTRINGARGS; j++)
@ -1491,6 +1629,10 @@ static void UnArchiveLines(void)
li->stringargs[j][len] = '\0'; li->stringargs[j][len] = '\0';
} }
} }
if (diff & LD_SIDE1)
UnArchiveSide(&sides[li->sidenum[0]]);
if (diff & LD_SIDE2)
UnArchiveSide(&sides[li->sidenum[1]]);
if (diff2 & LD_EXECUTORDELAY) if (diff2 & LD_EXECUTORDELAY)
li->executordelay = READINT32(save_p); li->executordelay = READINT32(save_p);
if (diff2 & LD_TRANSFPORTAL) if (diff2 & LD_TRANSFPORTAL)

View file

@ -1058,6 +1058,9 @@ static void P_LoadSectors(UINT8 *data)
ss->floorxoffset = ss->flooryoffset = 0; ss->floorxoffset = ss->flooryoffset = 0;
ss->ceilingxoffset = ss->ceilingyoffset = 0; ss->ceilingxoffset = ss->ceilingyoffset = 0;
ss->floorxscale = ss->flooryscale = FRACUNIT;
ss->ceilingxscale = ss->ceilingyscale = FRACUNIT;
ss->floorangle = ss->ceilingangle = 0; ss->floorangle = ss->ceilingangle = 0;
ss->floorlightlevel = ss->ceilinglightlevel = 0; ss->floorlightlevel = ss->ceilinglightlevel = 0;
@ -1356,8 +1359,11 @@ static void P_LoadSidedefs(UINT8 *data)
} }
sd->rowoffset = SHORT(msd->rowoffset)<<FRACBITS; sd->rowoffset = SHORT(msd->rowoffset)<<FRACBITS;
sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bot = 0; sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bottom = 0;
sd->offsety_top = sd->offsety_mid = sd->offsety_bot = 0; sd->offsety_top = sd->offsety_mid = sd->offsety_bottom = 0;
sd->scalex_top = sd->scalex_mid = sd->scalex_bottom = FRACUNIT;
sd->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT;
P_SetSidedefSector(i, (UINT16)SHORT(msd->sector)); P_SetSidedefSector(i, (UINT16)SHORT(msd->sector));
@ -1697,6 +1703,14 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char
sectors[i].ceilingxoffset = FLOAT_TO_FIXED(atof(val)); sectors[i].ceilingxoffset = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "ypanningceiling")) else if (fastcmp(param, "ypanningceiling"))
sectors[i].ceilingyoffset = FLOAT_TO_FIXED(atof(val)); sectors[i].ceilingyoffset = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "xscalefloor"))
sectors[i].floorxscale = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "yscalefloor"))
sectors[i].flooryscale = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "xscaleceiling"))
sectors[i].ceilingxscale = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "yscaleceiling"))
sectors[i].ceilingyscale = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "rotationfloor")) else if (fastcmp(param, "rotationfloor"))
sectors[i].floorangle = FixedAngle(FLOAT_TO_FIXED(atof(val))); sectors[i].floorangle = FixedAngle(FLOAT_TO_FIXED(atof(val)));
else if (fastcmp(param, "rotationceiling")) else if (fastcmp(param, "rotationceiling"))
@ -1892,13 +1906,25 @@ static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char
else if (fastcmp(param, "offsetx_mid")) else if (fastcmp(param, "offsetx_mid"))
sides[i].offsetx_mid = atol(val) << FRACBITS; sides[i].offsetx_mid = atol(val) << FRACBITS;
else if (fastcmp(param, "offsetx_bottom")) else if (fastcmp(param, "offsetx_bottom"))
sides[i].offsetx_bot = atol(val) << FRACBITS; sides[i].offsetx_bottom = atol(val) << FRACBITS;
else if (fastcmp(param, "offsety_top")) else if (fastcmp(param, "offsety_top"))
sides[i].offsety_top = atol(val) << FRACBITS; sides[i].offsety_top = atol(val) << FRACBITS;
else if (fastcmp(param, "offsety_mid")) else if (fastcmp(param, "offsety_mid"))
sides[i].offsety_mid = atol(val) << FRACBITS; sides[i].offsety_mid = atol(val) << FRACBITS;
else if (fastcmp(param, "offsety_bottom")) else if (fastcmp(param, "offsety_bottom"))
sides[i].offsety_bot = atol(val) << FRACBITS; sides[i].offsety_bottom = atol(val) << FRACBITS;
else if (fastcmp(param, "scalex_top"))
sides[i].scalex_top = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "scalex_mid"))
sides[i].scalex_mid = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "scalex_bottom"))
sides[i].scalex_bottom = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "scaley_top"))
sides[i].scaley_top = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "scaley_mid"))
sides[i].scaley_mid = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "scaley_bottom"))
sides[i].scaley_bottom = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "texturetop")) else if (fastcmp(param, "texturetop"))
sides[i].toptexture = R_TextureNumForName(val); sides[i].toptexture = R_TextureNumForName(val);
else if (fastcmp(param, "texturebottom")) else if (fastcmp(param, "texturebottom"))
@ -2603,10 +2629,22 @@ static void P_WriteTextmap(void)
fprintf(f, "offsetx_mid = %d;\n", wsides[i].offsetx_mid >> FRACBITS); fprintf(f, "offsetx_mid = %d;\n", wsides[i].offsetx_mid >> FRACBITS);
if (wsides[i].offsety_mid != 0) if (wsides[i].offsety_mid != 0)
fprintf(f, "offsety_mid = %d;\n", wsides[i].offsety_mid >> FRACBITS); fprintf(f, "offsety_mid = %d;\n", wsides[i].offsety_mid >> FRACBITS);
if (wsides[i].offsetx_bot != 0) if (wsides[i].offsetx_bottom != 0)
fprintf(f, "offsetx_bottom = %d;\n", wsides[i].offsetx_bot >> FRACBITS); fprintf(f, "offsetx_bottom = %d;\n", wsides[i].offsetx_bottom >> FRACBITS);
if (wsides[i].offsety_bot != 0) if (wsides[i].offsety_bottom != 0)
fprintf(f, "offsety_bottom = %d;\n", wsides[i].offsety_bot >> FRACBITS); fprintf(f, "offsety_bottom = %d;\n", wsides[i].offsety_bottom >> FRACBITS);
if (wsides[i].scalex_top != FRACUNIT)
fprintf(f, "scalex_top = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_top));
if (wsides[i].scaley_top != FRACUNIT)
fprintf(f, "scaley_top = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_top));
if (wsides[i].scalex_mid != FRACUNIT)
fprintf(f, "scalex_mid = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_mid));
if (wsides[i].scaley_mid != FRACUNIT)
fprintf(f, "scaley_mid = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_mid));
if (wsides[i].scalex_bottom != FRACUNIT)
fprintf(f, "scalex_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_bottom));
if (wsides[i].scaley_bottom != FRACUNIT)
fprintf(f, "scaley_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_bottom));
if (wsides[i].toptexture > 0 && wsides[i].toptexture < numtextures) if (wsides[i].toptexture > 0 && wsides[i].toptexture < numtextures)
fprintf(f, "texturetop = \"%.*s\";\n", 8, textures[wsides[i].toptexture]->name); fprintf(f, "texturetop = \"%.*s\";\n", 8, textures[wsides[i].toptexture]->name);
if (wsides[i].bottomtexture > 0 && wsides[i].bottomtexture < numtextures) if (wsides[i].bottomtexture > 0 && wsides[i].bottomtexture < numtextures)
@ -2662,6 +2700,14 @@ static void P_WriteTextmap(void)
fprintf(f, "xpanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingxoffset)); fprintf(f, "xpanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingxoffset));
if (tempsec.ceilingyoffset != 0) if (tempsec.ceilingyoffset != 0)
fprintf(f, "ypanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingyoffset)); fprintf(f, "ypanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingyoffset));
if (tempsec.floorxscale != 0)
fprintf(f, "xscalefloor = %f;\n", FIXED_TO_FLOAT(tempsec.floorxscale));
if (tempsec.flooryscale != 0)
fprintf(f, "yscalefloor = %f;\n", FIXED_TO_FLOAT(tempsec.flooryscale));
if (tempsec.ceilingxscale != 0)
fprintf(f, "xscaleceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingxscale));
if (tempsec.ceilingyscale != 0)
fprintf(f, "yscaleceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingyscale));
if (wsectors[i].floorangle != 0) if (wsectors[i].floorangle != 0)
fprintf(f, "rotationfloor = %f;\n", FIXED_TO_FLOAT(AngleFixed(wsectors[i].floorangle))); fprintf(f, "rotationfloor = %f;\n", FIXED_TO_FLOAT(AngleFixed(wsectors[i].floorangle)));
if (wsectors[i].ceilingangle != 0) if (wsectors[i].ceilingangle != 0)
@ -2897,6 +2943,9 @@ static void P_LoadTextmap(void)
sc->floorxoffset = sc->flooryoffset = 0; sc->floorxoffset = sc->flooryoffset = 0;
sc->ceilingxoffset = sc->ceilingyoffset = 0; sc->ceilingxoffset = sc->ceilingyoffset = 0;
sc->floorxscale = sc->flooryscale = FRACUNIT;
sc->ceilingxscale = sc->ceilingyscale = FRACUNIT;
sc->floorangle = sc->ceilingangle = 0; sc->floorangle = sc->ceilingangle = 0;
sc->floorlightlevel = sc->ceilinglightlevel = 0; sc->floorlightlevel = sc->ceilinglightlevel = 0;
@ -2931,22 +2980,26 @@ static void P_LoadTextmap(void)
P_InitializeSector(sc); P_InitializeSector(sc);
if (textmap_colormap.used) if (textmap_colormap.used)
{ {
INT32 rgba = P_ColorToRGBA(textmap_colormap.lightcolor, textmap_colormap.lightalpha); // Convert alpha values from old 0-25 (A-Z) range to 0-255 range
INT32 fadergba = P_ColorToRGBA(textmap_colormap.fadecolor, textmap_colormap.fadealpha); UINT8 lightalpha = (textmap_colormap.lightalpha * 102) / 10;
UINT8 fadealpha = (textmap_colormap.fadealpha * 102) / 10;
INT32 rgba = P_ColorToRGBA(textmap_colormap.lightcolor, lightalpha);
INT32 fadergba = P_ColorToRGBA(textmap_colormap.fadecolor, fadealpha);
sc->extra_colormap = sc->spawn_extra_colormap = R_CreateColormap(rgba, fadergba, textmap_colormap.fadestart, textmap_colormap.fadeend, textmap_colormap.flags); sc->extra_colormap = sc->spawn_extra_colormap = R_CreateColormap(rgba, fadergba, textmap_colormap.fadestart, textmap_colormap.fadeend, textmap_colormap.flags);
} }
if (textmap_planefloor.defined == (PD_A|PD_B|PD_C|PD_D)) if (textmap_planefloor.defined == (PD_A|PD_B|PD_C|PD_D))
{ {
sc->f_slope = MakeViaEquationConstants(textmap_planefloor.a, textmap_planefloor.b, textmap_planefloor.c, textmap_planefloor.d); sc->f_slope = MakeViaEquationConstants(textmap_planefloor.a, textmap_planefloor.b, textmap_planefloor.c, textmap_planefloor.d);
sc->hasslope = true; sc->hasslope = true;
} }
if (textmap_planeceiling.defined == (PD_A|PD_B|PD_C|PD_D)) if (textmap_planeceiling.defined == (PD_A|PD_B|PD_C|PD_D))
{ {
sc->c_slope = MakeViaEquationConstants(textmap_planeceiling.a, textmap_planeceiling.b, textmap_planeceiling.c, textmap_planeceiling.d); sc->c_slope = MakeViaEquationConstants(textmap_planeceiling.a, textmap_planeceiling.b, textmap_planeceiling.c, textmap_planeceiling.d);
sc->hasslope = true; sc->hasslope = true;
} }
TextmapFixFlatOffsets(sc); TextmapFixFlatOffsets(sc);
} }
@ -2983,8 +3036,10 @@ static void P_LoadTextmap(void)
// Defaults. // Defaults.
sd->textureoffset = 0; sd->textureoffset = 0;
sd->rowoffset = 0; sd->rowoffset = 0;
sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bot = 0; sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bottom = 0;
sd->offsety_top = sd->offsety_mid = sd->offsety_bot = 0; sd->offsety_top = sd->offsety_mid = sd->offsety_bottom = 0;
sd->scalex_top = sd->scalex_mid = sd->scalex_bottom = FRACUNIT;
sd->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT;
sd->toptexture = R_TextureNumForName("-"); sd->toptexture = R_TextureNumForName("-");
sd->midtexture = R_TextureNumForName("-"); sd->midtexture = R_TextureNumForName("-");
sd->bottomtexture = R_TextureNumForName("-"); sd->bottomtexture = R_TextureNumForName("-");
@ -3310,7 +3365,7 @@ static void P_LoadSegs(UINT8 *data)
seg->length = P_SegLength(seg); seg->length = P_SegLength(seg);
#ifdef HWRENDER #ifdef HWRENDER
seg->flength = (rendermode == render_opengl) ? P_SegLengthFloat(seg) : 0; seg->flength = P_SegLengthFloat(seg);
#endif #endif
seg->glseg = false; seg->glseg = false;
@ -3552,7 +3607,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype
} }
seg->length = P_SegLength(seg); seg->length = P_SegLength(seg);
#ifdef HWRENDER #ifdef HWRENDER
seg->flength = (rendermode == render_opengl) ? P_SegLengthFloat(seg) : 0; seg->flength = P_SegLengthFloat(seg);
#endif #endif
} }
@ -7825,6 +7880,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
Patch_FreeTag(PU_PATCH_LOWPRIORITY); Patch_FreeTag(PU_PATCH_LOWPRIORITY);
Patch_FreeTag(PU_PATCH_ROTATED); Patch_FreeTag(PU_PATCH_ROTATED);
Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1); Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1);
mobjcache = NULL;
R_InitializeLevelInterpolators(); R_InitializeLevelInterpolators();

View file

@ -2739,7 +2739,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
mo->player->rmomx = mo->player->rmomy = 1; mo->player->rmomx = mo->player->rmomy = 1;
mo->player->cmomx = mo->player->cmomy = 0; mo->player->cmomx = mo->player->cmomy = 0;
P_ResetPlayer(mo->player); P_ResetPlayer(mo->player);
P_SetPlayerMobjState(mo, S_PLAY_STND); P_SetMobjState(mo, S_PLAY_STND);
// Reset bot too. // Reset bot too.
if (bot) { if (bot) {
@ -2750,7 +2750,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
bot->player->rmomx = bot->player->rmomy = 1; bot->player->rmomx = bot->player->rmomy = 1;
bot->player->cmomx = bot->player->cmomy = 0; bot->player->cmomx = bot->player->cmomy = 0;
P_ResetPlayer(bot->player); P_ResetPlayer(bot->player);
P_SetPlayerMobjState(bot, S_PLAY_STND); P_SetMobjState(bot, S_PLAY_STND);
} }
} }
break; break;
@ -4570,7 +4570,7 @@ static void P_ProcessSpeedPad(player_t *player, sector_t *sector, sector_t *rove
if (!(player->pflags & PF_SPINNING)) if (!(player->pflags & PF_SPINNING))
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); P_SetMobjState(player->mo, S_PLAY_ROLL);
} }
player->powers[pw_flashing] = TICRATE/3; player->powers[pw_flashing] = TICRATE/3;
@ -4748,7 +4748,7 @@ static void P_ProcessZoomTube(player_t *player, mtag_t sectag, boolean end)
if (player->mo->state-states != S_PLAY_ROLL) if (player->mo->state-states != S_PLAY_ROLL)
{ {
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); P_SetMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_spin); S_StartSound(player->mo, sfx_spin);
} }
} }
@ -4962,7 +4962,7 @@ static void P_ProcessRopeHang(player_t *player, mtag_t sectag)
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY);
player->climbing = 0; player->climbing = 0;
P_SetThingPosition(player->mo); P_SetThingPosition(player->mo);
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); P_SetMobjState(player->mo, S_PLAY_RIDE);
} }
static boolean P_SectorHasSpecial(sector_t *sec) static boolean P_SectorHasSpecial(sector_t *sec)
@ -5021,7 +5021,7 @@ static void P_EvaluateSpecialFlags(player_t *player, sector_t *sector, sector_t
if (!player->powers[pw_carry]) if (!player->powers[pw_carry])
{ {
P_ResetPlayer(player); P_ResetPlayer(player);
P_SetPlayerMobjState(player->mo, S_PLAY_FALL); P_SetMobjState(player->mo, S_PLAY_FALL);
P_SetTarget(&player->mo->tracer, player->mo); P_SetTarget(&player->mo->tracer, player->mo);
player->powers[pw_carry] = CR_FAN; player->powers[pw_carry] = CR_FAN;
} }
@ -5036,7 +5036,7 @@ static void P_EvaluateSpecialFlags(player_t *player, sector_t *sector, sector_t
if (!(player->pflags & PF_SPINNING)) if (!(player->pflags & PF_SPINNING))
{ {
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); P_SetMobjState(player->mo, S_PLAY_ROLL);
S_StartAttackSound(player->mo, sfx_spin); S_StartAttackSound(player->mo, sfx_spin);
if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale) if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale)
@ -5609,6 +5609,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I
fflr->bottompic = &sec2->floorpic; fflr->bottompic = &sec2->floorpic;
fflr->bottomxoffs = &sec2->floorxoffset; fflr->bottomxoffs = &sec2->floorxoffset;
fflr->bottomyoffs = &sec2->flooryoffset; fflr->bottomyoffs = &sec2->flooryoffset;
fflr->bottomxscale = &sec2->floorxscale;
fflr->bottomyscale = &sec2->flooryscale;
fflr->bottomangle = &sec2->floorangle; fflr->bottomangle = &sec2->floorangle;
// Add the ceiling // Add the ceiling
@ -5617,6 +5619,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I
fflr->toplightlevel = &sec2->lightlevel; fflr->toplightlevel = &sec2->lightlevel;
fflr->topxoffs = &sec2->ceilingxoffset; fflr->topxoffs = &sec2->ceilingxoffset;
fflr->topyoffs = &sec2->ceilingyoffset; fflr->topyoffs = &sec2->ceilingyoffset;
fflr->topxscale = &sec2->ceilingxscale;
fflr->topyscale = &sec2->ceilingyscale;
fflr->topangle = &sec2->ceilingangle; fflr->topangle = &sec2->ceilingangle;
// Add slopes // Add slopes

View file

@ -96,7 +96,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
P_ClearStarPost(starpostnum); P_ClearStarPost(starpostnum);
P_ResetPlayer(thing->player); P_ResetPlayer(thing->player);
P_SetPlayerMobjState(thing, S_PLAY_STND); P_SetMobjState(thing, S_PLAY_STND);
P_FlashPal(thing->player, PAL_MIXUP, 10); P_FlashPal(thing->player, PAL_MIXUP, 10);
} }
@ -153,7 +153,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
thing->player->rmomx = thing->player->rmomy = 0; thing->player->rmomx = thing->player->rmomy = 0;
thing->player->speed = 0; thing->player->speed = 0;
P_ResetPlayer(thing->player); P_ResetPlayer(thing->player);
P_SetPlayerMobjState(thing, S_PLAY_STND); P_SetMobjState(thing, S_PLAY_STND);
thing->reactiontime = TICRATE/2; // don't move for about half a second thing->reactiontime = TICRATE/2; // don't move for about half a second
thing->player->drawangle = angle; thing->player->drawangle = angle;

View file

@ -217,6 +217,7 @@ void P_AddThinker(const thinklistnum_t n, thinker_t *thinker)
thlist[n].prev = thinker; thlist[n].prev = thinker;
thinker->references = 0; // killough 11/98: init reference counter to 0 thinker->references = 0; // killough 11/98: init reference counter to 0
thinker->cachable = n == THINK_MOBJ;
#ifdef PARANOIA #ifdef PARANOIA
thinker->debug_mobjtype = MT_NULL; thinker->debug_mobjtype = MT_NULL;
@ -226,21 +227,22 @@ void P_AddThinker(const thinklistnum_t n, thinker_t *thinker)
#ifdef PARANOIA #ifdef PARANOIA
static const char *MobjTypeName(const mobj_t *mobj) static const char *MobjTypeName(const mobj_t *mobj)
{ {
mobjtype_t type;
actionf_p1 p1 = mobj->thinker.function.acp1; actionf_p1 p1 = mobj->thinker.function.acp1;
if (p1 == (actionf_p1)P_MobjThinker) if (p1 == (actionf_p1)P_MobjThinker)
{ type = mobj->type;
return MOBJTYPE_LIST[mobj->type]; else if (p1 == (actionf_p1)P_RemoveThinkerDelayed && mobj->thinker.debug_mobjtype != MT_NULL)
} type = mobj->thinker.debug_mobjtype;
else if (p1 == (actionf_p1)P_RemoveThinkerDelayed) else
{ return "<Not a mobj>";
if (mobj->thinker.debug_mobjtype != MT_NULL)
{
return MOBJTYPE_LIST[mobj->thinker.debug_mobjtype];
}
}
return "<Not a mobj>"; if (type < 0 || type >= NUMMOBJTYPES || (type >= MT_FIRSTFREESLOT && !FREE_MOBJS[type - MT_FIRSTFREESLOT]))
return "<Invalid mobj type>";
else if (type >= MT_FIRSTFREESLOT)
return FREE_MOBJS[type - MT_FIRSTFREESLOT]; // This doesn't include "MT_"...
else
return MOBJTYPE_LIST[type];
} }
static const char *MobjThinkerName(const mobj_t *mobj) static const char *MobjThinkerName(const mobj_t *mobj)
@ -319,7 +321,16 @@ void P_RemoveThinkerDelayed(thinker_t *thinker)
(next->prev = currentthinker = thinker->prev)->next = next; (next->prev = currentthinker = thinker->prev)->next = next;
R_DestroyLevelInterpolators(thinker); R_DestroyLevelInterpolators(thinker);
Z_Free(thinker); if (thinker->cachable)
{
// put cachable thinkers in the mobj cache, so we can avoid allocations
((mobj_t *)thinker)->hnext = mobjcache;
mobjcache = (mobj_t *)thinker;
}
else
{
Z_Free(thinker);
}
} }
// //

File diff suppressed because it is too large Load diff

View file

@ -282,6 +282,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
tempsec->floorpic = s->floorpic; tempsec->floorpic = s->floorpic;
tempsec->floorxoffset = s->floorxoffset; tempsec->floorxoffset = s->floorxoffset;
tempsec->flooryoffset = s->flooryoffset; tempsec->flooryoffset = s->flooryoffset;
tempsec->floorxscale = s->floorxscale;
tempsec->flooryscale = s->flooryscale;
tempsec->floorangle = s->floorangle; tempsec->floorangle = s->floorangle;
if (underwater) if (underwater)
@ -292,6 +294,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
tempsec->ceilingpic = tempsec->floorpic; tempsec->ceilingpic = tempsec->floorpic;
tempsec->ceilingxoffset = tempsec->floorxoffset; tempsec->ceilingxoffset = tempsec->floorxoffset;
tempsec->ceilingyoffset = tempsec->flooryoffset; tempsec->ceilingyoffset = tempsec->flooryoffset;
tempsec->ceilingxscale = tempsec->floorxscale;
tempsec->ceilingyscale = tempsec->flooryscale;
tempsec->ceilingangle = tempsec->floorangle; tempsec->ceilingangle = tempsec->floorangle;
} }
else else
@ -299,6 +303,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
tempsec->ceilingpic = s->ceilingpic; tempsec->ceilingpic = s->ceilingpic;
tempsec->ceilingxoffset = s->ceilingxoffset; tempsec->ceilingxoffset = s->ceilingxoffset;
tempsec->ceilingyoffset = s->ceilingyoffset; tempsec->ceilingyoffset = s->ceilingyoffset;
tempsec->ceilingxscale = s->ceilingxscale;
tempsec->ceilingyscale = s->ceilingyscale;
tempsec->ceilingangle = s->ceilingangle; tempsec->ceilingangle = s->ceilingangle;
} }
} }
@ -322,6 +328,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
tempsec->floorpic = tempsec->ceilingpic = s->ceilingpic; tempsec->floorpic = tempsec->ceilingpic = s->ceilingpic;
tempsec->floorxoffset = tempsec->ceilingxoffset = s->ceilingxoffset; tempsec->floorxoffset = tempsec->ceilingxoffset = s->ceilingxoffset;
tempsec->flooryoffset = tempsec->ceilingyoffset = s->ceilingyoffset; tempsec->flooryoffset = tempsec->ceilingyoffset = s->ceilingyoffset;
tempsec->floorxscale = tempsec->ceilingxscale = s->ceilingxscale;
tempsec->flooryscale = tempsec->ceilingyscale = s->ceilingyscale;
tempsec->floorangle = tempsec->ceilingangle = s->ceilingangle; tempsec->floorangle = tempsec->ceilingangle = s->ceilingangle;
if (s->floorpic == skyflatnum) // SKYFIX? if (s->floorpic == skyflatnum) // SKYFIX?
@ -330,6 +338,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
tempsec->floorpic = tempsec->ceilingpic; tempsec->floorpic = tempsec->ceilingpic;
tempsec->floorxoffset = tempsec->ceilingxoffset; tempsec->floorxoffset = tempsec->ceilingxoffset;
tempsec->flooryoffset = tempsec->ceilingyoffset; tempsec->flooryoffset = tempsec->ceilingyoffset;
tempsec->floorxscale = tempsec->ceilingxscale;
tempsec->flooryscale = tempsec->ceilingyscale;
tempsec->floorangle = tempsec->ceilingangle; tempsec->floorangle = tempsec->ceilingangle;
} }
else else
@ -338,6 +348,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
tempsec->floorpic = s->floorpic; tempsec->floorpic = s->floorpic;
tempsec->floorxoffset = s->floorxoffset; tempsec->floorxoffset = s->floorxoffset;
tempsec->flooryoffset = s->flooryoffset; tempsec->flooryoffset = s->flooryoffset;
tempsec->floorxscale = s->floorxscale;
tempsec->flooryscale = s->flooryscale;
tempsec->floorangle = s->floorangle; tempsec->floorangle = s->floorangle;
} }
@ -372,12 +384,16 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back)
&& back->c_slope == front->c_slope && back->c_slope == front->c_slope
&& back->lightlevel == front->lightlevel && back->lightlevel == front->lightlevel
&& !line->sidedef->midtexture && !line->sidedef->midtexture
// Check offsets too! // Check offsets and scale too!
&& back->floorxoffset == front->floorxoffset && back->floorxoffset == front->floorxoffset
&& back->flooryoffset == front->flooryoffset && back->flooryoffset == front->flooryoffset
&& back->floorxscale == front->floorxscale
&& back->flooryscale == front->flooryscale
&& back->floorangle == front->floorangle && back->floorangle == front->floorangle
&& back->ceilingxoffset == front->ceilingxoffset && back->ceilingxoffset == front->ceilingxoffset
&& back->ceilingyoffset == front->ceilingyoffset && back->ceilingyoffset == front->ceilingyoffset
&& back->ceilingxscale == front->ceilingxscale
&& back->ceilingyscale == front->ceilingyscale
&& back->ceilingangle == front->ceilingangle && back->ceilingangle == front->ceilingangle
// Consider altered lighting. // Consider altered lighting.
&& back->floorlightlevel == front->floorlightlevel && back->floorlightlevel == front->floorlightlevel
@ -899,7 +915,9 @@ static void R_Subsector(size_t num)
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
{ {
floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel, floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel,
frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, frontsector->f_slope, P_SectorGetFloorPortal(frontsector)); frontsector->floorxoffset, frontsector->flooryoffset,
frontsector->floorxscale, frontsector->flooryscale, frontsector->floorangle,
floorcolormap, NULL, NULL, frontsector->f_slope, P_SectorGetFloorPortal(frontsector));
} }
else else
floorplane = NULL; floorplane = NULL;
@ -909,8 +927,9 @@ static void R_Subsector(size_t num)
|| P_SectorHasCeilingPortal(frontsector) || P_SectorHasCeilingPortal(frontsector)
|| (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->ceilingyoffset, frontsector->ceilingangle, frontsector->ceilingxoffset, frontsector->ceilingyoffset,
frontsector->ceilingxscale, frontsector->ceilingyscale, frontsector->ceilingangle,
ceilingcolormap, NULL, NULL, frontsector->c_slope, P_SectorGetCeilingPortal(frontsector)); ceilingcolormap, NULL, NULL, frontsector->c_slope, P_SectorGetCeilingPortal(frontsector));
} }
else else
@ -953,8 +972,9 @@ static void R_Subsector(size_t num)
viewz < heightcheck); viewz < heightcheck);
ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->bottomheight, *rover->bottompic, ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs,
*rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope, NULL); *rover->bottomxscale, *rover->bottomyscale, *rover->bottomangle,
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope, NULL);
ffloor[numffloors].slope = *rover->b_slope; ffloor[numffloors].slope = *rover->b_slope;
@ -982,7 +1002,8 @@ static void R_Subsector(size_t num)
light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck); light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);
ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->topheight, *rover->toppic, ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs,
*rover->topxscale, *rover->topyscale, *rover->topangle,
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope, NULL); *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope, NULL);
ffloor[numffloors].slope = *rover->t_slope; ffloor[numffloors].slope = *rover->t_slope;
@ -1024,7 +1045,9 @@ static void R_Subsector(size_t num)
{ {
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
ffloor[numffloors].plane = R_FindPlane(polysec, polysec->floorheight, polysec->floorpic, ffloor[numffloors].plane = R_FindPlane(polysec, polysec->floorheight, polysec->floorpic,
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floorxoffset, polysec->flooryoffset, (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel),
polysec->floorxoffset, polysec->flooryoffset,
polysec->floorxscale, polysec->flooryscale,
polysec->floorangle-po->angle, polysec->floorangle-po->angle,
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po,
NULL, NULL); NULL, NULL);
@ -1047,7 +1070,10 @@ static void R_Subsector(size_t num)
{ {
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
ffloor[numffloors].plane = R_FindPlane(polysec, polysec->ceilingheight, polysec->ceilingpic, ffloor[numffloors].plane = R_FindPlane(polysec, polysec->ceilingheight, polysec->ceilingpic,
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceilingxoffset, polysec->ceilingyoffset, polysec->ceilingangle-po->angle, (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel),
polysec->ceilingxoffset, polysec->ceilingyoffset,
polysec->ceilingxscale, polysec->ceilingyscale,
polysec->ceilingangle-po->angle,
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po,
NULL, NULL); NULL, NULL);
@ -1346,7 +1372,8 @@ void R_RenderPortalHorizonLine(sector_t *sector)
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
{ {
floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel, floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel,
frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, NULL, NULL); frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorxscale, frontsector->flooryscale,
frontsector->floorangle, floorcolormap, NULL, NULL, NULL, NULL);
} }
else else
floorplane = NULL; floorplane = NULL;
@ -1356,7 +1383,8 @@ void R_RenderPortalHorizonLine(sector_t *sector)
|| (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, frontsector->ceilingxoffset, frontsector->ceilingyoffset, frontsector->ceilingangle, ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingxscale, frontsector->ceilingyscale,
frontsector->ceilingyoffset, frontsector->ceilingangle,
ceilingcolormap, NULL, NULL, NULL, NULL); ceilingcolormap, NULL, NULL, NULL, NULL);
} }
else else

View file

@ -246,12 +246,16 @@ typedef struct ffloor_s
INT16 *toplightlevel; INT16 *toplightlevel;
fixed_t *topxoffs; fixed_t *topxoffs;
fixed_t *topyoffs; fixed_t *topyoffs;
fixed_t *topxscale;
fixed_t *topyscale;
angle_t *topangle; angle_t *topangle;
fixed_t *bottomheight; fixed_t *bottomheight;
INT32 *bottompic; INT32 *bottompic;
fixed_t *bottomxoffs; fixed_t *bottomxoffs;
fixed_t *bottomyoffs; fixed_t *bottomyoffs;
fixed_t *bottomxscale;
fixed_t *bottomyscale;
angle_t *bottomangle; angle_t *bottomangle;
// Pointers to pointers. Yup. // Pointers to pointers. Yup.
@ -457,6 +461,10 @@ typedef struct sector_s
fixed_t floorxoffset, flooryoffset; fixed_t floorxoffset, flooryoffset;
fixed_t ceilingxoffset, ceilingyoffset; fixed_t ceilingxoffset, ceilingyoffset;
// floor and ceiling texture scale
fixed_t floorxscale, flooryscale;
fixed_t ceilingxscale, ceilingyscale;
// flat angle // flat angle
angle_t floorangle; angle_t floorangle;
angle_t ceilingangle; angle_t ceilingangle;
@ -600,8 +608,11 @@ typedef struct
fixed_t rowoffset; fixed_t rowoffset;
// per-texture offsets for UDMF // per-texture offsets for UDMF
fixed_t offsetx_top, offsetx_mid, offsetx_bot; fixed_t offsetx_top, offsetx_mid, offsetx_bottom;
fixed_t offsety_top, offsety_mid, offsety_bot; fixed_t offsety_top, offsety_mid, offsety_bottom;
fixed_t scalex_top, scalex_mid, scalex_bottom;
fixed_t scaley_top, scaley_mid, scaley_bottom;
// Texture indices. // Texture indices.
// We do not maintain names here. // We do not maintain names here.
@ -795,10 +806,13 @@ typedef struct drawseg_s
fixed_t bsilheight; // do not clip sprites above this fixed_t bsilheight; // do not clip sprites above this
fixed_t tsilheight; // do not clip sprites below this fixed_t tsilheight; // do not clip sprites below this
fixed_t offsetx;
// Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value.
INT16 *sprtopclip; INT16 *sprtopclip;
INT16 *sprbottomclip; INT16 *sprbottomclip;
fixed_t *maskedtexturecol; fixed_t *maskedtexturecol;
fixed_t *invscale;
struct visplane_s *ffloorplanes[MAXFFLOORS]; struct visplane_s *ffloorplanes[MAXFFLOORS];
INT32 numffloorplanes; INT32 numffloorplanes;

View file

@ -106,14 +106,13 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
INT32 ds_waterofs, ds_bgofs; INT32 ds_waterofs, ds_bgofs;
UINT16 ds_flatwidth, ds_flatheight; UINT16 ds_flatwidth, ds_flatheight;
boolean ds_powersoftwo, ds_solidcolor; boolean ds_powersoftwo, ds_solidcolor, ds_fog;
UINT8 *ds_source; // points to the start of a flat UINT8 *ds_source; // points to the start of a flat
UINT8 *ds_transmap; // one of the translucency tables UINT8 *ds_transmap; // one of the translucency tables
// Vectors for Software's tilted slope drawers // Vectors for Software's tilted slope drawers
floatv3_t *ds_su, *ds_sv, *ds_sz; floatv3_t ds_su, ds_sv, ds_sz, ds_slopelight;
floatv3_t *ds_sup, *ds_svp, *ds_szp;
float focallengthf, zeroheight; float focallengthf, zeroheight;
/** \brief Variable flat sizes /** \brief Variable flat sizes
@ -906,13 +905,15 @@ static void R_CalcTiltedLighting(fixed_t start, fixed_t end)
} }
} }
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan))
// Lighting is simple. It's just linear interpolation from start to end // Lighting is simple. It's just linear interpolation from start to end
#define CALC_SLOPE_LIGHT { \ static void R_CalcSlopeLight(void)
float planelightfloat = PLANELIGHTFLOAT; \ {
float lightstart, lightend; \ float iz = ds_slopelight.z + ds_slopelight.y * (centery - ds_y) + ds_slopelight.x * (ds_x1 - centerx);
lightend = (iz + ds_szp->x*width) * planelightfloat; \ float lightstart = iz * PLANELIGHTFLOAT;
lightstart = iz * planelightfloat; \ float lightend = (iz + ds_slopelight.x * (ds_x2 - ds_x1)) * PLANELIGHTFLOAT;
R_CalcTiltedLighting(FloatToFixed(lightstart), FloatToFixed(lightend)); \ R_CalcTiltedLighting(FloatToFixed(lightstart), FloatToFixed(lightend));
} }
// ========================================================================== // ==========================================================================

View file

@ -61,7 +61,7 @@ extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
extern INT32 ds_waterofs, ds_bgofs; extern INT32 ds_waterofs, ds_bgofs;
extern UINT16 ds_flatwidth, ds_flatheight; extern UINT16 ds_flatwidth, ds_flatheight;
extern boolean ds_powersoftwo, ds_solidcolor; extern boolean ds_powersoftwo, ds_solidcolor, ds_fog;
extern UINT8 *ds_source; extern UINT8 *ds_source;
extern UINT8 *ds_transmap; extern UINT8 *ds_transmap;
@ -71,8 +71,7 @@ typedef struct {
} floatv3_t; } floatv3_t;
// Vectors for Software's tilted slope drawers // Vectors for Software's tilted slope drawers
extern floatv3_t *ds_su, *ds_sv, *ds_sz; extern floatv3_t ds_su, ds_sv, ds_sz, ds_slopelight;
extern floatv3_t *ds_sup, *ds_svp, *ds_szp;
extern float focallengthf, zeroheight; extern float focallengthf, zeroheight;
// Variable flat sizes // Variable flat sizes
@ -178,8 +177,6 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void);
void R_DrawFogColumn_8(void); void R_DrawFogColumn_8(void);
void R_DrawColumnShadowed_8(void); void R_DrawColumnShadowed_8(void);
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan))
void R_DrawSpan_8(void); void R_DrawSpan_8(void);
void R_DrawTranslucentSpan_8(void); void R_DrawTranslucentSpan_8(void);
void R_DrawTiltedSpan_8(void); void R_DrawTiltedSpan_8(void);

View file

@ -676,12 +676,11 @@ void R_DrawTiltedSpan_8(void)
double endz, endu, endv; double endz, endu, endv;
UINT32 stepu, stepv; UINT32 stepu, stepv;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
CALC_SLOPE_LIGHT R_CalcSlopeLight();
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source; source = ds_source;
@ -700,18 +699,18 @@ void R_DrawTiltedSpan_8(void)
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++; dest++;
iz += ds_szp->x; iz += ds_sz.x;
uz += ds_sup->x; uz += ds_su.x;
vz += ds_svp->x; vz += ds_sv.x;
} while (--width >= 0); } while (--width >= 0);
#else #else
startz = 1.f/iz; startz = 1.f/iz;
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -753,9 +752,9 @@ void R_DrawTiltedSpan_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -799,12 +798,11 @@ void R_DrawTiltedTranslucentSpan_8(void)
double endz, endu, endv; double endz, endu, endv;
UINT32 stepu, stepv; UINT32 stepu, stepv;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
CALC_SLOPE_LIGHT R_CalcSlopeLight();
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source; source = ds_source;
@ -822,18 +820,18 @@ void R_DrawTiltedTranslucentSpan_8(void)
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
dest++; dest++;
iz += ds_szp->x; iz += ds_sz.x;
uz += ds_sup->x; uz += ds_su.x;
vz += ds_svp->x; vz += ds_sv.x;
} while (--width >= 0); } while (--width >= 0);
#else #else
startz = 1.f/iz; startz = 1.f/iz;
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -875,9 +873,9 @@ void R_DrawTiltedTranslucentSpan_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -922,12 +920,11 @@ void R_DrawTiltedWaterSpan_8(void)
double endz, endu, endv; double endz, endu, endv;
UINT32 stepu, stepv; UINT32 stepu, stepv;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
CALC_SLOPE_LIGHT R_CalcSlopeLight();
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
@ -946,18 +943,18 @@ void R_DrawTiltedWaterSpan_8(void)
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++);
dest++; dest++;
iz += ds_szp->x; iz += ds_sz.x;
uz += ds_sup->x; uz += ds_su.x;
vz += ds_svp->x; vz += ds_sv.x;
} while (--width >= 0); } while (--width >= 0);
#else #else
startz = 1.f/iz; startz = 1.f/iz;
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -999,9 +996,9 @@ void R_DrawTiltedWaterSpan_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -1044,12 +1041,11 @@ void R_DrawTiltedSplat_8(void)
double endz, endu, endv; double endz, endu, endv;
UINT32 stepu, stepv; UINT32 stepu, stepv;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
CALC_SLOPE_LIGHT R_CalcSlopeLight();
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source; source = ds_source;
@ -1071,18 +1067,18 @@ void R_DrawTiltedSplat_8(void)
*dest = colormap[val]; *dest = colormap[val];
dest++; dest++;
iz += ds_szp->x; iz += ds_sz.x;
uz += ds_sup->x; uz += ds_su.x;
vz += ds_svp->x; vz += ds_sv.x;
} while (--width >= 0); } while (--width >= 0);
#else #else
startz = 1.f/iz; startz = 1.f/iz;
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -1128,9 +1124,9 @@ void R_DrawTiltedSplat_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -1613,9 +1609,9 @@ void R_DrawTiltedFloorSprite_8(void)
double endz, endu, endv; double endz, endu, endv;
UINT32 stepu, stepv; UINT32 stepu, stepv;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
source = (UINT16 *)ds_source; source = (UINT16 *)ds_source;
@ -1626,9 +1622,9 @@ void R_DrawTiltedFloorSprite_8(void)
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -1673,9 +1669,9 @@ void R_DrawTiltedFloorSprite_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -1722,9 +1718,9 @@ void R_DrawTiltedTranslucentFloorSprite_8(void)
double endz, endu, endv; double endz, endu, endv;
UINT32 stepu, stepv; UINT32 stepu, stepv;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
source = (UINT16 *)ds_source; source = (UINT16 *)ds_source;
@ -1735,9 +1731,9 @@ void R_DrawTiltedTranslucentFloorSprite_8(void)
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -1782,9 +1778,9 @@ void R_DrawTiltedTranslucentFloorSprite_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -2013,9 +2009,7 @@ void R_DrawTiltedFogSpan_8(void)
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); R_CalcSlopeLight();
CALC_SLOPE_LIGHT
do do
{ {
@ -2067,9 +2061,7 @@ void R_DrawTiltedSolidColorSpan_8(void)
UINT8 source = ds_source[0]; UINT8 source = ds_source[0];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); R_CalcSlopeLight();
CALC_SLOPE_LIGHT
do do
{ {
@ -2088,9 +2080,7 @@ void R_DrawTiltedTransSolidColorSpan_8(void)
UINT8 source = ds_source[0]; UINT8 source = ds_source[0];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); R_CalcSlopeLight();
CALC_SLOPE_LIGHT
do do
{ {
@ -2131,9 +2121,7 @@ void R_DrawTiltedWaterSolidColorSpan_8(void)
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1]; UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
UINT8 *dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; UINT8 *dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); R_CalcSlopeLight();
CALC_SLOPE_LIGHT
do do
{ {

View file

@ -114,12 +114,11 @@ void R_DrawTiltedSpan_NPO2_8(void)
struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth);
struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight);
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
CALC_SLOPE_LIGHT R_CalcSlopeLight();
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source; source = ds_source;
@ -154,18 +153,18 @@ void R_DrawTiltedSpan_NPO2_8(void)
*dest = colormap[source[((y * ds_flatwidth) + x)]]; *dest = colormap[source[((y * ds_flatwidth) + x)]];
} }
dest++; dest++;
iz += ds_szp->x; iz += ds_sz.x;
uz += ds_sup->x; uz += ds_su.x;
vz += ds_svp->x; vz += ds_sv.x;
} while (--width >= 0); } while (--width >= 0);
#else #else
startz = 1.f/iz; startz = 1.f/iz;
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -239,9 +238,9 @@ void R_DrawTiltedSpan_NPO2_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -304,12 +303,11 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void)
struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth);
struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight);
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
CALC_SLOPE_LIGHT R_CalcSlopeLight();
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source; source = ds_source;
@ -343,18 +341,18 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void)
*dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest);
} }
dest++; dest++;
iz += ds_szp->x; iz += ds_sz.x;
uz += ds_sup->x; uz += ds_su.x;
vz += ds_svp->x; vz += ds_sv.x;
} while (--width >= 0); } while (--width >= 0);
#else #else
startz = 1.f/iz; startz = 1.f/iz;
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -428,9 +426,9 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -492,12 +490,11 @@ void R_DrawTiltedSplat_NPO2_8(void)
struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth);
struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight);
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
CALC_SLOPE_LIGHT R_CalcSlopeLight();
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source; source = ds_source;
@ -536,18 +533,18 @@ void R_DrawTiltedSplat_NPO2_8(void)
*dest = colormap[val]; *dest = colormap[val];
dest++; dest++;
iz += ds_szp->x; iz += ds_sz.x;
uz += ds_sup->x; uz += ds_su.x;
vz += ds_svp->x; vz += ds_sv.x;
} while (--width >= 0); } while (--width >= 0);
#else #else
startz = 1.f/iz; startz = 1.f/iz;
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -625,9 +622,9 @@ void R_DrawTiltedSplat_NPO2_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -970,9 +967,9 @@ void R_DrawTiltedFloorSprite_NPO2_8(void)
struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth);
struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight);
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
source = (UINT16 *)ds_source; source = (UINT16 *)ds_source;
@ -983,9 +980,9 @@ void R_DrawTiltedFloorSprite_NPO2_8(void)
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -1060,9 +1057,9 @@ void R_DrawTiltedFloorSprite_NPO2_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -1126,9 +1123,9 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void)
struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth);
struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight);
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
source = (UINT16 *)ds_source; source = (UINT16 *)ds_source;
@ -1139,9 +1136,9 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void)
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -1216,9 +1213,9 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;
@ -1411,12 +1408,11 @@ void R_DrawTiltedWaterSpan_NPO2_8(void)
struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth);
struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight);
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
CALC_SLOPE_LIGHT R_CalcSlopeLight();
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1]; dest = ylookup[ds_y] + columnofs[ds_x1];
dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
@ -1451,18 +1447,18 @@ void R_DrawTiltedWaterSpan_NPO2_8(void)
*dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++);
} }
dest++; dest++;
iz += ds_szp->x; iz += ds_sz.x;
uz += ds_sup->x; uz += ds_su.x;
vz += ds_svp->x; vz += ds_sv.x;
} while (--width >= 0); } while (--width >= 0);
#else #else
startz = 1.f/iz; startz = 1.f/iz;
startu = uz*startz; startu = uz*startz;
startv = vz*startz; startv = vz*startz;
izstep = ds_szp->x * SPANSIZE; izstep = ds_sz.x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE; uzstep = ds_su.x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE; vzstep = ds_sv.x * SPANSIZE;
//x1 = 0; //x1 = 0;
width++; width++;
@ -1536,9 +1532,9 @@ void R_DrawTiltedWaterSpan_NPO2_8(void)
else else
{ {
double left = width; double left = width;
iz += ds_szp->x * left; iz += ds_sz.x * left;
uz += ds_sup->x * left; uz += ds_su.x * left;
vz += ds_svp->x * left; vz += ds_sv.x * left;
endz = 1.f/iz; endz = 1.f/iz;
endu = uz*endz; endu = uz*endz;

View file

@ -356,7 +356,7 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, 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)
{ {
angle_t angle; angle_t angle;
fixed_t dx, dy, dist; ufixed_t dx, dy, dist;
dx = abs(px1 - px2); dx = abs(px1 - px2);
dy = abs(py1 - py2); dy = abs(py1 - py2);
@ -957,16 +957,6 @@ void R_ExecuteSetViewSize(void)
dy = FixedMul(abs(dy), fovtan); dy = FixedMul(abs(dy), fovtan);
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy); yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
} }
if (ds_su)
Z_Free(ds_su);
if (ds_sv)
Z_Free(ds_sv);
if (ds_sz)
Z_Free(ds_sz);
ds_su = ds_sv = ds_sz = NULL;
ds_sup = ds_svp = ds_szp = NULL;
} }
memset(scalelight, 0xFF, sizeof(scalelight)); memset(scalelight, 0xFF, sizeof(scalelight));
@ -1012,9 +1002,6 @@ void R_Init(void)
R_InitViewBorder(); R_InitViewBorder();
R_SetViewSize(); // setsizeneeded is set true R_SetViewSize(); // setsizeneeded is set true
//I_OutputMsg("\nR_InitPlanes");
R_InitPlanes();
// this is now done by SCR_Recalc() at the first mode set // this is now done by SCR_Recalc() at the first mode set
//I_OutputMsg("\nR_InitLightTables"); //I_OutputMsg("\nR_InitLightTables");
R_InitLightTables(); R_InitLightTables();
@ -1027,6 +1014,34 @@ void R_Init(void)
framecount = 0; framecount = 0;
} }
//
// R_IsPointInSector
//
boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y)
{
size_t i;
line_t *closest = NULL;
fixed_t closestdist = INT32_MAX;
for (i = 0; i < sector->linecount; i++)
{
vertex_t v;
fixed_t dist;
// find the line closest to the point we're looking for.
P_ClosestPointOnLine(x, y, sector->lines[i], &v);
dist = R_PointToDist2(0, 0, v.x - x, v.y - y);
if (dist < closestdist)
{
closest = sector->lines[i];
closestdist = dist;
}
}
// if the side of the closest line is in this sector, we're inside of it.
return P_PointOnLineSide(x, y, closest) == 0 ? closest->frontsector == sector : closest->backsector == sector;
}
// //
// R_PointInSubsector // R_PointInSubsector
// //

View file

@ -79,6 +79,7 @@ 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); fixed_t R_ScaleFromGlobalAngle(angle_t visangle);
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);

View file

@ -83,22 +83,15 @@ static fixed_t planeheight;
fixed_t yslopetab[MAXVIDHEIGHT*16]; fixed_t yslopetab[MAXVIDHEIGHT*16];
fixed_t *yslope; fixed_t *yslope;
fixed_t cachedheight[MAXVIDHEIGHT];
fixed_t cacheddistance[MAXVIDHEIGHT];
fixed_t cachedxstep[MAXVIDHEIGHT];
fixed_t cachedystep[MAXVIDHEIGHT];
static fixed_t xoffs, yoffs; static fixed_t xoffs, yoffs;
static floatv3_t ds_slope_origin, ds_slope_u, ds_slope_v; static floatv3_t slope_origin, slope_u, slope_v;
static floatv3_t slope_lightu, slope_lightv;
// static void CalcSlopePlaneVectors(visplane_t *pl, fixed_t xoff, fixed_t yoff);
// R_InitPlanes static void CalcSlopeLightVectors(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t height, float ang, angle_t plangle);
// Only at game startup.
// static void DoSlopeCrossProducts(void);
void R_InitPlanes(void) static void DoSlopeLightCrossProduct(void);
{
// FIXME: unused
}
// //
// Water ripple effect // Water ripple effect
@ -159,37 +152,28 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
planecos = FINECOSINE(angle); planecos = FINECOSINE(angle);
planesin = FINESINE(angle); planesin = FINESINE(angle);
if (planeheight != cachedheight[y]) // [RH] Notice that I dumped the caching scheme used by Doom.
// It did not offer any appreciable speedup.
distance = FixedMul(planeheight, yslope[y]);
span = abs(centery - y);
if (span) // Don't divide by zero
{ {
cachedheight[y] = planeheight; ds_xstep = FixedMul(planesin, planeheight) / span;
cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]); ds_ystep = FixedMul(planecos, planeheight) / span;
span = abs(centery - y); ds_xstep = FixedMul(currentplane->xscale, ds_xstep);
ds_ystep = FixedMul(currentplane->yscale, ds_ystep);
if (span) // Don't divide by zero
{
ds_xstep = FixedMul(planesin, planeheight) / span;
ds_ystep = FixedMul(planecos, planeheight) / span;
}
else
ds_xstep = ds_ystep = FRACUNIT;
cachedxstep[y] = ds_xstep;
cachedystep[y] = ds_ystep;
} }
else else
{ ds_xstep = ds_ystep = FRACUNIT;
distance = cacheddistance[y];
ds_xstep = cachedxstep[y];
ds_ystep = cachedystep[y];
}
// [RH] Instead of using the xtoviewangle array, I calculated the fractional values // [RH] Instead of using the xtoviewangle array, I calculated the fractional values
// at the middle of the screen, then used the calculated ds_xstep and ds_ystep // at the middle of the screen, then used the calculated ds_xstep and ds_ystep
// to step from those to the proper texture coordinate to start drawing at. // to step from those to the proper texture coordinate to start drawing at.
// That way, the texture coordinate is always calculated by its position // That way, the texture coordinate is always calculated by its position
// on the screen and not by its position relative to the edge of the visplane. // on the screen and not by its position relative to the edge of the visplane.
ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep; ds_xfrac = xoffs + FixedMul(currentplane->xscale, FixedMul(planecos, distance)) + (x1 - centerx) * ds_xstep;
ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep; ds_yfrac = yoffs - FixedMul(currentplane->yscale, FixedMul(planesin, distance)) + (x1 - centerx) * ds_ystep;
// Water ripple effect // Water ripple effect
if (planeripple.active) if (planeripple.active)
@ -238,9 +222,9 @@ static void R_MapTiltedPlane(INT32 y, INT32 x1, INT32 x2)
{ {
ds_bgofs = R_CalculateRippleOffset(y); ds_bgofs = R_CalculateRippleOffset(y);
ds_sup = &ds_su[y]; R_CalculatePlaneRipple(currentplane->viewangle + currentplane->plangle);
ds_svp = &ds_sv[y];
ds_szp = &ds_sz[y]; CalcSlopePlaneVectors(currentplane, (xoffs + planeripple.xfrac), (yoffs + planeripple.yfrac));
ds_bgofs >>= FRACBITS; ds_bgofs >>= FRACBITS;
@ -275,10 +259,7 @@ static void R_MapFogPlane(INT32 y, INT32 x1, INT32 x2)
if (x1 >= vid.width) if (x1 >= vid.width)
x1 = vid.width - 1; x1 = vid.width - 1;
if (planeheight != cachedheight[y]) distance = FixedMul(planeheight, yslope[y]);
distance = FixedMul(planeheight, yslope[y]);
else
distance = cacheddistance[y];
pindex = distance >> LIGHTZSHIFT; pindex = distance >> LIGHTZSHIFT;
if (pindex >= MAXLIGHTZ) if (pindex >= MAXLIGHTZ)
@ -361,9 +342,6 @@ void R_ClearPlanes(void)
{ {
freehead = &(*freehead)->next; freehead = &(*freehead)->next;
} }
// texture calculation
memset(cachedheight, 0, sizeof (cachedheight));
} }
static visplane_t *new_visplane(unsigned hash) static visplane_t *new_visplane(unsigned hash)
@ -391,7 +369,8 @@ static visplane_t *new_visplane(unsigned hash)
// If not, allocates another of them. // If not, allocates another of them.
// //
visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 lightlevel, visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 lightlevel,
fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, fixed_t xoff, fixed_t yoff, fixed_t xscale, fixed_t yscale,
angle_t plangle, extracolormap_t *planecolormap,
ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope, sectorportal_t *portalsector) ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope, sectorportal_t *portalsector)
{ {
visplane_t *check; visplane_t *check;
@ -399,8 +378,9 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li
if (!slope) // Don't mess with this right now if a slope is involved if (!slope) // Don't mess with this right now if a slope is involved
{ {
xoff += viewx; xoff += FixedMul(viewx, xscale);
yoff -= viewy; yoff -= FixedMul(viewy, yscale);
if (plangle != 0) if (plangle != 0)
{ {
// Add the view offset, rotated by the plane angle. // Add the view offset, rotated by the plane angle.
@ -444,6 +424,7 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li
if (height == check->height && picnum == check->picnum if (height == check->height && picnum == check->picnum
&& lightlevel == check->lightlevel && lightlevel == check->lightlevel
&& xoff == check->xoffs && yoff == check->yoffs && xoff == check->xoffs && yoff == check->yoffs
&& xscale == check->xscale && yscale == check->yscale
&& planecolormap == check->extra_colormap && planecolormap == check->extra_colormap
&& check->viewx == viewx && check->viewy == viewy && check->viewz == viewz && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz
&& check->viewangle == viewangle && check->viewangle == viewangle
@ -470,6 +451,8 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li
check->maxx = -1; check->maxx = -1;
check->xoffs = xoff; check->xoffs = xoff;
check->yoffs = yoff; check->yoffs = yoff;
check->xscale = xscale;
check->yscale = yscale;
check->extra_colormap = planecolormap; check->extra_colormap = planecolormap;
check->ffloor = pfloor; check->ffloor = pfloor;
check->viewx = viewx; check->viewx = viewx;
@ -548,6 +531,8 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
new_pl->lightlevel = pl->lightlevel; new_pl->lightlevel = pl->lightlevel;
new_pl->xoffs = pl->xoffs; new_pl->xoffs = pl->xoffs;
new_pl->yoffs = pl->yoffs; new_pl->yoffs = pl->yoffs;
new_pl->xscale = pl->xscale;
new_pl->yscale = pl->yscale;
new_pl->extra_colormap = pl->extra_colormap; new_pl->extra_colormap = pl->extra_colormap;
new_pl->ffloor = pl->ffloor; new_pl->ffloor = pl->ffloor;
new_pl->viewx = pl->viewx; new_pl->viewx = pl->viewx;
@ -690,8 +675,6 @@ static INT64 R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y)
// Sets the texture origin vector of the sloped plane. // Sets the texture origin vector of the sloped plane.
static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle) static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle)
{ {
floatv3_t *p = &ds_slope_origin;
INT64 vx = (INT64)xpos + (INT64)xoff; INT64 vx = (INT64)xpos + (INT64)xoff;
INT64 vy = (INT64)ypos - (INT64)yoff; INT64 vy = (INT64)ypos - (INT64)yoff;
@ -699,125 +682,164 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f
float vyf = vy / (float)FRACUNIT; float vyf = vy / (float)FRACUNIT;
float ang = ANG2RAD(ANGLE_270 - angle); float ang = ANG2RAD(ANGLE_270 - angle);
// p is the texture origin in view space // slope_origin is the texture origin in view space
// Don't add in the offsets at this stage, because doing so can result in // Don't add in the offsets at this stage, because doing so can result in
// errors if the flat is rotated. // errors if the flat is rotated.
p->x = vxf * cos(ang) - vyf * sin(ang); slope_origin.x = vxf * cos(ang) - vyf * sin(ang);
p->z = vxf * sin(ang) + vyf * cos(ang); slope_origin.z = vxf * sin(ang) + vyf * cos(ang);
p->y = (R_GetSlopeZAt(slope, -xoff, yoff) - zpos) / (float)FRACUNIT; slope_origin.y = (R_GetSlopeZAt(slope, -xoff, yoff) - zpos) / (float)FRACUNIT;
} }
// This function calculates all of the vectors necessary for drawing a sloped plane. // This function calculates all of the vectors necessary for drawing a sloped plane.
void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle)
{ {
// Potentially override other stuff for now cus we're mean. :< But draw a slope plane!
// I copied ZDoom's code and adapted it to SRB2... -Red // I copied ZDoom's code and adapted it to SRB2... -Red
floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; fixed_t height, z_at_xy;
fixed_t height, temp;
float ang; float ang;
R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle);
height = P_GetSlopeZAt(slope, xpos, ypos); height = P_GetSlopeZAt(slope, xpos, ypos);
zeroheight = FixedToFloat(height - zpos); zeroheight = FixedToFloat(height - zpos);
// m is the v direction vector in view space
ang = ANG2RAD(ANGLE_180 - (angle + plangle)); ang = ANG2RAD(ANGLE_180 - (angle + plangle));
m->x = cos(ang);
m->z = sin(ang);
// n is the u direction vector in view space CalcSlopeLightVectors(slope, xpos, ypos, height, ang, plangle);
n->x = sin(ang);
n->z = -cos(ang); if (ds_solidcolor || ds_fog)
{
DoSlopeLightCrossProduct();
return;
}
// slope_v is the v direction vector in view space
slope_v.x = cos(ang);
slope_v.z = sin(ang);
// slope_u is the u direction vector in view space
slope_u.x = sin(ang);
slope_u.z = -cos(ang);
plangle >>= ANGLETOFINESHIFT; plangle >>= ANGLETOFINESHIFT;
temp = P_GetSlopeZAt(slope, xpos + FINESINE(plangle), ypos + FINECOSINE(plangle)); z_at_xy = P_GetSlopeZAt(slope, xpos + FINESINE(plangle), ypos + FINECOSINE(plangle));
m->y = FixedToFloat(temp - height); slope_v.y = FixedToFloat(z_at_xy - height);
temp = P_GetSlopeZAt(slope, xpos + FINECOSINE(plangle), ypos - FINESINE(plangle)); z_at_xy = P_GetSlopeZAt(slope, xpos + FINECOSINE(plangle), ypos - FINESINE(plangle));
n->y = FixedToFloat(temp - height); slope_u.y = FixedToFloat(z_at_xy - height);
DoSlopeCrossProducts();
DoSlopeLightCrossProduct();
} }
// This function calculates all of the vectors necessary for drawing a sloped and scaled plane. // This function calculates all of the vectors necessary for drawing a sloped and scaled plane.
void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle)
{ {
floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; fixed_t height, z_at_xy;
fixed_t height, temp;
float xscale = FixedToFloat(xs);
float yscale = FixedToFloat(ys);
float ang; float ang;
R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle);
height = P_GetSlopeZAt(slope, xpos, ypos); height = P_GetSlopeZAt(slope, xpos, ypos);
zeroheight = FixedToFloat(height - zpos); zeroheight = FixedToFloat(height - zpos);
// m is the v direction vector in view space
ang = ANG2RAD(ANGLE_180 - (angle + plangle)); ang = ANG2RAD(ANGLE_180 - (angle + plangle));
m->x = yscale * cos(ang);
m->z = yscale * sin(ang); CalcSlopeLightVectors(slope, xpos, ypos, height, ang, plangle);
if (ds_solidcolor || ds_fog)
{
DoSlopeLightCrossProduct();
return;
}
float xscale = FixedToFloat(xs);
float yscale = FixedToFloat(ys);
// m is the v direction vector in view space
slope_v.x = yscale * cos(ang);
slope_v.z = yscale * sin(ang);
// n is the u direction vector in view space // n is the u direction vector in view space
n->x = xscale * sin(ang); slope_u.x = xscale * sin(ang);
n->z = -xscale * cos(ang); slope_u.z = -xscale * cos(ang);
ang = ANG2RAD(plangle); ang = ANG2RAD(plangle);
temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(yscale * sin(ang)), ypos + FloatToFixed(yscale * cos(ang))); z_at_xy = P_GetSlopeZAt(slope, xpos + FloatToFixed(yscale * sin(ang)), ypos + FloatToFixed(yscale * cos(ang)));
m->y = FixedToFloat(temp - height); slope_v.y = FixedToFloat(z_at_xy - height);
temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(xscale * cos(ang)), ypos - FloatToFixed(xscale * sin(ang))); z_at_xy = P_GetSlopeZAt(slope, xpos + FloatToFixed(xscale * cos(ang)), ypos - FloatToFixed(xscale * sin(ang)));
n->y = FixedToFloat(temp - height); slope_u.y = FixedToFloat(z_at_xy - height);
DoSlopeCrossProducts();
DoSlopeLightCrossProduct();
} }
void R_CalculateSlopeVectors(void) static void CalcSlopeLightVectors(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t height, float ang, angle_t plangle)
{
fixed_t z_at_xy;
slope_lightv.x = cos(ang);
slope_lightv.z = sin(ang);
slope_lightu.x = sin(ang);
slope_lightu.z = -cos(ang);
plangle >>= ANGLETOFINESHIFT;
z_at_xy = P_GetSlopeZAt(slope, xpos + FINESINE(plangle), ypos + FINECOSINE(plangle));
slope_lightv.y = FixedToFloat(z_at_xy - height);
z_at_xy = P_GetSlopeZAt(slope, xpos + FINECOSINE(plangle), ypos - FINESINE(plangle));
slope_lightu.y = FixedToFloat(z_at_xy - height);
}
// Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using.
#define CROSS(d, v1, v2) \
d.x = (v1.y * v2.z) - (v1.z * v2.y);\
d.y = (v1.z * v2.x) - (v1.x * v2.z);\
d.z = (v1.x * v2.y) - (v1.y * v2.x)
static void DoSlopeCrossProducts(void)
{ {
float sfmult = 65536.f; float sfmult = 65536.f;
// Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using. CROSS(ds_su, slope_origin, slope_v);
#define CROSS(d, v1, v2) \ CROSS(ds_sv, slope_origin, slope_u);
d->x = (v1.y * v2.z) - (v1.z * v2.y);\ CROSS(ds_sz, slope_v, slope_u);
d->y = (v1.z * v2.x) - (v1.x * v2.z);\
d->z = (v1.x * v2.y) - (v1.y * v2.x)
CROSS(ds_sup, ds_slope_origin, ds_slope_v);
CROSS(ds_svp, ds_slope_origin, ds_slope_u);
CROSS(ds_szp, ds_slope_v, ds_slope_u);
#undef CROSS
ds_sup->z *= focallengthf; ds_su.z *= focallengthf;
ds_svp->z *= focallengthf; ds_sv.z *= focallengthf;
ds_szp->z *= focallengthf; ds_sz.z *= focallengthf;
if (ds_solidcolor) if (ds_solidcolor)
return; return;
// Premultiply the texture vectors with the scale factors // Premultiply the texture vectors with the scale factors
if (ds_powersoftwo) if (ds_powersoftwo)
sfmult *= (1 << nflatshiftup); sfmult *= 1 << nflatshiftup;
ds_sup->x *= sfmult; ds_su.x *= sfmult;
ds_sup->y *= sfmult; ds_su.y *= sfmult;
ds_sup->z *= sfmult; ds_su.z *= sfmult;
ds_svp->x *= sfmult; ds_sv.x *= sfmult;
ds_svp->y *= sfmult; ds_sv.y *= sfmult;
ds_svp->z *= sfmult; ds_sv.z *= sfmult;
} }
void R_SetTiltedSpan(INT32 span) static void DoSlopeLightCrossProduct(void)
{ {
if (ds_su == NULL) CROSS(ds_slopelight, slope_lightv, slope_lightu);
ds_su = Z_Malloc(sizeof(*ds_su) * vid.height, PU_STATIC, NULL);
if (ds_sv == NULL)
ds_sv = Z_Malloc(sizeof(*ds_sv) * vid.height, PU_STATIC, NULL);
if (ds_sz == NULL)
ds_sz = Z_Malloc(sizeof(*ds_sz) * vid.height, PU_STATIC, NULL);
ds_sup = &ds_su[span]; ds_slopelight.z *= focallengthf;
ds_svp = &ds_sv[span];
ds_szp = &ds_sz[span];
} }
static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff) #undef CROSS
static void CalcSlopePlaneVectors(visplane_t *pl, fixed_t xoff, fixed_t yoff)
{ {
R_SetTiltedSpan(y); if (!ds_fog && (pl->xscale != FRACUNIT || pl->yscale != FRACUNIT))
R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle); {
R_CalculateSlopeVectors(); R_SetScaledSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz,
FixedDiv(FRACUNIT, pl->xscale), FixedDiv(FRACUNIT, pl->yscale),
FixedDiv(xoff, pl->xscale), FixedDiv(yoff, pl->yscale), pl->viewangle, pl->plangle);
}
else
R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle);
} }
static inline void R_AdjustSlopeCoordinates(vector3_t *origin) static inline void R_AdjustSlopeCoordinates(vector3_t *origin)
@ -854,7 +876,6 @@ void R_DrawSinglePlane(visplane_t *pl)
INT32 light = 0; INT32 light = 0;
INT32 x, stop; INT32 x, stop;
ffloor_t *rover; ffloor_t *rover;
boolean fog = false;
INT32 spanfunctype = BASEDRAWFUNC; INT32 spanfunctype = BASEDRAWFUNC;
void (*mapfunc)(INT32, INT32, INT32); void (*mapfunc)(INT32, INT32, INT32);
@ -868,6 +889,8 @@ void R_DrawSinglePlane(visplane_t *pl)
return; return;
} }
ds_powersoftwo = ds_solidcolor = ds_fog = false;
planeripple.active = false; planeripple.active = false;
if (pl->polyobj) if (pl->polyobj)
@ -932,13 +955,13 @@ void R_DrawSinglePlane(visplane_t *pl)
} }
else if (pl->ffloor->fofflags & FOF_FOG) else if (pl->ffloor->fofflags & FOF_FOG)
{ {
fog = true; ds_fog = true;
spanfunctype = SPANDRAWFUNC_FOG; spanfunctype = SPANDRAWFUNC_FOG;
light = (pl->lightlevel >> LIGHTSEGSHIFT); light = (pl->lightlevel >> LIGHTSEGSHIFT);
} }
else light = (pl->lightlevel >> LIGHTSEGSHIFT); else light = (pl->lightlevel >> LIGHTSEGSHIFT);
if (pl->ffloor->fofflags & FOF_RIPPLE && !fog) if (pl->ffloor->fofflags & FOF_RIPPLE && !ds_fog)
{ {
planeripple.active = true; planeripple.active = true;
@ -966,9 +989,7 @@ void R_DrawSinglePlane(visplane_t *pl)
light = (pl->lightlevel >> LIGHTSEGSHIFT); light = (pl->lightlevel >> LIGHTSEGSHIFT);
} }
ds_powersoftwo = ds_solidcolor = false; if (ds_fog)
if (fog)
{ {
// Since all fog planes do is apply a colormap, it's not required // Since all fog planes do is apply a colormap, it's not required
// to know any information about their textures. // to know any information about their textures.
@ -1004,13 +1025,6 @@ void R_DrawSinglePlane(visplane_t *pl)
} }
} }
// Don't mess with angle on slopes! We'll handle this ourselves later
if (!pl->slope && viewangle != pl->viewangle+pl->plangle)
{
memset(cachedheight, 0, sizeof (cachedheight));
viewangle = pl->viewangle+pl->plangle;
}
mapfunc = R_MapPlane; mapfunc = R_MapPlane;
if (ds_solidcolor) if (ds_solidcolor)
@ -1041,13 +1055,13 @@ void R_DrawSinglePlane(visplane_t *pl)
if (pl->slope) if (pl->slope)
{ {
if (fog) if (ds_fog)
mapfunc = R_MapTiltedFogPlane; mapfunc = R_MapTiltedFogPlane;
else else
{ {
mapfunc = R_MapTiltedPlane; mapfunc = R_MapTiltedPlane;
if (!pl->plangle && !ds_solidcolor) if (!pl->plangle && !ds_solidcolor && pl->xscale == FRACUNIT && pl->yscale == FRACUNIT)
{ {
if (ds_powersoftwo) if (ds_powersoftwo)
R_AdjustSlopeCoordinates(&pl->slope->o); R_AdjustSlopeCoordinates(&pl->slope->o);
@ -1056,21 +1070,10 @@ void R_DrawSinglePlane(visplane_t *pl)
} }
} }
if (planeripple.active) if (!ds_fog && planeripple.active)
{
planeheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); planeheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz);
R_PlaneBounds(pl);
for (x = pl->high; x < pl->low; x++)
{
ds_bgofs = R_CalculateRippleOffset(x);
R_CalculatePlaneRipple(pl->viewangle + pl->plangle);
R_SetSlopePlaneVectors(pl, x, (xoffs + planeripple.xfrac), (yoffs + planeripple.yfrac));
}
}
else else
R_SetSlopePlaneVectors(pl, 0, xoffs, yoffs); CalcSlopePlaneVectors(pl, xoffs, yoffs);
switch (spanfunctype) switch (spanfunctype)
{ {

View file

@ -49,6 +49,7 @@ typedef struct visplane_s
INT32 high, low; // R_PlaneBounds should set these. INT32 high, low; // R_PlaneBounds should set these.
fixed_t xoffs, yoffs; // Scrolling flats. fixed_t xoffs, yoffs; // Scrolling flats.
fixed_t xscale, yscale;
sector_t *sector; sector_t *sector;
struct ffloor_s *ffloor; struct ffloor_s *ffloor;
@ -64,20 +65,16 @@ extern visplane_t *ceilingplane;
// Visplane related. // Visplane related.
extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH];
extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16]; extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16];
extern fixed_t cachedheight[MAXVIDHEIGHT];
extern fixed_t cacheddistance[MAXVIDHEIGHT];
extern fixed_t cachedxstep[MAXVIDHEIGHT];
extern fixed_t cachedystep[MAXVIDHEIGHT];
extern fixed_t *yslope; extern fixed_t *yslope;
extern lighttable_t **planezlight; extern lighttable_t **planezlight;
void R_InitPlanes(void);
void R_ClearPlanes(void); void R_ClearPlanes(void);
void R_ClearFFloorClips (void); void R_ClearFFloorClips (void);
void R_DrawPlanes(void); void R_DrawPlanes(void);
visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 lightlevel,
fixed_t xoff, fixed_t yoff, fixed_t xscale, fixed_t yscale, angle_t plangle,
extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope, sectorportal_t *portalsector); extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope, sectorportal_t *portalsector);
visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
@ -89,10 +86,6 @@ void R_DrawSinglePlane(visplane_t *pl);
// Calculates the slope vectors needed for tilted span drawing. // Calculates the slope vectors needed for tilted span drawing.
void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle);
void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle);
void R_CalculateSlopeVectors(void);
// Sets the slope vector pointers for the current tilted span.
void R_SetTiltedSpan(INT32 span);
typedef struct planemgr_s typedef struct planemgr_s
{ {

View file

@ -48,15 +48,18 @@ fixed_t rw_distance;
// //
static INT32 rw_x, rw_stopx; static INT32 rw_x, rw_stopx;
static angle_t rw_centerangle; static angle_t rw_centerangle;
static fixed_t rw_offset; static fixed_t rw_offset, rw_offsetx;
static fixed_t rw_offset_top, rw_offset_mid, rw_offset_bot; static fixed_t rw_offset_top, rw_offset_mid, rw_offset_bottom;
static fixed_t rw_offset2; // for splats
static fixed_t rw_scale, rw_scalestep; static fixed_t rw_scale, rw_scalestep;
static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid;
static INT32 worldtop, worldbottom, worldhigh, worldlow; static INT32 worldtop, worldbottom, worldhigh, worldlow;
static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope
static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes
static fixed_t rw_midtextureback, rw_midtexturebackslide; // Values for masked midtexture height calculation static fixed_t rw_midtextureback, rw_midtexturebackslide; // Values for masked midtexture height calculation
static fixed_t rw_midtexturescalex, rw_midtexturescaley;
static fixed_t rw_toptexturescalex, rw_toptexturescaley;
static fixed_t rw_bottomtexturescalex, rw_bottomtexturescaley;
static fixed_t rw_invmidtexturescalex, rw_invtoptexturescalex, rw_invbottomtexturescalex;
// Lactozilla: 3D floor clipping // Lactozilla: 3D floor clipping
static boolean rw_floormarked = false; static boolean rw_floormarked = false;
@ -71,8 +74,10 @@ static fixed_t topfrac, topstep;
static fixed_t bottomfrac, bottomstep; static fixed_t bottomfrac, bottomstep;
static lighttable_t **walllights; static lighttable_t **walllights;
static fixed_t *maskedtexturecol; static fixed_t *maskedtexturecol = NULL;
static fixed_t *maskedtextureheight = NULL; static fixed_t *maskedtextureheight = NULL;
static fixed_t *thicksidecol = NULL;
static fixed_t *invscale = NULL;
//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;
@ -162,7 +167,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
frontsector = curline->frontsector; frontsector = curline->frontsector;
backsector = curline->backsector; backsector = curline->backsector;
texnum = R_GetTextureNum(curline->sidedef->midtexture); sidedef = curline->sidedef;
texnum = R_GetTextureNum(sidedef->midtexture);
windowbottom = windowtop = sprbotscreen = INT32_MAX; windowbottom = windowtop = sprbotscreen = INT32_MAX;
ldef = curline->linedef; ldef = curline->linedef;
@ -200,9 +206,13 @@ 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;
fixed_t scalestep = FixedDiv(ds->scalestep, wall_scaley);
fixed_t scale1 = FixedDiv(ds->scale1, wall_scaley);
range = max(ds->x2-ds->x1, 1); range = max(ds->x2-ds->x1, 1);
rw_scalestep = ds->scalestep; rw_scalestep = scalestep;
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; spryscale = scale1 + (x1 - ds->x1)*rw_scalestep;
// Texture must be cached before setting colfunc_2s, // Texture must be cached before setting colfunc_2s,
// otherwise texture[texnum]->holes may be false when it shouldn't be // otherwise texture[texnum]->holes may be false when it shouldn't be
@ -313,8 +323,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
else else
back = backsector; back = backsector;
if (ds->curline->sidedef->repeatcnt) if (sidedef->repeatcnt)
repeats = 1 + ds->curline->sidedef->repeatcnt; repeats = 1 + sidedef->repeatcnt;
else if (ldef->flags & ML_WRAPMIDTEX) else if (ldef->flags & ML_WRAPMIDTEX)
{ {
fixed_t high, low; fixed_t high, low;
@ -340,15 +350,14 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{ {
if (times > 0) if (times > 0)
{ {
rw_scalestep = ds->scalestep; rw_scalestep = scalestep;
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; spryscale = scale1 + (x1 - ds->x1)*rw_scalestep;
if (dc_numlights)
{ // reset all lights to their starting heights // reset all lights to their starting heights
for (i = 0; i < dc_numlights; i++) for (i = 0; i < dc_numlights; i++)
{ {
rlight = &dc_lightlist[i]; rlight = &dc_lightlist[i];
rlight->height = rlight->startheight; rlight->height = rlight->startheight;
}
} }
} }
@ -390,8 +399,10 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
sprbotscreen = INT32_MAX; sprbotscreen = INT32_MAX;
sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale));
realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; realbot = FixedMul(textureheight[texnum], spryscale) + sprtopscreen;
dc_iscale = 0xffffffffu / (unsigned)spryscale; dc_iscale = FixedMul(ds->invscale[dc_x], wall_scaley);
windowbottom = realbot;
// draw the texture // draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3);
@ -466,7 +477,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
dc_iscale = 0xffffffffu / (unsigned)spryscale; dc_iscale = FixedMul(ds->invscale[dc_x], wall_scaley);
// draw the texture // draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3);
@ -525,7 +536,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
INT32 i, p; INT32 i, p;
fixed_t bottombounds = viewheight << FRACBITS; fixed_t bottombounds = viewheight << FRACBITS;
fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS;
fixed_t offsetvalue = 0; fixed_t offsetvalue;
lightlist_t *light; lightlist_t *light;
r_lightlist_t *rlight; r_lightlist_t *rlight;
INT32 range; INT32 range;
@ -534,11 +545,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// NOTE: INT64 instead of fixed_t because overflow concerns // NOTE: INT64 instead of fixed_t because overflow concerns
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?
boolean slopeskew = false;
fixed_t ffloortextureslide = 0; fixed_t ffloortextureslide = 0;
INT32 oldx = -1; INT32 oldx = -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;
UINT32 lineflags;
fixed_t wall_scalex, wall_scaley;
void (*colfunc_2s) (column_t *); void (*colfunc_2s) (column_t *);
@ -550,7 +563,7 @@ 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;
texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); sidedef = &sides[pfloor->master->sidenum[0]];
colfunc = colfuncs[BASEDRAWFUNC]; colfunc = colfuncs[BASEDRAWFUNC];
@ -558,8 +571,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{ {
size_t linenum = curline->linedef-backsector->lines[0]; size_t linenum = curline->linedef-backsector->lines[0];
newline = pfloor->master->frontsector->lines[0] + linenum; newline = pfloor->master->frontsector->lines[0] + linenum;
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); sidedef = &sides[newline->sidenum[0]];
lineflags = newline->flags;
} }
else
lineflags = pfloor->master->flags;
texnum = R_GetTextureNum(sidedef->midtexture);
if (pfloor->fofflags & FOF_TRANSLUCENT) if (pfloor->fofflags & FOF_TRANSLUCENT)
{ {
@ -711,7 +729,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
walllights = scalelight[lightnum]; walllights = scalelight[lightnum];
} }
maskedtexturecol = ds->thicksidecol; wall_scalex = FixedDiv(FRACUNIT, sidedef->scalex_mid);
wall_scaley = sidedef->scaley_mid;
thicksidecol = ds->thicksidecol;
for (INT32 x = x1; x <= x2; x++)
thicksidecol[x] = FixedDiv(thicksidecol[x], wall_scalex) + ds->offsetx;
mfloorclip = ds->sprbottomclip; mfloorclip = ds->sprbottomclip;
mceilingclip = ds->sprtopclip; mceilingclip = ds->sprtopclip;
@ -721,51 +745,29 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz;
left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewz;
do_texture_skew = lineflags & ML_SKEWTD;
skewslope = *pfloor->t_slope; // skew using top slope by default skewslope = *pfloor->t_slope; // skew using top slope by default
if (newline)
{
if (newline->flags & ML_SKEWTD)
slopeskew = true;
}
else if (pfloor->master->flags & ML_SKEWTD)
slopeskew = true;
if (slopeskew) if (do_texture_skew)
dc_texturemid = left_top; dc_texturemid = FixedMul(left_top, wall_scaley);
else else
dc_texturemid = *pfloor->topheight - viewz; dc_texturemid = FixedMul(*pfloor->topheight - viewz, wall_scaley);
if (newline) offsetvalue = sidedef->rowoffset + sidedef->offsety_mid;
if (lineflags & ML_DONTPEGBOTTOM)
{ {
offsetvalue = sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid; skewslope = *pfloor->b_slope; // skew using bottom slope
if (newline->flags & ML_DONTPEGBOTTOM) if (do_texture_skew)
{ dc_texturemid = FixedMul(left_bottom, wall_scaley);
skewslope = *pfloor->b_slope; // skew using bottom slope else
if (slopeskew) offsetvalue -= FixedMul(*pfloor->topheight - *pfloor->bottomheight, wall_scaley);
dc_texturemid = left_bottom;
else
offsetvalue -= *pfloor->topheight - *pfloor->bottomheight;
}
}
else
{
offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset + sides[pfloor->master->sidenum[0]].offsety_mid;
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
{
skewslope = *pfloor->b_slope; // skew using bottom slope
if (slopeskew)
dc_texturemid = left_bottom;
else
offsetvalue -= *pfloor->topheight - *pfloor->bottomheight;
}
} }
if (slopeskew) if (do_texture_skew && 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));
if (skewslope)
ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT));
} }
dc_texturemid += offsetvalue; dc_texturemid += offsetvalue;
@ -819,7 +821,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (ffloortextureslide) if (ffloortextureslide)
{ {
if (oldx != -1) if (oldx != -1)
dc_texturemid += FixedMul(ffloortextureslide, maskedtexturecol[oldx]-maskedtexturecol[dc_x]); dc_texturemid += FixedMul(ffloortextureslide, thicksidecol[oldx]-thicksidecol[dc_x]);
oldx = dc_x; oldx = dc_x;
} }
@ -852,10 +854,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
continue; continue;
} }
dc_iscale = 0xffffffffu / (unsigned)spryscale; dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley);
// Get data for the column // Get data for the column
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); col = (column_t *)((UINT8 *)R_GetColumn(texnum, (thicksidecol[dc_x] >> FRACBITS)) - 3);
// 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.
@ -1044,13 +1046,18 @@ UINT32 nombre = 100000;
static void R_RenderSegLoop (void) static void R_RenderSegLoop (void)
{ {
angle_t angle; angle_t angle;
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 bottomtexturecolumn = 0;
fixed_t oldtexturecolumn = -1; fixed_t oldtexturecolumn = -1;
fixed_t oldtexturecolumn_top = -1;
fixed_t oldtexturecolumn_bottom = -1;
INT32 top; INT32 top;
INT32 bottom; INT32 bottom;
INT32 i; INT32 i;
@ -1217,17 +1224,8 @@ static void R_RenderSegLoop (void)
//SoM: Calculate offsets for Thick fake floors. //SoM: Calculate offsets for Thick fake floors.
// calculate texture offset // calculate texture offset
angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); textureoffset = rw_offset - FixedMul(FINETANGENT(angle), rw_distance);
texturecolumn = FixedDiv(textureoffset, rw_invmidtexturescalex);
if (oldtexturecolumn != -1) {
rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn);
rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn);
rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn);
rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn);
}
oldtexturecolumn = texturecolumn;
INT32 itexturecolumn = texturecolumn >> FRACBITS;
// texturecolumn and lighting are independent of wall tiers // texturecolumn and lighting are independent of wall tiers
if (segtextured) if (segtextured)
@ -1240,7 +1238,6 @@ static void R_RenderSegLoop (void)
dc_colormap = walllights[pindex]; dc_colormap = walllights[pindex];
dc_x = rw_x; dc_x = rw_x;
dc_iscale = 0xffffffffu / (unsigned)rw_scale;
if (frontsector->extra_colormap) if (frontsector->extra_colormap)
dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
@ -1290,10 +1287,13 @@ 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)
{ {
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_source = R_GetColumn(midtexture, itexturecolumn + (rw_offset_mid>>FRACBITS)); dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_midtexturescaley);
dc_source = R_GetColumn(midtexture, offset >> FRACBITS);
dc_texheight = textureheight[midtexture]>>FRACBITS; dc_texheight = textureheight[midtexture]>>FRACBITS;
//profile stuff --------------------------------------------------------- //profile stuff ---------------------------------------------------------
@ -1342,6 +1342,8 @@ static void R_RenderSegLoop (void)
if (mid >= floorclip[rw_x]) if (mid >= floorclip[rw_x])
mid = floorclip[rw_x]-1; mid = floorclip[rw_x]-1;
toptexturecolumn = FixedDiv(textureoffset, rw_invtoptexturescalex);
if (mid >= yl) // back ceiling lower than front ceiling ? if (mid >= yl) // back ceiling lower than front ceiling ?
{ {
if (yl >= viewheight) // entirely off bottom of screen if (yl >= viewheight) // entirely off bottom of screen
@ -1351,10 +1353,16 @@ static void R_RenderSegLoop (void)
} }
else if (mid >= 0) // safe to draw top texture else if (mid >= 0) // safe to draw top texture
{ {
fixed_t offset = rw_offset_top;
if (rw_toptexturescalex < 0)
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_source = R_GetColumn(toptexture, itexturecolumn + (rw_offset_top>>FRACBITS)); dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_toptexturescaley);
dc_source = R_GetColumn(toptexture, offset >> FRACBITS);
dc_texheight = textureheight[toptexture]>>FRACBITS; dc_texheight = textureheight[toptexture]>>FRACBITS;
colfunc(); colfunc();
ceilingclip[rw_x] = (INT16)mid; ceilingclip[rw_x] = (INT16)mid;
@ -1364,6 +1372,10 @@ static void R_RenderSegLoop (void)
} }
else if (!rw_ceilingmarked) else if (!rw_ceilingmarked)
ceilingclip[rw_x] = topclip; ceilingclip[rw_x] = topclip;
if (oldtexturecolumn_top != -1)
rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn_top-toptexturecolumn);
oldtexturecolumn_top = toptexturecolumn;
} }
else if (markceiling && (!rw_ceilingmarked)) // no top wall else if (markceiling && (!rw_ceilingmarked)) // no top wall
ceilingclip[rw_x] = topclip; ceilingclip[rw_x] = topclip;
@ -1378,6 +1390,8 @@ static void R_RenderSegLoop (void)
if (mid <= ceilingclip[rw_x]) if (mid <= ceilingclip[rw_x])
mid = ceilingclip[rw_x]+1; mid = ceilingclip[rw_x]+1;
bottomtexturecolumn = FixedDiv(textureoffset, rw_invbottomtexturescalex);
if (mid <= yh) // back floor higher than front floor ? if (mid <= yh) // back floor higher than front floor ?
{ {
if (yh < 0) // entirely off top of screen if (yh < 0) // entirely off top of screen
@ -1387,10 +1401,16 @@ static void R_RenderSegLoop (void)
} }
else if (mid < viewheight) // safe to draw bottom texture else if (mid < viewheight) // safe to draw bottom texture
{ {
fixed_t offset = rw_offset_bottom;
if (rw_bottomtexturescalex < 0)
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_source = R_GetColumn(bottomtexture, itexturecolumn + (rw_offset_bot>>FRACBITS)); dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_bottomtexturescaley);
dc_source = R_GetColumn(bottomtexture, offset >> FRACBITS);
dc_texheight = textureheight[bottomtexture]>>FRACBITS; dc_texheight = textureheight[bottomtexture]>>FRACBITS;
colfunc(); colfunc();
floorclip[rw_x] = (INT16)mid; floorclip[rw_x] = (INT16)mid;
@ -1400,24 +1420,43 @@ static void R_RenderSegLoop (void)
} }
else if (!rw_floormarked) else if (!rw_floormarked)
floorclip[rw_x] = bottomclip; floorclip[rw_x] = bottomclip;
if (oldtexturecolumn_bottom != -1)
rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn_bottom-bottomtexturecolumn);
oldtexturecolumn_bottom = bottomtexturecolumn;
} }
else if (markfloor && (!rw_floormarked)) // no bottom wall else if (markfloor && (!rw_floormarked)) // no bottom wall
floorclip[rw_x] = bottomclip; floorclip[rw_x] = bottomclip;
} }
if (maskedtexture || numthicksides) if (maskedtexturecol)
{ maskedtexturecol[rw_x] = texturecolumn + rw_offsetx;
// save texturecol
// for backdrawing of masked mid texture
maskedtexturecol[rw_x] = texturecolumn + rw_offset_mid;
if (maskedtextureheight != NULL) { if (thicksidecol)
maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ? thicksidecol[rw_x] = textureoffset;
max(rw_midtexturemid, rw_midtextureback) :
min(rw_midtexturemid, rw_midtextureback); if (maskedtextureheight)
} {
if (curline->linedef->flags & ML_MIDPEG)
maskedtextureheight[rw_x] = max(rw_midtexturemid, rw_midtextureback);
else
maskedtextureheight[rw_x] = min(rw_midtexturemid, rw_midtextureback);
} }
if (midtexture || maskedtextureheight)
{
if (oldtexturecolumn != -1)
{
rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn);
rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn);
}
oldtexturecolumn = texturecolumn;
}
if (invscale)
invscale[rw_x] = 0xffffffffu / (unsigned)rw_scale;
if (dc_numlights) if (dc_numlights)
{ {
for (i = 0; i < dc_numlights; i++) for (i = 0; i < dc_numlights; i++)
@ -1506,10 +1545,9 @@ 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;
// For both tables, we reserve exactly an amount of memory that's equivalent to if (pos + need < texturecolumntablesize)
// how many columns the seg will take on the entire screen (think about it)
if (pos + range < texturecolumntablesize)
return; return;
fixed_t *oldtable = texturecolumntable; fixed_t *oldtable = texturecolumntable;
@ -1518,7 +1556,7 @@ static void R_AllocTextureColumnTables(size_t range)
if (texturecolumntablesize == 0) if (texturecolumntablesize == 0)
texturecolumntablesize = 16384; texturecolumntablesize = 16384;
texturecolumntablesize += range; texturecolumntablesize += need;
texturecolumntable = Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL); texturecolumntable = Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL);
curtexturecolumntable = texturecolumntable + pos; curtexturecolumntable = texturecolumntable + pos;
@ -1532,6 +1570,8 @@ static void R_AllocTextureColumnTables(size_t range)
ds->maskedtexturecol = (ds->maskedtexturecol - oldtable) + texturecolumntable; ds->maskedtexturecol = (ds->maskedtexturecol - oldtable) + texturecolumntable;
if (ds->thicksidecol + ds->x1 >= oldtable && ds->thicksidecol + ds->x1 <= oldlast) if (ds->thicksidecol + ds->x1 >= oldtable && ds->thicksidecol + ds->x1 <= oldlast)
ds->thicksidecol = (ds->thicksidecol - oldtable) + texturecolumntable; ds->thicksidecol = (ds->thicksidecol - oldtable) + texturecolumntable;
if (ds->invscale + ds->x1 >= oldtable && ds->invscale + ds->x1 <= oldlast)
ds->invscale = (ds->invscale - oldtable) + texturecolumntable;
} }
} }
@ -1555,7 +1595,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide;
static size_t maxdrawsegs = 0; static size_t maxdrawsegs = 0;
maskedtexturecol = NULL;
maskedtextureheight = NULL; maskedtextureheight = NULL;
thicksidecol = NULL;
invscale = NULL;
//initialize segleft and segright //initialize segleft and segright
memset(&segleft, 0x00, sizeof(segleft)); memset(&segleft, 0x00, sizeof(segleft));
memset(&segright, 0x00, sizeof(segright)); memset(&segright, 0x00, sizeof(segright));
@ -1712,6 +1756,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->maskedtexturecol = NULL; ds_p->maskedtexturecol = 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->tsilheight = 0; ds_p->tsilheight = 0;
numbackffloors = 0; numbackffloors = 0;
@ -1751,32 +1796,67 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT));
} }
rw_midtexturescalex = sidedef->scalex_mid;
rw_midtexturescaley = sidedef->scaley_mid;
rw_invmidtexturescalex = FixedDiv(FRACUNIT, rw_midtexturescalex);
if (!backsector) if (!backsector)
{ {
fixed_t texheight;
// single sided line
midtexture = R_GetTextureNum(sidedef->midtexture); midtexture = R_GetTextureNum(sidedef->midtexture);
texheight = textureheight[midtexture];
// a single sided line is terminal, so it must mark ends // a single sided line is terminal, so it must mark ends
markfloor = markceiling = true; markfloor = markceiling = true;
if (linedef->flags & ML_NOSKEW) {
if (linedef->flags & ML_DONTPEGBOTTOM) fixed_t rowoffset = sidedef->rowoffset + sidedef->offsety_mid;
rw_midtexturemid = frontsector->floorheight + texheight - viewz; fixed_t texheight = textureheight[midtexture];
else
rw_midtexturemid = frontsector->ceilingheight - viewz; if (rw_midtexturescaley > 0)
}
else if (linedef->flags & ML_DONTPEGBOTTOM)
{ {
rw_midtexturemid = worldbottom + texheight; if (linedef->flags & ML_NOSKEW)
rw_midtextureslide = floorfrontslide; {
if (linedef->flags & ML_DONTPEGBOTTOM)
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley) + texheight;
else
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley);
}
else if (linedef->flags & ML_DONTPEGBOTTOM)
{
rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley) + texheight;
rw_midtextureslide = floorfrontslide;
}
else
{
// top of texture at top
rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley);
rw_midtextureslide = ceilingfrontslide;
}
} }
else else
{ {
// top of texture at top // Upside down
rw_midtexturemid = worldtop; rowoffset = -rowoffset;
rw_midtextureslide = ceilingfrontslide;
if (linedef->flags & ML_NOSKEW)
{
if (linedef->flags & ML_DONTPEGBOTTOM)
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley);
else
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley) + texheight;
}
else if (linedef->flags & ML_DONTPEGBOTTOM)
{
rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley);
rw_midtextureslide = floorfrontslide;
}
else
{
// top of texture at top
rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley) + texheight;
rw_midtextureslide = ceilingfrontslide;
}
} }
rw_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid;
rw_midtexturemid += rowoffset;
ds_p->silhouette = SIL_BOTH; ds_p->silhouette = SIL_BOTH;
ds_p->sprtopclip = screenheightarray; ds_p->sprtopclip = screenheightarray;
@ -1883,6 +1963,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
//SoM: 3/22/2000: Check floor x and y offsets. //SoM: 3/22/2000: Check floor x and y offsets.
|| backsector->floorxoffset != frontsector->floorxoffset || backsector->floorxoffset != frontsector->floorxoffset
|| backsector->flooryoffset != frontsector->flooryoffset || backsector->flooryoffset != frontsector->flooryoffset
|| backsector->floorxscale != frontsector->floorxscale
|| backsector->flooryscale != frontsector->flooryscale
|| backsector->floorangle != frontsector->floorangle || backsector->floorangle != frontsector->floorangle
//SoM: 3/22/2000: Prevents bleeding. //SoM: 3/22/2000: Prevents bleeding.
|| (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum) || (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum)
@ -1917,6 +1999,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
//SoM: 3/22/2000: Check floor x and y offsets. //SoM: 3/22/2000: Check floor x and y offsets.
|| backsector->ceilingxoffset != frontsector->ceilingxoffset || backsector->ceilingxoffset != frontsector->ceilingxoffset
|| backsector->ceilingyoffset != frontsector->ceilingyoffset || backsector->ceilingyoffset != frontsector->ceilingyoffset
|| backsector->ceilingxscale != frontsector->ceilingxscale
|| backsector->ceilingyscale != frontsector->ceilingyscale
|| backsector->ceilingangle != frontsector->ceilingangle || backsector->ceilingangle != frontsector->ceilingangle
//SoM: 3/22/2000: Prevents bleeding. //SoM: 3/22/2000: Prevents bleeding.
|| (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum) || (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum)
@ -1946,16 +2030,28 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} }
} }
fixed_t toprowoffset = sidedef->rowoffset + sidedef->offsety_top;
fixed_t botrowoffset = sidedef->rowoffset + sidedef->offsety_bottom;
// check TOP TEXTURE // check TOP TEXTURE
if (!bothceilingssky // never draw the top texture if on if (!bothceilingssky // never draw the top texture if on
&& (worldhigh < worldtop || worldhighslope < worldtopslope)) && (worldhigh < worldtop || worldhighslope < worldtopslope))
{ {
fixed_t texheight;
// top texture
toptexture = R_GetTextureNum(sidedef->toptexture); toptexture = R_GetTextureNum(sidedef->toptexture);
texheight = textureheight[toptexture];
if (!(linedef->flags & ML_SKEWTD)) { // Ignore slopes for lower/upper textures unless flag is checked rw_toptexturescalex = sidedef->scalex_top;
rw_toptexturescaley = sidedef->scaley_top;
rw_invtoptexturescalex = FixedDiv(FRACUNIT, rw_toptexturescalex);
if (rw_toptexturescaley < 0)
toprowoffset = -toprowoffset;
fixed_t texheight = textureheight[toptexture];
// Ignore slopes for lower/upper textures unless flag is checked
if (!(linedef->flags & ML_SKEWTD))
{
if (linedef->flags & ML_DONTPEGTOP) if (linedef->flags & ML_DONTPEGTOP)
rw_toptexturemid = frontsector->ceilingheight - viewz; rw_toptexturemid = frontsector->ceilingheight - viewz;
else else
@ -1972,7 +2068,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_toptexturemid = worldhigh + texheight; rw_toptexturemid = worldhigh + texheight;
rw_toptextureslide = ceilingbackslide; rw_toptextureslide = ceilingbackslide;
} }
rw_toptexturemid = FixedMul(rw_toptexturemid, rw_toptexturescaley);
} }
// check BOTTOM TEXTURE // check BOTTOM TEXTURE
if (!bothfloorssky // never draw the bottom texture if on if (!bothfloorssky // never draw the bottom texture if on
&& (worldlow > worldbottom || worldlowslope > worldbottomslope)) // Only if VISIBLE!!! && (worldlow > worldbottom || worldlowslope > worldbottomslope)) // Only if VISIBLE!!!
@ -1980,7 +2079,17 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// bottom texture // bottom texture
bottomtexture = R_GetTextureNum(sidedef->bottomtexture); bottomtexture = R_GetTextureNum(sidedef->bottomtexture);
if (!(linedef->flags & ML_SKEWTD)) { // Ignore slopes for lower/upper textures unless flag is checked rw_bottomtexturescalex = sidedef->scalex_bottom;
rw_bottomtexturescaley = sidedef->scaley_bottom;
rw_invbottomtexturescalex = FixedDiv(FRACUNIT, rw_bottomtexturescalex);
if (rw_bottomtexturescaley < 0)
botrowoffset = -botrowoffset;
// Ignore slopes for lower/upper textures unless flag is checked
if (!(linedef->flags & ML_SKEWTD))
{
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_DONTPEGBOTTOM)
rw_bottomtexturemid = frontsector->floorheight - viewz; rw_bottomtexturemid = frontsector->floorheight - viewz;
else else
@ -1993,18 +2102,22 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_bottomtexturemid = worldbottom; rw_bottomtexturemid = worldbottom;
rw_bottomtextureslide = floorfrontslide; rw_bottomtextureslide = floorfrontslide;
} }
else { // top of texture at top else
{
// top of texture at top
rw_bottomtexturemid = worldlow; rw_bottomtexturemid = worldlow;
rw_bottomtextureslide = floorbackslide; rw_bottomtextureslide = floorbackslide;
} }
rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, rw_bottomtexturescaley);
} }
rw_toptexturemid += sidedef->rowoffset + sidedef->offsety_top; rw_toptexturemid += toprowoffset;
rw_bottomtexturemid += sidedef->rowoffset + sidedef->offsety_bot; rw_bottomtexturemid += botrowoffset;
R_AllocTextureColumnTables(rw_stopx - start);
// allocate space for masked texture tables // allocate space for masked texture tables
R_AllocTextureColumnTables(rw_stopx - start);
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;
@ -2015,10 +2128,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// 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, high2, highslope2, low2, lowslope2; fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2;
//markceiling = markfloor = true;
maskedtexture = true; maskedtexture = true;
ds_p->thicksidecol = maskedtexturecol = curtexturecolumntable - rw_x; ds_p->thicksidecol = thicksidecol = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x; curtexturecolumntable += rw_stopx - rw_x;
lowcut = max(worldbottom, worldlow) + viewz; lowcut = max(worldbottom, worldlow) + viewz;
@ -2197,21 +2309,20 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->numthicksides = numthicksides = i; ds_p->numthicksides = numthicksides = i;
} }
// masked midtexture
if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures)
{ {
// masked midtexture ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
if (!ds_p->thicksidecol) curtexturecolumntable += rw_stopx - rw_x;
{
ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x;
}
else
ds_p->maskedtexturecol = ds_p->thicksidecol;
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0])
maskedtexture = true;
if (curline->polyseg) if (curline->polyseg)
{ // use REAL front and back floors please, so midtexture rendering isn't mucked up {
// use REAL front and back floors please, so midtexture rendering isn't mucked up
rw_midtextureslide = rw_midtexturebackslide = 0; rw_midtextureslide = rw_midtexturebackslide = 0;
if (linedef->flags & ML_MIDPEG) if (linedef->flags & ML_MIDPEG)
rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz;
@ -2222,7 +2333,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{ {
// Set midtexture starting height // Set midtexture starting height
if (linedef->flags & ML_NOSKEW) if (linedef->flags & ML_NOSKEW)
{ // Ignore slopes when texturing {
// Ignore slopes when texturing
rw_midtextureslide = rw_midtexturebackslide = 0; rw_midtextureslide = rw_midtexturebackslide = 0;
if (linedef->flags & ML_MIDPEG) if (linedef->flags & ML_MIDPEG)
rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz;
@ -2245,6 +2357,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_midtexturebackslide = ceilingbackslide; rw_midtexturebackslide = ceilingbackslide;
} }
} }
rw_midtexturemid = FixedMul(rw_midtexturemid, rw_midtexturescaley);
rw_midtextureback = FixedMul(rw_midtextureback, 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;
@ -2257,6 +2373,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (segtextured) if (segtextured)
{ {
fixed_t sideoffset = sidedef->textureoffset;
offsetangle = rw_normalangle-rw_angle1; offsetangle = rw_normalangle-rw_angle1;
if (offsetangle > ANGLE_180) if (offsetangle > ANGLE_180)
@ -2281,14 +2399,20 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (rw_normalangle-rw_angle1 < ANGLE_180) if (rw_normalangle-rw_angle1 < ANGLE_180)
rw_offset = -rw_offset; rw_offset = -rw_offset;
/// don't use texture offset for splats rw_offset += curline->offset;
rw_offset2 = rw_offset + curline->offset;
rw_offset += sidedef->textureoffset + curline->offset;
rw_offset_top = sidedef->offsetx_top;
rw_offset_mid = sidedef->offsetx_mid;
rw_offset_bot = sidedef->offsetx_bot;
rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; rw_centerangle = ANGLE_90 + viewangle - rw_normalangle;
rw_offset_top = sideoffset + sidedef->offsetx_top;
rw_offset_mid = sideoffset + sidedef->offsetx_mid;
rw_offset_bottom = sideoffset + sidedef->offsetx_bottom;
rw_offsetx = rw_offset_mid;
if (rw_midtexturescalex < 0)
rw_offsetx = -rw_offsetx;
if (numthicksides)
ds_p->offsetx = rw_offsetx;
// calculate light table // calculate light table
// use different light tables // use different light tables
// for horizontal / vertical / diagonal // for horizontal / vertical / diagonal
@ -2308,6 +2432,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
walllights = scalelight[lightnum]; walllights = scalelight[lightnum];
} }
if (maskedtexture)
{
ds_p->invscale = invscale = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x;
}
// if a floor / ceiling plane is on the wrong side // if a floor / ceiling plane is on the wrong side
// of the view plane, it is definitely invisible // of the view plane, it is definitely invisible
// and doesn't need to be marked. // and doesn't need to be marked.

View file

@ -392,7 +392,7 @@ static void SetSkin(player_t *player, INT32 skinnum)
P_SetScale(player->mo, player->mo->scale); P_SetScale(player->mo, player->mo->scale);
player->mo->radius = radius; player->mo->radius = radius;
P_SetPlayerMobjState(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

@ -369,7 +369,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
ds_flatwidth = pSplat->width; ds_flatwidth = pSplat->width;
ds_flatheight = pSplat->height; ds_flatheight = pSplat->height;
ds_powersoftwo = ds_solidcolor = false; ds_powersoftwo = ds_solidcolor = ds_fog = false;
if (R_CheckSolidColorFlat()) if (R_CheckSolidColorFlat())
ds_solidcolor = true; ds_solidcolor = true;
@ -381,9 +381,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
if (pSplat->slope) if (pSplat->slope)
{ {
R_SetTiltedSpan(0);
R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle);
R_CalculateSlopeVectors();
} }
else if (!ds_solidcolor) else if (!ds_solidcolor)
{ {
@ -391,8 +389,6 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
if (pSplat->angle) if (pSplat->angle)
{ {
memset(cachedheight, 0, sizeof(cachedheight));
// Add the view offset, rotated by the plane angle. // Add the view offset, rotated by the plane angle.
fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x; fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x;
fixed_t b = -pSplat->verts[0].y + vis->viewpoint.y; fixed_t b = -pSplat->verts[0].y + vis->viewpoint.y;
@ -547,29 +543,18 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
angle_t planecos = FINECOSINE(angle); angle_t planecos = FINECOSINE(angle);
angle_t planesin = FINESINE(angle); angle_t planesin = FINESINE(angle);
if (planeheight != cachedheight[y]) // [RH] Notice that I dumped the caching scheme used by Doom.
// It did not offer any appreciable speedup.
distance = FixedMul(planeheight, yslope[y]);
span = abs(centery - y);
if (span) // Don't divide by zero
{ {
cachedheight[y] = planeheight; xstep = FixedMul(planesin, planeheight) / span;
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]); ystep = FixedMul(planecos, planeheight) / span;
span = abs(centery - y);
if (span) // Don't divide by zero
{
xstep = FixedMul(planesin, planeheight) / span;
ystep = FixedMul(planecos, planeheight) / span;
}
else
xstep = ystep = FRACUNIT;
cachedxstep[y] = xstep;
cachedystep[y] = ystep;
} }
else else
{ xstep = ystep = FRACUNIT;
distance = cacheddistance[y];
xstep = cachedxstep[y];
ystep = cachedystep[y];
}
ds_xstep = FixedDiv(xstep, pSplat->xscale); ds_xstep = FixedDiv(xstep, pSplat->xscale);
ds_ystep = FixedDiv(ystep, pSplat->yscale); ds_ystep = FixedDiv(ystep, pSplat->yscale);
@ -586,9 +571,6 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
rastertab[y].minx = INT32_MAX; rastertab[y].minx = INT32_MAX;
rastertab[y].maxx = INT32_MIN; rastertab[y].maxx = INT32_MIN;
} }
if (!ds_solidcolor && pSplat->angle && !pSplat->slope)
memset(cachedheight, 0, sizeof(cachedheight));
} }
static void prepare_rastertab(void) static void prepare_rastertab(void)

View file

@ -98,14 +98,6 @@ UINT8 *scr_borderpatch; // flat used to fill the reduced view borders set at ST_
// Short and Tall sky drawer, for the current color mode // Short and Tall sky drawer, for the current color mode
void (*walldrawerfunc)(void); void (*walldrawerfunc)(void);
boolean R_486 = false;
boolean R_586 = false;
boolean R_MMX = false;
boolean R_SSE = false;
boolean R_3DNow = false;
boolean R_MMXExt = false;
boolean R_SSE2 = false;
void SCR_SetDrawFuncs(void) void SCR_SetDrawFuncs(void)
{ {
// //
@ -225,48 +217,6 @@ void SCR_SetMode(void)
// //
void SCR_Startup(void) void SCR_Startup(void)
{ {
const CPUInfoFlags *RCpuInfo = I_CPUInfo();
if (!M_CheckParm("-NOCPUID") && RCpuInfo)
{
#if defined (__i386__) || defined (_M_IX86) || defined (__WATCOMC__)
R_486 = true;
#endif
if (RCpuInfo->RDTSC)
R_586 = true;
if (RCpuInfo->MMX)
R_MMX = true;
if (RCpuInfo->AMD3DNow)
R_3DNow = true;
if (RCpuInfo->MMXExt)
R_MMXExt = true;
if (RCpuInfo->SSE)
R_SSE = true;
if (RCpuInfo->SSE2)
R_SSE2 = true;
CONS_Printf("CPU Info: 486: %i, 586: %i, MMX: %i, 3DNow: %i, MMXExt: %i, SSE2: %i\n", R_486, R_586, R_MMX, R_3DNow, R_MMXExt, R_SSE2);
}
if (M_CheckParm("-486"))
R_486 = true;
if (M_CheckParm("-586"))
R_586 = true;
if (M_CheckParm("-MMX"))
R_MMX = true;
if (M_CheckParm("-3DNow"))
R_3DNow = true;
if (M_CheckParm("-MMXExt"))
R_MMXExt = true;
if (M_CheckParm("-SSE"))
R_SSE = true;
if (M_CheckParm("-noSSE"))
R_SSE = false;
if (M_CheckParm("-SSE2"))
R_SSE2 = true;
M_SetupMemcpy();
if (dedicated) if (dedicated)
{ {
V_Init(); V_Init();

View file

@ -172,17 +172,6 @@ extern void (*spanfunc)(void);
extern void (*spanfuncs[SPANDRAWFUNC_MAX])(void); extern void (*spanfuncs[SPANDRAWFUNC_MAX])(void);
extern void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void); extern void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void);
// -----
// CPUID
// -----
extern boolean R_ASM;
extern boolean R_486;
extern boolean R_586;
extern boolean R_MMX;
extern boolean R_3DNow;
extern boolean R_MMXExt;
extern boolean R_SSE2;
// ---------------- // ----------------
// screen variables // screen variables
// ---------------- // ----------------

View file

@ -41,6 +41,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include <ntsecapi.h> #include <ntsecapi.h>
#undef SystemFunction036 #undef SystemFunction036
// A little more than the minimum sleep duration on Windows.
// May be incorrect for other platforms, but we don't currently have a way to
// query the scheduler granularity. SDL will do what's needed to make this as
// low as possible though.
#define MIN_SLEEP_DURATION_MS 2.1
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -138,7 +144,9 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif #endif
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#ifndef NOEXECINFO
#include <execinfo.h> #include <execinfo.h>
#endif
#include <time.h> #include <time.h>
#define UNIXBACKTRACE #define UNIXBACKTRACE
#endif #endif
@ -269,13 +277,17 @@ UINT8 keyboard_started = false;
static void write_backtrace(INT32 signal) static void write_backtrace(INT32 signal)
{ {
int fd = -1; int fd = -1;
#ifndef NOEXECINFO
size_t size; size_t size;
#endif
time_t rawtime; time_t rawtime;
struct tm timeinfo; struct tm timeinfo;
ssize_t junk; ssize_t junk;
enum { BT_SIZE = 1024, STR_SIZE = 32 }; enum { BT_SIZE = 1024, STR_SIZE = 32 };
#ifndef NOEXECINFO
void *array[BT_SIZE]; void *array[BT_SIZE];
#endif
char timestr[STR_SIZE]; char timestr[STR_SIZE];
const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n"; const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n";
@ -308,12 +320,14 @@ static void write_backtrace(INT32 signal)
CRASHLOG_WRITE(strsignal(signal)); CRASHLOG_WRITE(strsignal(signal));
CRASHLOG_WRITE("\n"); // Newline for the signal name CRASHLOG_WRITE("\n"); // Newline for the signal name
#ifndef NOEXECINFO
CRASHLOG_STDERR_WRITE("\nBacktrace:\n"); CRASHLOG_STDERR_WRITE("\nBacktrace:\n");
// Flood the output and log with the backtrace // Flood the output and log with the backtrace
size = backtrace(array, BT_SIZE); size = backtrace(array, BT_SIZE);
backtrace_symbols_fd(array, size, fd); backtrace_symbols_fd(array, size, fd);
backtrace_symbols_fd(array, size, STDERR_FILENO); backtrace_symbols_fd(array, size, STDERR_FILENO);
#endif
CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :) CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :)
(void)junk; (void)junk;
@ -638,6 +652,7 @@ void I_GetConsoleEvents(void)
else if (tty_con.cursor < sizeof (tty_con.buffer)) else if (tty_con.cursor < sizeof (tty_con.buffer))
{ {
// push regular character // push regular character
ev.type = ev_text;
ev.key = tty_con.buffer[tty_con.cursor] = key; ev.key = tty_con.buffer[tty_con.cursor] = key;
tty_con.cursor++; tty_con.cursor++;
// print the current line (this is differential) // print the current line (this is differential)
@ -2266,6 +2281,52 @@ void I_Sleep(UINT32 ms)
SDL_Delay(ms); SDL_Delay(ms);
} }
void I_SleepDuration(precise_t duration)
{
#if defined(__linux__) || defined(__FreeBSD__)
UINT64 precision = I_GetPrecisePrecision();
struct timespec ts = {
.tv_sec = duration / precision,
.tv_nsec = duration * 1000000000 / precision % 1000000000,
};
int status;
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
while (status == EINTR);
#else
UINT64 precision = I_GetPrecisePrecision();
INT32 sleepvalue = cv_sleep.value;
UINT64 delaygranularity;
precise_t cur;
precise_t dest;
{
double gran = round(((double)(precision / 1000) * sleepvalue * MIN_SLEEP_DURATION_MS));
delaygranularity = (UINT64)gran;
}
cur = I_GetPreciseTime();
dest = cur + duration;
// the reason this is not dest > cur is because the precise counter may wrap
// two's complement arithmetic is our friend here, though!
// e.g. cur 0xFFFFFFFFFFFFFFFE = -2, dest 0x0000000000000001 = 1
// 0x0000000000000001 - 0xFFFFFFFFFFFFFFFE = 3
while ((INT64)(dest - cur) > 0)
{
// If our cv_sleep value exceeds the remaining sleep duration, use the
// hard sleep function.
if (sleepvalue > 0 && (dest - cur) > delaygranularity)
{
I_Sleep(sleepvalue);
}
// Otherwise, this is a spinloop.
cur = I_GetPreciseTime();
}
#endif
}
#ifdef NEWSIGNALHANDLER #ifdef NEWSIGNALHANDLER
ATTRNORETURN static FUNCNORETURN void newsignalhandler_Warn(const char *pr) ATTRNORETURN static FUNCNORETURN void newsignalhandler_Warn(const char *pr)
{ {

View file

@ -382,10 +382,8 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
return 0; return 0;
} }
static boolean IgnoreMouse(void) static boolean ShouldIgnoreMouse(void)
{ {
if (cv_alwaysgrabmouse.value)
return false;
if (menuactive) if (menuactive)
return !M_MouseNeeded(); return !M_MouseNeeded();
if (paused || con_destlines || chat_on) if (paused || con_destlines || chat_on)
@ -393,11 +391,20 @@ static boolean IgnoreMouse(void)
if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION && if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION &&
gamestate != GS_CONTINUING && gamestate != GS_CUTSCENE) gamestate != GS_CONTINUING && gamestate != GS_CUTSCENE)
return true; return true;
if (!mousegrabbedbylua)
return true;
return false; return false;
} }
static boolean ShouldGrabMouse(void)
{
if (cv_alwaysgrabmouse.value)
return true;
if (ShouldIgnoreMouse())
return false;
if (!mousegrabbedbylua)
return false;
return true;
}
static void SDLdoGrabMouse(void) static void SDLdoGrabMouse(void)
{ {
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
@ -424,7 +431,7 @@ void I_UpdateMouseGrab(void)
{ {
if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO && window != NULL if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO && window != NULL
&& SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window && SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window
&& USE_MOUSEINPUT && !IgnoreMouse()) && USE_MOUSEINPUT && ShouldGrabMouse())
SDLdoGrabMouse(); SDLdoGrabMouse();
} }
@ -640,7 +647,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
} }
//else firsttimeonmouse = SDL_FALSE; //else firsttimeonmouse = SDL_FALSE;
if (USE_MOUSEINPUT && !IgnoreMouse()) if (USE_MOUSEINPUT && ShouldGrabMouse())
SDLdoGrabMouse(); SDLdoGrabMouse();
} }
else if (!mousefocus && !kbfocus) else if (!mousefocus && !kbfocus)
@ -686,13 +693,26 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type)
if (event.key) D_PostEvent(&event); if (event.key) D_PostEvent(&event);
} }
static void Impl_HandleTextEvent(SDL_TextInputEvent evt)
{
event_t event;
event.type = ev_text;
if (evt.text[1] != '\0')
{
// limit ourselves to ASCII for now, we can add UTF-8 support later
return;
}
event.key = evt.text[0];
D_PostEvent(&event);
}
static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
{ {
static boolean firstmove = true; static boolean firstmove = true;
if (USE_MOUSEINPUT) if (USE_MOUSEINPUT)
{ {
if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || (IgnoreMouse() && !firstmove)) if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || (!ShouldGrabMouse() && !firstmove))
{ {
SDLdoUngrabMouse(); SDLdoUngrabMouse();
firstmove = false; firstmove = false;
@ -745,7 +765,7 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type)
// this apparently makes a mouse button down event but not a mouse button up event, // this apparently makes a mouse button down event but not a mouse button up event,
// resulting in whatever key was pressed down getting "stuck" if we don't ignore it. // resulting in whatever key was pressed down getting "stuck" if we don't ignore it.
// -- Monster Iestyn (28/05/18) // -- Monster Iestyn (28/05/18)
if (SDL_GetMouseFocus() != window || IgnoreMouse()) if (SDL_GetMouseFocus() != window || ShouldIgnoreMouse())
return; return;
/// \todo inputEvent.button.which /// \todo inputEvent.button.which
@ -934,6 +954,9 @@ void I_GetEvent(void)
case SDL_KEYDOWN: case SDL_KEYDOWN:
Impl_HandleKeyboardEvent(evt.key, evt.type); Impl_HandleKeyboardEvent(evt.key, evt.type);
break; break;
case SDL_TEXTINPUT:
Impl_HandleTextEvent(evt.text);
break;
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
//if (!mouseMotionOnce) //if (!mouseMotionOnce)
Impl_HandleMouseMotionEvent(evt.motion); Impl_HandleMouseMotionEvent(evt.motion);
@ -1127,7 +1150,7 @@ void I_StartupMouse(void)
} }
else else
firsttimeonmouse = SDL_FALSE; firsttimeonmouse = SDL_FALSE;
if (cv_usemouse.value && !IgnoreMouse()) if (cv_usemouse.value && ShouldGrabMouse())
SDLdoGrabMouse(); SDLdoGrabMouse();
else else
SDLdoUngrabMouse(); SDLdoUngrabMouse();

View file

@ -2133,7 +2133,7 @@
INSTALL_PATH = "$(HOME)/Applications"; INSTALL_PATH = "$(HOME)/Applications";
JAVA_COMPILER_DEBUGGING_SYMBOLS = NO; JAVA_COMPILER_DEBUGGING_SYMBOLS = NO;
OPTIMIZATION_CFLAGS = "-O2"; OPTIMIZATION_CFLAGS = "-O2";
OTHER_CFLAGS = "-DMAC_ALERT -DUNIXCOMMON -DSDLMAIN -DHAVE_MIXER -DHAVE_PNG -D_BIG_ENDIAN -DSTDC_HEADERS -DSDL -Wall -Winline -fno-strict-aliasing"; OTHER_CFLAGS = "-DMAC_ALERT -DUNIXCOMMON -DSDLMAIN -DHAVE_MIXER -DHAVE_PNG -D_BIG_ENDIAN -DSTDC_HEADERS -DSDL -Wall -Winline -fno-strict-aliasing -fwrapv";
OTHER_REZFLAGS = ""; OTHER_REZFLAGS = "";
PREBINDING = NO; PREBINDING = NO;
PRODUCT_NAME = Srb2; PRODUCT_NAME = Srb2;

View file

@ -180,10 +180,10 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id)
if (Taggroup_Find(group, id) != (size_t)-1) if (Taggroup_Find(group, id) != (size_t)-1)
return; return;
if (! in_bit_array(tags_available, tag)) if (! in_bit_array(tags_available, (UINT16)tag))
{ {
num_tags++; num_tags++;
set_bit_array(tags_available, tag); set_bit_array(tags_available, (UINT16)tag);
} }
// Create group if empty. // Create group if empty.
@ -220,10 +220,10 @@ static void Taggroup_Add_Init(taggroup_t *garray[], const mtag_t tag, size_t id)
group = garray[(UINT16)tag]; group = garray[(UINT16)tag];
if (! in_bit_array(tags_available, tag)) if (! in_bit_array(tags_available, (UINT16)tag))
{ {
num_tags++; num_tags++;
set_bit_array(tags_available, tag); set_bit_array(tags_available, (UINT16)tag);
} }
// Create group if empty. // Create group if empty.
@ -271,7 +271,7 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id)
if (group->count == 1 && total_elements_with_tag(tag) == 1) if (group->count == 1 && total_elements_with_tag(tag) == 1)
{ {
num_tags--; num_tags--;
unset_bit_array(tags_available, tag); unset_bit_array(tags_available, (UINT16)tag);
} }
// Strip away taggroup if no elements left. // Strip away taggroup if no elements left.