Merge remote-tracking branch 'stjr/next' into dontdothisinsoftwarelol

This commit is contained in:
katsy 2021-03-31 03:15:31 -05:00
commit d1700bbf18
97 changed files with 1773 additions and 688 deletions

2
dep/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
#All folders
*.d

2
dep/FreeBSD/SDL/Debug/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/FreeBSD/SDL/Release/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Linux/SDL/Debug/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Linux/SDL/Release/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Linux64/SDL/Debug/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Linux64/SDL/Release/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/MasterClient/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/MasterServer/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Mingw/Debug/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Mingw/Release/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Mingw/SDL/Debug/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Mingw/SDL/Release/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Mingw64/Debug/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Mingw64/Release/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Mingw64/SDL/Debug/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/Mingw64/SDL/Release/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/SDL/Release/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/VC/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/VC9/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/cygwin/Debug/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/cygwin/Release/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

2
dep/dummy/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

View file

@ -1247,6 +1247,7 @@ patterns
sprite = "SPHRA0";
width = 96;
height = 192;
}
609
{
title = "Circle of Rings and Spheres (Big)";

View file

@ -276,6 +276,7 @@ set(SRB2_LUA_SOURCES
lua_hudlib.c
lua_infolib.c
lua_maplib.c
lua_taglib.c
lua_mathlib.c
lua_mobjlib.c
lua_playerlib.c

View file

@ -2,7 +2,7 @@
# GNU Make makefile for SRB2
#############################################################################
# Copyright (C) 1998-2000 by DooM Legacy Team.
# Copyright (C) 2003-2020 by Sonic Team Junior.
# Copyright (C) 2003-2021 by Sonic Team Junior.
#
# This program is free software distributed under the
# terms of the GNU General Public License, version 2.
@ -24,7 +24,9 @@
# clean
# Remove all object files
# cleandep
# Remove depend.dep
# Remove dependency files
# distclean
# Remove autogenerated files
# dll
# compile primary HW render DLL/SO
# all_dll
@ -79,6 +81,17 @@
#
#############################################################################
,=,
ifeq (,$(filter-out cleandep clean distclean,$(or $(MAKECMDGOALS),all)))
CLEANONLY=1
else ifndef SILENT
echo=@echo "$(1)"
ifndef MAKE_RESTARTS
print=$(info $(1))
endif
endif
ALL_SYSTEMS=\
PANDORA\
LINUX64\
@ -98,7 +111,7 @@ ALL_SYSTEMS=\
ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES)))
ifeq ($(OS),Windows_NT) # all windows are Windows_NT...
$(info Detected a Windows system, compiling for 32-bit MinGW SDL2...)
$(call print,Detected a Windows system$(,) compiling for 32-bit MinGW SDL2...)
# go for a 32-bit sdl mingw exe by default
MINGW=1
@ -123,7 +136,7 @@ else # if you on the *nix
new_system:=$(new_system)64
endif
$(info Detected $(system) ($(new_system))...)
$(call print,Detected $(system) ($(new_system))...)
$(new_system)=1
endif
@ -237,6 +250,12 @@ endif
MSGFMT?=msgfmt
ifdef WINDOWSHELL
COMPTIME=-..\comptime.bat
else
COMPTIME=-../comptime.sh
endif
ifndef ECHO
NASM:=@$(NASM)
REMOVE:=@$(REMOVE)
@ -251,6 +270,7 @@ ifndef ECHO
MSGFMT:=@$(MSGFMT)
UPX:=@$(UPX)
UPX_OPTS+=-q
COMPTIME:=@$(COMPTIME)
endif
ifdef NONET
@ -415,7 +435,7 @@ ifdef GCC48
else
CFLAGS+=-O0
endif
CFLAGS+= -Wall -DPARANOIA -DRANGECHECK -DPACKETDROP -DMOBJCONSISTANCY
CFLAGS+= -Wall -DPARANOIA -DRANGECHECK -DPACKETDROP
else
@ -455,7 +475,6 @@ DBGNAME?=$(EXENAME).debug
# not too sophisticated dependency
OBJS:=$(i_main_o) \
$(OBJDIR)/comptime.o \
$(OBJDIR)/string.o \
$(OBJDIR)/d_main.o \
$(OBJDIR)/d_clisrv.o \
@ -542,7 +561,10 @@ OBJS:=$(i_main_o) \
$(i_sound_o) \
$(OBJS)
DEPS:=$(patsubst $(OBJDIR)/%.o,$(DEPDIR)/%.d,$(filter %.o,$(OBJS)))
OBJS+=$(OBJDIR)/comptime.o
ifndef SILENT
ifndef ECHO
ifndef NOECHOFILENAMES
define echoName =
@ -550,6 +572,7 @@ define echoName =
endef
endif
endif
endif
# List of languages to compile.
# For reference, this is the command I use to build a srb2.pot file from the source code.
@ -562,12 +585,12 @@ OPTS+=-DGETTEXT
endif
ifdef PANDORA
all: pre-build $(BIN)/$(PNDNAME)
all: $(BIN)/$(PNDNAME)
endif
ifdef SDL
all: pre-build $(BIN)/$(EXENAME)
all: $(BIN)/$(EXENAME)
endif
ifdef DUMMY
@ -575,20 +598,15 @@ all: $(BIN)/$(EXENAME)
endif
cleandep:
$(REMOVE) $(OBJDIR)/depend.dep
$(REMOVE) $(DEPS)
$(REMOVE) comptime.h
pre-build:
ifdef WINDOWSHELL
-..\comptime.bat .
else
-@../comptime.sh .
endif
clean:
$(REMOVE) *~ *.flc
$(REMOVE) $(OBJDIR)/*.o
distclean: clean cleandep
ifdef MINGW
$(REMOVE) $(OBJDIR)/*.res
endif
@ -608,11 +626,11 @@ asm:
$(BIN)/$(EXENAME): $(POS) $(OBJS)
-$(MKDIR) $(BIN)
@echo Linking $(EXENAME)...
$(call echo,Linking $(EXENAME)...)
$(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS)
ifndef VALGRIND
ifndef NOOBJDUMP
@echo Dumping debugging info
$(call echo,Dumping debugging info)
$(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(EXENAME) > $(BIN)/$(DBGNAME).txt
ifdef WINDOWSHELL
-$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt
@ -631,10 +649,10 @@ ifndef NOUPX
-$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME)
endif
endif
@echo Build is done, please look for $(EXENAME) in $(BIN), \(checking for post steps\)
$(call echo,Build is done$(,) please look for $(EXENAME) in $(BIN)$(,) (checking for post steps))
reobjdump:
@echo Redumping debugging info
$(call echo,Redumping debugging info)
$(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(DBGNAME) > $(BIN)/$(DBGNAME).txt
ifdef WINDOWSHELL
-$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt
@ -670,24 +688,40 @@ endif
endif
#dependecy made by gcc itself !
$(OBJS):
ifndef DUMMY
-include $(OBJDIR)/depend.dep
ifndef CLEANONLY
$(call print,Checking dependency files...)
-include $(DEPS)
endif
endif
$(OBJDIR)/depend.dep:
@echo "Creating dependency file, depend.dep"
@echo > comptime.h
-$(MKDIR) $(OBJDIR)
$(CC) $(CFLAGS) -MM *.c > $(OBJDIR)/depend.ped
$(CC) $(CFLAGS) -MM $(INTERFACE)/*.c >> $(OBJDIR)/depend.ped
ifndef NOHW
$(CC) $(CFLAGS) -MM hardware/*.c >> $(OBJDIR)/depend.ped
undefine deps_rule
# windows makes it too hard !
ifndef WINDOWSHELL
ifdef echoName
define deps_rule =
@printf "%-20.20s\r" $<
endef
endif
$(CC) $(CFLAGS) -MM blua/*.c >> $(OBJDIR)/depend.ped
@sed -e 's,\(.*\)\.o: ,$(subst /,\/,$(OBJDIR))\/&,g' < $(OBJDIR)/depend.ped > $(OBJDIR)/depend.dep
$(REMOVE) $(OBJDIR)/depend.ped
@echo "Created dependency file, depend.dep"
endif
define deps_rule +=
$(CC) $(CFLAGS) -M -MF $@ -MT $(OBJDIR)/$< $<
endef
$(DEPDIR)/%.d: %.c
$(deps_rule)
$(DEPDIR)/%.d: $(INTERFACE)/%.c
$(deps_rule)
$(DEPDIR)/%.d: hardware/%.c
$(deps_rule)
$(DEPDIR)/%.d: blua/%.c
$(deps_rule)
ifdef VALGRIND
$(OBJDIR)/z_zone.o: z_zone.c
@ -695,9 +729,12 @@ $(OBJDIR)/z_zone.o: z_zone.c
$(CC) $(CFLAGS) $(WFLAGS) -DHAVE_VALGRIND $(VALGRIND_CFLAGS) -c $< -o $@
endif
$(OBJDIR)/comptime.o: comptime.c pre-build
$(echoName)
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
$(OBJDIR)/comptime.o::
ifdef echoName
@echo -- comptime.c ...
endif
$(COMPTIME) .
$(CC) $(CFLAGS) $(WFLAGS) -c comptime.c -o $@
$(BIN)/%.mo: locale/%.po
-$(MKDIR) $(BIN)

View file

@ -47,7 +47,8 @@ ifdef MACOSX
endif
# Automatically set version flag, but not if one was manually set
ifeq (,$(filter GCC%,$(.VARIABLES)))
# And don't bother if this is a clean only run
ifeq (,$(filter GCC% CLEANONLY,$(.VARIABLES)))
version:=$(shell $(CC) --version)
# check if this is in fact GCC
ifneq (,$(or $(findstring gcc,$(version)),$(findstring GCC,$(version))))
@ -60,12 +61,14 @@ ifeq (,$(filter GCC%,$(.VARIABLES)))
# If this version is not in the list, default to the latest supported
ifeq (,$(filter $(v),$(SUPPORTED_GCC_VERSIONS)))
$(info\
Your compiler version, GCC $(version), is not supported by the Makefile.\
The Makefile will assume GCC $(LATEST_GCC_VERSION).)
define line =
Your compiler version, GCC $(version), is not supported by the Makefile.
The Makefile will assume GCC $(LATEST_GCC_VERSION).))
endef
$(call print,$(line))
GCC$(subst .,,$(LATEST_GCC_VERSION))=1
else
$(info Detected GCC $(version) (GCC$(v)))
$(call print,Detected GCC $(version) (GCC$(v)))
GCC$(v)=1
endif
endif
@ -361,6 +364,7 @@ i_main_o=$(OBJDIR)/i_main.o
#set OBJDIR and BIN's starting place
OBJDIR=../objs
BIN=../bin
DEPDIR=../dep
#Nasm ASM and rm
ifdef YASM
NASM?=yasm
@ -383,6 +387,7 @@ ifdef DUMMY
INTERFACE=dummy
OBJDIR:=$(OBJDIR)/dummy
BIN:=$(BIN)/dummy
DEPDIR:=$(DEPDIR)/dummy
else
ifdef LINUX
NASMFORMAT=elf -DLINUX
@ -390,9 +395,11 @@ ifdef LINUX
ifdef LINUX64
OBJDIR:=$(OBJDIR)/Linux64
BIN:=$(BIN)/Linux64
DEPDIR:=$(DEPDIR)/Linux64
else
OBJDIR:=$(OBJDIR)/Linux
BIN:=$(BIN)/Linux
DEPDIR:=$(DEPDIR)/Linux
endif
else
ifdef FREEBSD
@ -402,6 +409,7 @@ ifdef FREEBSD
OBJDIR:=$(OBJDIR)/FreeBSD
BIN:=$(BIN)/FreeBSD
DEPDIR:=$(DEPDIR)/Linux
else
ifdef SOLARIS
INTERFACE=sdl
@ -410,6 +418,7 @@ ifdef SOLARIS
OBJDIR:=$(OBJDIR)/Solaris
BIN:=$(BIN)/Solaris
DEPDIR:=$(DEPDIR)/Solaris
else
ifdef CYGWIN32
INTERFACE=sdl
@ -418,18 +427,21 @@ ifdef CYGWIN32
OBJDIR:=$(OBJDIR)/cygwin
BIN:=$(BIN)/Cygwin
DEPDIR:=$(DEPDIR)/Cygwin
else
ifdef MINGW64
#NASMFORMAT=win64
SDL=1
OBJDIR:=$(OBJDIR)/Mingw64
BIN:=$(BIN)/Mingw64
DEPDIR:=$(DEPDIR)/Mingw64
else
ifdef MINGW
NASMFORMAT=win32
SDL=1
OBJDIR:=$(OBJDIR)/Mingw
BIN:=$(BIN)/Mingw
DEPDIR:=$(DEPDIR)/Mingw
endif
endif
endif
@ -441,6 +453,7 @@ endif
ifdef ARCHNAME
OBJDIR:=$(OBJDIR)/$(ARCHNAME)
BIN:=$(BIN)/$(ARCHNAME)
DEPDIR:=$(DEPDIR)/$(ARCHNAME)
endif
OBJDUMP_OPTS?=--wide --source --line-numbers
@ -449,14 +462,17 @@ LD=$(CC)
ifdef SDL
INTERFACE=sdl
OBJDIR:=$(OBJDIR)/SDL
DEPDIR:=$(DEPDIR)/SDL
endif
ifndef DUMMY
ifdef DEBUGMODE
OBJDIR:=$(OBJDIR)/Debug
BIN:=$(BIN)/Debug
DEPDIR:=$(DEPDIR)/Debug
else
OBJDIR:=$(OBJDIR)/Release
BIN:=$(BIN)/Release
DEPDIR:=$(DEPDIR)/Release
endif
endif

View file

@ -47,6 +47,7 @@ OBJS:=$(OBJS) \
$(OBJDIR)/lua_skinlib.o \
$(OBJDIR)/lua_thinkerlib.o \
$(OBJDIR)/lua_maplib.o \
$(OBJDIR)/lua_taglib.o \
$(OBJDIR)/lua_polyobjlib.o \
$(OBJDIR)/lua_blockmaplib.o \
$(OBJDIR)/lua_hudlib.o

View file

@ -158,7 +158,7 @@ typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NUL
/* name, defaultvalue, flags, PossibleValue, func */
#define CVAR_INIT( ... ) \
{ __VA_ARGS__, 0, NULL, NULL, {0}, 0U, (char)0, NULL }
{ __VA_ARGS__, 0, NULL, NULL, {0, {NULL}}, 0U, (char)0, NULL }
#ifdef OLD22DEMOCOMPAT
typedef struct old_demo_var old_demo_var_t;

View file

@ -360,30 +360,48 @@ static void CON_SetupColormaps(void)
for (i = 0; i < (256*15); i++, ++memorysrc)
*memorysrc = (UINT8)(i & 0xFF); // remap each color to itself...
#define colset(map, a, b, c) \
map[1] = (UINT8)a;\
map[3] = (UINT8)b;\
map[9] = (UINT8)c
#define colset(map, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
map[0x0] = (UINT8)a;\
map[0x1] = (UINT8)b;\
map[0x2] = (UINT8)c;\
map[0x3] = (UINT8)d;\
map[0x4] = (UINT8)e;\
map[0x5] = (UINT8)f;\
map[0x6] = (UINT8)g;\
map[0x7] = (UINT8)h;\
map[0x8] = (UINT8)i;\
map[0x9] = (UINT8)j;\
map[0xA] = (UINT8)k;\
map[0xB] = (UINT8)l;\
map[0xC] = (UINT8)m;\
map[0xD] = (UINT8)n;\
map[0xE] = (UINT8)o;\
map[0xF] = (UINT8)p;
colset(magentamap, 177, 178, 184);
colset(yellowmap, 82, 73, 66);
colset(lgreenmap, 97, 98, 106);
colset(bluemap, 146, 147, 155);
colset(redmap, 210, 32, 39);
colset(graymap, 6, 8, 14);
colset(orangemap, 51, 52, 57);
colset(skymap, 129, 130, 133);
colset(purplemap, 160, 161, 163);
colset(aquamap, 120, 121, 123);
colset(peridotmap, 88, 188, 190);
colset(azuremap, 144, 145, 170);
colset(brownmap, 219, 221, 224);
colset(rosymap, 200, 201, 203);
colset(invertmap, 27, 26, 22);
invertmap[26] = (UINT8)3;
// Tried to keep the colors vanilla while adding some shades in between them ~SonicX8000
// 0x1 0x3 0x9 0xF
colset(magentamap, 177, 177, 178, 178, 178, 180, 180, 180, 182, 182, 182, 182, 184, 184, 184, 185);
colset(yellowmap, 82, 82, 73, 73, 73, 64, 64, 64, 66, 66, 66, 66, 67, 67, 67, 68);
colset(lgreenmap, 96, 96, 98, 98, 98, 101, 101, 101, 104, 104, 104, 104, 106, 106, 106, 107);
colset(bluemap, 146, 146, 147, 147, 147, 149, 149, 149, 152, 152, 152, 152, 155, 155, 155, 157);
colset(redmap, 32, 32, 33, 33, 33, 35, 35, 35, 39, 39, 39, 39, 42, 42, 42, 44);
colset(graymap, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23);
colset(orangemap, 50, 50, 52, 52, 52, 54, 54, 54, 56, 56, 56, 56, 59, 59, 59, 60);
colset(skymap, 129, 129, 130, 130, 130, 131, 131, 131, 133, 133, 133, 133, 135, 135, 135, 136);
colset(purplemap, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 163, 164, 164, 164, 165);
colset(aquamap, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125);
colset(peridotmap, 72, 72, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191, 191, 191, 94);
colset(azuremap, 144, 144, 145, 145, 145, 146, 146, 146, 170, 170, 170, 170, 171, 171, 171, 172);
colset(brownmap, 219, 219, 221, 221, 221, 222, 222, 222, 224, 224, 224, 224, 227, 227, 227, 229);
colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 203, 204, 204, 204, 205);
#undef colset
// Yeah just straight up invert it like a normal person
for (i = 0x00; i <= 0x1F; i++)
invertmap[0x1F - i] = i;
// Init back colormap
CON_SetupBackColormap();
}
@ -808,6 +826,12 @@ static void CON_InputDelSelection(void)
Lock_state();
if (!input_cur)
{
Unlock_state();
return;
}
if (input_cur > input_sel)
{
start = input_sel;

View file

@ -3112,7 +3112,7 @@ consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_SAVE|CV_NETVAR, maxpl
static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}};
consvar_t cv_joindelay = CVAR_INIT ("joindelay", "10", CV_SAVE|CV_NETVAR, joindelay_cons_t, NULL);
static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}};
consvar_t cv_rejointimeout = CVAR_INIT ("rejointimeout", "Off", CV_SAVE|CV_NETVAR|CV_FLOAT, rejointimeout_cons_t, NULL);
consvar_t cv_rejointimeout = CVAR_INIT ("rejointimeout", "2", CV_SAVE|CV_NETVAR|CV_FLOAT, rejointimeout_cons_t, NULL);
static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}};
consvar_t cv_resynchattempts = CVAR_INIT ("resynchattempts", "10", CV_SAVE|CV_NETVAR, resynchattempts_cons_t, NULL);
@ -4480,70 +4480,73 @@ static INT16 Consistancy(void)
ret += P_GetRandSeed();
#ifdef MOBJCONSISTANCY
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
if (gamestate == GS_LEVEL)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue;
mo = (mobj_t *)th;
if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY))
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
ret -= mo->type;
ret += mo->x;
ret -= mo->y;
ret += mo->z;
ret -= mo->momx;
ret += mo->momy;
ret -= mo->momz;
ret += mo->angle;
ret -= mo->flags;
ret += mo->flags2;
ret -= mo->eflags;
if (mo->target)
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue;
mo = (mobj_t *)th;
if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY))
{
ret += mo->target->type;
ret -= mo->target->x;
ret += mo->target->y;
ret -= mo->target->z;
ret += mo->target->momx;
ret -= mo->target->momy;
ret += mo->target->momz;
ret -= mo->target->angle;
ret += mo->target->flags;
ret -= mo->target->flags2;
ret += mo->target->eflags;
ret -= mo->target->state - states;
ret += mo->target->tics;
ret -= mo->target->sprite;
ret += mo->target->frame;
ret -= mo->type;
ret += mo->x;
ret -= mo->y;
ret += mo->z;
ret -= mo->momx;
ret += mo->momy;
ret -= mo->momz;
ret += mo->angle;
ret -= mo->flags;
ret += mo->flags2;
ret -= mo->eflags;
if (mo->target)
{
ret += mo->target->type;
ret -= mo->target->x;
ret += mo->target->y;
ret -= mo->target->z;
ret += mo->target->momx;
ret -= mo->target->momy;
ret += mo->target->momz;
ret -= mo->target->angle;
ret += mo->target->flags;
ret -= mo->target->flags2;
ret += mo->target->eflags;
ret -= mo->target->state - states;
ret += mo->target->tics;
ret -= mo->target->sprite;
ret += mo->target->frame;
}
else
ret ^= 0x3333;
if (mo->tracer && mo->tracer->type != MT_OVERLAY)
{
ret += mo->tracer->type;
ret -= mo->tracer->x;
ret += mo->tracer->y;
ret -= mo->tracer->z;
ret += mo->tracer->momx;
ret -= mo->tracer->momy;
ret += mo->tracer->momz;
ret -= mo->tracer->angle;
ret += mo->tracer->flags;
ret -= mo->tracer->flags2;
ret += mo->tracer->eflags;
ret -= mo->tracer->state - states;
ret += mo->tracer->tics;
ret -= mo->tracer->sprite;
ret += mo->tracer->frame;
}
else
ret ^= 0xAAAA;
ret -= mo->state - states;
ret += mo->tics;
ret -= mo->sprite;
ret += mo->frame;
}
else
ret ^= 0x3333;
if (mo->tracer && mo->tracer->type != MT_OVERLAY)
{
ret += mo->tracer->type;
ret -= mo->tracer->x;
ret += mo->tracer->y;
ret -= mo->tracer->z;
ret += mo->tracer->momx;
ret -= mo->tracer->momy;
ret += mo->tracer->momz;
ret -= mo->tracer->angle;
ret += mo->tracer->flags;
ret -= mo->tracer->flags2;
ret += mo->tracer->eflags;
ret -= mo->tracer->state - states;
ret += mo->tracer->tics;
ret -= mo->tracer->sprite;
ret += mo->tracer->frame;
}
else
ret ^= 0xAAAA;
ret -= mo->state - states;
ret += mo->tics;
ret -= mo->sprite;
ret += mo->frame;
}
}
#endif

View file

@ -61,7 +61,7 @@
#include "p_local.h" // chasecam
#include "mserv.h" // ms_RoomId
#include "m_misc.h" // screenshot functionality
#include "dehacked.h" // Dehacked list test
#include "deh_tables.h" // Dehacked list test
#include "m_cond.h" // condition initialization
#include "fastcmp.h"
#include "keys.h"
@ -1072,7 +1072,7 @@ void D_SRB2Main(void)
G_LoadGameSettings();
// Test Dehacked lists
DEH_Check();
DEH_TableCheck();
// Netgame URL special case: change working dir to EXE folder.
ChangeDirForUrlHandler();

View file

@ -2130,7 +2130,7 @@ static void Command_Pause(void)
if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer)))
{
if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION))
if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) || (marathonmode && gamestate == GS_INTERMISSION))
{
CONS_Printf(M_GetText("You can't pause here.\n"));
return;

View file

@ -52,6 +52,8 @@ typedef enum
SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super
SF_NOSUPERJUMPBOOST = 1<<17, // Disable the jump boost given while super (i.e. Knuckles)
SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles)
SF_NOSHIELDABILITY = 1<<19, // Disable shield abilities
// free up to and including 1<<31
} skinflags_t;

View file

@ -1522,6 +1522,13 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_SPINFIRE5",
"S_SPINFIRE6",
"S_TEAM_SPINFIRE1",
"S_TEAM_SPINFIRE2",
"S_TEAM_SPINFIRE3",
"S_TEAM_SPINFIRE4",
"S_TEAM_SPINFIRE5",
"S_TEAM_SPINFIRE6",
// Spikes
"S_SPIKE1",
"S_SPIKE2",
@ -5015,6 +5022,7 @@ struct int_const_s const INT_CONST[] = {
{"SF_NOSUPERSPRITES",SF_NOSUPERSPRITES},
{"SF_NOSUPERJUMPBOOST",SF_NOSUPERJUMPBOOST},
{"SF_CANBUSTWALLS",SF_CANBUSTWALLS},
{"SF_NOSHIELDABILITY",SF_NOSHIELDABILITY},
// Dashmode constants
{"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD},
@ -5449,3 +5457,27 @@ struct int_const_s const INT_CONST[] = {
{NULL,0}
};
// For this to work compile-time without being in this file,
// this function would need to check sizes at runtime, without sizeof
void DEH_TableCheck(void)
{
#if defined(_DEBUG) || defined(PARANOIA)
const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*);
const size_t dehmobjs = sizeof(MOBJTYPE_LIST)/sizeof(const char*);
const size_t dehpowers = sizeof(POWERS_LIST)/sizeof(const char*);
const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*);
if (dehstates != S_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked states list, you dolt!\n(%d states defined, versus %s in the Dehacked list)\n", S_FIRSTFREESLOT, sizeu1(dehstates));
if (dehmobjs != MT_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked mobjtype list, you dolt!\n(%d mobj types defined, versus %s in the Dehacked list)\n", MT_FIRSTFREESLOT, sizeu1(dehmobjs));
if (dehpowers != NUMPOWERS)
I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers));
if (dehcolors != SKINCOLOR_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors));
#endif
}

View file

@ -72,4 +72,7 @@ extern const char *const MENUTYPES_LIST[];
extern struct int_const_s const INT_CONST[];
// Moved to this file because it can't work compile-time otherwise
void DEH_TableCheck(void);
#endif

View file

@ -645,25 +645,3 @@ void DEH_LoadDehackedLump(lumpnum_t lumpnum)
{
DEH_LoadDehackedLumpPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum), false);
}
void DEH_Check(void)
{
#if defined(_DEBUG) || defined(PARANOIA)
const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*);
const size_t dehmobjs = sizeof(MOBJTYPE_LIST)/sizeof(const char*);
const size_t dehpowers = sizeof(POWERS_LIST)/sizeof(const char*);
const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*);
if (dehstates != S_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked states list, you dolt!\n(%d states defined, versus %s in the Dehacked list)\n", S_FIRSTFREESLOT, sizeu1(dehstates));
if (dehmobjs != MT_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked mobjtype list, you dolt!\n(%d mobj types defined, versus %s in the Dehacked list)\n", MT_FIRSTFREESLOT, sizeu1(dehmobjs));
if (dehpowers != NUMPOWERS)
I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers));
if (dehcolors != SKINCOLOR_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors));
#endif
}

View file

@ -30,8 +30,6 @@ typedef enum
void DEH_LoadDehackedLump(lumpnum_t lumpnum);
void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump, boolean mainfile);
void DEH_Check(void);
fixed_t get_number(const char *word);
FUNCPRINTF void deh_warning(const char *first, ...);
void deh_strlcpy(char *dst, const char *src, size_t size, const char *warntext);

View file

@ -379,6 +379,28 @@ Needed for some lua shenanigans.
#define FIELDFROM( type, field, have, want ) \
(void *)((intptr_t)(field) - offsetof (type, have) + offsetof (type, want))
typedef UINT8 bitarray_t;
#define BIT_ARRAY_SIZE(n) (((n) + 7) >> 3)
static inline int
in_bit_array (const bitarray_t * const array, const int value)
{
return (array[value >> 3] & (1<<(value & 7)));
}
static inline void
set_bit_array (bitarray_t * const array, const int value)
{
array[value >> 3] |= (1<<(value & 7));
}
static inline void
unset_bit_array (bitarray_t * const array, const int value)
{
array[value >> 3] &= ~(1<<(value & 7));
}
#ifdef HAVE_SDL
typedef UINT64 precise_t;
#endif

View file

@ -1138,6 +1138,7 @@ static const char *credits[] = {
"Iestyn \"Monster Iestyn\" Jealous",
"William \"GuyWithThePie\" Kloppenberg",
"Alice \"Alacroix\" de Lemos",
"Logan \"Hyperchaotix\" McCloud",
"Alexander \"DrTapeworm\" Moench-Ford",
"Andrew \"Senku Niola\" Moran",
"\"MotorRoach\"",
@ -2545,28 +2546,28 @@ static void F_UnloadAlacroixGraphics(SINT8 oldttscale)
oldttscale--; // zero-based index
for (i = 0; i < TTMAX_ALACROIX; i++)
{
if(ttembl[oldttscale][i]) { Z_Free(ttembl[oldttscale][i]); ttembl[oldttscale][i] = 0; }
if(ttribb[oldttscale][i]) { Z_Free(ttribb[oldttscale][i]); ttribb[oldttscale][i] = 0; }
if(ttsont[oldttscale][i]) { Z_Free(ttsont[oldttscale][i]); ttsont[oldttscale][i] = 0; }
if(ttrobo[oldttscale][i]) { Z_Free(ttrobo[oldttscale][i]); ttrobo[oldttscale][i] = 0; }
if(tttwot[oldttscale][i]) { Z_Free(tttwot[oldttscale][i]); tttwot[oldttscale][i] = 0; }
if(ttrbtx[oldttscale][i]) { Z_Free(ttrbtx[oldttscale][i]); ttrbtx[oldttscale][i] = 0; }
if(ttsoib[oldttscale][i]) { Z_Free(ttsoib[oldttscale][i]); ttsoib[oldttscale][i] = 0; }
if(ttsoif[oldttscale][i]) { Z_Free(ttsoif[oldttscale][i]); ttsoif[oldttscale][i] = 0; }
if(ttsoba[oldttscale][i]) { Z_Free(ttsoba[oldttscale][i]); ttsoba[oldttscale][i] = 0; }
if(ttsobk[oldttscale][i]) { Z_Free(ttsobk[oldttscale][i]); ttsobk[oldttscale][i] = 0; }
if(ttsodh[oldttscale][i]) { Z_Free(ttsodh[oldttscale][i]); ttsodh[oldttscale][i] = 0; }
if(tttaib[oldttscale][i]) { Z_Free(tttaib[oldttscale][i]); tttaib[oldttscale][i] = 0; }
if(tttaif[oldttscale][i]) { Z_Free(tttaif[oldttscale][i]); tttaif[oldttscale][i] = 0; }
if(tttaba[oldttscale][i]) { Z_Free(tttaba[oldttscale][i]); tttaba[oldttscale][i] = 0; }
if(tttabk[oldttscale][i]) { Z_Free(tttabk[oldttscale][i]); tttabk[oldttscale][i] = 0; }
if(tttabt[oldttscale][i]) { Z_Free(tttabt[oldttscale][i]); tttabt[oldttscale][i] = 0; }
if(tttaft[oldttscale][i]) { Z_Free(tttaft[oldttscale][i]); tttaft[oldttscale][i] = 0; }
if(ttknib[oldttscale][i]) { Z_Free(ttknib[oldttscale][i]); ttknib[oldttscale][i] = 0; }
if(ttknif[oldttscale][i]) { Z_Free(ttknif[oldttscale][i]); ttknif[oldttscale][i] = 0; }
if(ttknba[oldttscale][i]) { Z_Free(ttknba[oldttscale][i]); ttknba[oldttscale][i] = 0; }
if(ttknbk[oldttscale][i]) { Z_Free(ttknbk[oldttscale][i]); ttknbk[oldttscale][i] = 0; }
if(ttkndh[oldttscale][i]) { Z_Free(ttkndh[oldttscale][i]); ttkndh[oldttscale][i] = 0; }
if(ttembl[oldttscale][i]) { Patch_Free(ttembl[oldttscale][i]); ttembl[oldttscale][i] = 0; }
if(ttribb[oldttscale][i]) { Patch_Free(ttribb[oldttscale][i]); ttribb[oldttscale][i] = 0; }
if(ttsont[oldttscale][i]) { Patch_Free(ttsont[oldttscale][i]); ttsont[oldttscale][i] = 0; }
if(ttrobo[oldttscale][i]) { Patch_Free(ttrobo[oldttscale][i]); ttrobo[oldttscale][i] = 0; }
if(tttwot[oldttscale][i]) { Patch_Free(tttwot[oldttscale][i]); tttwot[oldttscale][i] = 0; }
if(ttrbtx[oldttscale][i]) { Patch_Free(ttrbtx[oldttscale][i]); ttrbtx[oldttscale][i] = 0; }
if(ttsoib[oldttscale][i]) { Patch_Free(ttsoib[oldttscale][i]); ttsoib[oldttscale][i] = 0; }
if(ttsoif[oldttscale][i]) { Patch_Free(ttsoif[oldttscale][i]); ttsoif[oldttscale][i] = 0; }
if(ttsoba[oldttscale][i]) { Patch_Free(ttsoba[oldttscale][i]); ttsoba[oldttscale][i] = 0; }
if(ttsobk[oldttscale][i]) { Patch_Free(ttsobk[oldttscale][i]); ttsobk[oldttscale][i] = 0; }
if(ttsodh[oldttscale][i]) { Patch_Free(ttsodh[oldttscale][i]); ttsodh[oldttscale][i] = 0; }
if(tttaib[oldttscale][i]) { Patch_Free(tttaib[oldttscale][i]); tttaib[oldttscale][i] = 0; }
if(tttaif[oldttscale][i]) { Patch_Free(tttaif[oldttscale][i]); tttaif[oldttscale][i] = 0; }
if(tttaba[oldttscale][i]) { Patch_Free(tttaba[oldttscale][i]); tttaba[oldttscale][i] = 0; }
if(tttabk[oldttscale][i]) { Patch_Free(tttabk[oldttscale][i]); tttabk[oldttscale][i] = 0; }
if(tttabt[oldttscale][i]) { Patch_Free(tttabt[oldttscale][i]); tttabt[oldttscale][i] = 0; }
if(tttaft[oldttscale][i]) { Patch_Free(tttaft[oldttscale][i]); tttaft[oldttscale][i] = 0; }
if(ttknib[oldttscale][i]) { Patch_Free(ttknib[oldttscale][i]); ttknib[oldttscale][i] = 0; }
if(ttknif[oldttscale][i]) { Patch_Free(ttknif[oldttscale][i]); ttknif[oldttscale][i] = 0; }
if(ttknba[oldttscale][i]) { Patch_Free(ttknba[oldttscale][i]); ttknba[oldttscale][i] = 0; }
if(ttknbk[oldttscale][i]) { Patch_Free(ttknbk[oldttscale][i]); ttknbk[oldttscale][i] = 0; }
if(ttkndh[oldttscale][i]) { Patch_Free(ttkndh[oldttscale][i]); ttkndh[oldttscale][i] = 0; }
}
ttloaded[oldttscale] = false;
}

View file

@ -1678,7 +1678,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
// At this point, cmd doesn't contain the final angle yet,
// So we need to temporarily transform it so Lua scripters
// don't need to handle it differently than in other hooks.
if (gamestate == GS_LEVEL)
if (addedtogame && gamestate == GS_LEVEL)
{
INT16 extra = ticcmd_oldangleturn[forplayer] - player->oldrelangleturn;
INT16 origangle = cmd->angleturn;
@ -2291,14 +2291,21 @@ void G_Ticker(boolean run)
{
if (playeringame[i])
{
INT16 received;
G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1);
received = (players[i].cmd.angleturn & TICCMD_RECEIVED);
players[i].angleturn += players[i].cmd.angleturn - players[i].oldrelangleturn;
players[i].oldrelangleturn = players[i].cmd.angleturn;
if (P_ControlStyle(&players[i]) == CS_LMAOGALOG)
P_ForceLocalAngle(&players[i], players[i].angleturn << 16);
else
players[i].cmd.angleturn = players[i].angleturn;
players[i].cmd.angleturn &= ~TICCMD_RECEIVED;
players[i].cmd.angleturn |= received;
}
}

View file

@ -108,7 +108,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
//Hurdler: 25/04/2000: now support colormap in hardware mode
if (mipmap->colormap)
texel = mipmap->colormap[texel];
texel = mipmap->colormap->data[texel];
// hope compiler will get this switch out of the loops (dreams...)
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
@ -218,7 +218,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
//Hurdler: 25/04/2000: now support colormap in hardware mode
if (mipmap->colormap)
texel = mipmap->colormap[texel];
texel = mipmap->colormap->data[texel];
// hope compiler will get this switch out of the loops (dreams...)
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
@ -659,7 +659,10 @@ void HWR_FreeTextureColormaps(patch_t *patch)
// Free image data from memory.
if (next->data)
Z_Free(next->data);
if (next->colormap)
Z_Free(next->colormap);
next->data = NULL;
next->colormap = NULL;
HWD.pfnDeleteTexture(next);
// Free the old colormap mipmap from memory.
@ -667,16 +670,29 @@ void HWR_FreeTextureColormaps(patch_t *patch)
}
}
static boolean FreeTextureCallback(void *mem)
{
patch_t *patch = (patch_t *)mem;
HWR_FreeTexture(patch);
return false;
}
static boolean FreeColormapsCallback(void *mem)
{
patch_t *patch = (patch_t *)mem;
HWR_FreeTextureColormaps(patch);
return false;
}
static void HWR_FreePatchCache(boolean freeall)
{
INT32 i;
boolean (*callback)(void *mem) = FreeTextureCallback;
for (i = 0; i < numwadfiles; i++)
{
INT32 j = 0;
for (; j < wadfiles[i]->numlumps; j++)
(freeall ? HWR_FreeTexture : HWR_FreeTextureColormaps)(wadfiles[i]->patchcache[j]);
}
if (!freeall)
callback = FreeColormapsCallback;
Z_IterateTags(PU_PATCH, PU_PATCH_ROTATED, callback);
Z_IterateTags(PU_SPRITE, PU_HUDGFX, callback);
}
// free all textures after each level
@ -850,7 +866,7 @@ static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum)
}
// Download a Doom 'flat' to the hardware cache and make it ready for use
void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum)
void HWR_GetRawFlat(lumpnum_t flatlumpnum)
{
GLMipmap_t *grmip;
patch_t *patch;
@ -879,7 +895,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
return;
if (levelflat->type == LEVELFLAT_FLAT)
HWR_LiterallyGetFlat(levelflat->u.flat.lumpnum);
HWR_GetRawFlat(levelflat->u.flat.lumpnum);
else if (levelflat->type == LEVELFLAT_TEXTURE)
{
GLMapTexture_t *grtex;
@ -918,15 +934,17 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
#ifndef NO_PNG_LUMPS
else if (levelflat->type == LEVELFLAT_PNG)
{
INT32 pngwidth = 0, pngheight = 0;
GLMipmap_t *mipmap = levelflat->mipmap;
UINT8 *flat;
size_t size;
// Cache the picture.
if (!levelflat->picture)
if (!levelflat->mippic)
{
levelflat->picture = Picture_PNGConvert(W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE), PICFMT_FLAT, &pngwidth, &pngheight, NULL, NULL, W_LumpLength(levelflat->u.flat.lumpnum), NULL, 0);
INT32 pngwidth = 0, pngheight = 0;
void *pic = Picture_PNGConvert(W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE), PICFMT_FLAT, &pngwidth, &pngheight, NULL, NULL, W_LumpLength(levelflat->u.flat.lumpnum), NULL, 0);
Z_ChangeTag(pic, PU_LEVEL);
Z_SetUser(pic, &levelflat->mippic);
levelflat->width = (UINT16)pngwidth;
levelflat->height = (UINT16)pngheight;
}
@ -934,7 +952,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
// Make the mipmap.
if (mipmap == NULL)
{
mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_LEVEL, NULL);
mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_STATIC, NULL);
mipmap->format = GL_TEXFMT_P_8;
mipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
levelflat->mipmap = mipmap;
@ -942,17 +960,22 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
if (!mipmap->data && !mipmap->downloaded)
{
UINT8 *flat;
size_t size;
if (levelflat->mippic == NULL)
I_Error("HWR_GetLevelFlat: levelflat->mippic == NULL");
mipmap->width = levelflat->width;
mipmap->height = levelflat->height;
size = (mipmap->width * mipmap->height);
flat = Z_Malloc(size, PU_LEVEL, &mipmap->data);
if (levelflat->picture == NULL)
I_Error("HWR_GetLevelFlat: levelflat->picture == NULL");
M_Memcpy(flat, levelflat->picture, size);
M_Memcpy(flat, levelflat->mippic, size);
}
// Tell the hardware driver to bind the current texture to the flat's mipmap
HWD.pfnSetTexture(mipmap);
HWR_SetCurrentTexture(mipmap);
}
#endif
else // set no texture
@ -977,8 +1000,28 @@ static void HWR_LoadPatchMipmap(patch_t *patch, GLMipmap_t *grMipmap)
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
}
// ----------------------+
// HWR_UpdatePatchMipmap : Updates a mipmap.
// ----------------------+
static void HWR_UpdatePatchMipmap(patch_t *patch, GLMipmap_t *grMipmap)
{
GLPatch_t *grPatch = patch->hardware;
HWR_MakePatch(patch, grPatch, grMipmap, true);
// If hardware does not have the texture, then call pfnSetTexture to upload it
// If it does have the texture, then call pfnUpdateTexture to update it
if (!grMipmap->downloaded)
HWD.pfnSetTexture(grMipmap);
else
HWD.pfnUpdateTexture(grMipmap);
HWR_SetCurrentTexture(grMipmap);
// The system-memory data can be purged now.
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
}
// -----------------+
// HWR_GetPatch : Download a patch to the hardware cache and make it ready for use
// HWR_GetPatch : Downloads a patch to the hardware cache and make it ready for use
// -----------------+
void HWR_GetPatch(patch_t *patch)
{
@ -1006,14 +1049,20 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
return;
}
// search for the mimmap
// search for the mipmap
// skip the first (no colormap translated)
for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; )
{
grMipmap = grMipmap->nextcolormap;
if (grMipmap->colormap == colormap)
if (grMipmap->colormap && grMipmap->colormap->source == colormap)
{
HWR_LoadPatchMipmap(patch, grMipmap);
if (memcmp(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8)))
{
M_Memcpy(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_UpdatePatchMipmap(patch, grMipmap);
}
else
HWR_LoadPatchMipmap(patch, grMipmap);
return;
}
}
@ -1029,7 +1078,10 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
I_Error("%s: Out of memory", "HWR_GetMappedPatch");
grMipmap->nextcolormap = newMipmap;
newMipmap->colormap = colormap;
newMipmap->colormap = Z_Calloc(sizeof(*newMipmap->colormap), PU_HWRPATCHCOLMIPMAP, NULL);
newMipmap->colormap->source = colormap;
M_Memcpy(newMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_LoadPatchMipmap(patch, newMipmap);
}
@ -1039,7 +1091,6 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch)
return;
Z_ChangeTag(gpatch->mipmap->data, PU_HWRCACHE_UNLOCKED);
Z_ChangeTag(gpatch, PU_HWRPATCHINFO_UNLOCKED);
}
static const INT32 picmode2GR[] =

View file

@ -39,45 +39,53 @@ typedef enum GLTextureFormat_e
GL_TEXFMT_ALPHA_INTENSITY_88 = 0x22,
} GLTextureFormat_t;
// data holds the address of the graphics data cached in heap memory
// NULL if the texture is not in Doom heap cache.
// Colormap structure for mipmaps.
struct GLColormap_s
{
const UINT8 *source;
UINT8 data[256];
};
typedef struct GLColormap_s GLColormap_t;
// Texture information (misleadingly named "mipmap" all over the code.)
// The *data pointer holds the address of the graphics data cached in heap memory.
// NULL if the texture is not in SRB2's heap cache.
struct GLMipmap_s
{
// for TexDownloadMipMap
// for UpdateTexture
GLTextureFormat_t format;
void *data;
UINT32 flags;
UINT16 height;
UINT16 width;
UINT32 downloaded; // The GPU has this texture.
UINT32 downloaded; // The GPU has this texture.
struct GLMipmap_s *nextcolormap;
const UINT8 *colormap;
struct GLMipmap_s *nextmipmap; // Linked list of all textures
struct GLColormap_s *colormap;
};
typedef struct GLMipmap_s GLMipmap_t;
//
// Doom texture info, as cached for hardware rendering
// Level textures, as cached for hardware rendering.
//
struct GLMapTexture_s
{
GLMipmap_t mipmap;
float scaleX; //used for scaling textures on walls
float scaleX; // Used for scaling textures on walls
float scaleY;
};
typedef struct GLMapTexture_s GLMapTexture_t;
// a cached patch as converted to hardware format
// Patch information for the hardware renderer.
struct GLPatch_s
{
float max_s,max_t;
GLMipmap_t *mipmap;
} ATTRPACK;
GLMipmap_t *mipmap; // Texture data. Allocated whenever the patch is.
float max_s, max_t;
};
typedef struct GLPatch_s GLPatch_t;
#endif //_HWR_DATA_

View file

@ -255,7 +255,16 @@ enum ETextureFlags
TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0
};
typedef struct GLMipmap_s FTextureInfo;
struct FTextureInfo
{
UINT32 width, height;
UINT32 downloaded;
UINT32 format;
struct GLMipmap_s *texture;
struct FTextureInfo *prev, *next;
};
typedef struct FTextureInfo FTextureInfo;
// jimita 14032019
struct FLightInfo

View file

@ -437,18 +437,9 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
if (!(option & V_SCALEPATCHMASK))
{
// if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT)
// cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre
if (cx >= -0.1f && cx <= 0.1f && gpatch->width == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && gpatch->height == BASEVIDHEIGHT)
{
const column_t *column = (const column_t *)((const UINT8 *)(gpatch->columns) + (gpatch->columnofs[0]));
if (!column->topdelta)
{
const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
}
}
// if it's meant to cover the whole screen, black out the rest
// no the patch is cropped do not do this ever
// centre screen
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
@ -470,11 +461,11 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
fwidth = w;
fheight = h;
if (fwidth > gpatch->width)
fwidth = gpatch->width;
if (sx + w > gpatch->width)
fwidth = gpatch->width - sx;
if (fheight > gpatch->height)
fheight = gpatch->height;
if (sy + h > gpatch->height)
fheight = gpatch->height - sy;
if (pscale != FRACUNIT)
{
@ -506,13 +497,13 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
v[0].s = v[3].s = ((sx)/(float)(gpatch->width))*hwrPatch->max_s;
if (sx + w > gpatch->width)
v[2].s = v[1].s = hwrPatch->max_s - ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s;
v[2].s = v[1].s = hwrPatch->max_s;
else
v[2].s = v[1].s = ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s;
v[0].t = v[1].t = ((sy)/(float)(gpatch->height))*hwrPatch->max_t;
if (sy + h > gpatch->height)
v[2].t = v[3].t = hwrPatch->max_t - ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t;
v[2].t = v[3].t = hwrPatch->max_t;
else
v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t;
@ -639,7 +630,7 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum
v[0].t = v[1].t = (float)((y & flatflag)/dflatsize);
v[2].t = v[3].t = (float)(v[0].t + h/dflatsize);
HWR_LiterallyGetFlat(flatlumpnum);
HWR_GetRawFlat(flatlumpnum);
//Hurdler: Boris, the same comment as above... but maybe for pics
// it not a problem since they don't have any transparent pixel

View file

@ -40,13 +40,12 @@ EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutV
EXPORT void HWRAPI(RenderSkyDome) (gl_sky_t *sky);
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor);
EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(DeleteTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data);
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
EXPORT void HWRAPI(ClearMipMapCache) (void);
EXPORT void HWRAPI(ClearCacheList) (void);
//Hurdler: added for backward compatibility
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
@ -101,7 +100,6 @@ struct hwdriver_s
ReadRect pfnReadRect;
GClipRect pfnGClipRect;
ClearMipMapCache pfnClearMipMapCache;
ClearCacheList pfnClearCacheList;
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility
DrawModel pfnDrawModel;
CreateModelVBOs pfnCreateModelVBOs;

View file

@ -118,7 +118,7 @@ patch_t *HWR_GetPic(lumpnum_t lumpnum);
GLMapTexture_t *HWR_GetTexture(INT32 tex);
void HWR_GetLevelFlat(levelflat_t *levelflat);
void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum);
void HWR_GetRawFlat(lumpnum_t flatlumpnum);
void HWR_FreeTexture(patch_t *patch);
void HWR_FreeTextureData(patch_t *patch);

View file

@ -253,6 +253,7 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_SIGN
&lspr[NOLIGHT], // SPR_SPIK
&lspr[NOLIGHT], // SPR_SFLM
&lspr[NOLIGHT], // SPR_TFLM
&lspr[NOLIGHT], // SPR_USPK
&lspr[NOLIGHT], // SPR_WSPK
&lspr[NOLIGHT], // SPR_WSPB

View file

@ -3665,7 +3665,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean precip)
{
if (cv_glspritebillboarding.value
&& spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)
&& spr && spr->mobj && !R_ThingIsPaperSprite(spr->mobj)
&& wallVerts)
{
float basey = FIXED_TO_FLOAT(spr->mobj->z);
@ -3707,7 +3707,6 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
FBITFIELD blend = 0;
FBITFIELD occlusion;
boolean use_linkdraw_hack = false;
boolean splat = R_ThingIsFloorSprite(spr->mobj);
UINT8 alpha;
INT32 i;
@ -3766,22 +3765,19 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
baseWallVerts[0].t = baseWallVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t;
}
if (!splat)
{
// if it has a dispoffset, push it a little towards the camera
if (spr->dispoffset) {
float co = -gl_viewcos*(0.05f*spr->dispoffset);
float si = -gl_viewsin*(0.05f*spr->dispoffset);
baseWallVerts[0].z = baseWallVerts[3].z = baseWallVerts[0].z+si;
baseWallVerts[1].z = baseWallVerts[2].z = baseWallVerts[1].z+si;
baseWallVerts[0].x = baseWallVerts[3].x = baseWallVerts[0].x+co;
baseWallVerts[1].x = baseWallVerts[2].x = baseWallVerts[1].x+co;
}
// Let dispoffset work first since this adjust each vertex
HWR_RotateSpritePolyToAim(spr, baseWallVerts, false);
// if it has a dispoffset, push it a little towards the camera
if (spr->dispoffset) {
float co = -gl_viewcos*(0.05f*spr->dispoffset);
float si = -gl_viewsin*(0.05f*spr->dispoffset);
baseWallVerts[0].z = baseWallVerts[3].z = baseWallVerts[0].z+si;
baseWallVerts[1].z = baseWallVerts[2].z = baseWallVerts[1].z+si;
baseWallVerts[0].x = baseWallVerts[3].x = baseWallVerts[0].x+co;
baseWallVerts[1].x = baseWallVerts[2].x = baseWallVerts[1].x+co;
}
// Let dispoffset work first since this adjust each vertex
HWR_RotateSpritePolyToAim(spr, baseWallVerts, false);
realtop = top = baseWallVerts[3].y;
realbot = bot = baseWallVerts[0].y;
ttop = baseWallVerts[3].t;
@ -3914,7 +3910,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
// The x and y only need to be adjusted in the case that it's not a papersprite
if (cv_glspritebillboarding.value
&& spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE))
&& spr->mobj && !R_ThingIsPaperSprite(spr->mobj))
{
// Get the x and z of the vertices so billboarding draws correctly
realheight = realbot - realtop;
@ -3983,7 +3979,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
static void HWR_DrawSprite(gl_vissprite_t *spr)
{
FOutVector wallVerts[4];
patch_t *gpatch; // sprite patch converted to hardware
patch_t *gpatch;
FSurfaceInfo Surf;
const boolean splat = R_ThingIsFloorSprite(spr->mobj);
@ -4284,7 +4280,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
{
FBITFIELD blend = 0;
FOutVector wallVerts[4];
patch_t *gpatch; // sprite patch converted to hardware
patch_t *gpatch;
FSurfaceInfo Surf;
if (!spr->mobj)
@ -4337,7 +4333,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
// Always use the light at the top instead of whatever I was doing before
INT32 light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false);
if (!(spr->mobj->frame & FF_FULLBRIGHT))
if (!R_ThingIsFullBright(spr->mobj))
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
if (*sector->lightlist[light].extra_colormap)
@ -4345,7 +4341,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
}
else
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
if (!R_ThingIsFullBright(spr->mobj))
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (sector->extra_colormap)
@ -4921,8 +4917,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
angle_t ang;
INT32 heightsec, phs;
const boolean papersprite = R_ThingIsPaperSprite(thing);
const boolean splat = R_ThingIsFloorSprite(thing);
const boolean papersprite = (R_ThingIsPaperSprite(thing) && !splat);
angle_t mobjangle = (thing->player ? thing->player->drawangle : thing->angle);
float z1, z2;
@ -5295,7 +5291,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE);
}
else
vis->colormap = colormaps;
vis->colormap = NULL;
// set top/bottom coords
vis->gzt = gzt;
@ -5396,7 +5392,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->flip = flip;
vis->mobj = (mobj_t *)thing;
vis->colormap = colormaps;
vis->colormap = NULL;
// set top/bottom coords
vis->gzt = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset);

View file

@ -158,7 +158,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
jmp_buf jmpbuf;
#endif
#endif
png_FILE_p png_FILE;
volatile png_FILE_p png_FILE;
//Filename checking fixed ~Monster Iestyn and Golden
char *pngfilename = va("%s"PATHSEP"models"PATHSEP"%s", srb2home, filename);
@ -1106,11 +1106,19 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; )
{
grMipmap = grMipmap->nextcolormap;
if (grMipmap->colormap == colormap)
if (grMipmap->colormap && grMipmap->colormap->source == colormap)
{
if (grMipmap->downloaded && grMipmap->data)
{
HWD.pfnSetTexture(grMipmap); // found the colormap, set it to the correct texture
if (memcmp(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8)))
{
M_Memcpy(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_CreateBlendedTexture(patch, blendpatch, grMipmap, skinnum, color);
HWD.pfnUpdateTexture(grMipmap);
}
else
HWD.pfnSetTexture(grMipmap); // found the colormap, set it to the correct texture
Z_ChangeTag(grMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED);
return;
}
@ -1128,7 +1136,10 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetBlendedTexture");
grMipmap->nextcolormap = newMipmap;
newMipmap->colormap = colormap;
newMipmap->colormap = Z_Calloc(sizeof(*newMipmap->colormap), PU_HWRPATCHCOLMIPMAP, NULL);
newMipmap->colormap->source = colormap;
M_Memcpy(newMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_CreateBlendedTexture(patch, blendpatch, newMipmap, skinnum, color);
@ -1303,7 +1314,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
if (!(spr->mobj->frame & FF_FULLBRIGHT))
if (!R_ThingIsFullBright(spr->mobj))
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
if (*sector->lightlist[light].extra_colormap)
@ -1311,7 +1322,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
}
else
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
if (!R_ThingIsFullBright(spr->mobj))
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (sector->extra_colormap)
@ -1329,10 +1340,9 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL;
INT32 durs = spr->mobj->state->tics;
INT32 tics = spr->mobj->tics;
//mdlframe_t *next = NULL;
const boolean papersprite = (spr->mobj->frame & FF_PAPERSPRITE);
const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP));
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !(spr->mobj->frame & FF_HORIZONTALFLIP));
const boolean papersprite = (R_ThingIsPaperSprite(spr->mobj) && !R_ThingIsFloorSprite(spr->mobj));
const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj));
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj));
spritedef_t *sprdef;
spriteframe_t *sprframe;
spriteinfo_t *sprinfo;
@ -1394,6 +1404,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|| ((!hwrBlendPatch->mipmap->format || !hwrBlendPatch->mipmap->downloaded) && !md2->noblendfile)))
md2_loadBlendTexture(md2);
// Load it again, because it isn't being loaded into blendgpatch after md2_loadblendtexture...
blendgpatch = md2->blendgrpatch;
if (blendgpatch)
hwrBlendPatch = ((GLPatch_t *)blendgpatch->hardware);
if (md2->error)
return false; // we already failed loading this before :(
if (!md2->model)

View file

@ -58,8 +58,9 @@ static GLuint tex_downloaded = 0;
static GLfloat fov = 90.0f;
static FBITFIELD CurrentPolyFlags;
static FTextureInfo *gl_cachetail = NULL;
static FTextureInfo *gl_cachehead = NULL;
// Linked list of all textures.
static FTextureInfo *TexCacheTail = NULL;
static FTextureInfo *TexCacheHead = NULL;
RGBA_t myPaletteData[256];
GLint screen_width = 0; // used by Draw2DLine()
@ -961,8 +962,6 @@ EXPORT boolean HWRAPI(CompileShaders) (void)
}
}
SetShader(SHADER_DEFAULT);
return true;
#else
return false;
@ -1287,10 +1286,30 @@ void SetStates(void)
// -----------------+
// DeleteTexture : Deletes a texture from the GPU and frees its data
// -----------------+
EXPORT void HWRAPI(DeleteTexture) (FTextureInfo *pTexInfo)
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo)
{
if (pTexInfo->downloaded)
FTextureInfo *head = TexCacheHead;
if (!pTexInfo)
return;
else if (pTexInfo->downloaded)
pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded);
while (head)
{
if (head->downloaded == pTexInfo->downloaded)
{
if (head->next)
head->next->prev = head->prev;
if (head->prev)
head->prev->next = head->next;
free(head);
break;
}
head = head->next;
}
pTexInfo->downloaded = 0;
}
@ -1303,26 +1322,29 @@ void Flush(void)
{
//GL_DBG_Printf ("HWR_Flush()\n");
while (gl_cachehead)
while (TexCacheHead)
{
DeleteTexture(gl_cachehead);
gl_cachehead = gl_cachehead->nextmipmap;
FTextureInfo *pTexInfo = TexCacheHead;
GLMipmap_t *texture = pTexInfo->texture;
if (pTexInfo->downloaded)
{
pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded);
pTexInfo->downloaded = 0;
}
if (texture)
texture->downloaded = 0;
TexCacheHead = pTexInfo->next;
free(pTexInfo);
}
ClearCacheList(); //Hurdler: well, gl_cachehead is already NULL
TexCacheTail = TexCacheHead = NULL; //Hurdler: well, TexCacheHead is already NULL
tex_downloaded = 0;
}
// -----------------+
// ClearCacheList : Clears the texture cache tail and head
// -----------------+
EXPORT void HWRAPI(ClearCacheList) (void)
{
gl_cachetail = gl_cachehead = NULL;
}
// -----------------+
// isExtAvailable : Look if an OpenGL extension is available
// Returns : true if extension available
@ -1718,7 +1740,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
// -----------------+
// UpdateTexture : Updates the texture data.
// -----------------+
EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
{
// Download a mipmap
boolean updatemipmap = true;
@ -1920,7 +1942,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
// -----------------+
// SetTexture : The mipmap becomes the current texture source
// -----------------+
EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *pTexInfo)
{
if (!pTexInfo)
{
@ -1937,17 +1959,25 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
}
else
{
FTextureInfo *newTex = calloc(1, sizeof (*newTex));
UpdateTexture(pTexInfo);
pTexInfo->nextmipmap = NULL;
newTex->texture = pTexInfo;
newTex->downloaded = (UINT32)pTexInfo->downloaded;
newTex->width = (UINT32)pTexInfo->width;
newTex->height = (UINT32)pTexInfo->height;
newTex->format = (UINT32)pTexInfo->format;
// insertion at the tail
if (gl_cachetail)
if (TexCacheTail)
{
gl_cachetail->nextmipmap = pTexInfo;
gl_cachetail = pTexInfo;
newTex->prev = TexCacheTail;
TexCacheTail->next = newTex;
TexCacheTail = newTex;
}
else // initialization of the linked list
gl_cachetail = gl_cachehead = pTexInfo;
TexCacheTail = TexCacheHead = newTex;
}
}
@ -3011,7 +3041,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
EXPORT INT32 HWRAPI(GetTextureUsed) (void)
{
FTextureInfo *tmp = gl_cachehead;
FTextureInfo *tmp = TexCacheHead;
INT32 res = 0;
while (tmp)
@ -3028,7 +3058,7 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void)
// Add it up!
res += tmp->height*tmp->width*bpp;
tmp = tmp->nextmipmap;
tmp = tmp->next;
}
return res;

View file

@ -98,6 +98,7 @@ patch_t *emeraldpics[3][8]; // 0 = normal, 1 = tiny, 2 = coinbox
static patch_t *emblemicon;
patch_t *tokenicon;
static patch_t *exiticon;
static patch_t *nopingicon;
//-------------------------------------------
// misc vars
@ -286,6 +287,7 @@ void HU_LoadGraphics(void)
emblemicon = W_CachePatchName("EMBLICON", PU_HUDGFX);
tokenicon = W_CachePatchName("TOKNICON", PU_HUDGFX);
exiticon = W_CachePatchName("EXITICON", PU_HUDGFX);
nopingicon = W_CachePatchName("NOPINGICON", PU_HUDGFX);
emeraldpics[0][0] = W_CachePatchName("CHAOS1", PU_HUDGFX);
emeraldpics[0][1] = W_CachePatchName("CHAOS2", PU_HUDGFX);
@ -2109,15 +2111,18 @@ void HU_Drawer(void)
return;
// draw the crosshair, not when viewing demos nor with chasecam
if (!automapactive && cv_crosshair.value && !demoplayback &&
(!camera.chase || ticcmd_ztargetfocus[0])
&& !players[displayplayer].spectator)
HU_DrawCrosshair();
if (LUA_HudEnabled(hud_crosshair))
{
if (!automapactive && cv_crosshair.value && !demoplayback &&
(!camera.chase || ticcmd_ztargetfocus[0])
&& !players[displayplayer].spectator)
HU_DrawCrosshair();
if (!automapactive && cv_crosshair2.value && !demoplayback &&
(!camera2.chase || ticcmd_ztargetfocus[1])
&& !players[secondarydisplayplayer].spectator)
HU_DrawCrosshair2();
if (!automapactive && cv_crosshair2.value && !demoplayback &&
(!camera2.chase || ticcmd_ztargetfocus[1])
&& !players[secondarydisplayplayer].spectator)
HU_DrawCrosshair2();
}
// draw desynch text
if (hu_redownloadinggamestate)
@ -2243,8 +2248,8 @@ void HU_Erase(void)
//
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags)
{
UINT8 numbars = 1; // how many ping bars do we draw?
UINT8 barcolor = 35; // color we use for the bars (green, yellow or red)
UINT8 numbars = 0; // how many ping bars do we draw?
UINT8 barcolor = 31; // color we use for the bars (green, yellow, red or black)
SINT8 i = 0;
SINT8 yoffset = 6;
INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping),
@ -2257,11 +2262,16 @@ void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags)
}
else if (ping < 256)
{
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
numbars = 2;
barcolor = 73;
}
else if (ping < UINT32_MAX)
{
numbars = 1;
barcolor = 35;
}
if (!notext || vid.width >= 640) // how sad, we're using a shit resolution.
if (ping < UINT32_MAX && (!notext || vid.width >= 640)) // how sad, we're using a shit resolution.
V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE|flags, va("%dms", ping));
for (i=0; (i<3); i++) // Draw the ping bar
@ -2272,6 +2282,9 @@ void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags)
yoffset -= 2;
}
if (ping == UINT32_MAX)
V_DrawSmallScaledPatch(x + 4 - nopingicon->width/2, y + 9 - nopingicon->height/2, 0, nopingicon);
}
//
@ -2298,16 +2311,17 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
if (!splitscreen) // don't draw it on splitscreen,
{
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
HU_drawPing(x+ 253, y, playerpingtable[tab[i].num], false, 0);
if (tab[i].num != serverplayer)
HU_drawPing(x + 253, y, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], false, 0);
//else
// V_DrawSmallString(x+ 246, y+4, V_YELLOWMAP, "SERVER");
}
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? V_60TRANS : 0)
| V_ALLOWLOWERCASE, tab[i].name);
if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1))
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? V_60TRANS : 0)
| V_ALLOWLOWERCASE, tab[i].name);
// Draw emeralds
if (players[tab[i].num].powers[pw_invulnerability] && (players[tab[i].num].powers[pw_invulnerability] == players[tab[i].num].powers[pw_sneakers]) && ((leveltime/7) & 1))
@ -2455,10 +2469,11 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
supercheck = supercheckdef;
strlcpy(name, tab[i].name, 8);
V_DrawString(x + 10, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? 0 : V_TRANSLUCENT)
| V_ALLOWLOWERCASE, name);
if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1))
V_DrawString(x + 10, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? 0 : V_TRANSLUCENT)
| V_ALLOWLOWERCASE, name);
if (gametyperules & GTR_TEAMFLAGS)
{
@ -2497,10 +2512,10 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].spectator || players[tab[i].num].playerstate == PST_DEAD) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
if (!splitscreen)
{
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
//else
//V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
if (tab[i].num != serverplayer)
HU_drawPing(x + 135, y+1, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], true, 0);
//else
//V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
}
}
}
@ -2583,10 +2598,11 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
supercheck = supercheckdef;
strlcpy(name, tab[i].name, 7);
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? V_TRANSLUCENT : 0)
| V_ALLOWLOWERCASE, name);
if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1))
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? V_TRANSLUCENT : 0)
| V_ALLOWLOWERCASE, name);
if (gametyperules & GTR_TEAMFLAGS)
{
@ -2621,10 +2637,10 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
V_DrawRightAlignedThinString(x+100, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
if (!splitscreen)
{
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
//else
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
if (tab[i].num != serverplayer)
HU_drawPing(x+ 113, y, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], false, 0);
//else
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
}
}
}
@ -2652,15 +2668,16 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
supercheck = supercheckdef;
strlcpy(name, tab[i].name, 7);
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
if (tab[i].num != serverplayer)
HU_drawPing(x+ 113, y, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], false, 0);
//else
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? V_TRANSLUCENT : 0)
| V_ALLOWLOWERCASE, name);
if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1))
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? V_TRANSLUCENT : 0)
| V_ALLOWLOWERCASE, name);
if (G_GametypeUsesLives() && !(G_GametypeUsesCoopLives() && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives));
@ -2760,16 +2777,17 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
strlcpy(name, tab[i].name, 7);
if (!splitscreen) // don't draw it on splitscreen,
{
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
//else
// V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
if (tab[i].num != serverplayer)
HU_drawPing(x+ 135, y+1, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], true, 0);
//else
// V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
}
V_DrawString(x + 10, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? 0 : V_TRANSLUCENT)
| V_ALLOWLOWERCASE, name);
if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1))
V_DrawString(x + 10, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| (greycheck ? 0 : V_TRANSLUCENT)
| V_ALLOWLOWERCASE, name);
if (G_GametypeUsesLives()) //show lives
V_DrawRightAlignedThinString(x-1, y, V_ALLOWLOWERCASE, va("%d", players[tab[i].num].lives));

View file

@ -150,6 +150,7 @@ char sprnames[NUMSPRITES + 1][5] =
"SIGN", // Level end sign
"SPIK", // Spike Ball
"SFLM", // Spin fire
"TFLM", // Spin fire (team)
"USPK", // Floor spike
"WSPK", // Wall spike
"WSPB", // Wall spike base
@ -1894,6 +1895,13 @@ state_t states[NUMSTATES] =
{SPR_SFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_SPINFIRE6}, // S_SPINFIRE5
{SPR_SFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_SPINFIRE1}, // S_SPINFIRE6
{SPR_TFLM, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE2}, // S_TEAM_SPINFIRE1
{SPR_TFLM, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE3}, // S_TEAM_SPINFIRE2
{SPR_TFLM, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE4}, // S_TEAM_SPINFIRE3
{SPR_TFLM, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE5}, // S_TEAM_SPINFIRE4
{SPR_TFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE6}, // S_TEAM_SPINFIRE5
{SPR_TFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE1}, // S_TEAM_SPINFIRE6
// Floor Spike
{SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended
{SPR_USPK, 1, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2
@ -3291,18 +3299,18 @@ state_t states[NUMSTATES] =
{SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_RANDOMANIM, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP
// Spindash dust
{SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1
{SPR_DUST, 1, 6, {NULL}, 0, 0, S_SPINDUST3}, // S_SPINDUST2
{SPR_DUST, FF_TRANS30|2, 4, {NULL}, 0, 0, S_SPINDUST4}, // S_SPINDUST3
{SPR_DUST, FF_TRANS60|3, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST4
{SPR_BUBL, 0, 7, {NULL}, 0, 0, S_SPINDUST_BUBBLE2}, // S_SPINDUST_BUBBLE1
{SPR_BUBL, 0, 6, {NULL}, 0, 0, S_SPINDUST_BUBBLE3}, // S_SPINDUST_BUBBLE2
{SPR_BUBL, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_BUBBLE4}, // S_SPINDUST_BUBBLE3
{SPR_BUBL, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4
{SPR_FPRT, 0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1
{SPR_FPRT, 0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2
{SPR_FPRT, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3
{SPR_FPRT, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4
{SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1
{SPR_DUST, 1, 6, {NULL}, 0, 0, S_SPINDUST3}, // S_SPINDUST2
{SPR_DUST, FF_TRANS30|2, 4, {NULL}, 0, 0, S_SPINDUST4}, // S_SPINDUST3
{SPR_DUST, FF_TRANS60|3, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST4
{SPR_BUBL, 0, 7, {NULL}, 0, 0, S_SPINDUST_BUBBLE2}, // S_SPINDUST_BUBBLE1
{SPR_BUBL, 0, 6, {NULL}, 0, 0, S_SPINDUST_BUBBLE3}, // S_SPINDUST_BUBBLE2
{SPR_BUBL, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_BUBBLE4}, // S_SPINDUST_BUBBLE3
{SPR_BUBL, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4
{SPR_FPRT, FF_FULLBRIGHT|0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1
{SPR_FPRT, FF_FULLBRIGHT|0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2
{SPR_FPRT, FF_FULLBRIGHT|FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3
{SPR_FPRT, FF_FULLBRIGHT|FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4
{SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1

View file

@ -684,6 +684,7 @@ typedef enum sprite
SPR_SIGN, // Level end sign
SPR_SPIK, // Spike Ball
SPR_SFLM, // Spin fire
SPR_TFLM, // Spin fire (team)
SPR_USPK, // Floor spike
SPR_WSPK, // Wall spike
SPR_WSPB, // Wall spike base
@ -2324,6 +2325,13 @@ typedef enum state
S_SPINFIRE5,
S_SPINFIRE6,
S_TEAM_SPINFIRE1,
S_TEAM_SPINFIRE2,
S_TEAM_SPINFIRE3,
S_TEAM_SPINFIRE4,
S_TEAM_SPINFIRE5,
S_TEAM_SPINFIRE6,
// Spikes
S_SPIKE1,
S_SPIKE2,

View file

@ -155,6 +155,8 @@ static const struct {
{META_PIVOTLIST, "spriteframepivot_t[]"},
{META_FRAMEPIVOT, "spriteframepivot_t"},
{META_TAGLIST, "taglist"},
{META_MOBJ, "mobj_t"},
{META_MAPTHING, "mapthing_t"},
@ -186,6 +188,9 @@ static const struct {
{META_CVAR, "consvar_t"},
{META_SECTORLINES, "sector_t.lines"},
#ifdef MUTABLE_TAGS
{META_SECTORTAGLIST, "sector_t.taglist"},
#endif
{META_SIDENUM, "line_t.sidenum"},
{META_LINEARGS, "line_t.args"},
{META_LINESTRINGARGS, "line_t.stringargs"},
@ -427,7 +432,7 @@ static int lib_pAproxDistance(lua_State *L)
fixed_t dx = luaL_checkfixed(L, 1);
fixed_t dy = luaL_checkfixed(L, 2);
//HUDSAFE
lua_pushfixed(L, P_AproxDistance(dx, dy));
lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy));
return 1;
}

View file

@ -285,8 +285,8 @@ static void Lua_OnChange(void)
/// \todo Network this! XD_LUAVAR
lua_settop(gL, 0); // Just in case...
lua_pushcfunction(gL, LUA_GetErrorMessage);
lua_insert(gL, 1); // Because LUA_Call wants it at index 1.
// From CV_OnChange registry field, get the function for this cvar by name.
lua_getfield(gL, LUA_REGISTRYINDEX, "CV_OnChange");
@ -301,6 +301,7 @@ static void Lua_OnChange(void)
LUA_Call(gL, 1, 0, 1); // call function(cvar)
lua_pop(gL, 1); // pop CV_OnChange table
lua_remove(gL, 1); // remove LUA_GetErrorMessage
}
static int lib_cvRegisterVar(lua_State *L)

View file

@ -13,6 +13,7 @@
enum hud {
hud_stagetitle = 0,
hud_textspectator,
hud_crosshair,
// Singleplayer / Co-op
hud_score,
hud_time,

View file

@ -39,6 +39,7 @@ static UINT8 hudAvailable; // hud hooks field
static const char *const hud_disable_options[] = {
"stagetitle",
"textspectator",
"crosshair",
"score",
"time",

View file

@ -1635,8 +1635,10 @@ static int skincolor_get(lua_State *L)
lua_pushinteger(L, info->chatcolor);
else if (fastcmp(field,"accessible"))
lua_pushboolean(L, info->accessible);
else
else {
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "skincolor_t", field);
return 0;
}
return 1;
}

View file

@ -12,6 +12,8 @@
extern lua_State *gL;
#define MUTABLE_TAGS
#define LREG_VALID "VALID_USERDATA"
#define LREG_EXTVARS "LUA_VARS"
#define LREG_STATEACTION "STATE_ACTION"
@ -27,6 +29,8 @@ extern lua_State *gL;
#define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]"
#define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*"
#define META_TAGLIST "TAGLIST"
#define META_MOBJ "MOBJ_T*"
#define META_MAPTHING "MAPTHING_T*"
@ -58,6 +62,9 @@ extern lua_State *gL;
#define META_CVAR "CONSVAR_T*"
#define META_SECTORLINES "SECTOR_T*LINES"
#ifdef MUTABLE_TAGS
#define META_SECTORTAGLIST "sector_t.taglist"
#endif
#define META_SIDENUM "LINE_T*SIDENUM"
#define META_LINEARGS "LINE_T*ARGS"
#define META_LINESTRINGARGS "LINE_T*STRINGARGS"
@ -95,6 +102,7 @@ int LUA_PlayerLib(lua_State *L);
int LUA_SkinLib(lua_State *L);
int LUA_ThinkerLib(lua_State *L);
int LUA_MapLib(lua_State *L);
int LUA_TagLib(lua_State *L);
int LUA_PolyObjLib(lua_State *L);
int LUA_BlockmapLib(lua_State *L);
int LUA_HudLib(lua_State *L);

View file

@ -37,6 +37,7 @@ enum sector_e {
sector_lightlevel,
sector_special,
sector_tag,
sector_taglist,
sector_thinglist,
sector_heightsec,
sector_camsec,
@ -55,6 +56,7 @@ static const char *const sector_opt[] = {
"lightlevel",
"special",
"tag",
"taglist",
"thinglist",
"heightsec",
"camsec",
@ -89,6 +91,7 @@ enum line_e {
line_flags,
line_special,
line_tag,
line_taglist,
line_args,
line_stringargs,
line_sidenum,
@ -113,6 +116,7 @@ static const char *const line_opt[] = {
"flags",
"special",
"tag",
"taglist",
"args",
"stringargs",
"sidenum",
@ -579,7 +583,10 @@ static int sector_get(lua_State *L)
lua_pushinteger(L, sector->special);
return 1;
case sector_tag:
lua_pushinteger(L, Tag_FGet(&sector->tags));
lua_pushinteger(L, (UINT16)Tag_FGet(&sector->tags));
return 1;
case sector_taglist:
LUA_PushUserdata(L, &sector->tags, META_SECTORTAGLIST);
return 1;
case sector_thinglist: // thinglist
lua_pushcfunction(L, lib_iterateSectorThinglist);
@ -682,6 +689,8 @@ static int sector_set(lua_State *L)
case sector_tag:
Tag_SectorFSet((UINT32)(sector - sectors), (INT16)luaL_checkinteger(L, 3));
break;
case sector_taglist:
return LUA_ErrSetDirectly(L, "sector_t", "taglist");
}
return 0;
}
@ -819,8 +828,22 @@ static int line_get(lua_State *L)
lua_pushinteger(L, line->special);
return 1;
case line_tag:
// HELLO
// THIS IS LJ SONIC
// HOW IS YOUR DAY?
// BY THE WAY WHEN 2.3 OR 3.0 OR 4.0 OR SRB3 OR SRB4 OR WHATEVER IS OUT
// YOU SHOULD REMEMBER TO CHANGE THIS SO IT ALWAYS RETURNS A UNSIGNED VALUE
// HAVE A NICE DAY
//
//
//
//
// you are ugly
lua_pushinteger(L, Tag_FGet(&line->tags));
return 1;
case line_taglist:
LUA_PushUserdata(L, &line->tags, META_TAGLIST);
return 1;
case line_args:
LUA_PushUserdata(L, line->args, META_LINEARGS);
return 1;
@ -1385,25 +1408,15 @@ static int lib_iterateSectors(lua_State *L)
static int lib_getSector(lua_State *L)
{
int field;
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))
if (lua_isnumber(L, 2))
{
size_t i = lua_tointeger(L, 1);
size_t i = lua_tointeger(L, 2);
if (i >= numsectors)
return 0;
LUA_PushUserdata(L, &sectors[i], META_SECTOR);
return 1;
}
field = luaL_checkoption(L, 1, NULL, array_opt);
switch(field)
{
case 0: // iterate
lua_pushcfunction(L, lib_iterateSectors);
return 1;
}
return 0;
}
@ -1489,25 +1502,15 @@ static int lib_iterateLines(lua_State *L)
static int lib_getLine(lua_State *L)
{
int field;
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))
if (lua_isnumber(L, 2))
{
size_t i = lua_tointeger(L, 1);
size_t i = lua_tointeger(L, 2);
if (i >= numlines)
return 0;
LUA_PushUserdata(L, &lines[i], META_LINE);
return 1;
}
field = luaL_checkoption(L, 1, NULL, array_opt);
switch(field)
{
case 0: // iterate
lua_pushcfunction(L, lib_iterateLines);
return 1;
}
return 0;
}
@ -2360,15 +2363,13 @@ int LUA_MapLib(lua_State *L)
//lua_setfield(L, -2, "__len");
lua_pop(L, 1);
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getSector);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_numsectors);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "sectors");
LUA_PushTaggableObjectArray(L, "sectors",
lib_iterateSectors,
lib_getSector,
lib_numsectors,
tags_sectors,
&numsectors, &sectors,
sizeof (sector_t), META_SECTOR);
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
@ -2380,15 +2381,13 @@ int LUA_MapLib(lua_State *L)
lua_setmetatable(L, -2);
lua_setglobal(L, "subsectors");
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getLine);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_numlines);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "lines");
LUA_PushTaggableObjectArray(L, "lines",
lib_iterateLines,
lib_getLine,
lib_numlines,
tags_lines,
&numlines, &lines,
sizeof (line_t), META_LINE);
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);

View file

@ -15,6 +15,7 @@
#include "tables.h"
#include "p_local.h"
#include "doomstat.h" // for ALL7EMERALDS
#include "r_main.h" // for R_PointToDist2
#include "lua_script.h"
#include "lua_libs.h"
@ -129,7 +130,7 @@ static int lib_fixedsqrt(lua_State *L)
static int lib_fixedhypot(lua_State *L)
{
lua_pushfixed(L, FixedHypot(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2)));
lua_pushfixed(L, R_PointToDist2(0, 0, luaL_checkfixed(L, 1), luaL_checkfixed(L, 2)));
return 1;
}

View file

@ -22,8 +22,6 @@
#include "lua_hud.h" // hud_running errors
#include "lua_hook.h" // hook_cmd_running errors
static const char *const array_opt[] ={"iterate",NULL};
enum mobj_e {
mobj_valid = 0,
mobj_x,
@ -904,6 +902,11 @@ static int mapthing_get(lua_State *L)
number = mt->extrainfo;
else if(fastcmp(field,"tag"))
number = Tag_FGet(&mt->tags);
else if(fastcmp(field,"taglist"))
{
LUA_PushUserdata(L, &mt->tags, META_TAGLIST);
return 1;
}
else if(fastcmp(field,"args"))
{
LUA_PushUserdata(L, mt->args, META_THINGARGS);
@ -966,6 +969,8 @@ static int mapthing_set(lua_State *L)
}
else if (fastcmp(field,"tag"))
Tag_FSet(&mt->tags, (INT16)luaL_checkinteger(L, 3));
else if (fastcmp(field,"taglist"))
return LUA_ErrSetDirectly(L, "mapthing_t", "taglist");
else if(fastcmp(field,"mobj"))
mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
else
@ -1003,25 +1008,15 @@ static int lib_iterateMapthings(lua_State *L)
static int lib_getMapthing(lua_State *L)
{
int field;
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))
if (lua_isnumber(L, 2))
{
size_t i = lua_tointeger(L, 1);
size_t i = lua_tointeger(L, 2);
if (i >= nummapthings)
return 0;
LUA_PushUserdata(L, &mapthings[i], META_MAPTHING);
return 1;
}
field = luaL_checkoption(L, 1, NULL, array_opt);
switch(field)
{
case 0: // iterate
lua_pushcfunction(L, lib_iterateMapthings);
return 1;
}
return 0;
}
@ -1068,14 +1063,13 @@ int LUA_MobjLib(lua_State *L)
lua_setfield(L, -2, "__len");
lua_pop(L,1);
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getMapthing);
lua_setfield(L, -2, "__index");
LUA_PushTaggableObjectArray(L, "mapthings",
lib_iterateMapthings,
lib_getMapthing,
lib_nummapthings,
tags_mapthings,
&nummapthings, &mapthings,
sizeof (mapthing_t), META_MAPTHING);
lua_pushcfunction(L, lib_nummapthings);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "mapthings");
return 0;
}

View file

@ -417,7 +417,7 @@ static int lib_getPolyObject(lua_State *L)
{
i = luaL_checkinteger(L, 2);
if (i < 0 || i >= numPolyObjects)
return luaL_error(L, "PolyObjects[] index %d out of range (0 - %d)", i, numPolyObjects-1);
return luaL_error(L, "polyobjects[] index %d out of range (0 - %d)", i, numPolyObjects-1);
LUA_PushUserdata(L, &PolyObjects[i], META_POLYOBJ);
return 1;
}
@ -481,6 +481,6 @@ int LUA_PolyObjLib(lua_State *L)
lua_pushcfunction(L, lib_numPolyObjects);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "PolyObjects");
lua_setglobal(L, "polyobjects");
return 0;
}

View file

@ -53,6 +53,7 @@ static lua_CFunction liblist[] = {
LUA_SkinLib, // skin_t, skins[]
LUA_ThinkerLib, // thinker_t
LUA_MapLib, // line_t, side_t, sector_t, subsector_t
LUA_TagLib, // tags
LUA_PolyObjLib, // polyobj_t
LUA_BlockmapLib, // blockmap stuff
LUA_HudLib, // HUD stuff
@ -332,7 +333,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
return 1;
// local player variables, by popular request
} else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1)
if (consoleplayer < 0 || !playeringame[consoleplayer])
if (!addedtogame || consoleplayer < 0 || !playeringame[consoleplayer])
return 0;
LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER);
return 1;
@ -739,25 +740,37 @@ void LUA_PushLightUserdata (lua_State *L, void *data, const char *meta)
// Pushes it to the stack and stores it in the registry.
void LUA_PushUserdata(lua_State *L, void *data, const char *meta)
{
if (LUA_RawPushUserdata(L, data) == LPUSHED_NEW)
{
luaL_getmetatable(L, meta);
lua_setmetatable(L, -2);
}
}
// Same as LUA_PushUserdata but don't set a metatable yet.
lpushed_t LUA_RawPushUserdata(lua_State *L, void *data)
{
lpushed_t status = LPUSHED_NIL;
void **userdata;
if (!data) { // push a NULL
lua_pushnil(L);
return;
return status;
}
lua_getfield(L, LUA_REGISTRYINDEX, LREG_VALID);
I_Assert(lua_istable(L, -1));
lua_pushlightuserdata(L, data);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) { // no userdata? deary me, we'll have to make one.
lua_pop(L, 1); // pop the nil
// create the userdata
userdata = lua_newuserdata(L, sizeof(void *));
*userdata = data;
luaL_getmetatable(L, meta);
lua_setmetatable(L, -2);
// Set it in the registry so we can find it again
lua_pushlightuserdata(L, data); // k (store the userdata via the data's pointer)
@ -765,8 +778,15 @@ void LUA_PushUserdata(lua_State *L, void *data, const char *meta)
lua_rawset(L, -4);
// stack is left with the userdata on top, as if getting it had originally succeeded.
status = LPUSHED_NEW;
}
else
status = LPUSHED_EXISTING;
lua_remove(L, -2); // remove LREG_VALID
return status;
}
// When userdata is freed, use this function to remove it from Lua.
@ -826,6 +846,7 @@ void LUA_InvalidateLevel(void)
{
LUA_InvalidateUserdata(&sectors[i]);
LUA_InvalidateUserdata(&sectors[i].lines);
LUA_InvalidateUserdata(&sectors[i].tags);
if (sectors[i].ffloors)
{
for (rover = sectors[i].ffloors; rover; rover = rover->next)
@ -835,6 +856,7 @@ void LUA_InvalidateLevel(void)
for (i = 0; i < numlines; i++)
{
LUA_InvalidateUserdata(&lines[i]);
LUA_InvalidateUserdata(&lines[i].tags);
LUA_InvalidateUserdata(lines[i].sidenum);
}
for (i = 0; i < numsides; i++)
@ -866,7 +888,10 @@ void LUA_InvalidateMapthings(void)
return;
for (i = 0; i < nummapthings; i++)
{
LUA_InvalidateUserdata(&mapthings[i]);
LUA_InvalidateUserdata(&mapthings[i].tags);
}
}
void LUA_InvalidatePlayer(player_t *player)
@ -1681,3 +1706,36 @@ int Lua_optoption(lua_State *L, int narg,
return i;
return -1;
}
void LUA_PushTaggableObjectArray
( lua_State *L,
const char *field,
lua_CFunction iterator,
lua_CFunction indexer,
lua_CFunction counter,
taggroup_t *garray[],
size_t * max_elements,
void * element_array,
size_t sizeof_element,
const char *meta)
{
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, iterator);
lua_setfield(L, -2, "iterate");
LUA_InsertTaggroupIterator(L, garray,
max_elements, element_array, sizeof_element, meta);
lua_createtable(L, 0, 1);
lua_pushcfunction(L, indexer);
lua_setfield(L, -2, "__index");
lua_setmetatable(L, -2);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, counter);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, field);
}

View file

@ -10,10 +10,14 @@
/// \file lua_script.h
/// \brief Lua scripting basics
#ifndef LUA_SCRIPT_H
#define LUA_SCRIPT_H
#include "m_fixed.h"
#include "doomtype.h"
#include "d_player.h"
#include "g_state.h"
#include "taglist.h"
#include "blua/lua.h"
#include "blua/lualib.h"
@ -46,12 +50,6 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump, boolean noresults);
void LUA_DumpFile(const char *filename);
#endif
fixed_t LUA_EvalMath(const char *word);
void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta);
void LUA_PushUserdata(lua_State *L, void *data, const char *meta);
void LUA_InvalidateUserdata(void *data);
void LUA_InvalidateLevel(void);
void LUA_InvalidateMapthings(void);
void LUA_InvalidatePlayer(player_t *player);
void LUA_Step(void);
void LUA_Archive(void);
void LUA_UnArchive(void);
@ -63,11 +61,49 @@ int Lua_optoption(lua_State *L, int narg,
const char *def, const char *const lst[]);
void LUAh_NetArchiveHook(lua_CFunction archFunc);
void LUA_PushTaggableObjectArray
( lua_State *L,
const char *field,
lua_CFunction iterator,
lua_CFunction indexer,
lua_CFunction counter,
taggroup_t *garray[],
size_t * max_elements,
void * element_array,
size_t sizeof_element,
const char *meta);
void LUA_InsertTaggroupIterator
( lua_State *L,
taggroup_t *garray[],
size_t * max_elements,
void * element_array,
size_t sizeof_element,
const char * meta);
typedef enum {
LPUSHED_NIL,
LPUSHED_NEW,
LPUSHED_EXISTING,
} lpushed_t;
void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta);
void LUA_PushUserdata(lua_State *L, void *data, const char *meta);
lpushed_t LUA_RawPushUserdata(lua_State *L, void *data);
void LUA_InvalidateUserdata(void *data);
void LUA_InvalidateLevel(void);
void LUA_InvalidateMapthings(void);
void LUA_InvalidatePlayer(player_t *player);
// Console wrapper
void COM_Lua_f(void);
#define LUA_ErrInvalid(L, type) luaL_error(L, "accessed " type " doesn't exist anymore, please check 'valid' before using " type ".");
#define LUA_ErrSetDirectly(L, type, field) luaL_error(L, type " field " LUA_QL(field) " cannot be set directly.")
// Deprecation warnings
// Shows once upon use. Then doesn't show again.
#define LUA_Deprecated(L,this_func,use_instead)\
@ -98,3 +134,5 @@ void COM_Lua_f(void);
#define INLEVEL if (! ISINLEVEL)\
return luaL_error(L, "This can only be used in a level!");
#endif/*LUA_SCRIPT_H*/

451
src/lua_taglib.c Normal file
View file

@ -0,0 +1,451 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2020 by James R.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_taglib.c
/// \brief tag list iterator for Lua scripting
#include "doomdef.h"
#include "taglist.h"
#include "r_state.h"
#include "lua_script.h"
#include "lua_libs.h"
#ifdef MUTABLE_TAGS
#include "z_zone.h"
#endif
static int tag_iterator(lua_State *L)
{
INT32 tag = lua_isnil(L, 2) ? -1 : lua_tonumber(L, 2);
do
{
if (++tag >= MAXTAGS)
return 0;
}
while (! in_bit_array(tags_available, tag)) ;
lua_pushnumber(L, tag);
return 1;
}
enum {
#define UPVALUE lua_upvalueindex
up_garray = UPVALUE(1),
up_max_elements = UPVALUE(2),
up_element_array = UPVALUE(3),
up_sizeof_element = UPVALUE(4),
up_meta = UPVALUE(5),
#undef UPVALUE
};
static INT32 next_element(lua_State *L, const mtag_t tag, const size_t p)
{
taggroup_t ** garray = lua_touserdata(L, up_garray);
const size_t * max_elements = lua_touserdata(L, up_max_elements);
return Taggroup_Iterate(garray, *max_elements, tag, p);
}
static void push_element(lua_State *L, void *element)
{
if (LUA_RawPushUserdata(L, element) == LPUSHED_NEW)
{
lua_pushvalue(L, up_meta);
lua_setmetatable(L, -2);
}
}
static void push_next_element(lua_State *L, const INT32 element)
{
char * element_array = *(char **)lua_touserdata(L, up_element_array);
const size_t sizeof_element = lua_tonumber(L, up_sizeof_element);
push_element(L, &element_array[element * sizeof_element]);
}
struct element_iterator_state {
mtag_t tag;
size_t p;
};
static int element_iterator(lua_State *L)
{
struct element_iterator_state * state = lua_touserdata(L, 1);
if (lua_isnoneornil(L, 3))
state->p = 0;
lua_pushnumber(L, ++state->p);
lua_gettable(L, 1);
return 1;
}
static int lib_iterateTags(lua_State *L)
{
if (lua_gettop(L) < 2)
{
lua_pushcfunction(L, tag_iterator);
return 1;
}
else
return tag_iterator(L);
}
static int lib_numTags(lua_State *L)
{
lua_pushnumber(L, num_tags);
return 1;
}
static int lib_getTaggroup(lua_State *L)
{
struct element_iterator_state *state;
mtag_t tag;
if (lua_gettop(L) > 1)
return luaL_error(L, "too many arguments");
if (lua_isnoneornil(L, 1))
{
tag = MTAG_GLOBAL;
}
else
{
tag = lua_tonumber(L, 1);
luaL_argcheck(L, tag >= -1, 1, "tag out of range");
}
state = lua_newuserdata(L, sizeof *state);
state->tag = tag;
state->p = 0;
lua_pushvalue(L, lua_upvalueindex(1));
lua_setmetatable(L, -2);
return 1;
}
static int lib_getTaggroupElement(lua_State *L)
{
const size_t p = luaL_checknumber(L, 2) - 1;
const mtag_t tag = *(mtag_t *)lua_touserdata(L, 1);
const INT32 element = next_element(L, tag, p);
if (element == -1)
return 0;
else
{
push_next_element(L, element);
return 1;
}
}
static int lib_numTaggroupElements(lua_State *L)
{
const mtag_t tag = *(mtag_t *)lua_touserdata(L, 1);
if (tag == MTAG_GLOBAL)
lua_pushnumber(L, *(size_t *)lua_touserdata(L, up_max_elements));
else
{
const taggroup_t ** garray = lua_touserdata(L, up_garray);
lua_pushnumber(L, Taggroup_Count(garray[tag]));
}
return 1;
}
#ifdef MUTABLE_TAGS
static int meta_ref[2];
#endif
static int has_valid_field(lua_State *L)
{
int equal;
lua_rawgeti(L, LUA_ENVIRONINDEX, 1);
equal = lua_rawequal(L, 2, -1);
lua_pop(L, 1);
return equal;
}
static taglist_t * valid_taglist(lua_State *L, int idx, boolean getting)
{
taglist_t *list = *(taglist_t **)lua_touserdata(L, idx);
if (list == NULL)
{
if (getting && has_valid_field(L))
lua_pushboolean(L, 0);
else
LUA_ErrInvalid(L, "taglist");/* doesn't actually return */
return NULL;
}
else
return list;
}
static taglist_t * check_taglist(lua_State *L, int idx)
{
if (lua_isuserdata(L, idx) && lua_getmetatable(L, idx))
{
lua_getref(L, meta_ref[0]);
lua_getref(L, meta_ref[1]);
if (lua_rawequal(L, -3, -2) || lua_rawequal(L, -3, -1))
{
lua_pop(L, 3);
return valid_taglist(L, idx, false);
}
}
return luaL_argerror(L, idx, "must be a tag list"), NULL;
}
static int taglist_get(lua_State *L)
{
const taglist_t *list = valid_taglist(L, 1, true);
if (list == NULL)/* valid check */
return 1;
if (lua_isnumber(L, 2))
{
const size_t i = lua_tonumber(L, 2);
if (list && i <= list->count)
{
lua_pushnumber(L, list->tags[i - 1]);
return 1;
}
else
return 0;
}
else if (has_valid_field(L))
{
lua_pushboolean(L, 1);
return 1;
}
else
{
lua_getmetatable(L, 1);
lua_replace(L, 1);
lua_rawget(L, 1);
return 1;
}
}
static int taglist_len(lua_State *L)
{
const taglist_t *list = valid_taglist(L, 1, false);
lua_pushnumber(L, list->count);
return 1;
}
static int taglist_equal(lua_State *L)
{
const taglist_t *lhs = check_taglist(L, 1);
const taglist_t *rhs = check_taglist(L, 2);
lua_pushboolean(L, Tag_Compare(lhs, rhs));
return 1;
}
static int taglist_iterator(lua_State *L)
{
const taglist_t *list = valid_taglist(L, 1, false);
const size_t i = 1 + lua_tonumber(L, lua_upvalueindex(1));
if (i <= list->count)
{
lua_pushnumber(L, list->tags[i - 1]);
/* watch me exploit an upvalue as a control because
I want to use the control as the value */
lua_pushnumber(L, i);
lua_replace(L, lua_upvalueindex(1));
return 1;
}
else
return 0;
}
static int taglist_iterate(lua_State *L)
{
check_taglist(L, 1);
lua_pushnumber(L, 0);
lua_pushcclosure(L, taglist_iterator, 1);
lua_pushvalue(L, 1);
return 2;
}
static int taglist_find(lua_State *L)
{
const taglist_t *list = check_taglist(L, 1);
const mtag_t tag = luaL_checknumber(L, 2);
lua_pushboolean(L, Tag_Find(list, tag));
return 1;
}
static int taglist_shares(lua_State *L)
{
const taglist_t *lhs = check_taglist(L, 1);
const taglist_t *rhs = check_taglist(L, 2);
lua_pushboolean(L, Tag_Share(lhs, rhs));
return 1;
}
/* only sector tags are mutable... */
#ifdef MUTABLE_TAGS
static size_t sector_of_taglist(taglist_t *list)
{
return (sector_t *)((char *)list - offsetof (sector_t, tags)) - sectors;
}
static int this_taglist(lua_State *L)
{
lua_settop(L, 1);
return 1;
}
static int taglist_add(lua_State *L)
{
taglist_t *list = *(taglist_t **)luaL_checkudata(L, 1, META_SECTORTAGLIST);
const mtag_t tag = luaL_checknumber(L, 2);
if (! Tag_Find(list, tag))
{
Taggroup_Add(tags_sectors, tag, sector_of_taglist(list));
Tag_Add(list, tag);
}
return this_taglist(L);
}
static int taglist_remove(lua_State *L)
{
taglist_t *list = *(taglist_t **)luaL_checkudata(L, 1, META_SECTORTAGLIST);
const mtag_t tag = luaL_checknumber(L, 2);
size_t i;
for (i = 0; i < list->count; ++i)
{
if (list->tags[i] == tag)
{
if (list->count > 1)
{
memmove(&list->tags[i], &list->tags[i + 1],
(list->count - 1 - i) * sizeof (mtag_t));
list->tags = Z_Realloc(list->tags,
(--list->count) * sizeof (mtag_t), PU_LEVEL, NULL);
Taggroup_Remove(tags_sectors, tag, sector_of_taglist(list));
}
else/* reset to default tag */
Tag_SectorFSet(sector_of_taglist(list), 0);
break;
}
}
return this_taglist(L);
}
#endif/*MUTABLE_TAGS*/
void LUA_InsertTaggroupIterator
( lua_State *L,
taggroup_t *garray[],
size_t * max_elements,
void * element_array,
size_t sizeof_element,
const char * meta)
{
lua_createtable(L, 0, 3);
lua_pushlightuserdata(L, garray);
lua_pushlightuserdata(L, max_elements);
lua_pushvalue(L, -2);
lua_pushvalue(L, -2);
lua_pushlightuserdata(L, element_array);
lua_pushnumber(L, sizeof_element);
luaL_getmetatable(L, meta);
lua_pushcclosure(L, lib_getTaggroupElement, 5);
lua_setfield(L, -4, "__index");
lua_pushcclosure(L, lib_numTaggroupElements, 2);
lua_setfield(L, -2, "__len");
lua_pushcfunction(L, element_iterator);
lua_setfield(L, -2, "__call");
lua_pushcclosure(L, lib_getTaggroup, 1);
lua_setfield(L, -2, "tagged");
}
static luaL_Reg taglist_lib[] = {
{"iterate", taglist_iterate},
{"find", taglist_find},
{"shares", taglist_shares},
#ifdef MUTABLE_TAGS
{"add", taglist_add},
{"remove", taglist_remove},
#endif
{0}
};
static void open_taglist(lua_State *L)
{
luaL_register(L, "taglist", taglist_lib);
lua_getfield(L, -1, "find");
lua_setfield(L, -2, "has");
}
#define new_literal(L, s) \
(lua_pushliteral(L, s), luaL_ref(L, -2))
#ifdef MUTABLE_TAGS
static int
#else
static void
#endif
set_taglist_metatable(lua_State *L, const char *meta)
{
luaL_newmetatable(L, meta);
lua_pushcfunction(L, taglist_get);
lua_createtable(L, 0, 1);
new_literal(L, "valid");
lua_setfenv(L, -2);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, taglist_len);
lua_setfield(L, -2, "__len");
lua_pushcfunction(L, taglist_equal);
lua_setfield(L, -2, "__eq");
#ifdef MUTABLE_TAGS
return luaL_ref(L, LUA_REGISTRYINDEX);
#endif
}
int LUA_TagLib(lua_State *L)
{
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_createtable(L, 0, 1);
lua_pushcfunction(L, lib_iterateTags);
lua_setfield(L, -2, "iterate");
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_numTags);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "tags");
open_taglist(L);
#ifdef MUTABLE_TAGS
meta_ref[0] = set_taglist_metatable(L, META_TAGLIST);
meta_ref[1] = set_taglist_metatable(L, META_SECTORTAGLIST);
#else
set_taglist_metatable(L, META_TAGLIST);
#endif
return 0;
}

View file

@ -1612,53 +1612,54 @@ static menuitem_t OP_ServerOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21},
{IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26},
{IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31},
{IT_STRING | IT_CVAR, NULL, "Minutes for reconnecting", &cv_rejointimeout, 36},
#endif
{IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 36},
{IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 41},
{IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 41},
{IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 46},
{IT_HEADER, NULL, "Characters", NULL, 50},
{IT_STRING | IT_CVAR, NULL, "Force a character", &cv_forceskin, 56},
{IT_STRING | IT_CVAR, NULL, "Restrict character changes", &cv_restrictskinchange, 61},
{IT_HEADER, NULL, "Characters", NULL, 55},
{IT_STRING | IT_CVAR, NULL, "Force a character", &cv_forceskin, 61},
{IT_STRING | IT_CVAR, NULL, "Restrict character changes", &cv_restrictskinchange, 66},
{IT_HEADER, NULL, "Items", NULL, 70},
{IT_STRING | IT_CVAR, NULL, "Item respawn delay", &cv_itemrespawntime, 76},
{IT_STRING | IT_SUBMENU, NULL, "Mystery Item Monitor Toggles...", &OP_MonitorToggleDef, 81},
{IT_HEADER, NULL, "Items", NULL, 75},
{IT_STRING | IT_CVAR, NULL, "Item respawn delay", &cv_itemrespawntime, 81},
{IT_STRING | IT_SUBMENU, NULL, "Mystery Item Monitor Toggles...", &OP_MonitorToggleDef, 86},
{IT_HEADER, NULL, "Cooperative", NULL, 90},
{IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96},
{IT_STRING | IT_CVAR, NULL, "Starposts", &cv_coopstarposts, 101},
{IT_STRING | IT_CVAR, NULL, "Life sharing", &cv_cooplives, 106},
{IT_STRING | IT_CVAR, NULL, "Post-goal free roaming", &cv_exitmove, 111},
{IT_HEADER, NULL, "Cooperative", NULL, 95},
{IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 101},
{IT_STRING | IT_CVAR, NULL, "Starposts", &cv_coopstarposts, 106},
{IT_STRING | IT_CVAR, NULL, "Life sharing", &cv_cooplives, 111},
{IT_STRING | IT_CVAR, NULL, "Post-goal free roaming", &cv_exitmove, 116},
{IT_HEADER, NULL, "Race, Competition", NULL, 120},
{IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 126},
{IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_competitionboxes, 131},
{IT_HEADER, NULL, "Race, Competition", NULL, 125},
{IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 131},
{IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_competitionboxes, 136},
{IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 140},
{IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 146},
{IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 151},
{IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 156},
{IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 161},
{IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 145},
{IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 151},
{IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 156},
{IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 161},
{IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 166},
{IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_matchboxes, 171},
{IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 176},
{IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 181},
{IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_matchboxes, 176},
{IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 181},
{IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 186},
{IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 191},
{IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 196},
{IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 196},
{IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 201},
{IT_HEADER, NULL, "Teams", NULL, 205},
{IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 211},
{IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 216},
{IT_HEADER, NULL, "Teams", NULL, 210},
{IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 216},
{IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 221},
#ifndef NONET
{IT_HEADER, NULL, "Advanced", NULL, 225},
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231},
{IT_HEADER, NULL, "Advanced", NULL, 230},
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 236},
{IT_STRING | IT_CVAR, NULL, "Join delay", &cv_joindelay, 246},
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 251},
{IT_STRING | IT_CVAR, NULL, "Join delay", &cv_joindelay, 251},
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 256},
{IT_STRING | IT_CVAR, NULL, "Show IP Address of Joiners", &cv_showjoinaddress, 256},
{IT_STRING | IT_CVAR, NULL, "Show IP Address of Joiners", &cv_showjoinaddress, 261},
#endif
};
@ -8421,7 +8422,7 @@ static void M_DrawLoadGameData(void)
sprdef = &charbotskin->sprites[SPR2_SIGN];
if (!sprdef->numframes)
goto skipbot;
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin-1, charbotskin->prefcolor, 0);
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin-1, charbotskin->prefcolor, GTC_CACHE);
sprframe = &sprdef->spriteframes[0];
patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
@ -8431,8 +8432,6 @@ static void M_DrawLoadGameData(void)
charbotskin->highresscale,
0, patch, colormap);
Z_Free(colormap);
tempx -= (20<<FRACBITS);
//flip = V_FLIP;
}
@ -8441,7 +8440,7 @@ skipbot:
if (!charskin) // shut up compiler
goto skipsign;
sprdef = &charskin->sprites[SPR2_SIGN];
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, 0);
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, GTC_CACHE);
if (!sprdef->numframes)
goto skipsign;
sprframe = &sprdef->spriteframes[0];
@ -8481,8 +8480,6 @@ skipsign:
charskin->highresscale/2,
0, patch, colormap);
skiplife:
if (colormap)
Z_Free(colormap);
patch = W_CachePatchName("STLIVEX", PU_PATCH);
@ -11753,7 +11750,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
goto faildraw;
// ok, draw player sprite for sure now
colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor->color, 0);
colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor->color, GTC_CACHE);
if (multi_frame >= sprdef->numframes)
multi_frame = 0;
@ -11771,7 +11768,6 @@ static void M_DrawSetupMultiPlayerMenu(void)
FixedDiv(skins[setupm_fakeskin].highresscale, skins[setupm_fakeskin].shieldscale),
flags, patch, colormap);
Z_Free(colormap);
goto colordraw;
faildraw:

View file

@ -165,7 +165,9 @@ consvar_t cv_zlib_window_bitsa = CVAR_INIT ("apng_window_size", "32k", CV_SAVE,
consvar_t cv_apng_delay = CVAR_INIT ("apng_speed", "1x", CV_SAVE, apng_delay_t, NULL);
consvar_t cv_apng_downscale = CVAR_INIT ("apng_downscale", "On", CV_SAVE, CV_OnOff, NULL);
#ifdef USE_APNG
static boolean apng_downscale = false; // So nobody can do something dumb like changing cvars mid output
#endif
boolean takescreenshot = false; // Take a screenshot this tic

View file

@ -1834,7 +1834,7 @@ void A_SnailerThink(mobj_t *actor)
fixed_t dist;
fixed_t dx, dy;
dist = R_PointToDist2(0, 0, actor->x - actor->target->x, actor->y - actor->target->y);
dist = P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y);
if (an > ANGLE_45 && an <= ANGLE_90) // fire at 45 degrees to the left
{
@ -4912,7 +4912,7 @@ void A_ThrownRing(mobj_t *actor)
}
if (actor->tracer && (actor->tracer->health)
&& (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC))// Already found someone to follow.
&& (actor->tracer->player && actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC))// Already found someone to follow.
{
const INT32 temp = actor->threshold;
actor->threshold = 32000;
@ -5920,13 +5920,18 @@ void A_DetonChase(mobj_t *actor)
if (actor->reactiontime == -42)
{
fixed_t xyspeed;
fixed_t xyspeed, speed;
if (actor->target->player)
speed = actor->target->player->normalspeed;
else
speed = actor->target->info->speed;
actor->reactiontime = -42;
exact = actor->movedir>>ANGLETOFINESHIFT;
xyspeed = FixedMul(FixedMul(actor->tracer->player->normalspeed,3*FRACUNIT/4), FINECOSINE(exact));
actor->momz = FixedMul(FixedMul(actor->tracer->player->normalspeed,3*FRACUNIT/4), FINESINE(exact));
xyspeed = FixedMul(FixedMul(speed,3*FRACUNIT/4), FINECOSINE(exact));
actor->momz = FixedMul(FixedMul(speed,3*FRACUNIT/4), FINESINE(exact));
exact = actor->angle>>ANGLETOFINESHIFT;
actor->momx = FixedMul(xyspeed, FINECOSINE(exact));
@ -7521,7 +7526,7 @@ void A_Boss2PogoTarget(mobj_t *actor)
}
// Target hit, retreat!
if (actor->target->player->powers[pw_flashing] > TICRATE || actor->flags2 & MF2_FRET)
if ((actor->target->player && actor->target->player->powers[pw_flashing] > TICRATE) || actor->flags2 & MF2_FRET)
{
UINT8 prandom = P_RandomByte();
actor->z++; // unstick from the floor
@ -7532,7 +7537,7 @@ void A_Boss2PogoTarget(mobj_t *actor)
// Try to land on top of the player.
else if (P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) < FixedMul(512*FRACUNIT, actor->scale))
{
fixed_t airtime, gravityadd, zoffs;
fixed_t airtime, gravityadd, zoffs, height;
// check gravity in the sector (for later math)
P_CheckGravity(actor, true);
@ -7554,7 +7559,13 @@ void A_Boss2PogoTarget(mobj_t *actor)
// Remember, kids!
// Reduced down Calculus lets you avoid bad 'logic math' loops!
//airtime = FixedDiv(-actor->momz<<1, gravityadd)<<1; // going from 0 to 0 is much simpler
zoffs = (P_GetPlayerHeight(actor->target->player)>>1) + (actor->target->floorz - actor->floorz); // offset by the difference in floor height plus half the player height,
if (actor->target->player)
height = P_GetPlayerHeight(actor->target->player) >> 1;
else
height = actor->target->height >> 1;
zoffs = height + (actor->target->floorz - actor->floorz); // offset by the difference in floor height plus half the player height,
airtime = FixedDiv((-actor->momz - FixedSqrt(FixedMul(actor->momz,actor->momz)+zoffs)), gravityadd)<<1; // to try and land on their head rather than on their feet
actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y);
@ -9868,22 +9879,23 @@ void A_Custom3DRotate(mobj_t *actor)
if (LUA_CallAction(A_CUSTOM3DROTATE, actor))
return;
if (!actor->target) // Ensure we actually have a target first.
{
CONS_Printf("Error: A_Custom3DRotate: Object has no target.\n");
P_RemoveMobj(actor);
return;
}
if (actor->target->health == 0)
{
P_RemoveMobj(actor);
return;
}
if (!actor->target) // This should NEVER happen.
{
if (cv_debug)
CONS_Printf("Error: Object has no target\n");
P_RemoveMobj(actor);
return;
}
if (hspeed==0 && vspeed==0)
{
CONS_Printf("Error: A_Custom3DRotate: Object has no speed.\n");
if (cv_debug)
CONS_Printf("Error: A_Custom3DRotate: Object has no speed.\n");
return;
}

View file

@ -2257,6 +2257,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
{
if (!P_BlockThingsIterator(bx, by, PIT_CheckThing))
blockval = false;
else
tmhitthing = tmfloorthing;
if (P_MobjWasRemoved(tmthing))
return false;
}

View file

@ -3188,13 +3188,16 @@ boolean P_SceneryZMovement(mobj_t *mo)
//
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
{
fixed_t topheight = P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y);
boolean flip = player->mo->eflags & MFE_VERTICALFLIP;
fixed_t surfaceheight = flip ? P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y) : P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y);
fixed_t playerbottom = flip ? (player->mo->z + player->mo->height) : player->mo->z;
boolean doifit = flip ? (surfaceheight - player->mo->floorz >= player->mo->height) : (player->mo->ceilingz - surfaceheight >= player->mo->height);
if (!player->powers[pw_carry] && !player->homing
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= DASHMODE_THRESHOLD) && player->mo->ceilingz-topheight >= player->mo->height)
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= DASHMODE_THRESHOLD) && doifit)
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
&& !(player->pflags & PF_SLIDING)
&& abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
&& abs(playerbottom - surfaceheight) < FixedMul(30*FRACUNIT, player->mo->scale))
return true;
return false;
@ -9837,7 +9840,7 @@ static void P_FlagFuseThink(mobj_t *mobj)
if (mobj->type == MT_REDFLAG)
{
if (!(mobj->flags2 & MF2_JUSTATTACKED))
CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80);
CONS_Printf(M_GetText("The \205Red flag\200 has returned to base.\n"));
// Assumedly in splitscreen players will be on opposing teams
if (players[consoleplayer].ctfteam == 1 || splitscreen)
@ -9850,7 +9853,7 @@ static void P_FlagFuseThink(mobj_t *mobj)
else // MT_BLUEFLAG
{
if (!(mobj->flags2 & MF2_JUSTATTACKED))
CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80);
CONS_Printf(M_GetText("The \204Blue flag\200 has returned to base.\n"));
// Assumedly in splitscreen players will be on opposing teams
if (players[consoleplayer].ctfteam == 2 || splitscreen)
@ -10483,9 +10486,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
P_SetThingPosition(mobj);
I_Assert(mobj->subsector != NULL);
// Make sure scale matches destscale immediately when spawned
P_SetScale(mobj, mobj->destscale);
mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
@ -11798,7 +11798,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
if (!(G_CoopGametype() || (mthing->options & MTF_EXTRA)))
return false; // she doesn't hang out here
if (!mariomode && !(netgame || multiplayer) && players[consoleplayer].skin == 3)
if (!(netgame || multiplayer) && players[consoleplayer].skin == 3)
return false; // no doubles
break;

View file

@ -1506,7 +1506,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
{
const mobj_t *mobj = (const mobj_t *)th;
UINT32 diff;
UINT16 diff2;
UINT32 diff2;
// Ignore stationary hoops - these will be respawned from mapthings.
if (mobj->type == MT_HOOP)
@ -1638,7 +1638,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_SHADOWSCALE;
if (mobj->renderflags)
diff2 |= MD2_RENDERFLAGS;
if (mobj->renderflags)
if (mobj->blendmode != AST_TRANSLUCENT)
diff2 |= MD2_BLENDMODE;
if (mobj->spritexscale != FRACUNIT)
diff2 |= MD2_SPRITEXSCALE;
@ -1646,6 +1646,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_SPRITEYSCALE;
if (mobj->spritexoffset)
diff2 |= MD2_SPRITEXOFFSET;
if (mobj->spriteyoffset)
diff2 |= MD2_SPRITEYOFFSET;
if (mobj->floorspriteslope)
{
pslope_t *slope = mobj->floorspriteslope;
@ -1667,7 +1669,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, diff);
if (diff & MD_MORE)
WRITEUINT16(save_p, diff2);
WRITEUINT32(save_p, diff2);
// save pointer, at load time we will search this pointer to reinitilize pointers
WRITEUINT32(save_p, (size_t)mobj);
@ -2615,14 +2617,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
thinker_t *next;
mobj_t *mobj;
UINT32 diff;
UINT16 diff2;
UINT32 diff2;
INT32 i;
fixed_t z, floorz, ceilingz;
ffloor_t *floorrover = NULL, *ceilingrover = NULL;
diff = READUINT32(save_p);
if (diff & MD_MORE)
diff2 = READUINT16(save_p);
diff2 = READUINT32(save_p);
else
diff2 = 0;
@ -2843,10 +2845,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->renderflags = READUINT32(save_p);
if (diff2 & MD2_BLENDMODE)
mobj->blendmode = READINT32(save_p);
else
mobj->blendmode = AST_TRANSLUCENT;
if (diff2 & MD2_SPRITEXSCALE)
mobj->spritexscale = READFIXED(save_p);
else
mobj->spritexscale = FRACUNIT;
if (diff2 & MD2_SPRITEYSCALE)
mobj->spriteyscale = READFIXED(save_p);
else
mobj->spriteyscale = FRACUNIT;
if (diff2 & MD2_SPRITEXOFFSET)
mobj->spritexoffset = READFIXED(save_p);
if (diff2 & MD2_SPRITEYOFFSET)

View file

@ -3171,7 +3171,7 @@ static void P_ConvertBinaryMap(void)
switch (mapthings[i].type)
{
case 750:
Tag_Add(&mapthings[i].tags, mapthings[i].angle);
Tag_FSet(&mapthings[i].tags, mapthings[i].angle);
break;
case 760:
case 761:

View file

@ -80,6 +80,7 @@ typedef struct
UINT8 *picture;
#ifdef HWRENDER
void *mipmap;
void *mippic;
#endif
} levelflat_t;

View file

@ -4304,7 +4304,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
if (leveltime % (TICRATE/2) == 0 && player->rings > 0)
{
player->rings--;
S_StartSound(player->mo, sfx_itemup);
S_StartSound(player->mo, sfx_antiri);
}
break;
case 11: // Special Stage Damage
@ -4604,7 +4604,7 @@ DoneSection2:
HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE);
HU_SetCEchoDuration(5);
HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sBLUE FLAG%s.\\\\\\\\"), "\x85", player_names[player-players], "\x80", "\x84", "\x80"));
HU_DoCEcho(va(M_GetText("\205%s\200\\CAPTURED THE \204BLUE FLAG\200.\\\\\\\\"), player_names[player-players]));
if (splitscreen || players[consoleplayer].ctfteam == 1)
S_StartSound(NULL, sfx_flgcap);
@ -4637,7 +4637,7 @@ DoneSection2:
HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE);
HU_SetCEchoDuration(5);
HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sRED FLAG%s.\\\\\\\\"), "\x84", player_names[player-players], "\x80", "\x85", "\x80"));
HU_DoCEcho(va(M_GetText("\204%s\200\\CAPTURED THE \205RED FLAG\200.\\\\\\\\"), player_names[player-players]));
if (splitscreen || players[consoleplayer].ctfteam == 2)
S_StartSound(NULL, sfx_flgcap);
@ -4827,6 +4827,8 @@ DoneSection2:
if (player->laps >= (UINT8)cv_numlaps.value)
CONS_Printf(M_GetText("%s has finished the race.\n"), player_names[player-players]);
else if (player->laps == (UINT8)cv_numlaps.value-1)
CONS_Printf(M_GetText("%s started the \205final lap\200!\n"), player_names[player-players]);
else
CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1);

View file

@ -190,7 +190,7 @@ fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move)
boolean P_AutoPause(void)
{
// Don't pause even on menu-up or focus-lost in netgames or record attack
if (netgame || modeattacking || gamestate == GS_TITLESCREEN)
if (netgame || modeattacking || gamestate == GS_TITLESCREEN || (marathonmode && gamestate == GS_INTERMISSION))
return false;
return (menuactive || ( window_notinfocus && cv_pauseifunfocused.value ));
@ -4499,7 +4499,7 @@ void P_DoJump(player_t *player, boolean soundandstate)
if (twodlevel || (player->mo->flags2 & MF2_TWOD))
factor += player->jumpfactor / 10;
if (player->charflags & SF_MULTIABILITY && player->charability == CA_DOUBLEJUMP)
if (player->charflags & SF_MULTIABILITY && player->charability == CA_DOUBLEJUMP && (player->actionspd >> FRACBITS) != -1)
factor -= max(0, player->secondjump * player->jumpfactor / ((player->actionspd >> FRACBITS) + 1)); // Reduce the jump height each time
//if (maptol & TOL_NIGHTS)
@ -4880,22 +4880,28 @@ void P_DoBubbleBounce(player_t *player)
//
void P_DoAbilityBounce(player_t *player, boolean changemomz)
{
fixed_t prevmomz;
if (player->mo->state-states == S_PLAY_BOUNCE_LANDING)
return;
if (changemomz)
{
fixed_t minmomz;
prevmomz = player->mo->momz;
fixed_t prevmomz = player->mo->momz, minmomz;
if (P_MobjFlip(player->mo)*prevmomz < 0)
prevmomz = 0;
else if (player->mo->eflags & MFE_UNDERWATER)
prevmomz /= 2;
P_DoJump(player, false);
player->pflags &= ~(PF_STARTJUMP|PF_JUMPED);
minmomz = FixedMul(player->mo->momz, 3*FRACUNIT/2);
player->mo->momz = max(minmomz, (minmomz + prevmomz)/2);
if (player->mo->eflags & MFE_VERTICALFLIP) // Use "min" or "max" depending on if the player is flipped
player->mo->momz = min(minmomz, (minmomz + prevmomz)/2);
else
player->mo->momz = max(minmomz, (minmomz + prevmomz)/2);
}
S_StartSound(player->mo, sfx_boingf);
P_SetPlayerMobjState(player->mo, S_PLAY_BOUNCE_LANDING);
player->pflags |= PF_BOUNCING|PF_THOKKED;
@ -5024,7 +5030,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN)
&& ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted
{
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT)
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY))
{
if ((lockonshield = P_LookForEnemies(player, false, false)))
{
@ -5047,7 +5053,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
}
}
}
if (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player)) // Spin button effects
if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player))) // Spin button effects
{
// Force stop
if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE)
@ -5495,7 +5501,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
break;
}
}
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super])
else if ((!(player->charflags & SF_NOSHIELDABILITY)) && ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super] && !LUAh_ShieldSpecial(player)))
P_DoJumpShield(player);
}
@ -5924,7 +5930,7 @@ static void P_3dMovement(player_t *player)
player->rmomy = player->mo->momy - player->cmomy;
// Calculates player's speed based on distance-of-a-line formula
player->speed = R_PointToDist2(0, 0, player->rmomx, player->rmomy);
player->speed = P_AproxDistance(player->rmomx, player->rmomy);
// Monster Iestyn - 04-11-13
// Quadrants are stupid, excessive and broken, let's do this a much simpler way!
@ -7756,6 +7762,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale));
P_SetObjectMomZ(flame, 3*FRACUNIT, false);
if (!(gametyperules & GTR_FRIENDLY))
{
P_SetMobjState(flame, S_TEAM_SPINFIRE1);
flame->color = player->mo->color;
}
}
#undef limitangle
#undef numangles
@ -7783,6 +7794,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
flame->destscale = player->mo->scale;
P_SetScale(flame, player->mo->scale);
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
if (!(gametyperules & GTR_FRIENDLY))
{
P_SetMobjState(flame, S_TEAM_SPINFIRE1);
flame->color = player->mo->color;
}
flame->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others
P_XYMovement(flame);

View file

@ -134,9 +134,43 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
#define DEFAULT_STARTTRANSCOLOR 96
#define NUM_PALETTE_ENTRIES 256
static UINT8** translationtablecache[MAXSKINS + 7] = {NULL};
static UINT8 **translationtablecache[MAXSKINS + 7] = {NULL};
UINT8 skincolor_modified[MAXSKINCOLORS];
static INT32 SkinToCacheIndex(INT32 skinnum)
{
switch (skinnum)
{
case TC_DEFAULT: return DEFAULT_TT_CACHE_INDEX;
case TC_BOSS: return BOSS_TT_CACHE_INDEX;
case TC_METALSONIC: return METALSONIC_TT_CACHE_INDEX;
case TC_ALLWHITE: return ALLWHITE_TT_CACHE_INDEX;
case TC_RAINBOW: return RAINBOW_TT_CACHE_INDEX;
case TC_BLINK: return BLINK_TT_CACHE_INDEX;
case TC_DASHMODE: return DASHMODE_TT_CACHE_INDEX;
default: break;
}
return skinnum;
}
static INT32 CacheIndexToSkin(INT32 ttc)
{
switch (ttc)
{
case DEFAULT_TT_CACHE_INDEX: return TC_DEFAULT;
case BOSS_TT_CACHE_INDEX: return TC_BOSS;
case METALSONIC_TT_CACHE_INDEX: return TC_METALSONIC;
case ALLWHITE_TT_CACHE_INDEX: return TC_ALLWHITE;
case RAINBOW_TT_CACHE_INDEX: return TC_RAINBOW;
case BLINK_TT_CACHE_INDEX: return TC_BLINK;
case DASHMODE_TT_CACHE_INDEX: return TC_DASHMODE;
default: break;
}
return ttc;
}
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
#define TRANSTAB_AMTMUL10 (256.0f / 10.0f)
@ -308,7 +342,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor)
/** \brief Generates a translation colormap.
\param dest_colormap colormap to populate
\param skinnum number of skin, TC_DEFAULT or TC_BOSS
\param skinnum skin number, or a translation mode
\param color translation color
\return void
@ -412,6 +446,9 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
if (color >= numskincolors)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (skinnum < 0 && skinnum > TC_DEFAULT)
I_Error("Invalid translation colormap index %d.", skinnum);
starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR;
if (starttranscolor >= NUM_PALETTE_ENTRIES)
@ -448,25 +485,11 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags)
{
UINT8* ret;
INT32 skintableindex;
INT32 skintableindex = SkinToCacheIndex(skinnum); // Adjust if we want the default colormap
INT32 i;
// Adjust if we want the default colormap
switch (skinnum)
{
case TC_DEFAULT: skintableindex = DEFAULT_TT_CACHE_INDEX; break;
case TC_BOSS: skintableindex = BOSS_TT_CACHE_INDEX; break;
case TC_METALSONIC: skintableindex = METALSONIC_TT_CACHE_INDEX; break;
case TC_ALLWHITE: skintableindex = ALLWHITE_TT_CACHE_INDEX; break;
case TC_RAINBOW: skintableindex = RAINBOW_TT_CACHE_INDEX; break;
case TC_BLINK: skintableindex = BLINK_TT_CACHE_INDEX; break;
case TC_DASHMODE: skintableindex = DASHMODE_TT_CACHE_INDEX; break;
default: skintableindex = skinnum; break;
}
if (flags & GTC_CACHE)
{
// Allocate table for skin if necessary
if (!translationtablecache[skintableindex])
translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL);
@ -479,7 +502,8 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags
{
for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++)
if (translationtablecache[i] && translationtablecache[i][color])
R_GenerateTranslationColormap(translationtablecache[i][color], i>=MAXSKINS ? MAXSKINS-i-1 : i, color);
R_GenerateTranslationColormap(translationtablecache[i][color], CacheIndexToSkin(i), color);
skincolor_modified[color] = false;
}
}

View file

@ -544,21 +544,22 @@ void *Picture_GetPatchPixel(
UINT16 *s16 = NULL;
UINT32 *s32 = NULL;
softwarepatch_t *doompatch = (softwarepatch_t *)patch;
boolean isdoompatch = Picture_IsDoomPatchFormat(informat);
INT16 width;
if (patch == NULL)
I_Error("Picture_GetPatchPixel: patch == NULL");
width = (Picture_IsDoomPatchFormat(informat) ? patch->width : SHORT(patch->width));
width = (isdoompatch ? SHORT(doompatch->width) : patch->width);
if (x >= 0 && x < width)
{
INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x;
INT32 topdelta, prevdelta = -1;
INT32 colofs = (Picture_IsDoomPatchFormat(informat) ? LONG(patch->columnofs[colx]) : patch->columnofs[colx]);
INT32 colofs = (isdoompatch ? LONG(doompatch->columnofs[colx]) : patch->columnofs[colx]);
// Column offsets are pointers so no casting required
if (Picture_IsDoomPatchFormat(informat))
// Column offsets are pointers, so no casting is required.
if (isdoompatch)
column = (column_t *)((UINT8 *)doompatch + colofs);
else
column = (column_t *)((UINT8 *)patch->columns + colofs);

View file

@ -607,6 +607,7 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
void R_DrawPlanes(void)
{
visplane_t *pl;
angle_t va = viewangle;
INT32 i;
R_UpdatePlaneRipple();
@ -621,6 +622,8 @@ void R_DrawPlanes(void)
R_DrawSinglePlane(pl);
}
}
viewangle = va;
}
// R_DrawSkyPlane
@ -705,9 +708,9 @@ void R_CalculateSlopeVectors(pslope_t *slope, fixed_t planeviewx, fixed_t planev
n.z = -xscale * cos(ang);
ang = ANG2RAD(planeangle);
temp = P_GetSlopeZAt(slope, planeviewx + yscale * FLOAT_TO_FIXED(sin(ang)), planeviewy + yscale * FLOAT_TO_FIXED(cos(ang)));
temp = P_GetSlopeZAt(slope, planeviewx + FLOAT_TO_FIXED(yscale * sin(ang)), planeviewy + FLOAT_TO_FIXED(yscale * cos(ang)));
m.y = FIXED_TO_FLOAT(temp) - zeroheight;
temp = P_GetSlopeZAt(slope, planeviewx + xscale * FLOAT_TO_FIXED(cos(ang)), planeviewy - xscale * FLOAT_TO_FIXED(sin(ang)));
temp = P_GetSlopeZAt(slope, planeviewx + FLOAT_TO_FIXED(xscale * cos(ang)), planeviewy - FLOAT_TO_FIXED(xscale * sin(ang)));
n.y = FIXED_TO_FLOAT(temp) - zeroheight;
if (ds_powersoftwo)
@ -788,7 +791,6 @@ void R_DrawSinglePlane(visplane_t *pl)
ffloor_t *rover;
int type;
int spanfunctype = BASEDRAWFUNC;
angle_t viewang = viewangle;
if (!(pl->minx <= pl->maxx))
return;
@ -1153,8 +1155,6 @@ using the palette colors.
}
}
#endif
viewangle = viewang;
}
void R_PlaneBounds(visplane_t *plane)

View file

@ -1649,23 +1649,26 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// left
temp = xtoviewangle[start]+viewangle;
#define FIXED_TO_DOUBLE(x) (((double)(x)) / ((double)FRACUNIT))
#define DOUBLE_TO_FIXED(x) (fixed_t)((x) * ((double)FRACUNIT))
{
// Both lines can be written in slope-intercept form, so figure out line intersection
float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector...
///TODO: convert to FPU
double a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector...
///TODO: convert to fixed point
a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y);
b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x);
c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y);
a1 = FIXED_TO_DOUBLE(curline->v2->y-curline->v1->y);
b1 = FIXED_TO_DOUBLE(curline->v1->x-curline->v2->x);
c1 = a1*FIXED_TO_DOUBLE(curline->v1->x) + b1*FIXED_TO_DOUBLE(curline->v1->y);
a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT));
b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT));
c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy);
a2 = -FIXED_TO_DOUBLE(FINESINE(temp>>ANGLETOFINESHIFT));
b2 = FIXED_TO_DOUBLE(FINECOSINE(temp>>ANGLETOFINESHIFT));
c2 = a2*FIXED_TO_DOUBLE(viewx) + b2*FIXED_TO_DOUBLE(viewy);
det = a1*b2 - a2*b1;
ds_p->leftpos.x = segleft.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det);
ds_p->leftpos.y = segleft.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det);
ds_p->leftpos.x = segleft.x = DOUBLE_TO_FIXED((b2*c1 - b1*c2)/det);
ds_p->leftpos.y = segleft.y = DOUBLE_TO_FIXED((a1*c2 - a2*c1)/det);
}
// right
@ -1673,22 +1676,26 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
// Both lines can be written in slope-intercept form, so figure out line intersection
float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector...
///TODO: convert to FPU
double a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector...
///TODO: convert to fixed point
a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y);
b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x);
c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y);
a1 = FIXED_TO_DOUBLE(curline->v2->y-curline->v1->y);
b1 = FIXED_TO_DOUBLE(curline->v1->x-curline->v2->x);
c1 = a1*FIXED_TO_DOUBLE(curline->v1->x) + b1*FIXED_TO_DOUBLE(curline->v1->y);
a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT));
b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT));
c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy);
a2 = -FIXED_TO_DOUBLE(FINESINE(temp>>ANGLETOFINESHIFT));
b2 = FIXED_TO_DOUBLE(FINECOSINE(temp>>ANGLETOFINESHIFT));
c2 = a2*FIXED_TO_DOUBLE(viewx) + b2*FIXED_TO_DOUBLE(viewy);
det = a1*b2 - a2*b1;
ds_p->rightpos.x = segright.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det);
ds_p->rightpos.y = segright.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det);
ds_p->rightpos.x = segright.x = DOUBLE_TO_FIXED((b2*c1 - b1*c2)/det);
ds_p->rightpos.y = segright.y = DOUBLE_TO_FIXED((a1*c2 - a2*c1)/det);
}
#undef FIXED_TO_DOUBLE
#undef DOUBLE_TO_FIXED
}

View file

@ -514,6 +514,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
GETFLAG(NOSUPERSPRITES)
GETFLAG(NOSUPERJUMPBOOST)
GETFLAG(CANBUSTWALLS)
GETFLAG(NOSHIELDABILITY)
#undef GETFLAG
else // let's check if it's a sound, otherwise error out

View file

@ -604,7 +604,7 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
levelflat->height = ds_flatheight = SHORT(patch->height);
levelflat->picture = Z_Malloc(levelflat->width * levelflat->height, PU_LEVEL, NULL);
converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, patch->topoffset, patch->leftoffset, 0);
converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, SHORT(patch->topoffset), SHORT(patch->leftoffset), 0);
M_Memcpy(levelflat->picture, converted, size);
Z_Free(converted);
}

View file

@ -796,7 +796,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
INT32 pwidth;
fixed_t frac;
patch_t *patch = vis->patch;
fixed_t this_scale = vis->mobj->scale;
fixed_t this_scale = vis->thingscale;
INT32 x1, x2;
INT64 overflow_test;
@ -1078,6 +1078,14 @@ static void R_SplitSprite(vissprite_t *sprite)
sprite->sz = cutfrac;
newsprite->szt = (INT16)(sprite->sz - 1);
if (testheight < sprite->pzt && testheight > sprite->pz)
sprite->pz = newsprite->pzt = testheight;
else
{
newsprite->pz = newsprite->gz;
newsprite->pzt = newsprite->gzt;
}
newsprite->szt -= 8;
newsprite->cut |= SC_TOP;
@ -1300,12 +1308,16 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadow->patch = patch;
shadow->heightsec = vis->heightsec;
shadow->thingheight = FRACUNIT;
shadow->pz = groundz + (isflipped ? -shadow->thingheight : 0);
shadow->pzt = shadow->pz + shadow->thingheight;
shadow->mobjflags = 0;
shadow->sortscale = vis->sortscale;
shadow->dispoffset = vis->dispoffset - 5;
shadow->gx = thing->x;
shadow->gy = thing->y;
shadow->gzt = groundz + patch->height * shadowyscale / 2;
shadow->gzt = (isflipped ? shadow->pzt : shadow->pz) + patch->height * shadowyscale / 2;
shadow->gz = shadow->gzt - patch->height * shadowyscale;
shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
@ -1320,6 +1332,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000
shadow->scale = FixedMul(yscale, shadowyscale);
shadow->thingscale = thing->scale;
shadow->sector = vis->sector;
shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS);
shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS);
@ -1411,7 +1424,7 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t sheartan = 0;
fixed_t shadowscale = FRACUNIT;
fixed_t basetx; // drop shadows
fixed_t basetx, basetz; // drop shadows
boolean shadowdraw, shadoweffects, shadowskew;
boolean splat = R_ThingIsFloorSprite(thing);
@ -1441,7 +1454,7 @@ static void R_ProjectSprite(mobj_t *thing)
tr_x = thing->x - viewx;
tr_y = thing->y - viewy;
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
basetz = tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
// thing is behind view plane?
if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
@ -1935,6 +1948,9 @@ static void R_ProjectSprite(mobj_t *thing)
vis->gy = thing->y;
vis->gz = gz;
vis->gzt = gzt;
vis->thingheight = thing->height;
vis->pz = thing->z;
vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = FixedDiv(gzt - viewz, spriteyscale);
vis->scalestep = scalestep;
vis->paperoffset = paperoffset;
@ -1960,6 +1976,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->xscale = FixedMul(spritexscale, xscale); //SoM: 4/17/2000
vis->scale = FixedMul(spriteyscale, yscale); //<<detailshift;
vis->thingscale = oldthing->scale;
vis->spritexscale = spritexscale;
vis->spriteyscale = spriteyscale;
@ -2037,7 +2054,7 @@ static void R_ProjectSprite(mobj_t *thing)
R_SplitSprite(vis);
if (oldthing->shadowscale && cv_shadow.value)
R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, tz);
R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, basetz);
// Debug
++objectsdrawn;
@ -2151,6 +2168,9 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->gy = thing->y;
vis->gz = gz;
vis->gzt = gzt;
vis->thingheight = 4*FRACUNIT;
vis->pz = thing->z;
vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = vis->gzt - viewz;
vis->scalestep = 0;
vis->paperdistance = 0;
@ -2544,15 +2564,19 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy, r2->plane->height);
planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy, r2->plane->height);
// bird: if any part of the sprite peeks in front the plane
if (planecameraz < viewz)
if (rover->mobjflags & MF_NOCLIPHEIGHT)
{
if (rover->gzt >= planeobjectz)
//Objects with NOCLIPHEIGHT can appear halfway in.
if (planecameraz < viewz && rover->pz+(rover->thingheight/2) >= planeobjectz)
continue;
if (planecameraz > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz)
continue;
}
else if (planecameraz > viewz)
else
{
if (rover->gz <= planeobjectz)
if (planecameraz < viewz && rover->pz >= planeobjectz)
continue;
if (planecameraz > viewz && rover->pzt <= planeobjectz)
continue;
}
@ -2585,7 +2609,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
}
else if (r2->thickseg)
{
//fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz;
fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz;
if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1)
continue;
@ -2596,11 +2620,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
if (scale <= rover->sortscale)
continue;
// bird: Always sort sprites behind segs. This helps the plane
// sorting above too. Basically if the sprite gets sorted behind
// the seg here, it will be behind the plane too, since planes
// are added after segs in the list.
#if 0
topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy);
topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy);
botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy);
@ -2609,7 +2628,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
if ((topplanecameraz > viewz && botplanecameraz < viewz) ||
(topplanecameraz < viewz && rover->gzt < topplaneobjectz) ||
(botplanecameraz > viewz && rover->gz > botplaneobjectz))
#endif
{
entry = R_CreateDrawNode(NULL);
(entry->prev = r2->prev)->next = entry;
@ -2650,11 +2668,23 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
if (!behind)
{
// FIXME: calculate gz and gzt for splats properly and use that
if (rover->mobj->z < viewz)
infront = (r2->sprite->mobj->z >= rover->mobj->z);
fixed_t z1 = 0, z2 = 0;
if (rover->mobj->z - viewz > 0)
{
z1 = rover->pz;
z2 = r2->sprite->pz;
}
else
infront = (r2->sprite->mobj->z <= rover->mobj->z);
{
z1 = r2->sprite->pz;
z2 = rover->pz;
}
z1 -= viewz;
z2 -= viewz;
infront = (z1 >= z2);
}
}
else

View file

@ -151,10 +151,12 @@ typedef struct vissprite_s
INT32 x1, x2;
fixed_t gx, gy; // for line side calculation
fixed_t gz, gzt; // global bottom/top for silhouette clipping and sorting with 3D floors
fixed_t gz, gzt; // global bottom/top for silhouette clipping
fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors
fixed_t startfrac; // horizontal position of x1
fixed_t scale;
fixed_t xscale, scale; // projected horizontal and vertical scales
fixed_t thingscale; // the object's scale
fixed_t sortscale; // sortscale only differs from scale for paper sprites, floor sprites, and MF2_LINKDRAW
fixed_t sortsplat; // the sortscale from behind the floor sprite
fixed_t scalestep; // only for paper sprites, 0 otherwise
@ -182,9 +184,8 @@ typedef struct vissprite_s
extracolormap_t *extra_colormap; // global colormaps
fixed_t xscale;
// Precalculated top and bottom screen coords for the sprite.
fixed_t thingheight; // The actual height of the thing (for 3D floors)
sector_t *sector; // The sector containing the thing.
INT16 sz, szt;

View file

@ -222,7 +222,7 @@ void SCR_SetMode(void)
// Set the video mode in the video interface.
if (setmodeneeded)
VID_SetMode(--setmodeneeded);
VID_SetMode(setmodeneeded - 1);
V_SetPalette(0);

View file

@ -90,7 +90,6 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(ReadRect);
GETFUNC(GClipRect);
GETFUNC(ClearMipMapCache);
GETFUNC(ClearCacheList);
GETFUNC(SetSpecialState);
GETFUNC(GetTextureUsed);
GETFUNC(DrawModel);

View file

@ -137,6 +137,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include <errno.h>
#endif
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#include <execinfo.h>
#include <time.h>
#define UNIXBACKTRACE
#endif
// Locations for searching the srb2.pk3
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2"
@ -238,6 +244,71 @@ SDL_bool framebuffer = SDL_FALSE;
UINT8 keyboard_started = false;
#ifdef UNIXBACKTRACE
#define STDERR_WRITE(string) if (fd != -1) I_OutputMsg("%s", string)
#define CRASHLOG_WRITE(string) if (fd != -1) write(fd, string, strlen(string))
#define CRASHLOG_STDERR_WRITE(string) \
if (fd != -1)\
write(fd, string, strlen(string));\
I_OutputMsg("%s", string)
static void write_backtrace(INT32 signal)
{
int fd = -1;
size_t size;
time_t rawtime;
struct tm timeinfo;
enum { BT_SIZE = 1024, STR_SIZE = 32 };
void *array[BT_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 *error2 = "(Or find crash-log.txt in your SRB2 directory.)\n"; // Shown only to stderr.
fd = open(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR);
if (fd == -1)
I_OutputMsg("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n");
// Get the current time as a string.
time(&rawtime);
localtime_r(&rawtime, &timeinfo);
strftime(timestr, STR_SIZE, "%a, %d %b %Y %T %z", &timeinfo);
CRASHLOG_WRITE("------------------------\n"); // Nice looking seperator
CRASHLOG_STDERR_WRITE("\n"); // Newline to look nice for both outputs.
CRASHLOG_STDERR_WRITE(error); // "Oops, SRB2 crashed" message
STDERR_WRITE(error2); // Tell the user where the crash log is.
// Tell the log when we crashed.
CRASHLOG_WRITE("Time of crash: ");
CRASHLOG_WRITE(timestr);
CRASHLOG_WRITE("\n");
// Give the crash log the cause and a nice 'Backtrace:' thing
// The signal is given to the user when the parent process sees we crashed.
CRASHLOG_WRITE("Cause: ");
CRASHLOG_WRITE(strsignal(signal));
CRASHLOG_WRITE("\n"); // Newline for the signal name
CRASHLOG_STDERR_WRITE("\nBacktrace:\n");
// Flood the output and log with the backtrace
size = backtrace(array, BT_SIZE);
backtrace_symbols_fd(array, size, fd);
backtrace_symbols_fd(array, size, STDERR_FILENO);
CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :)
close(fd);
}
#undef STDERR_WRITE
#undef CRASHLOG_WRITE
#undef CRASHLOG_STDERR_WRITE
#endif // UNIXBACKTRACE
static void I_ReportSignal(int num, int coredumped)
{
//static char msg[] = "oh no! back to reality!\r\n";
@ -297,6 +368,9 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
{
D_QuitNetGame(); // Fix server freezes
CL_AbortDownloadResume();
#ifdef UNIXBACKTRACE
write_backtrace(num);
#endif
I_ReportSignal(num, 0);
I_ShutdownSystem();
signal(num, SIG_DFL); //default signal action
@ -687,6 +761,28 @@ static void I_RegisterSignals (void)
#endif
}
#ifdef NEWSIGNALHANDLER
static void signal_handler_child(INT32 num)
{
#ifdef UNIXBACKTRACE
write_backtrace(num);
#endif
signal(num, SIG_DFL); //default signal action
raise(num);
}
static void I_RegisterChildSignals(void)
{
// If these defines don't exist,
// then compilation would have failed above us...
signal(SIGILL , signal_handler_child);
signal(SIGSEGV , signal_handler_child);
signal(SIGABRT , signal_handler_child);
signal(SIGFPE , signal_handler_child);
}
#endif
//
//I_OutputMsg
//
@ -2123,6 +2219,7 @@ static void I_Fork(void)
newsignalhandler_Warn("fork()");
break;
case 0:
I_RegisterChildSignals();
break;
default:
if (logstream)

View file

@ -1862,7 +1862,6 @@ void VID_StartupOpenGL(void)
HWD.pfnReadRect = hwSym("ReadRect",NULL);
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
HWD.pfnClearCacheList = hwSym("ClearCacheList",NULL);
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);

View file

@ -1298,6 +1298,10 @@ boolean I_PlaySong(boolean looping)
if (gme)
{
gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
#if defined (GME_VERSION) && GME_VERSION >= 0x000603
if (looping)
gme_set_autoload_playback_limit(gme, 0);
#endif
gme_set_equalizer(gme, &eq);
gme_start_track(gme, 0);
current_track = 0;

View file

@ -15,6 +15,11 @@
#include "z_zone.h"
#include "r_data.h"
// Bit array of whether a tag exists for sectors/lines/things.
bitarray_t tags_available[BIT_ARRAY_SIZE (MAXTAGS)];
size_t num_tags;
// Taggroups are used to list elements of the same tag, for iteration.
// Since elements can now have multiple tags, it means an element may appear
// in several taggroups at the same time. These are built on level load.
@ -105,6 +110,39 @@ size_t Taggroup_Find (const taggroup_t *group, const size_t id)
return -1;
}
/// group->count, but also checks for NULL
size_t Taggroup_Count (const taggroup_t *group)
{
return group ? group->count : 0;
}
/// Iterate thru elements in a global taggroup.
INT32 Taggroup_Iterate
( taggroup_t *garray[],
const size_t max_elements,
const mtag_t tag,
const size_t p)
{
const taggroup_t *group;
if (tag == MTAG_GLOBAL)
{
if (p < max_elements)
return p;
return -1;
}
group = garray[(UINT16)tag];
if (group)
{
if (p < group->count)
return group->elements[p];
return -1;
}
return -1;
}
/// Add an element to a global taggroup.
void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id)
{
@ -120,6 +158,12 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id)
if (Taggroup_Find(group, id) != (size_t)-1)
return;
if (! in_bit_array(tags_available, tag))
{
num_tags++;
set_bit_array(tags_available, tag);
}
// Create group if empty.
if (!group)
{
@ -133,25 +177,34 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id)
for (i = 0; i < group->count; i++)
if (group->elements[i] > id)
break;
group->elements = Z_Realloc(group->elements, (group->count + 1) * sizeof(size_t), PU_LEVEL, NULL);
// Offset existing elements to make room for the new one.
if (i < group->count)
memmove(&group->elements[i + 1], &group->elements[i], group->count - i);
}
group->elements = Z_Realloc(group->elements, (group->count + 1) * sizeof(size_t), PU_LEVEL, NULL);
// Offset existing elements to make room for the new one.
if (i < group->count)
memmove(&group->elements[i + 1], &group->elements[i], group->count - i);
group->count++;
group->elements = Z_Realloc(group->elements, group->count * sizeof(size_t), PU_LEVEL, NULL);
group->elements[i] = id;
}
static size_t total_elements_with_tag (const mtag_t tag)
{
return
(
Taggroup_Count(tags_sectors[tag]) +
Taggroup_Count(tags_lines[tag]) +
Taggroup_Count(tags_mapthings[tag])
);
}
/// Remove an element from a global taggroup.
void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id)
{
taggroup_t *group;
size_t rempos;
size_t newcount;
size_t oldcount;
if (tag == MTAG_GLOBAL)
return;
@ -161,8 +214,14 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id)
if ((rempos = Taggroup_Find(group, id)) == (size_t)-1)
return;
if (group->count == 1 && total_elements_with_tag(tag) == 1)
{
num_tags--;
unset_bit_array(tags_available, tag);
}
// Strip away taggroup if no elements left.
if (!(newcount = --group->count))
if (!(oldcount = group->count--))
{
Z_Free(group->elements);
Z_Free(group);
@ -170,19 +229,18 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id)
}
else
{
size_t *newelements = Z_Malloc(newcount * sizeof(size_t), PU_LEVEL, NULL);
size_t *newelements = Z_Malloc(group->count * sizeof(size_t), PU_LEVEL, NULL);
size_t i;
// Copy the previous entries save for the one to remove.
for (i = 0; i < rempos; i++)
newelements[i] = group->elements[i];
for (i = rempos + 1; i < group->count; i++)
for (i = rempos + 1; i < oldcount; i++)
newelements[i - 1] = group->elements[i];
Z_Free(group->elements);
group->elements = newelements;
group->count = newcount;
}
}
@ -209,6 +267,9 @@ void Taglist_InitGlobalTables(void)
{
size_t i, j;
memset(tags_available, 0, sizeof tags_available);
num_tags = 0;
for (i = 0; i < MAXTAGS; i++)
{
tags_sectors[i] = NULL;
@ -236,56 +297,17 @@ void Taglist_InitGlobalTables(void)
INT32 Tag_Iterate_Sectors (const mtag_t tag, const size_t p)
{
if (tag == MTAG_GLOBAL)
{
if (p < numsectors)
return p;
return -1;
}
if (tags_sectors[(UINT16)tag])
{
if (p < tags_sectors[(UINT16)tag]->count)
return tags_sectors[(UINT16)tag]->elements[p];
return -1;
}
return -1;
return Taggroup_Iterate(tags_sectors, numsectors, tag, p);
}
INT32 Tag_Iterate_Lines (const mtag_t tag, const size_t p)
{
if (tag == MTAG_GLOBAL)
{
if (p < numlines)
return p;
return -1;
}
if (tags_lines[(UINT16)tag])
{
if (p < tags_lines[(UINT16)tag]->count)
return tags_lines[(UINT16)tag]->elements[p];
return -1;
}
return -1;
return Taggroup_Iterate(tags_lines, numlines, tag, p);
}
INT32 Tag_Iterate_Things (const mtag_t tag, const size_t p)
{
if (tag == MTAG_GLOBAL)
{
if (p < nummapthings)
return p;
return -1;
}
if (tags_mapthings[(UINT16)tag])
{
if (p < tags_mapthings[(UINT16)tag]->count)
return tags_mapthings[(UINT16)tag]->elements[p];
return -1;
}
return -1;
return Taggroup_Iterate(tags_mapthings, nummapthings, tag, p);
}
INT32 Tag_FindLineSpecial(const INT16 special, const mtag_t tag)

View file

@ -43,6 +43,10 @@ typedef struct
size_t count;
} taggroup_t;
extern bitarray_t tags_available[];
extern size_t num_tags;
extern taggroup_t* tags_sectors[];
extern taggroup_t* tags_lines[];
extern taggroup_t* tags_mapthings[];
@ -50,6 +54,13 @@ extern taggroup_t* tags_mapthings[];
void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id);
void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id);
size_t Taggroup_Find (const taggroup_t *group, const size_t id);
size_t Taggroup_Count (const taggroup_t *group);
INT32 Taggroup_Iterate
( taggroup_t *garray[],
const size_t max_elements,
const mtag_t tag,
const size_t p);
void Taglist_InitGlobalTables(void);

View file

@ -821,7 +821,8 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
}
if (important && !mainfile)
G_SetGameModified(true);
//G_SetGameModified(true);
modifiedgame = true; // avoid savemoddata being set to false
//
// link wad file to search files
@ -1682,26 +1683,12 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
// read the lump in full
W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0);
ptr = lumpdata;
#ifndef NO_PNG_LUMPS
// lump is a png so convert it
if (Picture_IsLumpPNG((UINT8 *)lumpdata, len))
{
size_t newlen;
void *converted = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &newlen, 0);
ptr = Z_Malloc(newlen, PU_STATIC, NULL);
M_Memcpy(ptr, converted, newlen);
Z_Free(converted);
len = newlen;
}
else // just copy it into the patch cache
ptr = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &len, 0);
#endif
{
ptr = Z_Malloc(len, PU_STATIC, NULL);
M_Memcpy(ptr, lumpdata, len);
}
Z_Free(lumpdata);
dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]);
Patch_Create(ptr, len, dest);

View file

@ -111,7 +111,6 @@ static loadfunc_t hwdFuncTable[] = {
{"ReadRect@24", &hwdriver.pfnReadRect},
{"GClipRect@20", &hwdriver.pfnGClipRect},
{"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache},
{"ClearCacheList@0", &hwdriver.pfnClearCacheList},
{"SetSpecialState@8", &hwdriver.pfnSetSpecialState},
{"DrawModel@16", &hwdriver.pfnDrawModel},
{"SetTransform@4", &hwdriver.pfnSetTransform},
@ -145,7 +144,6 @@ static loadfunc_t hwdFuncTable[] = {
{"ReadRect", &hwdriver.pfnReadRect},
{"GClipRect", &hwdriver.pfnGClipRect},
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},
{"ClearCacheList", &hwdriver.pfnClearCacheList},
{"SetSpecialState", &hwdriver.pfnSetSpecialState},
{"DrawModel", &hwdriver.pfnDrawModel},
{"SetTransform", &hwdriver.pfnSetTransform},

View file

@ -1229,7 +1229,10 @@ void Y_StartIntermission(void)
data.coop.tics = players[consoleplayer].realtime;
for (i = 0; i < 4; ++i)
data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH);
{
if (strlen(data.coop.bonuses[i].patch))
data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH);
}
data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH);
// get act number
@ -1733,7 +1736,6 @@ static void Y_SetNullBonus(player_t *player, y_bonus_t *bstruct)
{
(void)player;
memset(bstruct, 0, sizeof(y_bonus_t));
strncpy(bstruct->patch, "MISSING", sizeof(bstruct->patch));
}
//

View file

@ -813,12 +813,12 @@ static void Command_Memfree_f(void)
#ifdef HWRENDER
if (rendermode == render_opengl)
{
CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10));
CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10));
CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10));
CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10));
CONS_Printf(M_GetText("HW model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10));
CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10);
CONS_Printf(M_GetText("Patch info headers : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10));
CONS_Printf(M_GetText("Cached textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10));
CONS_Printf(M_GetText("Texture colormaps : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10));
CONS_Printf(M_GetText("Model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10));
CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10));
CONS_Printf(M_GetText("All GPU textures : %7d KB\n"), HWR_GetTextureUsed()>>10);
}
#endif

View file

@ -68,8 +68,7 @@ enum
PU_HWRCACHE_UNLOCKED = 102, // 'unlocked' PU_HWRCACHE memory:
// 'second-level' cache for graphics
// stored in hardware format and downloaded as needed
PU_HWRPATCHINFO_UNLOCKED = 103, // 'unlocked' PU_HWRPATCHINFO memory
PU_HWRMODELTEXTURE_UNLOCKED = 104, // 'unlocked' PU_HWRMODELTEXTURE memory
PU_HWRMODELTEXTURE_UNLOCKED = 103, // 'unlocked' PU_HWRMODELTEXTURE memory
};
//