mirror of
https://github.com/nzp-team/fteqw.git
synced 2025-01-31 12:40:43 +00:00
destroy software rendering and break everything (and that won't be all!)
also note that merged builds on non-windows no longer make much sense git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3283 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
fb2b58979b
commit
a94a33212c
108 changed files with 2702 additions and 47022 deletions
182
engine/Makefile
182
engine/Makefile
|
@ -150,7 +150,6 @@ endif
|
|||
|
||||
CLIENT_DIR=$(BASE_DIR)/client
|
||||
GL_DIR=$(BASE_DIR)/gl
|
||||
SW_DIR=$(BASE_DIR)/sw
|
||||
D3D7_DIR=$(BASE_DIR)/d3d
|
||||
D3D9_DIR=$(BASE_DIR)/d3d9
|
||||
SERVER_DIR=$(BASE_DIR)/server
|
||||
|
@ -234,7 +233,7 @@ else
|
|||
BASE_ASM_CFLAGS = -DNOASM
|
||||
endif
|
||||
|
||||
BASE_CFLAGS=$(BASE_ASM_CFLAGS) -Wall -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(SW_DIR) -I$(GL_DIR) -I$(D3D9_DIR) -I$(D3D7_DIR) -I$(PROGS_DIR) -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk7/include -I$(LIBS_DIR)/sdl/include -I$(LIBS_DIR)/sdl/include/SDL -D_vsnprintf=vsnprintf -D_snprintf=snprintf
|
||||
BASE_CFLAGS=$(BASE_ASM_CFLAGS) -Wall -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D9_DIR) -I$(D3D7_DIR) -I$(PROGS_DIR) -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk7/include -I$(LIBS_DIR)/sdl/include -I$(LIBS_DIR)/sdl/include/SDL -D_vsnprintf=vsnprintf -D_snprintf=snprintf
|
||||
CLIENT_ONLY_CFLAGS=-DCLIENTONLY
|
||||
SERVER_ONLY_CFLAGS=-DSERVERONLY
|
||||
JOINT_CFLAGS=
|
||||
|
@ -250,7 +249,6 @@ RELEASE_CFLAGS ?= -O2 -fno-strict-aliasing $(CPUOPTIMIZATIONS)
|
|||
#RELEASE_CFLAGS=-O6 -fno-strict-aliasing -ffast-math -funroll-loops -fexpensive-optimizations $(CPUOPTIMIZATIONS)
|
||||
|
||||
GLCFLAGS=-DGLQUAKE
|
||||
SWCFLAGS=-DSWQUAKE
|
||||
D3DCFLAGS=-DD3DQUAKE
|
||||
NPQTVCFLAGS=-DNPQTV
|
||||
|
||||
|
@ -315,38 +313,6 @@ CLIENT_OBJS = $(CLIENT_ASM_OBJS) \
|
|||
\
|
||||
pr_menu.o
|
||||
|
||||
|
||||
SOFTWARE_OBJS = $(SOFTWARE_ASM_OBJS) \
|
||||
sw_screen.o \
|
||||
sw_draw.o \
|
||||
sw_model.o \
|
||||
r_aclip.o \
|
||||
r_alias.o \
|
||||
r_bsp.o \
|
||||
r_draw.o \
|
||||
r_edge.o \
|
||||
r_light.o \
|
||||
r_main.o \
|
||||
r_misc.o \
|
||||
r_sky.o \
|
||||
r_sprite.o \
|
||||
r_surf.o \
|
||||
r_vars.o \
|
||||
d_edge.o \
|
||||
d_fill.o \
|
||||
d_init.o \
|
||||
d_modech.o \
|
||||
d_part.o \
|
||||
d_polyse.o \
|
||||
d_scan.o \
|
||||
d_sky.o \
|
||||
d_sprite.o \
|
||||
d_surf.o \
|
||||
d_trans.o \
|
||||
d_vars.o \
|
||||
d_zpoint.o \
|
||||
nonintel.o
|
||||
|
||||
GLQUAKE_OBJS = \
|
||||
gl_alias.o \
|
||||
gl_draw.o \
|
||||
|
@ -495,19 +461,6 @@ GL_CFLAGS=$(GLCFLAGS) `sdl-config --cflags`
|
|||
GLB_DIR=gl_sdl$(BITS)
|
||||
GLCL_DIR=glcl_sdl$(BITS)
|
||||
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) vid_sdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
|
||||
SW_EXE_NAME=../fteqw_sdl.sw$(BITS)
|
||||
SWCL_EXE_NAME=../fteqwcl_sdl.sw$(BITS)
|
||||
ifdef windir
|
||||
SW_LDFLAGS=$(SWLDFLAGS) -lmingw32 -lws2_32 -lSDLmain -lSDL
|
||||
else
|
||||
#pthread is needed because of SDL.
|
||||
SW_LDFLAGS=$(SWLDFLAGS) `sdl-config --libs` $(IMAGELDFLAGS)
|
||||
endif
|
||||
SW_CFLAGS=$(SWCFLAGS) `sdl-config --cflags`
|
||||
SWB_DIR=sw_sdl$(BITS)
|
||||
SWCL_DIR=swcl_sdl$(BITS)
|
||||
|
||||
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS)
|
||||
SV_EXE_NAME=../fteqw_sdl.sv$(BITS)
|
||||
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -lz
|
||||
|
@ -518,7 +471,7 @@ MINGL_EXE_NAME=../fteqw_sdl.mingl$(BITS)
|
|||
MB_DIR=m_sdl$(BITS)
|
||||
M_EXE_NAME=../fteqw_sdl$(BITS)
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidsdl.o vid_sdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
|
||||
M_CFLAGS=$(SWCFLAGS) $(GLCFLAGS) `sdl-config --cflags` -D_MERGED_SDL
|
||||
M_CFLAGS=$(GLCFLAGS) `sdl-config --cflags` -D_MERGED_SDL
|
||||
M_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS)
|
||||
|
||||
ifdef windir
|
||||
|
@ -547,19 +500,6 @@ ifeq ($(FTE_TARGET),win32_SDL)
|
|||
GLB_DIR=gl_mgw_sdl$(BITS)
|
||||
GLCL_DIR=glcl_mgw_sdl$(BITS)
|
||||
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) vid_sdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o resources.o
|
||||
SW_EXE_NAME=../fteqw_sdl_sw.exe
|
||||
SWCL_EXE_NAME=../fteqwcl_sdl.exe
|
||||
ifdef windir
|
||||
SW_LDFLAGS=$(SWLDFLAGS) -lmingw32 -lws2_32 -lSDLmain -lSDL
|
||||
else
|
||||
#pthread is needed because of SDL.
|
||||
SW_LDFLAGS=$(IMAGELDFLAGS) -lws2_32 -lmingw32 ./libs/mingw-libs/libSDL.a ./libs/mingw-libs/libSDLmain.a -mwindows -ldxguid -lwinmm -lole32 $(SWLDFLAGS) `sdl-config --libs` $(IMAGELDFLAGS)
|
||||
endif
|
||||
SW_CFLAGS=-D_MINGW_VFPRINTF -D_SDL -I./libs/ -I./libs/mingw-libs/ -I./libs/dxsdk7/include/ -I./libs/mingw-libs $(SWCFLAGS) `sdl-config --cflags`
|
||||
SWB_DIR=sw_mgw_sdl$(BITS)
|
||||
SWCL_DIR=swcl_mgw_sdl$(BITS)
|
||||
|
||||
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) resources.o
|
||||
SV_EXE_NAME=../fteqw_sdl_sv.exe
|
||||
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -D_SDL
|
||||
|
@ -571,7 +511,7 @@ ifeq ($(FTE_TARGET),win32_SDL)
|
|||
MB_DIR=m_mgw_sdl$(BITS)
|
||||
M_EXE_NAME=../fteqw_sdl.exe
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidsdl.o vid_sdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o resources.o
|
||||
M_CFLAGS=-D_MINGW_VFPRINTF -D_SDL -I./libs/ -I./libs/mingw-libs/ -I./libs/dxsdk7/include/ -I./libs/mingw-libs $(SWCFLAGS) $(GLCFLAGS) `sdl-config --cflags` -D_MERGED_SDL
|
||||
M_CFLAGS=-D_MINGW_VFPRINTF -D_SDL -I./libs/ -I./libs/mingw-libs/ -I./libs/dxsdk7/include/ -I./libs/mingw-libs $(GLCFLAGS) `sdl-config --cflags` -D_MERGED_SDL
|
||||
M_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS)
|
||||
|
||||
ifdef windir
|
||||
|
@ -624,18 +564,6 @@ endif
|
|||
NPQTVB_DIR=npqtv_mgw
|
||||
NPQTVCL_DIR=npqtvcl_mgw
|
||||
|
||||
ifeq ($(USEASM),true)
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) fs_win32.o vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_dosa.o resources.o
|
||||
else
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) fs_win32.o vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o resources.o
|
||||
endif
|
||||
SW_EXE_NAME=../fteswqw.exe
|
||||
SWCL_EXE_NAME=../fteswqwcl.exe
|
||||
SW_LDFLAGS=$(SWLDFLAGS) $(IMAGELDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32
|
||||
SW_CFLAGS=$(SWCFLAGS) $(W32_CFLAGS)
|
||||
SWB_DIR=sw_mgw
|
||||
SWCL_DIR=swcl_mgw
|
||||
|
||||
ifeq ($(USEASM),true)
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) fs_win32.o gl_vidnt.o vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_dosa.o resources.o
|
||||
else
|
||||
|
@ -644,7 +572,7 @@ endif
|
|||
M_EXE_NAME=../fteqw.exe
|
||||
MCL_EXE_NAME=../fteqwcl.exe
|
||||
M_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32
|
||||
M_CFLAGS=$(SWCFLAGS) $(GLCFLAGS) $(W32_CFLAGS)
|
||||
M_CFLAGS=$(GLCFLAGS) $(W32_CFLAGS)
|
||||
MB_DIR=m_mgw
|
||||
MCL_DIR=mcl_mgw
|
||||
|
||||
|
@ -679,26 +607,14 @@ endif
|
|||
GLCL_DIR=glcl_bsd
|
||||
|
||||
ifeq ($(USEASM),true)
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) vid_x.o snd_linux.o cd_null.o sys_linux.o sys_dosa.o
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_dosa.o
|
||||
else
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) vid_x.o snd_linux.o cd_null.o sys_linux.o
|
||||
endif
|
||||
SW_EXE_NAME=../fteqw.sw
|
||||
SWCL_EXE_NAME=../fteqwcl.sw
|
||||
SW_LDFLAGS=-L/usr/local/lib $(SWLDFLAGS) $(XLDFLAGS) -lXxf86vm -lpthread
|
||||
SW_CFLAGS=$(SWCFLAGS) -I/usr/local/include -I/usr/X11R6/include
|
||||
SWB_DIR=sw_bsd
|
||||
SWCL_DIR=swcl_bsd
|
||||
|
||||
ifeq ($(USEASM),true)
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o vid_x.o snd_linux.o cd_null.o sys_linux.o sys_dosa.o
|
||||
else
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o vid_x.o snd_linux.o cd_null.o sys_linux.o
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o
|
||||
endif
|
||||
M_EXE_NAME=../fteqw
|
||||
MCL_EXE_NAME=../fteqwcl
|
||||
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm -lpthread
|
||||
M_CFLAGS=$(SWCFLAGS) $(GLCFLAGS) -I/usr/X11R6/include
|
||||
M_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include
|
||||
MB_DIR=m_bsd
|
||||
MCL_DIR=mcl_bsd
|
||||
|
||||
|
@ -722,25 +638,14 @@ endif
|
|||
GLB_DIR=gl_linux$(BITS)
|
||||
GLCL_DIR=glcl_linux$(BITS)
|
||||
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) vid_x.o snd_linux.o snd_alsa.oo cd_linux.o sys_linux.o
|
||||
ifeq ($(USEASM),true)
|
||||
SWCL_OBJS+= sys_dosa.o
|
||||
endif
|
||||
SW_EXE_NAME=../fteqw.sw$(BITS)
|
||||
SWCL_EXE_NAME=../fteqwcl.sw$(BITS)
|
||||
SW_LDFLAGS=$(SWLDFLAGS) $(XLDFLAGS) -lXxf86vm -lXxf86dga
|
||||
SW_CFLAGS=$(SWCFLAGS) -I/usr/X11R6/include
|
||||
SWB_DIR=sw_linux$(BITS)
|
||||
SWCL_DIR=swcl_linux$(BITS)
|
||||
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o vid_x.o snd_linux.o snd_alsa.oo cd_linux.o sys_linux.o
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o snd_linux.o snd_alsa.oo cd_linux.o sys_linux.o
|
||||
ifeq ($(USEASM),true)
|
||||
MCL_OBJS+= sys_dosa.o
|
||||
endif
|
||||
M_EXE_NAME=../fteqw$(BITS)
|
||||
MCL_EXE_NAME=../fteqwcl$(BITS)
|
||||
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS) -lXxf86vm -lXxf86dga
|
||||
M_CFLAGS=$(SWCFLAGS) $(GLCFLAGS) -I/usr/X11R6/include
|
||||
M_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include
|
||||
MB_DIR=m_linux$(BITS)
|
||||
MCL_DIR=mcl_linux$(BITS)
|
||||
|
||||
|
@ -754,21 +659,13 @@ ifneq ($(shell echo $(FTE_TARGET)|grep macosx),)
|
|||
GLB_DIR=gl_macosx$(EXTENSION)$(BITS)
|
||||
GLCL_DIR=glcl_macosx$(EXTENSION)$(BITS)
|
||||
MINGL_DIR=mingl_macosx$(EXTENSION)$(BITS)
|
||||
SWB_DIR=sw_macosx$(EXTENSION)$(BITS)
|
||||
SWCL_DIR=sw_macosx$(EXTENSION)$(BITS)
|
||||
|
||||
GL_CFLAGS=$(GLCFLAGS) -D__MACOSX__
|
||||
GL_LDFLAGS=-framework AGL -framework OpenGL -framework Cocoa -framework AudioUnit
|
||||
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidcocoa.mo gl_vidmacos.o sys_linux.o in_macos.o cd_null.o snd_macos.o
|
||||
|
||||
SW_CFLAGS=$(SWCFLAGS) -D__MACOSX__
|
||||
SW_LDFLAGS=
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) cd_null.o sys_linux.o vid_null.o
|
||||
|
||||
GL_EXE_NAME=../macosx_fteqw.gl$(EXTENSION)$(BITS)
|
||||
GLCL_EXE_NAME=../macosx_fteqwcl.gl$(EXTENSION)$(BITS)
|
||||
SW_EXE_NAME=../macosx_fteqw.sw$(EXTENSION)$(BITS)
|
||||
SWCL_EXE_NAME=../macosx_fteqwcl.sw$(EXTENSION)$(BITS)
|
||||
M_EXE_NAME=../macosx_fteqw$(EXTENSION)$(BITS)
|
||||
MCL_EXE_NAME=../macosx_fteqwcl$(EXTENSION)$(BITS)
|
||||
MINGL_EXE_NAME=../macosx_fteqw.mingl$(EXTENSION)$(BITS)
|
||||
|
@ -794,19 +691,11 @@ ifeq ($(FTE_TARGET),morphos)
|
|||
GLB_DIR=gl_morphos
|
||||
GLCL_DIR=glcl_morphos
|
||||
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) vid_morphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o
|
||||
SW_EXE_NAME=../morphos_fteqw.sw
|
||||
SWCL_EXE_NAME=../morphos_fteqwcl.sw
|
||||
SW_LDFLAGS=$(SWLDFLAGS) -ldl $(IMAGELDFLAGS) -lz
|
||||
SW_CFLAGS=$(SWCFLAGS) -noixemul
|
||||
SWB_DIR=sw_morphos
|
||||
SWCL_DIR=swcl_morphos
|
||||
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidmorphos.o vid_morphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o
|
||||
M_EXE_NAME=../morphos_fteqw
|
||||
MCL_EXE_NAME=../morphos_fteqwcl
|
||||
M_LDFLAGS=$(GLLDFLAGS)
|
||||
M_CFLAGS=$(SWCFLAGS) $(GLCFLAGS)
|
||||
M_CFLAGS=$(GLCFLAGS)
|
||||
MB_DIR=m_morphos
|
||||
MCL_DIR=mcl_morphos
|
||||
|
||||
|
@ -838,26 +727,14 @@ endif
|
|||
GLCL_DIR=glcl_cygwin
|
||||
|
||||
ifeq ($(USEASM),true)
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) vid_x.o snd_linux.o cd_null.o sys_linux.o sys_dosa.o
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_dosa.o
|
||||
else
|
||||
SWCL_OBJS=$(SOFTWARE_OBJS) vid_x.o snd_linux.o cd_null.o sys_linux.o
|
||||
endif
|
||||
SW_EXE_NAME=../fteqwswcyg.exe
|
||||
SWCL_EXE_NAME=../fteqwclswcyg.exe
|
||||
SW_LDFLAGS=$(SWLDFLAGS) $(XLDFLAGS)
|
||||
SW_CFLAGS=$(SWCFLAGS)
|
||||
SWB_DIR=sw_cygwin
|
||||
SWCL_DIR=swcl_cygwin
|
||||
|
||||
ifeq ($(USEASM),true)
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o vid_x.o snd_linux.o cd_null.o sys_linux.o sys_dosa.o
|
||||
else
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o vid_x.o snd_linux.o cd_null.o sys_linux.o
|
||||
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o
|
||||
endif
|
||||
M_EXE_NAME=../fteqwcyg.exe
|
||||
MCL_EXE_NAME=../fteqwclcyg.exe
|
||||
M_LDFLAGS=$(GLLDFLAGS) $(GLXLDFLAGS)
|
||||
M_CFLAGS=$(SWCFLAGS) $(GLCFLAGS)
|
||||
M_CFLAGS=$(GLCFLAGS)
|
||||
MB_DIR=m_cygwin
|
||||
MCL_DIR=mcl_cygwin
|
||||
|
||||
|
@ -871,9 +748,9 @@ SV_DIR?=sv_sdl
|
|||
|
||||
.default: help
|
||||
all: rel
|
||||
rel: sv-rel sw-rel gl-rel m-rel mingl-rel
|
||||
dbg: sv-dbg sw-dbg gl-dbg m-dbg mingl-dbg
|
||||
relcl: swcl-rel glcl-rel mcl-rel
|
||||
rel: sv-rel gl-rel m-rel mingl-rel
|
||||
dbg: sv-dbg gl-dbg m-dbg mingl-dbg
|
||||
relcl: glcl-rel mcl-rel
|
||||
|
||||
releases:
|
||||
#this is for releasing things from a linux box
|
||||
|
@ -896,7 +773,7 @@ ifneq ($(OUT_DIR),)
|
|||
endif
|
||||
|
||||
|
||||
VPATH = $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(COMMON_DIR) : $(SW_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(BASE_DIR)/irc : $(BASE_DIR)/email : $(QUX_DIR) : $(PROGS_DIR) : $(SNDCODEC_DIR) : $(D3D7_DIR) : $(D3D9_DIR)
|
||||
VPATH = $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(COMMON_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(BASE_DIR)/irc : $(BASE_DIR)/email : $(QUX_DIR) : $(PROGS_DIR) : $(SNDCODEC_DIR) : $(D3D7_DIR) : $(D3D9_DIR)
|
||||
|
||||
# This is for linking the FTE icon to the MinGW target
|
||||
$(OUT_DIR)/resources.o : winquake.rc
|
||||
|
@ -934,11 +811,6 @@ $(OUT_DIR)/%.mo $(OUT_DIR)/%.d : %.m
|
|||
rm -f $@.d.$$$$
|
||||
$(DO_CC) -I$(OUT_DIR)
|
||||
|
||||
ifeq ($(USEASM),true)
|
||||
$(OUT_DIR)/%.o : %.s sw/*.h
|
||||
$(DO_AS)
|
||||
endif
|
||||
|
||||
#enables use of precompiled headers in gcc 3.4 onwards.
|
||||
$(OUT_DIR)/quakedef.h.gch : quakedef.h
|
||||
$(CC) -x c $(BASE_CFLAGS) $(WCFLAGS) -o $@ -c $< $(CFLAGS)
|
||||
|
@ -1032,20 +904,6 @@ mingl-rel:
|
|||
$(MAKE) mingl-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(MINGL_DIR)"
|
||||
|
||||
|
||||
swcl-tmp:
|
||||
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(SWCL_EXE_NAME)" WCFLAGS="$(SW_CFLAGS)" LDFLAGS="$(SW_LDFLAGS) $(LDFLAGS)" SOBJS="$(SWCL_OBJS)"
|
||||
sw-tmp:
|
||||
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(SW_EXE_NAME)" WCFLAGS="$(SW_CFLAGS)" LDFLAGS="$(SW_LDFLAGS) $(LDFLAGS)" SOBJS="$(SWCL_OBJS)"
|
||||
|
||||
swcl-rel:
|
||||
$(MAKE) swcl-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(SWCL_DIR)"
|
||||
swcl-dbg:
|
||||
$(MAKE) swcl-tmp TYPE=_cl-dbg OUT_DIR="$(DEBUG_DIR)/$(SWCL_DIR)"
|
||||
sw-rel:
|
||||
$(MAKE) sw-tmp TYPE=_clsv-rel OUT_DIR="$(RELEASE_DIR)/$(SWB_DIR)"
|
||||
sw-dbg:
|
||||
$(MAKE) sw-tmp TYPE=_clsv-dbg OUT_DIR="$(DEBUG_DIR)/$(SWB_DIR)"
|
||||
|
||||
mcl-tmp:
|
||||
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(MCL_EXE_NAME)" WCFLAGS="$(M_CFLAGS)" LDFLAGS="$(M_LDFLAGS) $(LDFLAGS)" SOBJS="$(MCL_OBJS)"
|
||||
m-tmp:
|
||||
|
@ -1060,7 +918,7 @@ m-rel:
|
|||
m-dbg:
|
||||
$(MAKE) m-tmp TYPE=_clsv-dbg OUT_DIR="$(DEBUG_DIR)/$(MB_DIR)"
|
||||
|
||||
.PHONY: m-tmp mcl-tmp sw-tmp swcl-tmp mingl-tmp glcl-tmp gl-tmp sv-tmp _clsv-dbg _clsv-rel _cl-dbg _cl-rel _out-rel _out-dbg
|
||||
.PHONY: m-tmp mcl-tmp mingl-tmp glcl-tmp gl-tmp sv-tmp _clsv-dbg _clsv-rel _cl-dbg _cl-rel _out-rel _out-dbg
|
||||
|
||||
ifdef windir
|
||||
debugdir:
|
||||
|
@ -1095,14 +953,12 @@ help:
|
|||
@-echo "(each of these targets must have the postfix -rel or -dbg)"
|
||||
@-echo "'sv-???' (Dedicated Server)"
|
||||
@-echo "'gl-???' (OpenGL rendering + Built-in Server)"
|
||||
@-echo "'sw-???' (Software rendering + Built-in Server)"
|
||||
@-echo "'m-???' (Merged client, OpenGL & Software rendering + Dedicated server)"
|
||||
@-echo "'m-???' (Merged client, OpenGL & D3D rendering + Dedicated server)"
|
||||
@-echo "'mingl-???' (Minimal featured OpenGL render)"
|
||||
@-echo "'npqtv-???' (FTE_TARGET=win32 only, for now) (QuakeTV Firefox/Netscape browser plugin)"
|
||||
@-echo "'d3d-???' (for windows builds)"
|
||||
@-echo "'mcl-???' (currently broken)"
|
||||
@-echo "'glcl-???' (currently broken)"
|
||||
@-echo "'swcl-???' (currently broken)"
|
||||
|
||||
install:
|
||||
-cp debug/*.* /opt/quake/
|
||||
|
|
|
@ -1726,16 +1726,10 @@ void CL_LinkPacketEntities (void)
|
|||
&& (gl_nocolors.value == -1 || (ent->model/* && state->modelindex == cl_playerindex*/)))
|
||||
{
|
||||
// TODO: DP colormap/colormod extension?
|
||||
#ifdef SWQUAKE
|
||||
ent->palremap = cl.players[state->colormap-1].palremap;
|
||||
#endif
|
||||
ent->scoreboard = &cl.players[state->colormap-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef SWQUAKE
|
||||
ent->palremap = D_IdentityRemap();
|
||||
#endif
|
||||
ent->scoreboard = NULL;
|
||||
}
|
||||
|
||||
|
@ -2302,9 +2296,6 @@ void CL_LinkProjectiles (void)
|
|||
ent->skinnum = 0;
|
||||
memset(&ent->framestate, 0, sizeof(ent->framestate));
|
||||
ent->flags = 0;
|
||||
#ifdef SWQUAKE
|
||||
ent->palremap = D_IdentityRemap();
|
||||
#endif
|
||||
ent->scoreboard = NULL;
|
||||
#ifdef PEXT_SCALE
|
||||
ent->scale = 1;
|
||||
|
@ -2908,9 +2899,6 @@ void CL_LinkPlayers (void)
|
|||
//state->lerpstarttime = 0;
|
||||
}
|
||||
|
||||
#ifdef SWQUAKE
|
||||
ent->palremap = info->palremap;
|
||||
#endif
|
||||
if (state->modelindex == cl_playerindex)
|
||||
ent->scoreboard = info; // use custom skin
|
||||
else
|
||||
|
|
|
@ -967,7 +967,6 @@ void CL_ClearState (void)
|
|||
{
|
||||
if (serverrunning)
|
||||
SV_UnspawnServer();
|
||||
D_FlushCaches ();
|
||||
Mod_ClearAll ();
|
||||
|
||||
if (host_hunklevel) // FIXME: check this...
|
||||
|
|
|
@ -3111,9 +3111,6 @@ void CL_ParseStatic (int version)
|
|||
// copy it to the current state
|
||||
ent->model = cl.model_precache[es.modelindex];
|
||||
ent->framestate.g[FS_REG].frame[0] = ent->framestate.g[FS_REG].frame[1] = es.frame;
|
||||
#ifdef SWQUAKE
|
||||
ent->palremap = D_IdentityRemap();
|
||||
#endif
|
||||
ent->skinnum = es.skinnum;
|
||||
ent->drawflags = es.hexen2flags;
|
||||
|
||||
|
@ -3473,19 +3470,6 @@ void CL_NewTranslation (int slot)
|
|||
if (bottom > 13 || bottom < 0)
|
||||
bottom = 13;
|
||||
*/
|
||||
#ifdef SWQUAKE
|
||||
if (qrenderer == QR_SOFTWARE)
|
||||
{
|
||||
if (player->ttopcolor != top || player->tbottomcolor != bottom || !player->skin)
|
||||
{
|
||||
player->ttopcolor = top;
|
||||
player->tbottomcolor = bottom;
|
||||
D_DereferenceRemap(player->palremap);
|
||||
player->palremap = D_GetPaletteRemap(255, 255, 255, false, true, top, bottom);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//other renderers still need the team stuff set, but that's all
|
||||
player->ttopcolor = top;
|
||||
player->tbottomcolor = bottom;
|
||||
|
|
|
@ -976,23 +976,6 @@ void SCR_CalcRefdef (void)
|
|||
|
||||
// r_refdef.vrect.height/=2;
|
||||
|
||||
#ifdef SWQUAKE
|
||||
if (qrenderer == QR_SOFTWARE)
|
||||
{
|
||||
|
||||
R_SetVrect (&r_refdef.vrect, &scr_vrect, sb_lines);
|
||||
|
||||
// guard against going from one mode to another that's less than half the
|
||||
// vertical resolution
|
||||
if (scr_con_current > vid.height)
|
||||
scr_con_current = vid.height;
|
||||
|
||||
// notify the refresh of the change
|
||||
SWR_ViewChanged (&r_refdef.vrect, sb_lines, vid.aspect);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
scr_vrect = r_refdef.vrect;
|
||||
}
|
||||
|
||||
|
@ -1122,9 +1105,6 @@ void SCR_DrawRam (void)
|
|||
if (!scr_showram.value || !scr_ram)
|
||||
return;
|
||||
|
||||
if (!r_cache_thrash)
|
||||
return;
|
||||
|
||||
Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram);
|
||||
}
|
||||
|
||||
|
@ -1652,21 +1632,10 @@ void SCR_SetUpToDrawConsole (void)
|
|||
|
||||
if (clearconsole++ < vid.numpages)
|
||||
{
|
||||
if (qrenderer == QR_SOFTWARE && !Media_PlayingFullScreen())
|
||||
{
|
||||
scr_copytop = 1;
|
||||
Draw_TileClear (0, (int) scr_con_current, vid.width, vid.height - (int) scr_con_current);
|
||||
}
|
||||
|
||||
Sbar_Changed ();
|
||||
}
|
||||
else if (clearnotify++ < vid.numpages)
|
||||
{
|
||||
if (qrenderer == QR_SOFTWARE && !Media_PlayingFullScreen())
|
||||
{
|
||||
scr_copytop = 1;
|
||||
Draw_TileClear (0, 0, vid.width, con_notifylines);
|
||||
}
|
||||
}
|
||||
else
|
||||
con_notifylines = 0;
|
||||
|
@ -2157,29 +2126,8 @@ void SCR_TileClear (void)
|
|||
if (cl.splitclients>1)
|
||||
return; //splitclients always takes the entire screen.
|
||||
|
||||
if (qrenderer == QR_SOFTWARE)
|
||||
{
|
||||
if (scr_fullupdate++ < vid.numpages)
|
||||
{ // clear the entire screen
|
||||
scr_copyeverything = 1;
|
||||
Draw_TileClear (0, 0, vid.width, vid.height);
|
||||
Sbar_Changed ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scr_viewsize.value < 100)
|
||||
{
|
||||
int x, y;
|
||||
x = vid.width - 10 * 8 - 8;
|
||||
y = vid.height - sb_lines - 8;
|
||||
// clear background for counters
|
||||
if (show_fps.value)
|
||||
Draw_TileClear(x, y, 10 * 8, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef PLUGINS
|
||||
else if (plug_sbar.value)
|
||||
if (plug_sbar.value)
|
||||
{
|
||||
if (scr_vrect.x > 0)
|
||||
{
|
||||
|
@ -2203,8 +2151,8 @@ void SCR_TileClear (void)
|
|||
vid.height);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (scr_vrect.x > 0)
|
||||
{
|
||||
|
|
|
@ -2602,9 +2602,6 @@ entity_t *CL_NewTempEntity (void)
|
|||
|
||||
memset (ent, 0, sizeof(*ent));
|
||||
|
||||
#ifdef SWQUAKE
|
||||
ent->palremap = D_IdentityRemap();
|
||||
#endif
|
||||
#ifdef PEXT_SCALE
|
||||
ent->scale = 1;
|
||||
#endif
|
||||
|
|
|
@ -1204,9 +1204,6 @@ int UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg)
|
|||
VM_LONG(ret) = sizeof(vidinfo_t);
|
||||
vi->width = vid.width;
|
||||
vi->height = vid.height;
|
||||
#ifdef SWQUAKE
|
||||
vi->bpp = r_pixbytes;
|
||||
#endif
|
||||
vi->refreshrate = 60;
|
||||
vi->fullscreen = 1;
|
||||
Q_strncpyz(vi->renderername, q_renderername, sizeof(vi->renderername));
|
||||
|
|
|
@ -161,10 +161,6 @@ typedef struct player_info_s
|
|||
unsigned int ttopcolor; //team, according to colour forcing
|
||||
unsigned int tbottomcolor;
|
||||
|
||||
#ifdef SWQUAKE
|
||||
struct palremap_s *palremap;
|
||||
#endif
|
||||
|
||||
int spectator;
|
||||
skin_t *skin;
|
||||
|
||||
|
|
|
@ -605,11 +605,9 @@ void IN_UpdateGrabs(int fullscreen, int activeapp)
|
|||
{
|
||||
int grabmouse;
|
||||
|
||||
if (!activeapp)
|
||||
grabmouse = false;
|
||||
else if (fullscreen)
|
||||
if (fullscreen)
|
||||
grabmouse = true;
|
||||
else if (_windowed_mouse.value)
|
||||
else if (activeapp && _windowed_mouse.value)
|
||||
{
|
||||
if (!Key_MouseShouldBeFree())
|
||||
grabmouse = true;
|
||||
|
@ -1741,7 +1739,7 @@ void IN_MouseMove (float *movements, int pnum)
|
|||
#ifdef USINGRAWINPUT
|
||||
if (rawmicecount)
|
||||
{
|
||||
if ((in_rawinput_combine.value && pnum == 0) || cl.splitclients <= 1)
|
||||
if (in_rawinput_combine.value && pnum == 0)
|
||||
{
|
||||
// not the right way to do this but it'll work for now
|
||||
int x;
|
||||
|
|
|
@ -21,9 +21,6 @@ HWND hwnd_winamp;
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef SWQUAKE
|
||||
#include "d_local.h"
|
||||
#endif
|
||||
qboolean Media_EvaluateNextTrack(void);
|
||||
|
||||
typedef struct mediatrack_s{
|
||||
|
@ -918,9 +915,6 @@ qboolean Media_WinAvi_DecodeFrame(cin_t *cin, qboolean nosound)
|
|||
if (!lpbi || lpbi->biBitCount != 24)//oops
|
||||
{
|
||||
SCR_SetUpToDrawConsole();
|
||||
#ifdef SWQUAKE
|
||||
D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly
|
||||
#endif
|
||||
Draw_ConsoleBackground(0, vid.height, true);
|
||||
Draw_String(0, 0, "Video stream is corrupt\n");
|
||||
}
|
||||
|
|
|
@ -447,9 +447,6 @@ void M_Menu_FPS_f (void)
|
|||
int i, len;
|
||||
#ifdef RGLQUAKE
|
||||
extern cvar_t gl_compress, gl_detail, gl_bump, r_flashblend, r_shadow_realtime_world, gl_motionblur;
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
extern cvar_t d_smooth, d_mipscale, d_mipcap;
|
||||
#endif
|
||||
extern cvar_t r_stains, r_bloodstains, r_loadlits, r_dynamic, v_contentblend, show_fps;
|
||||
|
||||
|
@ -507,15 +504,6 @@ void M_Menu_FPS_f (void)
|
|||
MC_AddCheckBox(menu, 48, y, " Waterwarp", &r_waterwarp,0);y+=8;
|
||||
MC_AddSlider(menu, 48, y, " Motion blur", &gl_motionblur, 0, 0.99, 0);y+=8;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
case QR_SOFTWARE:
|
||||
if (r_pixbytes == 4)
|
||||
{MC_AddCheckBox(menu, 48, y, " Load .lit files", &r_loadlits,0);y+=8;}
|
||||
MC_AddCheckBox(menu, 48, y, " Texture Smoothing", &d_smooth,0);y+=8;
|
||||
MC_AddSlider(menu, 48, y, " Mipmap scale", &d_mipscale, 0.1, 3, 1);y+=8;
|
||||
MC_AddSlider(menu, 48, y, " Mipmap Capping", &d_mipcap, 0, 3, 1);y+=8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -272,13 +272,6 @@ static void PClassic_DrawParticles(void)
|
|||
|
||||
classicnumverts = 0;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
case QR_SOFTWARE:
|
||||
VectorScale (vright, xscaleshrink, r_pright);
|
||||
VectorScale (vup, yscaleshrink, r_pup);
|
||||
VectorCopy (vpn, r_ppn);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
RQ_RenderDistAndClear();
|
||||
|
@ -367,11 +360,6 @@ static void PClassic_DrawParticles(void)
|
|||
qglTexCoord2f (0, 1); qglVertex3f (p->org[0] + right[0] * scale, p->org[1] + right[1] * scale, p->org[2] + right[2] * scale);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
case QR_SOFTWARE:
|
||||
D_DrawParticleTrans (p->org, 1, 1, p->color, BM_BLEND);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -29,9 +29,6 @@ The engine has a few builtins.
|
|||
|
||||
#ifdef PSET_SCRIPT
|
||||
|
||||
#ifdef SWQUAKE
|
||||
#include "r_local.h"
|
||||
#endif
|
||||
#ifdef RGLQUAKE
|
||||
#include "glquake.h"//hack
|
||||
#endif
|
||||
|
@ -55,18 +52,6 @@ static int pe_size2 = P_INVALID;
|
|||
static int pe_size3 = P_INVALID;
|
||||
static int pe_defaulttrail = P_INVALID;
|
||||
|
||||
static float psintable[64];
|
||||
|
||||
static void buildsintable(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 64; i++)
|
||||
psintable[i] = sin((i*M_PI)/32);
|
||||
}
|
||||
#define sin(x) (psintable[(int)(x*(64/M_PI)) & 63])
|
||||
#define cos(x) (psintable[((int)(x*(64/M_PI)) + 16) & 63])
|
||||
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
typedef struct particle_s
|
||||
{
|
||||
|
@ -1320,8 +1305,6 @@ static void PScript_InitParticles (void)
|
|||
if (r_numparticles) //already inited
|
||||
return;
|
||||
|
||||
buildsintable();
|
||||
|
||||
i = COM_CheckParm ("-particles");
|
||||
|
||||
if (i)
|
||||
|
@ -3216,18 +3199,13 @@ static void GL_DrawTexturedParticle(int count, particle_t **plist, plooks_t *typ
|
|||
{
|
||||
p = *plist++;
|
||||
|
||||
if (type->scalefactor == 1)
|
||||
{
|
||||
scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
|
||||
+ (p->org[2] - r_origin[2])*vpn[2];
|
||||
scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250);
|
||||
if (scale < 20)
|
||||
scale = 0.25;
|
||||
else
|
||||
scale = 0.25 + scale * 0.001;
|
||||
}
|
||||
scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
|
||||
+ (p->org[2] - r_origin[2])*vpn[2];
|
||||
scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250);
|
||||
if (scale < 20)
|
||||
scale = 0.25;
|
||||
else
|
||||
scale = 1;
|
||||
scale = 0.25 + scale * 0.001;
|
||||
|
||||
qglColor4f (p->rgb[0],
|
||||
p->rgb[1],
|
||||
|
@ -3238,27 +3216,20 @@ static void GL_DrawTexturedParticle(int count, particle_t **plist, plooks_t *typ
|
|||
{
|
||||
x = sin(p->angle)*scale;
|
||||
y = cos(p->angle)*scale;
|
||||
|
||||
qglTexCoord2f(p->s1,p->t1);
|
||||
qglVertex3f (p->org[0] - x*pright[0] - y*pup[0], p->org[1] - x*pright[1] - y*pup[1], p->org[2] - x*pright[2] - y*pup[2]);
|
||||
qglTexCoord2f(p->s1,p->t2);
|
||||
qglVertex3f (p->org[0] - y*pright[0] + x*pup[0], p->org[1] - y*pright[1] + x*pup[1], p->org[2] - y*pright[2] + x*pup[2]);
|
||||
qglTexCoord2f(p->s2,p->t2);
|
||||
qglVertex3f (p->org[0] + x*pright[0] + y*pup[0], p->org[1] + x*pright[1] + y*pup[1], p->org[2] + x*pright[2] + y*pup[2]);
|
||||
qglTexCoord2f(p->s2,p->t1);
|
||||
qglVertex3f (p->org[0] + y*pright[0] - x*pup[0], p->org[1] + y*pright[1] - x*pup[1], p->org[2] + y*pright[2] - x*pup[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
qglTexCoord2f(p->s1,p->t1);
|
||||
qglVertex3f (p->org[0] - scale*pup[0], p->org[1] - scale*pup[1], p->org[2] - scale*pup[2]);
|
||||
qglTexCoord2f(p->s1,p->t2);
|
||||
qglVertex3f (p->org[0] - scale*pright[0], p->org[1] - scale*pright[1], p->org[2] - scale*pright[2]);
|
||||
qglTexCoord2f(p->s2,p->t2);
|
||||
qglVertex3f (p->org[0] + scale*pup[0], p->org[1] + scale*pup[1], p->org[2] + scale*pup[2]);
|
||||
qglTexCoord2f(p->s2,p->t1);
|
||||
qglVertex3f (p->org[0] + scale*pright[0], p->org[1] + scale*pright[1], p->org[2] + scale*pright[2]);
|
||||
x = 0;
|
||||
y = scale;
|
||||
}
|
||||
qglTexCoord2f(p->s1,p->t1);
|
||||
qglVertex3f (p->org[0] - x*pright[0] - y*pup[0], p->org[1] - x*pright[1] - y*pup[1], p->org[2] - x*pright[2] - y*pup[2]);
|
||||
qglTexCoord2f(p->s1,p->t2);
|
||||
qglVertex3f (p->org[0] - y*pright[0] + x*pup[0], p->org[1] - y*pright[1] + x*pup[1], p->org[2] - y*pright[2] + x*pup[2]);
|
||||
qglTexCoord2f(p->s2,p->t2);
|
||||
qglVertex3f (p->org[0] + x*pright[0] + y*pup[0], p->org[1] + x*pright[1] + y*pup[1], p->org[2] + x*pright[2] + y*pup[2]);
|
||||
qglTexCoord2f(p->s2,p->t1);
|
||||
qglVertex3f (p->org[0] + y*pright[0] - x*pup[0], p->org[1] + y*pright[1] - x*pup[1], p->org[2] + y*pright[2] - x*pup[2]);
|
||||
}
|
||||
qglEnd();
|
||||
}
|
||||
|
@ -3305,19 +3276,16 @@ static void GL_DrawSketchParticle(int count, particle_t **plist, plooks_t *type)
|
|||
{
|
||||
x = sin(p->angle)*scale;
|
||||
y = cos(p->angle)*scale;
|
||||
|
||||
qglVertex3f (p->org[0] - x*pright[0] - y*pup[0], p->org[1] - x*pright[1] - y*pup[1], p->org[2] - x*pright[2] - y*pup[2]);
|
||||
qglVertex3f (p->org[0] + x*pright[0] + y*pup[0], p->org[1] + x*pright[1] + y*pup[1], p->org[2] + x*pright[2] + y*pup[2]);
|
||||
qglVertex3f (p->org[0] + y*pright[0] - x*pup[0], p->org[1] + y*pright[1] - x*pup[1], p->org[2] + y*pright[2] - x*pup[2]);
|
||||
qglVertex3f (p->org[0] - y*pright[0] + x*pup[0], p->org[1] - y*pright[1] + x*pup[1], p->org[2] - y*pright[2] + x*pup[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
qglVertex3f (p->org[0] - scale*pup[0], p->org[1] - scale*pup[1], p->org[2] - scale*pup[2]);
|
||||
qglVertex3f (p->org[0] + scale*pup[0], p->org[1] + scale*pup[1], p->org[2] + scale*pup[2]);
|
||||
qglVertex3f (p->org[0] + scale*pright[0], p->org[1] + scale*pright[1], p->org[2] + scale*pright[2]);
|
||||
qglVertex3f (p->org[0] - scale*pright[0], p->org[1] - scale*pright[1], p->org[2] - scale*pright[2]);
|
||||
x = 0;
|
||||
y = scale;
|
||||
}
|
||||
qglVertex3f (p->org[0] - x*pright[0] - y*pup[0], p->org[1] - x*pright[1] - y*pup[1], p->org[2] - x*pright[2] - y*pup[2]);
|
||||
qglVertex3f (p->org[0] + x*pright[0] + y*pup[0], p->org[1] + x*pright[1] + y*pup[1], p->org[2] + x*pright[2] + y*pup[2]);
|
||||
qglVertex3f (p->org[0] + y*pright[0] - x*pup[0], p->org[1] + y*pright[1] - x*pup[1], p->org[2] + y*pright[2] - x*pup[2]);
|
||||
qglVertex3f (p->org[0] - y*pright[0] + x*pup[0], p->org[1] - y*pright[1] + x*pup[1], p->org[2] - y*pright[2] + x*pup[2]);
|
||||
}
|
||||
qglEnd();
|
||||
}
|
||||
|
@ -3676,124 +3644,6 @@ static void GL_DrawClippedDecal(int count, clippeddecal_t **dlist, plooks_t *typ
|
|||
qglEnd();
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
static void SWD_DrawParticleSpark(int count, particle_t **plist, plooks_t *type)
|
||||
{
|
||||
float speed;
|
||||
vec3_t src, dest;
|
||||
particle_t *p;
|
||||
|
||||
int r,g,b; //if you have a cpu with mmx, good for you...
|
||||
|
||||
while (count--)
|
||||
{
|
||||
p = *plist++;
|
||||
|
||||
r = p->rgb[0]*255;
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
else if (r > 255)
|
||||
r = 255;
|
||||
g = p->rgb[1]*255;
|
||||
if (g < 0)
|
||||
g = 0;
|
||||
else if (g > 255)
|
||||
g = 255;
|
||||
b = p->rgb[2]*255;
|
||||
if (b < 0)
|
||||
b = 0;
|
||||
else if (b > 255)
|
||||
b = 255;
|
||||
p->color = GetPaletteIndex(r, g, b);
|
||||
|
||||
speed = Length(p->vel);
|
||||
if ((speed) < 1)
|
||||
{
|
||||
VectorCopy(p->org, src);
|
||||
VectorCopy(p->org, dest);
|
||||
}
|
||||
else
|
||||
{ //causes flickers with lower vels (due to bouncing in physics)
|
||||
if (speed < 50)
|
||||
speed *= 50/speed;
|
||||
VectorMA(p->org, 2.5/(speed), p->vel, src);
|
||||
VectorMA(p->org, -2.5/(speed), p->vel, dest);
|
||||
}
|
||||
|
||||
D_DrawSparkTrans(src, dest, p->alpha, p->color, type->blendmode);
|
||||
}
|
||||
}
|
||||
static void SWD_DrawParticleBlob(int count, particle_t **plist, plooks_t *type)
|
||||
{
|
||||
particle_t *p;
|
||||
int r,g,b; //This really shouldn't be like this. Pitty the 32 bit renderer...
|
||||
|
||||
while(count--)
|
||||
{
|
||||
p = *plist++;
|
||||
|
||||
r = p->rgb[0]*255;
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
else if (r > 255)
|
||||
r = 255;
|
||||
g = p->rgb[1]*255;
|
||||
if (g < 0)
|
||||
g = 0;
|
||||
else if (g > 255)
|
||||
g = 255;
|
||||
b = p->rgb[2]*255;
|
||||
if (b < 0)
|
||||
b = 0;
|
||||
else if (b > 255)
|
||||
b = 255;
|
||||
p->color = GetPaletteIndex(r, g, b);
|
||||
D_DrawParticleTrans(p->org, p->alpha, p->scale, p->color, type->blendmode);
|
||||
}
|
||||
}
|
||||
static void SWD_DrawParticleBeam(int count, beamseg_t **blist, plooks_t *type)
|
||||
{
|
||||
int r,g,b; //if you have a cpu with mmx, good for you...
|
||||
beamseg_t *beam;
|
||||
beamseg_t *c;
|
||||
particle_t *p;
|
||||
particle_t *q;
|
||||
|
||||
// if (!b->next)
|
||||
// return;
|
||||
|
||||
while(count--)
|
||||
{
|
||||
beam = *blist++;
|
||||
|
||||
c = beam->next;
|
||||
|
||||
q = c->p;
|
||||
// if (!q)
|
||||
// return;
|
||||
|
||||
p = beam->p;
|
||||
|
||||
r = p->rgb[0]*255;
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
else if (r > 255)
|
||||
r = 255;
|
||||
g = p->rgb[1]*255;
|
||||
if (g < 0)
|
||||
g = 0;
|
||||
else if (g > 255)
|
||||
g = 255;
|
||||
b = p->rgb[2]*255;
|
||||
if (b < 0)
|
||||
b = 0;
|
||||
else if (b > 255)
|
||||
b = 255;
|
||||
p->color = GetPaletteIndex(r, g, b);
|
||||
D_DrawSparkTrans(p->org, q->org, p->alpha, p->color, type->blendmode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t **,plooks_t*), void (*sparklineparticles)(int count, particle_t **,plooks_t*), void (*sparkfanparticles)(int count, particle_t **,plooks_t*), void (*sparktexturedparticles)(int count, particle_t **,plooks_t*), void (*beamparticlest)(int count, beamseg_t**,plooks_t*), void (*beamparticlesut)(int count, beamseg_t**,plooks_t*), void (*drawdecalparticles)(int count, clippeddecal_t**,plooks_t*))
|
||||
|
@ -3845,11 +3695,6 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t
|
|||
|
||||
VectorScale (vup, 1.5, pup);
|
||||
VectorScale (vright, 1.5, pright);
|
||||
#ifdef SWQUAKE
|
||||
VectorScale (vright, xscaleshrink, r_pright);
|
||||
VectorScale (vup, yscaleshrink, r_pup);
|
||||
VectorCopy (vpn, r_ppn);
|
||||
#endif
|
||||
|
||||
#ifdef Q2BSPS
|
||||
if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3)
|
||||
|
@ -4418,19 +4263,6 @@ static void PScript_DrawParticles (void)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
if (qrenderer == QR_SOFTWARE)
|
||||
{
|
||||
PScript_DrawParticleTypes(SWD_DrawParticleBlob, SWD_DrawParticleSpark, SWD_DrawParticleSpark, SWD_DrawParticleSpark, SWD_DrawParticleBeam, SWD_DrawParticleBeam, NULL);
|
||||
|
||||
RSpeedRemark();
|
||||
D_StartParticles();
|
||||
RQ_RenderDistAndClear();
|
||||
D_EndParticles();
|
||||
RSpeedEnd(RSPEED_PARTICLESDRAW);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(D3DQUAKE)
|
||||
if (qrenderer == QR_DIRECT3D)
|
||||
{
|
||||
|
|
|
@ -1035,9 +1035,6 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
|
|||
|
||||
if (in->v->colormap > 0 && in->v->colormap <= MAX_CLIENTS)
|
||||
{
|
||||
#ifdef SWQUAKE
|
||||
out->palremap = cl.players[(int)in->v->colormap-1].palremap;
|
||||
#endif
|
||||
out->scoreboard = &cl.players[(int)in->v->colormap-1];
|
||||
} // TODO: DP COLORMAP extension?
|
||||
|
||||
|
|
|
@ -365,20 +365,7 @@ void PF_CL_drawcharacter (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
if (Draw_ImageColours)
|
||||
Draw_ImageColours(rgb[0], rgb[1], rgb[2], alpha);
|
||||
if (Draw_Image)
|
||||
{
|
||||
if (qrenderer == QR_SOFTWARE)
|
||||
{
|
||||
extern cvar_t vid_conwidth, vid_conheight;
|
||||
float xratio, yratio;
|
||||
// this has to be done this way because CSQC drawing needs
|
||||
// to respect these cvars
|
||||
xratio = vid.width / vid_conwidth.value;
|
||||
yratio = vid.height / vid_conheight.value;
|
||||
Draw_Image(pos[0]*xratio, pos[1]*yratio, size[0]*xratio, size[1]*yratio, fcol, frow, fcol+fsize, frow+fsize, Draw_CachePic("conchars"));
|
||||
}
|
||||
else
|
||||
Draw_Image(pos[0], pos[1], size[0], size[1], fcol, frow, fcol+fsize, frow+fsize, Draw_CachePic("conchars"));
|
||||
}
|
||||
Draw_Image(pos[0], pos[1], size[0], size[1], fcol, frow, fcol+fsize, frow+fsize, Draw_CachePic("conchars"));
|
||||
|
||||
G_FLOAT(OFS_RETURN) = 1;
|
||||
}
|
||||
|
|
|
@ -157,10 +157,6 @@ extern "C" {
|
|||
//#include "model.h"
|
||||
//#endif
|
||||
|
||||
#if defined(SWQUAKE)
|
||||
#include "d_iface.h"
|
||||
#endif
|
||||
|
||||
#ifdef PEXT_BULLETENS
|
||||
#include "r_bulleten.h"
|
||||
#endif
|
||||
|
|
|
@ -25,10 +25,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "quakedef.h"
|
||||
#ifdef PEXT_BULLETENS
|
||||
|
||||
#ifdef SWQUAKE
|
||||
#include "r_local.h"
|
||||
#include "d_local.h"
|
||||
#endif
|
||||
#ifdef RGLQUAKE
|
||||
#include "glquake.h"//hack
|
||||
#endif
|
||||
|
|
|
@ -20,9 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
// r_efrag.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#ifdef SWQUAKE
|
||||
#include "r_local.h"
|
||||
#endif
|
||||
|
||||
extern int r_framecount;
|
||||
|
||||
|
@ -168,46 +165,6 @@ void R_Q1Q2BSP_SplitEntityOnNode (mnode_t *node)
|
|||
R_Q1Q2BSP_SplitEntityOnNode (node->children[1]);
|
||||
}
|
||||
|
||||
#ifdef SWQUAKE
|
||||
/*
|
||||
===================
|
||||
R_SplitEntityOnNode2
|
||||
===================
|
||||
*/
|
||||
void R_Q1BSP_SplitEntityOnNode2 (mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
int sides;
|
||||
|
||||
if (node->visframe != r_visframecount)
|
||||
return;
|
||||
|
||||
if (node->contents < 0)
|
||||
{
|
||||
if (node->contents != Q1CONTENTS_SOLID)
|
||||
r_pefragtopnode = node; // we've reached a non-solid leaf, so it's
|
||||
// visible and not BSP clipped
|
||||
return;
|
||||
}
|
||||
|
||||
splitplane = node->plane;
|
||||
sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane);
|
||||
|
||||
if (sides == 3)
|
||||
{
|
||||
// remember first splitter
|
||||
r_pefragtopnode = node;
|
||||
return;
|
||||
}
|
||||
|
||||
// not split yet; recurse down the contacted side
|
||||
if (sides & 1)
|
||||
R_Q1BSP_SplitEntityOnNode2 (node->children[0]);
|
||||
else
|
||||
R_Q1BSP_SplitEntityOnNode2 (node->children[1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
===========
|
||||
R_AddEfrags
|
||||
|
|
|
@ -107,9 +107,6 @@ typedef struct entity_s
|
|||
int drawflags;
|
||||
int abslight;
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
struct palremap_s *palremap;
|
||||
#endif
|
||||
} entity_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
|
@ -151,13 +148,6 @@ typedef struct
|
|||
qboolean useperspective;
|
||||
} refdef_t;
|
||||
|
||||
|
||||
//
|
||||
// refresh
|
||||
//
|
||||
extern int reinit_surfcache;
|
||||
|
||||
|
||||
extern refdef_t r_refdef;
|
||||
extern vec3_t r_origin, vpn, vright, vup;
|
||||
|
||||
|
@ -205,62 +195,9 @@ int GLR_LightPoint (vec3_t p);
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(SWQUAKE)
|
||||
void SWR_Init (void);
|
||||
void SWR_InitTextures (void);
|
||||
void SWR_InitEfrags (void);
|
||||
void SWR_RenderView (void); // must set r_refdef first
|
||||
void SWR_ViewChanged (vrect_t *pvrect, int lineadj, float aspect);
|
||||
// called whenever r_refdef or vid change
|
||||
void SWR_InitSky (struct texture_s *mt); // called at level load
|
||||
void SWR_SetSky (char *name, float rotate, vec3_t axis);
|
||||
qboolean SWR_CheckSky(void);
|
||||
|
||||
void SWR_AddEfrags (entity_t *ent);
|
||||
void SWR_RemoveEfrags (entity_t *ent);
|
||||
|
||||
void SWR_NewMap (void);
|
||||
|
||||
void SWR_PushDlights (void);
|
||||
|
||||
void SWR_AddStain(vec3_t org, float red, float green, float blue, float radius);
|
||||
void SWR_LessenStains(void);
|
||||
|
||||
void MediaSW_ShowFrame8bit(qbyte *framedata, int inwidth, int inheight, qbyte *palette);
|
||||
void MediaSW_ShowFrameRGBA_32(qbyte *framedata, int inwidth, int inheight); //top down
|
||||
void MediaSW_ShowFrameBGR_24_Flip(qbyte *framedata, int inwidth, int inheight); //input is bottom up...
|
||||
|
||||
void SWR_SetSky (char *name, float rotate, vec3_t axis);
|
||||
qboolean SWR_CheckSky(void);
|
||||
void SWR_AddStain(vec3_t org, float red, float green, float blue, float radius);
|
||||
void SWR_LessenStains(void);
|
||||
|
||||
void SWVID_Shutdown (void);
|
||||
void SWR_DeInit (void);
|
||||
void SWSCR_DeInit (void);
|
||||
|
||||
int SWR_LightPoint (vec3_t p);
|
||||
#endif
|
||||
|
||||
void R_AddEfrags (entity_t *ent);
|
||||
void R_RemoveEfrags (entity_t *ent);
|
||||
|
||||
//
|
||||
// surface cache related
|
||||
//
|
||||
extern int reinit_surfcache; // if 1, surface cache is currently empty and
|
||||
extern qboolean r_cache_thrash; // set if thrashing the surface cache
|
||||
|
||||
int D_SurfaceCacheForRes (int width, int height, int bpp);
|
||||
void D_FlushCaches (void);
|
||||
void D_DeleteSurfaceCache (void);
|
||||
void D_InitCaches (void *buffer, int size);
|
||||
void R_SetVrect (vrect_t *pvrect, vrect_t *pvrectin, int lineadj);
|
||||
|
||||
struct palremap_s *D_IdentityRemap(void);
|
||||
|
||||
//normalmaps
|
||||
//bumpmaps
|
||||
|
@ -400,21 +337,6 @@ void GLR_WipeStains(void);
|
|||
void GLR_LoadSkys (void);
|
||||
#endif
|
||||
|
||||
#if defined(SWQUAKE)
|
||||
|
||||
void SWMod_Init (void);
|
||||
void SWMod_ClearAll (void);
|
||||
struct model_s *SWMod_ForName (char *name, qboolean crash);
|
||||
struct model_s *SWMod_FindName (char *name);
|
||||
void *SWMod_Extradata (struct model_s *mod); // handles caching
|
||||
void SWMod_TouchModel (char *name);
|
||||
|
||||
struct mleaf_s *SWMod_PointInLeaf (struct model_s *model, float *p);
|
||||
|
||||
void SWMod_Think (void);
|
||||
void SWMod_NowLoadExternal(void);
|
||||
#endif
|
||||
|
||||
extern struct model_s *currentmodel;
|
||||
|
||||
qboolean Media_ShowFilm(void);
|
||||
|
@ -462,7 +384,6 @@ void R_RestartRenderer_f (void);//this goes here so we can save some stack when
|
|||
|
||||
//used to live in glquake.h
|
||||
qbyte GetPaletteIndex(int red, int green, int blue);
|
||||
qbyte GetPaletteNoFB(int red, int green, int blue);
|
||||
extern cvar_t r_norefresh;
|
||||
extern cvar_t r_drawentities;
|
||||
extern cvar_t r_drawworld;
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
#ifdef RGLQUAKE
|
||||
#include "gl_draw.h"
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
#include "sw_draw.h"
|
||||
#endif
|
||||
|
||||
|
||||
qboolean vid_isfullscreen;
|
||||
|
@ -246,32 +243,6 @@ void R_BulletenForce_f (void);
|
|||
|
||||
rendererstate_t currentrendererstate;
|
||||
|
||||
#if defined(SWQUAKE)
|
||||
cvar_t d_smooth = SCVAR ("d_smooth", "0");
|
||||
|
||||
cvar_t r_aliastransadj = SCVAR ("r_aliastransadj", "100");
|
||||
cvar_t r_aliastransbase = SCVAR ("r_aliastransbase", "200");
|
||||
cvar_t r_clearcolor = SCVAR ("r_clearcolor", "218");
|
||||
//cvar_t r_drawflat = SCVARF ("r_drawflat", "0",
|
||||
// CVAR_CHEAT);
|
||||
cvar_t r_draworder = SCVARF ("r_draworder", "0",
|
||||
CVAR_CHEAT);
|
||||
cvar_t r_dspeeds = SCVAR ("r_dspeeds", "0");
|
||||
cvar_t r_graphheight = SCVAR ("r_graphheight", "15");
|
||||
cvar_t r_maxedges = SCVAR ("r_maxedges", "0");
|
||||
cvar_t r_maxsurfs = SCVAR ("r_maxsurfs", "0");
|
||||
cvar_t r_numedges = SCVAR ("r_numedges", "0");
|
||||
cvar_t r_numsurfs = SCVAR ("r_numsurfs", "0");
|
||||
cvar_t r_aliasstats = SCVAR ("r_polymodelstats", "0");
|
||||
cvar_t r_reportedgeout = SCVAR ("r_reportedgeout", "0");
|
||||
cvar_t r_reportsurfout = SCVAR ("r_reportsurfout", "0");
|
||||
cvar_t r_timegraph = SCVAR ("r_timegraph", "0");
|
||||
cvar_t r_zgraph = SCVAR ("r_zgraph","0");
|
||||
|
||||
cvar_t sw_surfcachesize = SCVARF ("sw_surfcachesize", "0",
|
||||
CVAR_RENDERERLATCH);
|
||||
#endif
|
||||
|
||||
#if defined(RGLQUAKE) || defined(D3DQUAKE)
|
||||
cvar_t gl_ati_truform = SCVAR ("gl_ati_truform", "0");
|
||||
cvar_t gl_ati_truform_type = SCVAR ("gl_ati_truform_type", "1");
|
||||
|
@ -507,49 +478,8 @@ void GLRenderer_Init(void)
|
|||
Cvar_Register (&gl_menutint_shader, GLRENDEREROPTIONS);
|
||||
|
||||
R_BloomRegister();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SWQUAKE)
|
||||
extern cvar_t d_subdiv16;
|
||||
extern cvar_t d_mipcap;
|
||||
extern cvar_t d_mipscale;
|
||||
extern cvar_t d_smooth;
|
||||
void SWRenderer_Init(void)
|
||||
{
|
||||
Cvar_Register (&d_subdiv16, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&d_mipcap, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&d_mipscale, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&d_smooth, SWRENDEREROPTIONS);
|
||||
|
||||
Cvar_Register (&r_maxsurfs, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_numsurfs, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_maxedges, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_numedges, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_sirds, SWRENDEREROPTIONS);
|
||||
|
||||
Cvar_Register (&r_aliastransbase, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_aliastransadj, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_reportedgeout, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_aliasstats, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_clearcolor, SWRENDEREROPTIONS);
|
||||
|
||||
Cvar_Register (&r_timegraph, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_draworder, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_zgraph, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_graphheight, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_aliasstats, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_dspeeds, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_ambient, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_ambient, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&r_reportsurfout, SWRENDEREROPTIONS);
|
||||
|
||||
Cvar_Register (&d_palconvwrite, SWRENDEREROPTIONS);
|
||||
Cvar_Register (&d_palremapsize, SWRENDEREROPTIONS);
|
||||
|
||||
Cvar_Register (&sw_surfcachesize, SWRENDEREROPTIONS);
|
||||
}
|
||||
#endif
|
||||
|
||||
void R_InitTextures (void)
|
||||
{
|
||||
|
@ -600,9 +530,6 @@ void Renderer_Init(void)
|
|||
#if defined(RGLQUAKE)
|
||||
GLRenderer_Init();
|
||||
#endif
|
||||
#if defined(SWQUAKE)
|
||||
SWRenderer_Init();
|
||||
#endif
|
||||
|
||||
Cvar_Register (&r_novis, GLRENDEREROPTIONS);
|
||||
|
||||
|
@ -883,23 +810,7 @@ rendererinfo_t dedicatedrendererinfo = {
|
|||
NULL, //Media_ShowFrameRGBA_32;
|
||||
NULL, //Media_ShowFrame8bit;
|
||||
|
||||
#ifdef SWQUAKE
|
||||
SWMod_Init,
|
||||
SWMod_ClearAll,
|
||||
SWMod_ForName,
|
||||
SWMod_FindName,
|
||||
SWMod_Extradata,
|
||||
SWMod_TouchModel,
|
||||
|
||||
SWMod_NowLoadExternal,
|
||||
SWMod_Think,
|
||||
|
||||
NULL, //Mod_GetTag
|
||||
NULL, //fixme: server will need this one at some point.
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
#elif defined(RGLQUAKE) || defined(D3DQUAKE)
|
||||
#if defined(RGLQUAKE) || defined(D3DQUAKE)
|
||||
GLMod_Init,
|
||||
GLMod_ClearAll,
|
||||
GLMod_ForName,
|
||||
|
@ -941,100 +852,6 @@ rendererinfo_t dedicatedrendererinfo = {
|
|||
};
|
||||
rendererinfo_t *pdedicatedrendererinfo = &dedicatedrendererinfo;
|
||||
|
||||
#ifdef SWQUAKE
|
||||
rendererinfo_t softwarerendererinfo = {
|
||||
"Software rendering",
|
||||
{
|
||||
"sw",
|
||||
"software",
|
||||
},
|
||||
QR_SOFTWARE,
|
||||
|
||||
SWDraw_PicFromWad,
|
||||
SWDraw_CachePic,
|
||||
SWDraw_SafeCachePic,
|
||||
SWDraw_Init,
|
||||
SWDraw_Init,
|
||||
SWDraw_Character,
|
||||
SWDraw_ColouredCharacter,
|
||||
SWDraw_TinyCharacter,
|
||||
SWDraw_String,
|
||||
SWDraw_Alt_String,
|
||||
SWDraw_Crosshair,
|
||||
SWDraw_DebugChar,
|
||||
SWDraw_Pic,
|
||||
NULL,//SWDraw_ScaledPic,
|
||||
SWDraw_SubPic,
|
||||
SWDraw_TransPic,
|
||||
SWDraw_TransPicTranslate,
|
||||
SWDraw_ConsoleBackground,
|
||||
SWDraw_EditorBackground,
|
||||
SWDraw_TileClear,
|
||||
SWDraw_Fill,
|
||||
SWDraw_FillRGB,
|
||||
SWDraw_FadeScreen,
|
||||
SWDraw_BeginDisc,
|
||||
SWDraw_EndDisc,
|
||||
|
||||
SWDraw_Image,
|
||||
SWDraw_ImageColours,
|
||||
|
||||
SWR_Init,
|
||||
SWR_DeInit,
|
||||
NULL,//SWR_ReInit,
|
||||
SWR_RenderView,
|
||||
|
||||
SWR_CheckSky,
|
||||
SWR_SetSky,
|
||||
|
||||
SWR_NewMap,
|
||||
NULL,
|
||||
SWR_LightPoint,
|
||||
SWR_PushDlights,
|
||||
|
||||
SWR_AddStain,
|
||||
SWR_LessenStains,
|
||||
|
||||
MediaSW_ShowFrameBGR_24_Flip,
|
||||
MediaSW_ShowFrameRGBA_32,
|
||||
MediaSW_ShowFrame8bit,
|
||||
|
||||
SWMod_Init,
|
||||
SWMod_ClearAll,
|
||||
SWMod_ForName,
|
||||
SWMod_FindName,
|
||||
SWMod_Extradata,
|
||||
SWMod_TouchModel,
|
||||
|
||||
SWMod_NowLoadExternal,
|
||||
SWMod_Think,
|
||||
|
||||
NULL, //Mod_GetTag
|
||||
NULL, //Mod_TagForName
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
SWVID_Init,
|
||||
SWVID_Shutdown,
|
||||
SWVID_LockBuffer,
|
||||
SWVID_UnlockBuffer,
|
||||
SWD_BeginDirectRect,
|
||||
SWD_EndDirectRect,
|
||||
SWVID_ForceLockState,
|
||||
SWVID_ForceUnlockedAndReturnState,
|
||||
SWVID_SetPalette,
|
||||
SWVID_ShiftPalette,
|
||||
SWVID_GetRGBInfo,
|
||||
|
||||
SWVID_SetCaption,
|
||||
|
||||
SWSCR_UpdateScreen,
|
||||
|
||||
""
|
||||
};
|
||||
rendererinfo_t *psoftwarerendererinfo = &softwarerendererinfo;
|
||||
#endif
|
||||
#ifdef RGLQUAKE
|
||||
rendererinfo_t openglrendererinfo = {
|
||||
"OpenGL",
|
||||
|
@ -1151,9 +968,6 @@ rendererinfo_t **rendererinfo[] =
|
|||
#ifndef NPQTV
|
||||
&pdedicatedrendererinfo,
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
&psoftwarerendererinfo,
|
||||
#endif
|
||||
#ifdef RGLQUAKE
|
||||
&popenglrendererinfo,
|
||||
&pd3drendererinfo,
|
||||
|
@ -1232,19 +1046,10 @@ void CheckCustomMode(struct menu_s *menu)
|
|||
info->customheight->common.ishidden = false;
|
||||
}
|
||||
|
||||
#ifdef SWQUAKE
|
||||
if (info->renderer->selectedoption < 1)
|
||||
{
|
||||
info->conscalecombo->common.ishidden = true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (!info->bppcombo->selectedoption)
|
||||
info->bppcombo->selectedoption = 1;
|
||||
if (!info->bppcombo->selectedoption)
|
||||
info->bppcombo->selectedoption = 1;
|
||||
|
||||
info->conscalecombo->common.ishidden = false;
|
||||
}
|
||||
info->conscalecombo->common.ishidden = false;
|
||||
}
|
||||
qboolean M_VideoApply (union menuoption_s *op,struct menu_s *menu,int key)
|
||||
{
|
||||
|
@ -1310,26 +1115,16 @@ qboolean M_VideoApply (union menuoption_s *op,struct menu_s *menu,int key)
|
|||
|
||||
switch(info->renderer->selectedoption)
|
||||
{
|
||||
#ifdef SWQUAKE
|
||||
#ifdef RGLQUAKE
|
||||
case 0:
|
||||
Cbuf_AddText("setrenderer sw\n", RESTRICT_LOCAL);
|
||||
break;
|
||||
case 1:
|
||||
#else
|
||||
case 0:
|
||||
#endif
|
||||
Cbuf_AddText("setrenderer gl\n", RESTRICT_LOCAL);
|
||||
break;
|
||||
#ifdef SWQUAKE
|
||||
case 2:
|
||||
#else
|
||||
case 1:
|
||||
#endif
|
||||
Cbuf_AddText("setrenderer d3d7\n", RESTRICT_LOCAL);
|
||||
break;
|
||||
case 3:
|
||||
Cbuf_AddText("setrenderer d3d9\n", RESTRICT_LOCAL);
|
||||
break;
|
||||
#ifdef D3DQUAKE
|
||||
case 1:
|
||||
Cbuf_AddText("setrenderer d3d9\n", RESTRICT_LOCAL);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
M_RemoveMenu(menu);
|
||||
Cbuf_AddText("menu_video\n", RESTRICT_LOCAL);
|
||||
|
@ -1338,23 +1133,14 @@ qboolean M_VideoApply (union menuoption_s *op,struct menu_s *menu,int key)
|
|||
void M_Menu_Video_f (void)
|
||||
{
|
||||
extern cvar_t r_stains, v_contrast;
|
||||
#if defined(SWQUAKE)
|
||||
extern cvar_t d_smooth;
|
||||
#endif
|
||||
#if defined(RGLQUAKE)
|
||||
extern cvar_t r_bloom;
|
||||
#endif
|
||||
extern cvar_t r_bouncysparks;
|
||||
static const char *modenames[128] = {"Custom"};
|
||||
static const char *rendererops[] = {
|
||||
#ifdef SWQUAKE
|
||||
"Software",
|
||||
#endif
|
||||
#ifdef RGLQUAKE
|
||||
"OpenGL",
|
||||
#ifdef USE_D3D
|
||||
"DirectX7",
|
||||
#endif
|
||||
#endif
|
||||
#ifdef D3DQUAKE
|
||||
"DirectX9",
|
||||
|
@ -1404,20 +1190,8 @@ void M_Menu_Video_f (void)
|
|||
menu = M_CreateMenu(sizeof(videomenuinfo_t));
|
||||
info = menu->data;
|
||||
|
||||
#if defined(SWQUAKE) && defined(RGLQUAKE)
|
||||
if (qrenderer == QR_OPENGL)
|
||||
{
|
||||
#ifdef USE_D3D
|
||||
if (!strcmp(vid_renderer.string, "d3d"))
|
||||
i = 2;
|
||||
else
|
||||
#endif
|
||||
i = 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if defined(RGLQUAKE) && defined(USE_D3D)
|
||||
if (!strcmp(vid_renderer.string, "d3d"))
|
||||
if (!strcmp(vid_renderer.string, "d3d9"))
|
||||
i = 1;
|
||||
else
|
||||
#endif
|
||||
|
@ -1458,9 +1232,6 @@ void M_Menu_Video_f (void)
|
|||
MC_AddCheckBox(menu, 16, y, " Stain maps", &r_stains,0); y+=8;
|
||||
MC_AddCheckBox(menu, 16, y, " Bouncy sparks", &r_bouncysparks,0); y+=8;
|
||||
MC_AddCheckBox(menu, 16, y, " Rain", &r_part_rain,0); y+=8;
|
||||
#if defined(SWQUAKE)
|
||||
MC_AddCheckBox(menu, 16, y, " SW Smoothing", &d_smooth,0); y+=8;
|
||||
#endif
|
||||
#ifdef RGLQUAKE
|
||||
MC_AddCheckBox(menu, 16, y, " GL Bumpmapping", &gl_bump,0); y+=8;
|
||||
MC_AddCheckBox(menu, 16, y, " Bloom", &r_bloom,0); y+=8;
|
||||
|
@ -1691,26 +1462,6 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
|
|||
host_colormap = (qbyte *)COM_LoadMallocFile ("gfx/colormap.lmp");
|
||||
if (!host_colormap)
|
||||
{
|
||||
#ifdef SWQUAKE
|
||||
float f;
|
||||
if (qrenderer == QR_SOFTWARE) //glquake doesn't care
|
||||
{
|
||||
data = host_colormap = BZ_Malloc(256*VID_GRADES+sizeof(int));
|
||||
//let's try making one. this is probably caused by running out of baseq2.
|
||||
for (j = 0; j < VID_GRADES; j++)
|
||||
{
|
||||
f = 1 - ((float)j/VID_GRADES);
|
||||
for (i = 0; i < 256-vid.fullbright; i++)
|
||||
{
|
||||
data[i] = GetPaletteIndex(host_basepal[i*3+0]*f, host_basepal[i*3+1]*f, host_basepal[i*3+2]*f);
|
||||
}
|
||||
for (; i < 256; i++)
|
||||
data[i] = i;
|
||||
data+=256;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vid.fullbright=0;
|
||||
}
|
||||
else
|
||||
|
@ -1967,9 +1718,6 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n"));
|
|||
for (i = 0; i < cl.num_statics; i++) //make the static entities reappear.
|
||||
{
|
||||
cl_static_entities[i].model = cl.model_precache[staticmodelindex[i]];
|
||||
#ifdef SWQUAKE
|
||||
cl_static_entities[i].palremap = D_IdentityRemap();
|
||||
#endif
|
||||
if (staticmodelindex[i]) //make sure it's worthwhile.
|
||||
{
|
||||
R_AddEfrags(&cl_static_entities[i]);
|
||||
|
@ -1989,12 +1737,6 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n"));
|
|||
"Dedicated console created\n");
|
||||
break;
|
||||
|
||||
case QR_SOFTWARE:
|
||||
Con_Printf( "\n"
|
||||
"-----------------------------\n"
|
||||
"Software renderer initialized\n");
|
||||
break;
|
||||
|
||||
case QR_OPENGL:
|
||||
Con_Printf( "\n"
|
||||
"-----------------------------\n"
|
||||
|
@ -2067,16 +1809,10 @@ TRACE(("dbg: R_RestartRenderer_f\n"));
|
|||
{
|
||||
Con_Printf("vid_renderer unset or invalid. Using default.\n");
|
||||
//gotta do this after main hunk is saved off.
|
||||
#if defined(RGLQUAKE) && defined(SWQUAKE)
|
||||
Cmd_ExecuteString("setrenderer sw 8\n", RESTRICT_LOCAL);
|
||||
Cbuf_AddText("menu_video\n", RESTRICT_LOCAL);
|
||||
|
||||
#elif defined(RGLQUAKE)
|
||||
#if defined(RGLQUAKE)
|
||||
Cmd_ExecuteString("setrenderer gl\n", RESTRICT_LOCAL);
|
||||
#elif defined(D3DQUAKE)
|
||||
Cmd_ExecuteString("setrenderer d3d9\n", RESTRICT_LOCAL);
|
||||
#else
|
||||
Cmd_ExecuteString("setrenderer sw\n", RESTRICT_LOCAL);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
@ -2091,10 +1827,7 @@ TRACE(("dbg: R_RestartRenderer_f\n"));
|
|||
// force default values for systems not supporting desktop parameters
|
||||
dwidth = 640;
|
||||
dheight = 480;
|
||||
if (newr.renderer == QR_SOFTWARE) // hack for software default
|
||||
dbpp = 8;
|
||||
else
|
||||
dbpp = 32;
|
||||
dbpp = 32;
|
||||
}
|
||||
|
||||
if (vid_desktopsettings.value)
|
||||
|
|
|
@ -60,12 +60,6 @@ void GLSCR_UpdateScreen (void);
|
|||
|
||||
void SCR_ImageName (char *mapname);
|
||||
|
||||
#if defined(SWQUAKE)
|
||||
void SWSCR_UpdateScreen (void);
|
||||
void SCR_UpdateWholeScreen (void);
|
||||
#endif
|
||||
|
||||
|
||||
//this stuff is internal to the screen systems.
|
||||
void RSpeedShow(void);
|
||||
|
||||
|
|
|
@ -227,18 +227,8 @@ qbyte *Skin_Cache8 (skin_t *skin)
|
|||
return out;
|
||||
|
||||
// TODO: we build a fullbright remap.. can we get rid of this?
|
||||
#ifdef SWQUAKE
|
||||
if (qrenderer == QR_SOFTWARE && r_pixbytes == 1 && cls.allow_fbskins<0.2) //only time FB has to exist... (gl can be disabled)
|
||||
{
|
||||
for (x = 0; x < vid.fullbright; x++)
|
||||
fbremap[x] = GetPaletteIndex(host_basepal[((x+256-vid.fullbright)*3)], host_basepal[((x+256-vid.fullbright)*3)+1], host_basepal[((x+256-vid.fullbright)*3)+2]);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (x = 0; x < vid.fullbright; x++)
|
||||
fbremap[x] = x + (256-vid.fullbright); //fullbrights don't exist, so don't loose palette info.
|
||||
}
|
||||
for (x = 0; x < vid.fullbright; x++)
|
||||
fbremap[x] = x + (256-vid.fullbright); //fullbrights don't exist, so don't loose palette info.
|
||||
|
||||
//
|
||||
// load the pic from disk
|
||||
|
@ -327,16 +317,8 @@ qbyte *Skin_Cache8 (skin_t *skin)
|
|||
Con_Printf ("Bad skin %s (unsupported size)\n", name);
|
||||
return NULL;
|
||||
}
|
||||
if (qrenderer == QR_SOFTWARE)
|
||||
{//biggest size possible, by the way
|
||||
skin->width = 320;
|
||||
skin->height = 200;
|
||||
}
|
||||
else
|
||||
{
|
||||
skin->width = srcw;
|
||||
skin->height = srch;
|
||||
}
|
||||
skin->width = srcw;
|
||||
skin->height = srch;
|
||||
|
||||
out = Cache_Alloc (&skin->cache, skin->width*skin->height, skin->name);
|
||||
if (!out)
|
||||
|
|
|
@ -29,10 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include <io.h>
|
||||
#include <direct.h>
|
||||
|
||||
#ifndef AVAIL_DDRAW
|
||||
#define DDActive 0
|
||||
#endif
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
@ -1500,12 +1496,12 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
{
|
||||
#ifndef SERVERONLY
|
||||
// yield the CPU for a little while when paused, minimized, or not the focus
|
||||
if (((cl.paused && (!ActiveApp && !DDActive)) || Minimized || block_drawing) && !Media_PlayingFullScreen())
|
||||
if ((cl.paused || Minimized || block_drawing) && !Media_PlayingFullScreen())
|
||||
{
|
||||
SleepUntilInput (PAUSE_SLEEP);
|
||||
scr_skipupdate = 1; // no point in bothering to draw
|
||||
}
|
||||
else if (!ActiveApp && !DDActive && !Media_PlayingFullScreen())
|
||||
else if (!ActiveApp && !Media_PlayingFullScreen())
|
||||
{
|
||||
SleepUntilInput (NOT_FOCUS_SLEEP);
|
||||
}
|
||||
|
@ -1567,11 +1563,11 @@ void Sys_LowFPPrecision (void)
|
|||
{
|
||||
}
|
||||
|
||||
void Sys_SetFPCW (void)
|
||||
void VARGS Sys_SetFPCW (void)
|
||||
{
|
||||
}
|
||||
|
||||
void MaskExceptions (void)
|
||||
void VARGS MaskExceptions (void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -93,22 +93,6 @@ static void Validation_Version(void)
|
|||
|
||||
*s = *"";
|
||||
break;
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
case QR_SOFTWARE:
|
||||
if (r_pixbytes == 4)
|
||||
{
|
||||
*s++ = '3';
|
||||
*s++ = '2';
|
||||
}
|
||||
else if (r_pixbytes == 2)
|
||||
{
|
||||
*s++ = '1';
|
||||
*s++ = '6';
|
||||
}
|
||||
else
|
||||
*s++ = '8';
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
*sr = *"";
|
||||
|
|
|
@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
// a pixel can be one, two, or four bytes
|
||||
typedef qbyte pixel_t;
|
||||
|
||||
typedef enum {QR_NONE, QR_SOFTWARE, QR_OPENGL, QR_DIRECT3D} r_qrenderer_t;
|
||||
typedef enum {QR_NONE, QR_OPENGL, QR_DIRECT3D} r_qrenderer_t;
|
||||
|
||||
typedef struct {
|
||||
//you are not allowed to make anything not work if it's not based on these vars...
|
||||
|
@ -113,32 +113,3 @@ void GLD_EndDirectRect (int x, int y, int width, int height);
|
|||
char *GLVID_GetRGBInfo(int prepadbytes, int *truewidth, int *trueheight);
|
||||
void GLVID_SetCaption(char *caption);
|
||||
#endif
|
||||
|
||||
#ifdef SWQUAKE
|
||||
void SWVID_SetPalette (unsigned char *palette);
|
||||
// called at startup and after any gamma correction
|
||||
|
||||
void SWVID_ShiftPalette (unsigned char *palette);
|
||||
// called for bonus and pain flashes, and for underwater color changes
|
||||
|
||||
qboolean SWVID_Init (rendererstate_t *info, unsigned char *palette);
|
||||
// Called at startup to set up translation tables, takes 256 8 bit RGB values
|
||||
// the palette data will go away after the call, so it must be copied off if
|
||||
// the video driver will need it again
|
||||
|
||||
void SWVID_Shutdown (void);
|
||||
// Called at shutdown
|
||||
|
||||
void SWVID_Update (vrect_t *rects);
|
||||
// flushes the given rectangles from the view buffer to the screen
|
||||
|
||||
void SWVID_LockBuffer (void);
|
||||
void SWVID_UnlockBuffer (void);
|
||||
|
||||
int SWVID_ForceUnlockedAndReturnState (void);
|
||||
void SWVID_ForceLockState (int lk);
|
||||
|
||||
char *SWVID_GetRGBInfo(int prepadbytes, int *truewidth, int *trueheight);
|
||||
|
||||
void SWVID_SetCaption(char *caption);
|
||||
#endif
|
||||
|
|
|
@ -21,10 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "quakedef.h"
|
||||
|
||||
#ifdef SWQUAKE
|
||||
#include "r_local.h"
|
||||
#endif
|
||||
|
||||
#include "winquake.h"
|
||||
|
||||
#ifdef FISH
|
||||
|
@ -366,15 +362,6 @@ void BuildGammaTable (float g, float c)
|
|||
V_CheckGamma
|
||||
=================
|
||||
*/
|
||||
#ifdef SWQUAKE
|
||||
void SWV_Gamma_Callback(struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
BuildGammaTable (v_gamma.value, v_contrast.value);
|
||||
vid.recalc_refdef = 1; // force a surface cache flush
|
||||
SWV_UpdatePalette (true, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RGLQUAKE) || defined(D3DQUAKE)
|
||||
void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
|
@ -785,101 +772,6 @@ void GLV_UpdatePalette (qboolean force, double ftime)
|
|||
V_UpdatePalette
|
||||
=============
|
||||
*/
|
||||
#ifdef SWQUAKE
|
||||
void SWV_UpdatePalette (qboolean force, double ftime)
|
||||
{
|
||||
int i, j;
|
||||
qboolean update;
|
||||
qbyte *basepal, *newpal;
|
||||
qbyte pal[768];
|
||||
int r,g,b;
|
||||
|
||||
V_CalcPowerupCshift ();
|
||||
|
||||
update = false;
|
||||
|
||||
for (i=0 ; i<NUM_CSHIFTS ; i++)
|
||||
{
|
||||
if (cl.cshifts[i].percent != cl.prev_cshifts[i].percent)
|
||||
{
|
||||
if (i == CSHIFT_SERVER)
|
||||
force = true; // don't let them cheat.
|
||||
update = true;
|
||||
cl.prev_cshifts[i].percent = cl.cshifts[i].percent;
|
||||
}
|
||||
for (j=0 ; j<3 ; j++)
|
||||
if (cl.cshifts[i].destcolor[j] != cl.prev_cshifts[i].destcolor[j])
|
||||
{
|
||||
update = true;
|
||||
cl.prev_cshifts[i].destcolor[j] = cl.cshifts[i].destcolor[j];
|
||||
}
|
||||
}
|
||||
|
||||
// drop the damage value
|
||||
cl.cshifts[CSHIFT_DAMAGE].percent -= ftime*150;
|
||||
if (cl.cshifts[CSHIFT_DAMAGE].percent <= 0)
|
||||
cl.cshifts[CSHIFT_DAMAGE].percent = 0;
|
||||
|
||||
// drop the bonus value
|
||||
cl.cshifts[CSHIFT_BONUS].percent -= ftime*100;
|
||||
if (cl.cshifts[CSHIFT_BONUS].percent <= 0)
|
||||
cl.cshifts[CSHIFT_BONUS].percent = 0;
|
||||
|
||||
|
||||
if (r_pixbytes == 4) //doesn't support palette cycling. It messes up caches.
|
||||
{
|
||||
if (!update && !force)
|
||||
return;
|
||||
basepal = host_basepal;
|
||||
newpal = pal;
|
||||
|
||||
for (i=0 ; i<256 ; i++)
|
||||
{
|
||||
r = basepal[0];
|
||||
g = basepal[1];
|
||||
b = basepal[2];
|
||||
basepal += 3;
|
||||
|
||||
newpal[0] = gammatable[r];
|
||||
newpal[1] = gammatable[g];
|
||||
newpal[2] = gammatable[b];
|
||||
newpal += 3;
|
||||
}
|
||||
|
||||
VID_ShiftPalette (pal);
|
||||
D_FlushCaches();
|
||||
return;
|
||||
}
|
||||
if (!update && !force)
|
||||
return;
|
||||
|
||||
basepal = host_basepal;
|
||||
newpal = pal;
|
||||
|
||||
for (i=0 ; i<256 ; i++)
|
||||
{
|
||||
r = basepal[0];
|
||||
g = basepal[1];
|
||||
b = basepal[2];
|
||||
basepal += 3;
|
||||
|
||||
for (j=0 ; j<NUM_CSHIFTS ; j++)
|
||||
{
|
||||
r += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[0]-r))>>8;
|
||||
g += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[1]-g))>>8;
|
||||
b += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[2]-b))>>8;
|
||||
}
|
||||
|
||||
newpal[0] = gammatable[r];
|
||||
newpal[1] = gammatable[g];
|
||||
newpal[2] = gammatable[b];
|
||||
newpal += 3;
|
||||
}
|
||||
|
||||
VID_ShiftPalette (pal);
|
||||
}
|
||||
|
||||
#endif // SWQUAKE
|
||||
|
||||
void V_ClearCShifts (void)
|
||||
{
|
||||
|
@ -1202,9 +1094,6 @@ void V_CalcRefdef (int pnum)
|
|||
if (!CLHL_AnimateViewEntity(view))
|
||||
#endif
|
||||
view->framestate.g[FS_REG].frame[0] = view_message?view_message->weaponframe:0;
|
||||
#ifdef SWQUAKE
|
||||
view->palremap = D_IdentityRemap();
|
||||
#endif
|
||||
|
||||
// set up the refresh position
|
||||
if (v_gunkick.value)
|
||||
|
@ -1420,17 +1309,7 @@ void V_RenderPlayerViews(int plnum)
|
|||
oldnuments = cl_numvisedicts;
|
||||
CL_LinkViewModel ();
|
||||
|
||||
#ifdef SWQUAKE
|
||||
if (cl.splitclients>1)
|
||||
r_viewchanged = true;
|
||||
#endif
|
||||
|
||||
Cam_SelfTrack(plnum);
|
||||
#if defined(FISH) && defined(SWQUAKE)
|
||||
if (ffov.value && cls.allow_fish && qrenderer == QR_SOFTWARE)
|
||||
R_RenderView_fisheye();
|
||||
else
|
||||
#endif
|
||||
{
|
||||
R_RenderView ();
|
||||
R_DrawNameTags();
|
||||
|
@ -1487,9 +1366,6 @@ void V_RenderPlayerViews(int plnum)
|
|||
float ofy;
|
||||
|
||||
gl_ztrickdisabled|=1;
|
||||
#ifdef SWQUAKE
|
||||
r_viewchanged = true;
|
||||
#endif
|
||||
vid.recalc_refdef=true;
|
||||
|
||||
r_secondaryview = true;
|
||||
|
@ -1564,9 +1440,6 @@ void V_RenderPlayerViews(int plnum)
|
|||
r_refdef.fov_x = ofx;
|
||||
r_refdef.fov_y = ofy;
|
||||
|
||||
#ifdef SWQUAKE
|
||||
r_viewchanged = true;
|
||||
#endif
|
||||
vid.recalc_refdef=true;
|
||||
}
|
||||
#endif
|
||||
|
@ -1728,370 +1601,3 @@ void V_Init (void)
|
|||
Cvar_Register (&v_gamma, VIEWVARS);
|
||||
Cvar_Register (&v_contrast, VIEWVARS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(FISH) && defined(SWQUAKE)
|
||||
|
||||
|
||||
|
||||
typedef unsigned char B;
|
||||
|
||||
#define BOX_FRONT 0
|
||||
#define BOX_BEHIND 2
|
||||
#define BOX_LEFT 3
|
||||
#define BOX_RIGHT 1
|
||||
#define BOX_TOP 4
|
||||
#define BOX_BOTTOM 5
|
||||
|
||||
#define PI 3.141592654
|
||||
|
||||
#define DEG(x) (x / PI * 180.0)
|
||||
#define RAD(x) (x * PI / 180.0)
|
||||
|
||||
struct my_coords
|
||||
{
|
||||
double x, y, z;
|
||||
};
|
||||
|
||||
struct my_angles
|
||||
{
|
||||
double yaw, pitch, roll;
|
||||
};
|
||||
|
||||
void x_rot(struct my_coords *c, double pitch);
|
||||
void y_rot(struct my_coords *c, double yaw);
|
||||
void z_rot(struct my_coords *c, double roll);
|
||||
void my_get_angles(struct my_coords *in_o, struct my_coords *in_u, struct my_angles *a);
|
||||
|
||||
// get_ypr()
|
||||
|
||||
void get_ypr(double yaw, double pitch, double roll, int side, struct my_angles *a)
|
||||
{
|
||||
struct my_coords o, u;
|
||||
|
||||
// get 'o' (observer) and 'u' ('this_way_up') depending on box side
|
||||
|
||||
switch(side)
|
||||
{
|
||||
case BOX_FRONT:
|
||||
//printf("(FRONT)");
|
||||
o.x = 0.0; o.y = 0.0; o.z = 1.0;
|
||||
u.x = 0.0; u.y = 1.0; u.z = 0.0; break;
|
||||
case BOX_BEHIND:
|
||||
//printf("(BEHIND)");
|
||||
o.x = 0.0; o.y = 0.0; o.z = -1.0;
|
||||
u.x = 0.0; u.y = 1.0; u.z = 0.0; break;
|
||||
case BOX_LEFT:
|
||||
//printf("(LEFT)");
|
||||
o.x = -1.0; o.y = 0.0; o.z = 0.0;
|
||||
u.x = -1.0; u.y = 1.0; u.z = 0.0; break;
|
||||
case BOX_RIGHT:
|
||||
o.x = 1.0; o.y = 0.0; o.z = 0.0;
|
||||
//printf("(RIGHT)");
|
||||
u.x = 0.0; u.y = 1.0; u.z = 0.0; break;
|
||||
case BOX_TOP:
|
||||
//printf("(TOP)");
|
||||
o.x = 0.0; o.y = -1.0; o.z = 0.0;
|
||||
u.x = 0.0; u.y = 0.0; u.z = -1.0; break;
|
||||
case BOX_BOTTOM:
|
||||
//printf("(BOTTOM)");
|
||||
o.x = 0.0; o.y = 1.0; o.z = 0.0;
|
||||
u.x = 0.0; u.y = 0.0; u.z = -1.0; break;
|
||||
}
|
||||
|
||||
//printf(" - [inputs: yaw = %.4f, pitch = %.4f, roll = %.4f]\n", yaw, pitch, roll);
|
||||
|
||||
z_rot(&o, roll); z_rot(&u, roll);
|
||||
x_rot(&o, pitch); x_rot(&u, pitch);
|
||||
y_rot(&o, yaw); y_rot(&u, yaw);
|
||||
|
||||
my_get_angles(&o, &u, a);
|
||||
|
||||
/* normalise angles */
|
||||
|
||||
while (a->yaw < 0.0) a->yaw += 360.0;
|
||||
while (a->yaw > 360.0) a->yaw -= 360.0;
|
||||
while (a->pitch < 0.0) a->pitch += 360.0;
|
||||
while (a->pitch > 360.0) a->pitch -= 360.0;
|
||||
while (a->roll < 0.0) a->roll += 360.0;
|
||||
while (a->roll > 360.0) a->roll -= 360.0;
|
||||
|
||||
//printf("get_ypr -> %.4f, %.4f, %.4f\n", a->yaw, a->pitch, a->roll);
|
||||
}
|
||||
|
||||
/* my_get_angles */
|
||||
|
||||
void my_get_angles(struct my_coords *in_o, struct my_coords *in_u, struct my_angles *a)
|
||||
{
|
||||
double rad_yaw, rad_pitch;
|
||||
struct my_coords o, u;
|
||||
|
||||
a->pitch = 0.0;
|
||||
a->yaw = 0.0;
|
||||
a->roll = 0.0;
|
||||
|
||||
// make a copy of the coords
|
||||
|
||||
o.x = in_o->x; o.y = in_o->y; o.z = in_o->z;
|
||||
u.x = in_u->x; u.y = in_u->y; u.z = in_u->z;
|
||||
|
||||
//printf("%.4f, %.4f, %.4f - \n", o.x, o.y, o.z);
|
||||
|
||||
// special case when looking straight up or down
|
||||
|
||||
if ((o.x == 0.0) && (o.z == 0.0))
|
||||
{
|
||||
// printf("special!\n");
|
||||
a->yaw = 0.0;
|
||||
if (o.y > 0.0) { a->pitch = -90.0; a->roll = 180.0 - DEG(atan2(u.x, u.z)); } // down
|
||||
else { a->pitch = 90.0; a->roll = DEG(atan2(u.x, u.z)); } // up
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// get yaw angle and then rotate o and u so that yaw = 0
|
||||
|
||||
rad_yaw = atan2(-o.x, o.z);
|
||||
a->yaw = DEG(rad_yaw);
|
||||
|
||||
y_rot(&o, -rad_yaw);
|
||||
y_rot(&u, -rad_yaw);
|
||||
|
||||
//printf("%.4f, %.4f, %.4f - stage 1\n", o.x, o.y, o.z);
|
||||
|
||||
// get pitch and then rotate o and u so that pitch = 0
|
||||
|
||||
rad_pitch = atan2(-o.y, o.z);
|
||||
a->pitch = DEG(rad_pitch);
|
||||
|
||||
x_rot(&o, -rad_pitch);
|
||||
x_rot(&u, -rad_pitch);
|
||||
|
||||
//printf("%.4f, %.4f, %.4f - stage 2\n", u.x, u.y, u.z);
|
||||
|
||||
// get roll
|
||||
|
||||
a->roll = DEG(-atan2(u.x, u.y));
|
||||
|
||||
//printf("yaw = %.4f, pitch = %.4f, roll = %.4f\n", a->yaw, a->pitch, a->roll);
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
/* x_rot (pitch) */
|
||||
|
||||
void x_rot(struct my_coords *c, double pitch)
|
||||
{
|
||||
double nx, ny, nz;
|
||||
|
||||
nx = c->x;
|
||||
ny = (c->y * cos(pitch)) - (c->z * sin(pitch));
|
||||
nz = (c->y * sin(pitch)) + (c->z * cos(pitch));
|
||||
|
||||
c->x = nx; c->y = ny; c->z = nz;
|
||||
|
||||
/*printf("x_rot: %.4f, %.4f, %.4f\n", c->x, c->y, c->z);*/
|
||||
}
|
||||
|
||||
/* y_rot (yaw) */
|
||||
|
||||
void y_rot(struct my_coords *c, double yaw)
|
||||
{
|
||||
double nx, ny, nz;
|
||||
|
||||
nx = (c->x * cos(yaw)) - (c->z * sin(yaw));
|
||||
ny = c->y;
|
||||
nz = (c->x * sin(yaw)) + (c->z * cos(yaw));
|
||||
|
||||
c->x = nx; c->y = ny; c->z = nz;
|
||||
}
|
||||
|
||||
/* z_rot (roll) */
|
||||
|
||||
void z_rot(struct my_coords *c, double roll)
|
||||
{
|
||||
double nx, ny, nz;
|
||||
|
||||
nx = (c->x * cos(roll)) - (c->y * sin(roll));
|
||||
ny = (c->x * sin(roll)) + (c->y * cos(roll));
|
||||
nz = c->z;
|
||||
|
||||
c->x = nx; c->y = ny; c->z = nz;
|
||||
}
|
||||
|
||||
void rendercopy(int *dest)
|
||||
{
|
||||
int *p = (int*)vid.buffer;
|
||||
int x, y;
|
||||
int nw = (vid.width/4) * r_pixbytes;
|
||||
R_PushDlights();
|
||||
R_RenderView();
|
||||
for(y = 0;y<vid.height;y++) {
|
||||
for(x = 0;x<nw;x++,dest++) *dest = p[x];
|
||||
p += (vid.rowbytes/4) * r_pixbytes;
|
||||
};
|
||||
};
|
||||
|
||||
void renderlookup(B **offs, B* bufs) {
|
||||
B *p = (B*)vid.buffer;
|
||||
int x, y;
|
||||
for(y = 0;y<vid.height;y++) {
|
||||
for(x = 0;x<vid.width;x++,offs++) p[x] = **offs;
|
||||
p += vid.rowbytes;
|
||||
};
|
||||
};
|
||||
|
||||
void renderlookup32(unsigned int **offs, unsigned int* bufs) {
|
||||
unsigned int *p = (unsigned int*)vid.buffer;
|
||||
int x, y;
|
||||
for(y = 0;y<vid.height;y++) {
|
||||
for(x = 0;x<vid.width;x++,offs++) p[x] = **offs;
|
||||
p += vid.rowbytes;
|
||||
};
|
||||
};
|
||||
|
||||
void fisheyelookuptable(B **buf, int width, int height, B *scrp, double fov) {
|
||||
int x, y;
|
||||
|
||||
for(y = 0;y<height;y++) for(x = 0;x<width;x++) {
|
||||
double dx = x-width/2;
|
||||
double dy = -(y-height/2);
|
||||
double yaw = sqrt(dx*dx+dy*dy)*fov/((double)width);
|
||||
double roll = -atan2(dy,dx);
|
||||
double sx = sin(yaw) * cos(roll);
|
||||
double sy = sin(yaw) * sin(roll);
|
||||
double sz = cos(yaw);
|
||||
|
||||
// determine which side of the box we need
|
||||
double abs_x = fabs(sx);
|
||||
double abs_y = fabs(sy);
|
||||
double abs_z = fabs(sz);
|
||||
int side;
|
||||
double xs=0, ys=0;
|
||||
if (abs_x > abs_y) {
|
||||
if (abs_x > abs_z) { side = ((sx > 0.0) ? BOX_RIGHT : BOX_LEFT); }
|
||||
else { side = ((sz > 0.0) ? BOX_FRONT : BOX_BEHIND); }
|
||||
} else {
|
||||
if (abs_y > abs_z) { side = ((sy > 0.0) ? BOX_TOP : BOX_BOTTOM); }
|
||||
else { side = ((sz > 0.0) ? BOX_FRONT : BOX_BEHIND); }
|
||||
}
|
||||
|
||||
#define RC(x) ((x / 2.06) + 0.5)
|
||||
#define R2(x) RC(x)//((x / 2.03) + 0.5)
|
||||
|
||||
// scale up our vector [x,y,z] to the box
|
||||
switch(side) {
|
||||
case BOX_FRONT: xs = RC( sx / sz); ys = R2( sy / sz); break;
|
||||
case BOX_BEHIND: xs = RC(-sx / -sz); ys = R2( sy / -sz); break;
|
||||
case BOX_LEFT: xs = RC( sz / -sx); ys = R2( sy / -sx); break;
|
||||
case BOX_RIGHT: xs = RC(-sz / sx); ys = R2( sy / sx); break;
|
||||
case BOX_TOP: xs = RC( sx / sy); ys = R2( sz / -sy); break; //bot
|
||||
case BOX_BOTTOM: xs = RC(-sx / sy); ys = R2( sz / -sy); break; //top??
|
||||
}
|
||||
|
||||
if (xs < 0.0) xs = 0.0;
|
||||
if (xs >= 1.0) xs = 0.999;
|
||||
if (ys < 0.0) ys = 0.0;
|
||||
if (ys >= 1.0) ys = 0.999;
|
||||
*buf++=scrp+((((int)(xs*(double)width))+
|
||||
((int)(ys*(double)height))*width)+
|
||||
side*width*height)*r_pixbytes;
|
||||
};
|
||||
};
|
||||
|
||||
void renderside(B* bufs, double yaw, double pitch, double roll, int side) {
|
||||
struct my_angles a;
|
||||
get_ypr(RAD(yaw), RAD(pitch), RAD(roll), side, &a);
|
||||
if (side == BOX_RIGHT) { a.roll = -a.roll; a.pitch = -a.pitch; }
|
||||
if (side == BOX_LEFT) { a.roll = -a.roll; a.pitch = -a.pitch; }
|
||||
if (side == BOX_TOP) { a.yaw += 180.0; a.pitch = 180.0 - a.pitch; }
|
||||
r_refdef.viewangles[YAW] = a.yaw;
|
||||
r_refdef.viewangles[PITCH] = a.pitch;
|
||||
r_refdef.viewangles[ROLL] = a.roll;
|
||||
rendercopy((int *)bufs);
|
||||
};
|
||||
|
||||
//extern int istimedemo;
|
||||
|
||||
void R_RenderView_fisheye(void)
|
||||
{
|
||||
int width = vid.width; //r_refdef.vrect.width;
|
||||
int height = vid.height; //r_refdef.vrect.height;
|
||||
int scrsize = width*height*r_pixbytes;
|
||||
int fov = (int)ffov.value;
|
||||
int views = (int)fviews.value;
|
||||
double yaw = r_refdef.viewangles[YAW];
|
||||
double pitch = r_refdef.viewangles[PITCH];
|
||||
double roll = 0;//r_refdef.viewangles[ROLL];
|
||||
static int pwidth = -1;
|
||||
static int pheight = -1;
|
||||
static int pfov = -1;
|
||||
static int pviews = -1;
|
||||
static B *scrbufs = NULL;
|
||||
static B **offs = NULL;
|
||||
//Con_Printf("renderfisheye: %d %d %d\n",vid.height,vid.width,vid.rowbytes);
|
||||
|
||||
Cvar_Set(&scr_fov, "90");
|
||||
Cvar_Set(&scr_viewsize, "120");
|
||||
|
||||
if(fov<1) fov = 1;
|
||||
|
||||
if(pwidth!=width || pheight!=height || pfov!=fov) {
|
||||
if(scrbufs) BZ_Free(scrbufs);
|
||||
if(offs) BZ_Free(offs);
|
||||
scrbufs = (B*)BZ_Malloc(scrsize*6); // front|right|back|left|top|bottom
|
||||
offs = (B**)BZ_Malloc(scrsize*sizeof(B*));
|
||||
if(!scrbufs || !offs) Sys_Error("Out of mem"); // the rude way
|
||||
pwidth = width;
|
||||
pheight = height;
|
||||
pfov = fov;
|
||||
fisheyelookuptable(offs,width,height,scrbufs,((double)fov)*PI/180.0);
|
||||
};
|
||||
|
||||
if(views!=pviews) {
|
||||
int i;
|
||||
pviews = views;
|
||||
for(i = 0;i<scrsize*6;i++) scrbufs[i] = 0;
|
||||
};
|
||||
|
||||
switch(views) {
|
||||
case 6: renderside(scrbufs+scrsize*2,yaw,pitch,roll, BOX_BEHIND);
|
||||
case 5: renderside(scrbufs+scrsize*5,yaw,pitch,roll, BOX_BOTTOM);
|
||||
case 4: renderside(scrbufs+scrsize*4,yaw,pitch,roll, BOX_TOP);
|
||||
case 3: renderside(scrbufs+scrsize*3,yaw,pitch,roll, BOX_LEFT);
|
||||
case 2: renderside(scrbufs+scrsize, yaw,pitch,roll, BOX_RIGHT);
|
||||
default: renderside(scrbufs, yaw,pitch,roll, BOX_FRONT);
|
||||
};
|
||||
|
||||
r_refdef.viewangles[YAW] = yaw;
|
||||
r_refdef.viewangles[PITCH] = pitch;
|
||||
r_refdef.viewangles[ROLL] = roll;
|
||||
if (r_pixbytes == 4)
|
||||
renderlookup32((unsigned int **)offs,(unsigned int *)scrbufs);
|
||||
else
|
||||
renderlookup(offs,scrbufs);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -381,11 +381,7 @@ qbyte *W_ConvertWAD3Texture(miptex_t *tex, int *width, int *height, qboolean *us
|
|||
alpha = 2;
|
||||
|
||||
//use malloc here if you want, but you'll have to free it again... NUR!
|
||||
#ifndef SWQUAKE //quantity optimisation.
|
||||
data = out = Hunk_TempAllocMore(tex->width * tex->height * 4);
|
||||
#else
|
||||
data = out = Hunk_TempAllocMore(((tex->width*4 * tex->height) * 85)/64); //sw mip
|
||||
#endif
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
@ -396,11 +392,7 @@ qbyte *W_ConvertWAD3Texture(miptex_t *tex, int *width, int *height, qboolean *us
|
|||
*height = tex->height;
|
||||
pal = in + (((tex->width * tex->height) * 85) >> 6);
|
||||
pal += 2;
|
||||
#ifndef SWQUAKE
|
||||
for (d = 0;d < tex->width * tex->height;d++)
|
||||
#else
|
||||
for (d = 0;d < (tex->width * tex->height* 85)/64;d++) //sw mip
|
||||
#endif
|
||||
{
|
||||
p = *in++;
|
||||
if (alpha==1 && p == 255) //only allow alpha on '{' textures
|
||||
|
|
|
@ -64,9 +64,6 @@ typedef struct //use this so we don't have to go slow over pics, and don't have
|
|||
int dummy;
|
||||
#ifdef RGLQUAKE
|
||||
glpic_t gl;
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
qbyte data[4]; // variably sized
|
||||
#endif
|
||||
} d;
|
||||
} mpic_t;
|
||||
|
|
|
@ -50,11 +50,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#ifdef AVAIL_DDRAW
|
||||
#include <ddraw.h>
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
#ifdef MGL
|
||||
#include <mgraph.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef byte
|
||||
|
@ -72,15 +67,6 @@ extern unsigned int sys_parentheight;
|
|||
LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef AVAIL_DDRAW
|
||||
extern qboolean DDActive;
|
||||
extern LPDIRECTDRAW lpDD;
|
||||
extern LPDIRECTDRAWSURFACE lpPrimary;
|
||||
extern LPDIRECTDRAWSURFACE lpFrontBuffer;
|
||||
extern LPDIRECTDRAWSURFACE lpBackBuffer;
|
||||
extern LPDIRECTDRAWPALETTE lpDDPal;
|
||||
#endif
|
||||
/*
|
||||
struct soundcardinfo_s {
|
||||
int snd_linear_count; //change in asm_i386.h. MUST be first
|
||||
|
|
|
@ -104,7 +104,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
#define SVRANKING
|
||||
#define SWSTAINS
|
||||
|
||||
#ifdef MINIMAL
|
||||
#define CL_MASTER //this is useful
|
||||
|
@ -240,14 +239,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#undef VM_Q1
|
||||
#endif
|
||||
|
||||
#if defined(SWQUAKE) || defined(GLQUAKE)
|
||||
#if defined(GLQUAKE)
|
||||
//not supported in anything but GL. avoid bugs.
|
||||
#undef AVAIL_FREETYPE
|
||||
#endif
|
||||
|
||||
//remove any options that depend upon GL.
|
||||
#ifndef SERVERONLY
|
||||
#if defined(SWQUAKE) && !defined(GLQUAKE)
|
||||
#if !defined(GLQUAKE)
|
||||
#undef DOOMWADS
|
||||
#undef HALFLIFEMODELS
|
||||
#undef Q3BSPS
|
||||
|
|
|
@ -26,10 +26,6 @@
|
|||
#error "nodraw isn't constant"
|
||||
#endif
|
||||
|
||||
#ifdef SWQUAKE
|
||||
extern qboolean r_usinglits;
|
||||
#endif
|
||||
|
||||
extern cvar_t r_shadow_bumpscale_basetexture;
|
||||
|
||||
//these are in model.c (or gl_model.c)
|
||||
|
@ -1087,60 +1083,6 @@ void *Mod_LoadWall(char *name)
|
|||
tex->tn.base = GL_LoadTexture32 (name, width, height, (unsigned int *)in, true, false);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
if (qrenderer == QR_SOFTWARE)
|
||||
{
|
||||
int i, j;
|
||||
qbyte *out;
|
||||
|
||||
tex = Hunk_AllocName(sizeof(texture_t) + width*r_pixbytes*height/64*85, ln);
|
||||
tex->pixbytes = r_pixbytes;
|
||||
tex->width = width;
|
||||
tex->height = height;
|
||||
|
||||
tex->offsets[0] = sizeof(*tex);
|
||||
tex->offsets[1] = tex->offsets[0] + width*height*r_pixbytes;
|
||||
tex->offsets[2] = tex->offsets[1] + (width*height*r_pixbytes)/4;
|
||||
tex->offsets[3] = tex->offsets[2] + (width*height*r_pixbytes)/(4*4);
|
||||
|
||||
out = (qbyte *)(tex+1);
|
||||
|
||||
if (tex->pixbytes == 4)
|
||||
{
|
||||
for (i = 0; i < width*height; i++)
|
||||
{
|
||||
*out++ = in[2];
|
||||
*out++ = in[1];
|
||||
*out++ = in[0];
|
||||
*out++ = in[3];
|
||||
in+=4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < tex->width*tex->height; i++) //downgrade colour
|
||||
{
|
||||
*out++ = GetPaletteNoFB(in[0], in[1], in[2]);
|
||||
in+=4;
|
||||
}
|
||||
|
||||
in = (qbyte *)tex+tex->offsets[0]; //shrink mips.
|
||||
|
||||
for (j = 0; j < tex->height; j+=2) //we could convert mip[1], but shrinking is probably faster.
|
||||
for (i = 0; i < tex->width; i+=2)
|
||||
*out++ = in[i + tex->width*j];
|
||||
|
||||
for (j = 0; j < tex->height; j+=4)
|
||||
for (i = 0; i < tex->width; i+=4)
|
||||
*out++ = in[i + tex->width*j];
|
||||
|
||||
for (j = 0; j < tex->height; j+=8)
|
||||
for (i = 0; i < tex->width; i+=8)
|
||||
*out++ = in[i + tex->width*j];
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Sys_Error("Mod_LoadWall with bad renderer\n");
|
||||
|
@ -1174,58 +1116,6 @@ void *Mod_LoadWall(char *name)
|
|||
tex->tn.bump = R_LoadTexture8Bump (va("%s_bump", wal->name), tex->width, tex->height, in, true, r_shadow_bumpscale_basetexture.value);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if defined(SWQUAKE)
|
||||
if (qrenderer == QR_SOFTWARE)
|
||||
{
|
||||
int i, j;
|
||||
qbyte *out;
|
||||
|
||||
tex = Hunk_AllocName(sizeof(texture_t) + wal->width*r_pixbytes*wal->height/64*85, ln);
|
||||
tex->width = wal->width;
|
||||
tex->height = wal->height;
|
||||
|
||||
tex->pixbytes = r_pixbytes;
|
||||
for (i = 0; i < MIPLEVELS; i++)
|
||||
tex->offsets[i] = (wal->offsets[i] - sizeof(*wal))*tex->pixbytes + sizeof(*tex);
|
||||
|
||||
out = (qbyte *)(tex+1);
|
||||
in = (qbyte *)wal+wal->offsets[0];
|
||||
|
||||
if (tex->pixbytes == 4)
|
||||
{
|
||||
for (i = 0; i < wal->width*wal->height/64*85; i++)
|
||||
{
|
||||
*out++ = d_q28to24table[*in*3+0];
|
||||
*out++ = d_q28to24table[*in*3+1];
|
||||
*out++ = d_q28to24table[*in*3+2];
|
||||
*out++ = 255;
|
||||
in++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < tex->width*tex->height; i++) //downgrade colour
|
||||
{
|
||||
*out++ = GetPaletteNoFB(d_q28to24table[*in*3+0], d_q28to24table[*in*3+1], d_q28to24table[*in*3+2]);
|
||||
in++;
|
||||
}
|
||||
in = (qbyte *)tex+tex->offsets[0]; //shrink mips.
|
||||
|
||||
for (j = 0; j < tex->height; j+=2) //we could convert mip[1], but shrinking is probably faster.
|
||||
for (i = 0; i < tex->width; i+=2)
|
||||
*out++ = in[i + tex->width*j];
|
||||
|
||||
for (j = 0; j < tex->height; j+=4)
|
||||
for (i = 0; i < tex->width; i+=4)
|
||||
*out++ = in[i + tex->width*j];
|
||||
|
||||
for (j = 0; j < tex->height; j+=8)
|
||||
for (i = 0; i < tex->width; i+=8)
|
||||
*out++ = in[i + tex->width*j];
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Sys_Error("Mod_LoadWall with bad renderer\n");
|
||||
|
@ -1467,10 +1357,6 @@ qboolean CMod_LoadFaces (lump_t *l)
|
|||
#ifdef RGLQUAKE
|
||||
else if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D)
|
||||
out->samples = loadmodel->lightdata + i;
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
else if (r_usinglits)
|
||||
out->samples = loadmodel->lightdata + i;
|
||||
#endif
|
||||
else
|
||||
out->samples = loadmodel->lightdata + i/3;
|
||||
|
@ -3737,45 +3623,6 @@ void GLR_Q2BSP_StainNode (mnode_t *node, float *parms)
|
|||
GLR_Q2BSP_StainNode (node->children[1], parms);
|
||||
}
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
void SWR_StainSurf (msurface_t *surf, float *parms);
|
||||
void SWR_Q2BSP_StainNode (mnode_t *node, float *parms)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
|
||||
if (node->contents != -1)
|
||||
return;
|
||||
|
||||
splitplane = node->plane;
|
||||
dist = DotProduct ((parms+1), splitplane->normal) - splitplane->dist;
|
||||
|
||||
if (dist > (*parms))
|
||||
{
|
||||
SWR_Q2BSP_StainNode (node->children[0], parms);
|
||||
return;
|
||||
}
|
||||
if (dist < (-*parms))
|
||||
{
|
||||
SWR_Q2BSP_StainNode (node->children[1], parms);
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the polygons
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->flags&~(SURF_DONTWARP|SURF_PLANEBACK))
|
||||
continue;
|
||||
SWR_StainSurf(surf, parms);
|
||||
}
|
||||
|
||||
SWR_Q2BSP_StainNode (node->children[0], parms);
|
||||
SWR_Q2BSP_StainNode (node->children[1], parms);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -4139,57 +3986,6 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
|
|||
loadmodel->funcs.NativeTrace = CM_NativeTrace;
|
||||
loadmodel->funcs.NativeContents = CM_NativeContents;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SWQUAKE)
|
||||
case QR_SOFTWARE:
|
||||
// load into heap
|
||||
#ifndef SERVERONLY
|
||||
noerrors = noerrors && SWMod_LoadVertexes (&header.lumps[Q2LUMP_VERTEXES]);
|
||||
noerrors = noerrors && SWMod_LoadEdges (&header.lumps[Q2LUMP_EDGES]);
|
||||
noerrors = noerrors && SWMod_LoadSurfedges (&header.lumps[Q2LUMP_SURFEDGES]);
|
||||
if (noerrors)
|
||||
SWMod_LoadLighting (&header.lumps[Q2LUMP_LIGHTING]);
|
||||
#endif
|
||||
noerrors = noerrors && CMod_LoadSurfaces (&header.lumps[Q2LUMP_TEXINFO]);
|
||||
noerrors = noerrors && CMod_LoadLeafBrushes (&header.lumps[Q2LUMP_LEAFBRUSHES]);
|
||||
noerrors = noerrors && CMod_LoadPlanes (&header.lumps[Q2LUMP_PLANES]);
|
||||
#ifndef SERVERONLY
|
||||
noerrors = noerrors && CMod_LoadTexInfo (&header.lumps[Q2LUMP_TEXINFO]);
|
||||
noerrors = noerrors && CMod_LoadFaces (&header.lumps[Q2LUMP_FACES]);
|
||||
noerrors = noerrors && SWMod_LoadMarksurfaces (&header.lumps[Q2LUMP_LEAFFACES]);
|
||||
#endif
|
||||
noerrors = noerrors && CMod_LoadVisibility (&header.lumps[Q2LUMP_VISIBILITY]);
|
||||
noerrors = noerrors && CMod_LoadBrushes (&header.lumps[Q2LUMP_BRUSHES]);
|
||||
noerrors = noerrors && CMod_LoadBrushSides (&header.lumps[Q2LUMP_BRUSHSIDES]);
|
||||
noerrors = noerrors && CMod_LoadSubmodels (&header.lumps[Q2LUMP_MODELS]);
|
||||
noerrors = noerrors && CMod_LoadLeafs (&header.lumps[Q2LUMP_LEAFS]);
|
||||
noerrors = noerrors && CMod_LoadNodes (&header.lumps[Q2LUMP_NODES]);
|
||||
noerrors = noerrors && CMod_LoadAreas (&header.lumps[Q2LUMP_AREAS]);
|
||||
noerrors = noerrors && CMod_LoadAreaPortals (&header.lumps[Q2LUMP_AREAPORTALS]);
|
||||
if (noerrors)
|
||||
CMod_LoadEntityString (&header.lumps[Q2LUMP_ENTITIES]);
|
||||
|
||||
if (!noerrors)
|
||||
{
|
||||
Hunk_FreeToLowMark(start);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
loadmodel->funcs.FatPVS = Q2BSP_FatPVS;
|
||||
loadmodel->funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS;
|
||||
loadmodel->funcs.FindTouchedLeafs_Q1 = Q2BSP_FindTouchedLeafs;
|
||||
#endif
|
||||
loadmodel->funcs.LightPointValues = SWQ2BSP_LightPointValues;
|
||||
loadmodel->funcs.StainNode = SWR_Q2BSP_StainNode;
|
||||
loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
|
||||
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
|
||||
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
|
||||
loadmodel->funcs.Trace = CM_Trace;
|
||||
loadmodel->funcs.PointContents = Q2BSP_PointContents;
|
||||
loadmodel->funcs.NativeTrace = CM_NativeTrace;
|
||||
loadmodel->funcs.NativeContents = CM_NativeContents;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
Hunk_FreeToLowMark(start);
|
||||
|
|
|
@ -182,7 +182,7 @@ BoxOnPlaneSide
|
|||
Returns 1, 2, or 1 + 2
|
||||
==================
|
||||
*/
|
||||
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, mplane_t *p)
|
||||
int VARGS BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, mplane_t *p)
|
||||
{
|
||||
float dist1, dist2;
|
||||
int sides;
|
||||
|
|
|
@ -36,7 +36,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
|
||||
#ifdef MQUAKE
|
||||
#define SWQUAKE
|
||||
#define GLQUAKE
|
||||
#endif
|
||||
|
||||
|
@ -44,236 +43,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define TRANSPARENT_COLOR 255
|
||||
|
||||
#ifndef NeXT
|
||||
#ifdef SWQUAKE
|
||||
.extern C(d_zistepu)
|
||||
.extern C(d_pzbuffer)
|
||||
.extern C(d_zistepv)
|
||||
.extern C(d_zrowbytes)
|
||||
.extern C(d_ziorigin)
|
||||
.extern C(r_turb_s)
|
||||
.extern C(r_turb_t)
|
||||
.extern C(r_turb_pdest)
|
||||
.extern C(r_turb_spancount)
|
||||
.extern C(r_turb_turb)
|
||||
.extern C(r_turb_pbase)
|
||||
.extern C(r_turb_sstep)
|
||||
.extern C(r_turb_tstep)
|
||||
.extern C(r_bmodelactive)
|
||||
.extern C(d_sdivzstepu)
|
||||
.extern C(d_tdivzstepu)
|
||||
.extern C(d_sdivzstepv)
|
||||
.extern C(d_tdivzstepv)
|
||||
.extern C(d_sdivzorigin)
|
||||
.extern C(d_tdivzorigin)
|
||||
.extern C(sadjust)
|
||||
.extern C(tadjust)
|
||||
.extern C(bbextents)
|
||||
.extern C(bbextentt)
|
||||
.extern C(cacheblock)
|
||||
.extern C(d_viewbuffer)
|
||||
.extern C(cachewidth)
|
||||
.extern C(d_pzbuffer)
|
||||
.extern C(d_zrowbytes)
|
||||
.extern C(d_zwidth)
|
||||
.extern C(d_scantable)
|
||||
.extern C(r_lightptr)
|
||||
.extern C(r_numvblocks)
|
||||
.extern C(prowdestbase)
|
||||
.extern C(pbasesource)
|
||||
.extern C(r_lightwidth)
|
||||
.extern C(lightright)
|
||||
.extern C(lightrightstep)
|
||||
.extern C(lightdeltastep)
|
||||
.extern C(lightdelta)
|
||||
.extern C(lightright)
|
||||
.extern C(lightdelta)
|
||||
.extern C(sourcetstep)
|
||||
.extern C(surfrowbytes)
|
||||
.extern C(lightrightstep)
|
||||
.extern C(lightdeltastep)
|
||||
.extern C(r_sourcemax)
|
||||
.extern C(r_stepback)
|
||||
.extern C(colormap)
|
||||
.extern C(blocksize)
|
||||
.extern C(sourcesstep)
|
||||
.extern C(lightleft)
|
||||
.extern C(blockdivshift)
|
||||
.extern C(blockdivmask)
|
||||
.extern C(lightleftstep)
|
||||
.extern C(r_origin)
|
||||
.extern C(r_ppn)
|
||||
.extern C(r_pup)
|
||||
.extern C(r_pright)
|
||||
.extern C(ycenter)
|
||||
.extern C(xcenter)
|
||||
.extern C(d_vrectbottom_particle)
|
||||
.extern C(d_vrectright_particle)
|
||||
.extern C(d_vrecty)
|
||||
.extern C(d_vrectx)
|
||||
.extern C(d_pix_shift)
|
||||
.extern C(d_pix_min)
|
||||
.extern C(d_pix_max)
|
||||
.extern C(d_y_aspect_shift)
|
||||
.extern C(screenwidth)
|
||||
.extern C(r_leftclipped)
|
||||
.extern C(r_leftenter)
|
||||
.extern C(r_rightclipped)
|
||||
.extern C(r_rightenter)
|
||||
.extern C(modelorg)
|
||||
.extern C(xscale)
|
||||
.extern C(r_refdef)
|
||||
.extern C(yscale)
|
||||
.extern C(r_leftexit)
|
||||
.extern C(r_rightexit)
|
||||
.extern C(r_lastvertvalid)
|
||||
.extern C(cacheoffset)
|
||||
.extern C(newedges)
|
||||
.extern C(removeedges)
|
||||
.extern C(r_pedge)
|
||||
.extern C(r_framecount)
|
||||
.extern C(r_u1)
|
||||
.extern C(r_emitted)
|
||||
.extern C(edge_p)
|
||||
.extern C(surface_p)
|
||||
.extern C(surfaces)
|
||||
.extern C(r_lzi1)
|
||||
.extern C(r_v1)
|
||||
.extern C(r_ceilv1)
|
||||
.extern C(r_nearzi)
|
||||
.extern C(r_nearzionly)
|
||||
.extern C(edge_aftertail)
|
||||
.extern C(edge_tail)
|
||||
.extern C(current_iv)
|
||||
.extern C(edge_head_u_shift20)
|
||||
.extern C(span_p)
|
||||
.extern C(edge_head)
|
||||
.extern C(fv)
|
||||
.extern C(edge_tail_u_shift20)
|
||||
|
||||
.extern C(r_apoldverts) //trivertex_t
|
||||
.extern C(r_apnewverts)
|
||||
.extern C(r_afrntlerp) //float of quantity.
|
||||
.extern C(r_abacklerp)
|
||||
|
||||
.extern C(r_anumverts)
|
||||
.extern C(aliastransform)
|
||||
.extern C(r_avertexnormals)
|
||||
.extern C(r_plightvec)
|
||||
.extern C(r_ambientlight)
|
||||
.extern C(r_shadelight)
|
||||
.extern C(aliasxcenter)
|
||||
.extern C(aliasycenter)
|
||||
.extern C(a_sstepxfrac)
|
||||
.extern C(r_affinetridesc)
|
||||
.extern C(acolormap)
|
||||
.extern C(d_pcolormap)
|
||||
.extern C(apalremap)
|
||||
.extern C(r_affinetridesc)
|
||||
.extern C(d_sfrac)
|
||||
.extern C(d_ptex)
|
||||
.extern C(d_pedgespanpackage)
|
||||
.extern C(d_tfrac)
|
||||
.extern C(d_light)
|
||||
.extern C(d_zi)
|
||||
.extern C(d_pdest)
|
||||
.extern C(d_pz)
|
||||
.extern C(d_aspancount)
|
||||
.extern C(erroradjustup)
|
||||
.extern C(errorterm)
|
||||
.extern C(d_xdenom)
|
||||
.extern C(r_p0)
|
||||
.extern C(r_p1)
|
||||
.extern C(r_p2)
|
||||
.extern C(a_tstepxfrac)
|
||||
.extern C(r_sstepx)
|
||||
.extern C(r_tstepx)
|
||||
.extern C(a_ststepxwhole)
|
||||
.extern C(zspantable)
|
||||
.extern C(skintable)
|
||||
.extern C(r_zistepx)
|
||||
.extern C(erroradjustdown)
|
||||
.extern C(d_countextrastep)
|
||||
.extern C(ubasestep)
|
||||
.extern C(a_ststepxwhole)
|
||||
.extern C(a_tstepxfrac)
|
||||
.extern C(r_lstepx)
|
||||
.extern C(a_spans)
|
||||
.extern C(erroradjustdown)
|
||||
.extern C(d_pdestextrastep)
|
||||
.extern C(d_pzextrastep)
|
||||
.extern C(d_sfracextrastep)
|
||||
.extern C(d_ptexextrastep)
|
||||
.extern C(d_countextrastep)
|
||||
.extern C(d_tfracextrastep)
|
||||
.extern C(d_lightextrastep)
|
||||
.extern C(d_ziextrastep)
|
||||
.extern C(d_pdestbasestep)
|
||||
.extern C(d_pzbasestep)
|
||||
.extern C(d_sfracbasestep)
|
||||
.extern C(d_ptexbasestep)
|
||||
.extern C(ubasestep)
|
||||
.extern C(d_tfracbasestep)
|
||||
.extern C(d_lightbasestep)
|
||||
.extern C(d_zibasestep)
|
||||
.extern C(zspantable)
|
||||
.extern C(r_lstepy)
|
||||
.extern C(r_sstepy)
|
||||
.extern C(r_tstepy)
|
||||
.extern C(r_zistepy)
|
||||
.extern C(D_PolysetSetEdgeTable)
|
||||
.extern C(D_RasterizeAliasPolySmooth)
|
||||
|
||||
.extern float_point5
|
||||
.extern Float2ToThe31nd
|
||||
.extern izistep
|
||||
.extern izi
|
||||
.extern FloatMinus2ToThe31nd
|
||||
.extern float_1
|
||||
.extern float_particle_z_clip
|
||||
.extern float_minus_1
|
||||
.extern float_0
|
||||
.extern fp_16
|
||||
.extern fp_64k
|
||||
.extern fp_1m
|
||||
.extern fp_1m_minus_1
|
||||
.extern fp_8
|
||||
.extern entryvec_table
|
||||
.extern advancetable
|
||||
.extern sstep
|
||||
.extern tstep
|
||||
.extern pspantemp
|
||||
.extern counttemp
|
||||
.extern jumptemp
|
||||
.extern reciprocal_table
|
||||
.extern DP_Count
|
||||
.extern DP_u
|
||||
.extern DP_v
|
||||
.extern DP_Partfac
|
||||
.extern DP_Color
|
||||
.extern DP_Pix
|
||||
.extern DP_EntryTable
|
||||
.extern pbase
|
||||
.extern s
|
||||
.extern t
|
||||
.extern sfracf
|
||||
.extern tfracf
|
||||
.extern snext
|
||||
.extern tnext
|
||||
.extern spancountminus1
|
||||
.extern zi16stepu
|
||||
.extern sdivz16stepu
|
||||
.extern tdivz16stepu
|
||||
.extern zi8stepu
|
||||
.extern sdivz8stepu
|
||||
.extern tdivz8stepu
|
||||
.extern reciprocal_table_16
|
||||
.extern entryvec_table_16
|
||||
.extern ceil_cw
|
||||
.extern single_cw
|
||||
.extern fp_64kx64k
|
||||
.extern pz
|
||||
.extern spr8entryvec_table
|
||||
#endif
|
||||
|
||||
.extern C(paintbuffer)
|
||||
// .extern C(snd_linear_count)
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
//its optional... but if its not in there then its unlikely you'll actually be able to get the engine to a stage where it *can* load anything
|
||||
#include <stdint.h>
|
||||
#define qintptr_t intptr_t
|
||||
#define quintptr_t uintptr_t
|
||||
#else
|
||||
#if defined(_WIN64)
|
||||
#define qintptr_t __int64
|
||||
|
@ -25,11 +24,10 @@
|
|||
#define qintptr_t long
|
||||
#endif
|
||||
#endif
|
||||
#define quintptr_t unsigned qintptr_t
|
||||
#endif
|
||||
|
||||
typedef qintptr_t (EXPORT_FN *sys_calldll_t) (qintptr_t arg, ...);
|
||||
typedef int (*sys_callqvm_t) (void *offset, quintptr_t mask, int fn, const int *arg);
|
||||
typedef int (*sys_callqvm_t) (void *offset, unsigned qintptr_t mask, int fn, const int *arg);
|
||||
|
||||
typedef struct vm_s vm_t;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -76,8 +76,6 @@ model_t *currentmodel;
|
|||
char loadname[32];
|
||||
qbyte *mod_base;
|
||||
|
||||
qboolean DDActive;
|
||||
|
||||
model_t *lightmodel;
|
||||
int relitsurface;
|
||||
|
||||
|
@ -89,7 +87,7 @@ qboolean r_cache_thrash; // set if thrashing the surface cache
|
|||
|
||||
mpic_t *draw_disc; // also used on sbar
|
||||
|
||||
#if !defined(SWQUAKE) && !defined(RGLQUAKE)
|
||||
#if !defined(RGLQUAKE)
|
||||
qbyte GetPaletteIndex(int red, int green, int blue)
|
||||
{
|
||||
//slow, horrible method.
|
||||
|
@ -182,12 +180,6 @@ void D3D7_VID_GenPaletteTables (unsigned char *palette)
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(SWQUAKE) && !defined(GLQUAKE)
|
||||
void D_FlushCaches (void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -74,8 +74,6 @@ model_t *currentmodel;
|
|||
char loadname[32];
|
||||
qbyte *mod_base;
|
||||
|
||||
qboolean DDActive;
|
||||
|
||||
model_t *lightmodel;
|
||||
int relitsurface;
|
||||
|
||||
|
@ -83,13 +81,11 @@ int window_center_x, window_center_y;
|
|||
RECT window_rect;
|
||||
int window_x, window_y;
|
||||
|
||||
qboolean r_cache_thrash; // set if thrashing the surface cache
|
||||
|
||||
mpic_t *draw_disc; // also used on sbar
|
||||
|
||||
int d3d9width, d3d9height;
|
||||
#if 0
|
||||
#if !defined(SWQUAKE) && !defined(RGLQUAKE)
|
||||
#if !defined(RGLQUAKE)
|
||||
qbyte GetPaletteIndex(int red, int green, int blue)
|
||||
{
|
||||
//slow, horrible method.
|
||||
|
@ -189,13 +185,6 @@ void D3D9_VID_GenPaletteTables (unsigned char *palette)
|
|||
if (pD3DDev9)
|
||||
IDirect3DDevice9_SetGammaRamp(pD3DDev9, 0, D3DSGR_NO_CALIBRATION, (D3DGAMMARAMP *)ramps);
|
||||
}
|
||||
#if 0
|
||||
#if !defined(SWQUAKE) && !defined(GLQUAKE)
|
||||
void D_FlushCaches (void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
|
|
|
@ -43,13 +43,8 @@ extern cvar_t r_replacemodels;
|
|||
extern int gl_bumpmappingpossible;
|
||||
qboolean isnotmap = true; //used to not warp ammo models.
|
||||
|
||||
#ifndef SWQUAKE
|
||||
model_t *loadmodel;
|
||||
char loadname[32]; // for hunk tags
|
||||
#else
|
||||
extern model_t *loadmodel;
|
||||
extern char loadname[32]; // for hunk tags
|
||||
#endif
|
||||
|
||||
void CM_Init(void);
|
||||
|
||||
|
@ -72,14 +67,8 @@ void GLMod_LoadDoomSprite (model_t *mod);
|
|||
#endif
|
||||
|
||||
#define MAX_MOD_KNOWN 2048
|
||||
#ifndef SWQUAKE
|
||||
model_t mod_known[MAX_MOD_KNOWN];
|
||||
int mod_numknown;
|
||||
#else
|
||||
|
||||
extern model_t mod_known[MAX_MOD_KNOWN];
|
||||
extern int mod_numknown;
|
||||
#endif
|
||||
|
||||
extern cvar_t r_loadlits;
|
||||
#ifdef SPECULAR
|
||||
|
@ -731,11 +720,7 @@ model_t *GLMod_ForName (char *name, qboolean crash)
|
|||
===============================================================================
|
||||
*/
|
||||
|
||||
#ifdef SWQUAKE
|
||||
extern qbyte *mod_base;
|
||||
#else
|
||||
qbyte *mod_base;
|
||||
#endif
|
||||
|
||||
char *advtexturedesc;
|
||||
char *mapsection;
|
||||
|
|
|
@ -310,9 +310,6 @@ typedef struct msurface_s
|
|||
int firstedge; // look up in model->surfedges[], negative numbers
|
||||
int numedges; // are backwards edges
|
||||
|
||||
#ifdef SWQUAKE
|
||||
struct surfcache_s *cachespots[MIPLEVELS];
|
||||
#endif
|
||||
struct msurface_s *nextalphasurface;
|
||||
|
||||
short texturemins[2];
|
||||
|
@ -464,14 +461,6 @@ SPRITE MODELS
|
|||
typedef struct mspriteframe_s
|
||||
{
|
||||
float up, down, left, right;
|
||||
/*
|
||||
int width;
|
||||
int height;
|
||||
int gl_texturenum;
|
||||
#ifdef SWQUAKE
|
||||
qbyte pixels[4];
|
||||
#endif
|
||||
*/
|
||||
mpic_t p;
|
||||
} mspriteframe_t;
|
||||
|
||||
|
@ -518,9 +507,6 @@ typedef struct {
|
|||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef SWQUAKE
|
||||
aliasframetype_t type;
|
||||
#endif
|
||||
int firstpose;
|
||||
int numposes;
|
||||
float interval;
|
||||
|
@ -574,11 +560,6 @@ typedef struct {
|
|||
synctype_t synctype;
|
||||
int flags;
|
||||
float size;
|
||||
#ifdef SWQUAKE
|
||||
int model;
|
||||
int stverts;
|
||||
int skindesc;
|
||||
#endif
|
||||
int numposes;
|
||||
int poseverts;
|
||||
int posedata; // numposes*poseverts trivert_t
|
||||
|
|
|
@ -46,8 +46,6 @@ FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
|
|||
|
||||
entity_t r_worldentity;
|
||||
|
||||
qboolean r_cache_thrash; // compatability
|
||||
|
||||
vec3_t modelorg, r_entorigin;
|
||||
entity_t *currententity;
|
||||
|
||||
|
@ -978,8 +976,6 @@ void GLR_SetupFrame (void)
|
|||
}
|
||||
GLV_CalcBlend ();
|
||||
|
||||
r_cache_thrash = false;
|
||||
|
||||
c_brush_polys = 0;
|
||||
c_alias_polys = 0;
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ cvar_t r_waterlayers = SCVAR("r_waterlayers","");
|
|||
|
||||
extern void R_InitBubble();
|
||||
|
||||
#ifndef SWQUAKE
|
||||
//SW rendering has a faster method, which takes more memory and stuff.
|
||||
//We need this for minor things though, so we'5ll just use the slow accurate method.
|
||||
//this is unlikly to be called very often.
|
||||
|
@ -63,7 +62,6 @@ qbyte GetPaletteIndex(int red, int green, int blue)
|
|||
return best;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
|
@ -1246,10 +1244,4 @@ void GLR_TimeRefresh_f (void)
|
|||
GL_DoSwap();
|
||||
}
|
||||
|
||||
#ifndef SWQUAKE
|
||||
void D_FlushCaches (void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -104,7 +104,6 @@ BOOL bSetupPixelFormat(HDC hDC);
|
|||
qboolean VID_SetWindowedMode (rendererstate_t *info); //-1 on bpp or hz for default.
|
||||
qboolean VID_SetFullDIBMode (rendererstate_t *info); //-1 on bpp or hz for default.
|
||||
|
||||
qboolean DDActive;
|
||||
qboolean scr_skipupdate;
|
||||
|
||||
static DEVMODE gdevmode;
|
||||
|
@ -118,10 +117,7 @@ extern qboolean vid_isfullscreen;
|
|||
|
||||
unsigned short originalgammaramps[3][256];
|
||||
|
||||
#ifdef SWQUAKE
|
||||
extern
|
||||
#endif
|
||||
qboolean vid_initializing;
|
||||
qboolean vid_initializing;
|
||||
|
||||
qboolean VID_AttachGL (rendererstate_t *info);
|
||||
|
||||
|
|
|
@ -201,7 +201,6 @@ texture_t *R_TextureAnimation (texture_t *base);
|
|||
|
||||
|
||||
extern entity_t r_worldentity;
|
||||
extern qboolean r_cache_thrash; // compatability
|
||||
extern vec3_t modelorg, r_entorigin;
|
||||
extern entity_t *currententity;
|
||||
extern int r_visframecount; // ??? what difs?
|
||||
|
@ -873,75 +872,6 @@ void GL_Init(void *(*getglfunction) (char *name));
|
|||
qbyte GetPaletteIndex(int red, int green, int blue);
|
||||
int Mod_ReadFlagsFromMD1(char *name, int md3version);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SWQUAKE
|
||||
|
||||
|
||||
#define CYCLE 128 // turbulent cycle size
|
||||
extern int r_pixbytes;
|
||||
|
||||
#define WARP_WIDTH 320
|
||||
#define WARP_HEIGHT 200
|
||||
|
||||
extern cvar_t d_palconvwrite;
|
||||
extern cvar_t d_palremapsize;
|
||||
|
||||
extern cvar_t r_drawflat;
|
||||
extern int d_spanpixcount;
|
||||
extern int r_framecount; // sequence # of current frame since Quake
|
||||
// started
|
||||
extern qboolean r_drawpolys; // 1 if driver wants clipped polygons
|
||||
// rather than a span list
|
||||
extern qboolean r_drawculledpolys; // 1 if driver wants clipped polygons that
|
||||
// have been culled by the edge list
|
||||
extern qboolean r_worldpolysbacktofront; // 1 if driver wants polygons
|
||||
// delivered back to front rather
|
||||
// than front to back
|
||||
extern qboolean r_recursiveaffinetriangles; // true if a driver wants to use
|
||||
// recursive triangular subdivison
|
||||
// and vertex drawing via
|
||||
// D_PolysetDrawFinalVerts() past
|
||||
// a certain distance (normally
|
||||
// only used by the software
|
||||
// driver)
|
||||
extern float r_aliasuvscale; // scale-up factor for screen u and v
|
||||
// on Alias vertices passed to driver
|
||||
extern int r_pixbytes;
|
||||
extern qboolean r_dowarp;
|
||||
|
||||
/*extern affinetridesc_t r_affinetridesc;
|
||||
extern spritedesc_t r_spritedesc;
|
||||
extern zpointdesc_t r_zpointdesc;
|
||||
extern polydesc_t r_polydesc;
|
||||
*/
|
||||
extern int d_con_indirect; // if 0, Quake will draw console directly
|
||||
// to vid.buffer; if 1, Quake will
|
||||
// draw console via D_DrawRect. Must be
|
||||
// defined by driver
|
||||
|
||||
extern vec3_t r_pright, r_pup, r_ppn;
|
||||
|
||||
|
||||
|
||||
|
||||
extern float xscaleshrink, yscaleshrink;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
//opengl 3 deprecation
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#if defined(D3DQUAKE) || defined(RGLQUAKE) || (!defined(RGLQUAKE) && !defined(SWQUAKE))
|
||||
|
||||
#ifdef RUNTIMELIGHTING
|
||||
#if defined(RGLQUAKE) || defined(D3DQUAKE)
|
||||
|
||||
|
@ -947,5 +945,3 @@ void LightFace (int surfnum)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -518,7 +518,7 @@ void PF_precache_model_Internal (progfuncs_t *prinst, char *s);
|
|||
void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m);
|
||||
char *PF_infokey_Internal (int entnum, char *value);;
|
||||
|
||||
static int WrapQCBuiltin(builtin_t func, void *offset, quintptr_t mask, const qintptr_t *arg, char *argtypes)
|
||||
static int WrapQCBuiltin(builtin_t func, void *offset, unsigned qintptr_t mask, const qintptr_t *arg, char *argtypes)
|
||||
{
|
||||
globalvars_t gv;
|
||||
int argnum=0;
|
||||
|
@ -554,7 +554,7 @@ static int WrapQCBuiltin(builtin_t func, void *offset, quintptr_t mask, const qi
|
|||
}
|
||||
|
||||
#define VALIDATEPOINTER(o,l) if ((qintptr_t)o + l >= mask || VM_POINTER(o) < offset) SV_Error("Call to game trap %i passes invalid pointer\n", fn); //out of bounds.
|
||||
static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, const qintptr_t *arg)
|
||||
static qintptr_t syscallhandle (void *offset, unsigned qintptr_t mask, qintptr_t fn, const qintptr_t *arg)
|
||||
{
|
||||
switch (fn)
|
||||
{
|
||||
|
@ -1259,7 +1259,7 @@ Con_DPrintf("PF_readcmd: %s\n%s", s, output);
|
|||
}
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
static int syscallqvm (void *offset, quintptr_t mask, int fn, const int *arg)
|
||||
static int syscallqvm (void *offset, unsigned qintptr_t mask, int fn, const int *arg)
|
||||
{
|
||||
qintptr_t args[13];
|
||||
int i;
|
||||
|
|
|
@ -663,7 +663,6 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
|
||||
VoteFlushAll();
|
||||
#ifndef SERVERONLY
|
||||
D_FlushCaches();
|
||||
cl.worldmodel = NULL;
|
||||
r_worldentity.model = NULL;
|
||||
if (0)
|
||||
|
|
1074
engine/sw/adivtab.h
1074
engine/sw/adivtab.h
File diff suppressed because it is too large
Load diff
|
@ -1,153 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// asm_draw.h
|
||||
//
|
||||
// Include file for asm drawing routines.
|
||||
//
|
||||
|
||||
//
|
||||
// !!! note that this file must match the corresponding C structures at all
|
||||
// times !!!
|
||||
//
|
||||
|
||||
// !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
#define NEAR_CLIP 0.01
|
||||
|
||||
// !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
#define CYCLE 128
|
||||
|
||||
// espan_t structure
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define espan_t_u 0
|
||||
#define espan_t_v 4
|
||||
#define espan_t_count 8
|
||||
#define espan_t_pnext 12
|
||||
#define espan_t_size 16
|
||||
|
||||
// sspan_t structure
|
||||
// !!! if this is changed, it must be changed in d_local.h too !!!
|
||||
#define sspan_t_u 0
|
||||
#define sspan_t_v 4
|
||||
#define sspan_t_count 8
|
||||
#define sspan_t_size 12
|
||||
|
||||
// spanpackage_t structure
|
||||
// !!! if this is changed, it must be changed in d_polyset.c too !!!
|
||||
#define spanpackage_t_pdest 0
|
||||
#define spanpackage_t_pz 4
|
||||
#define spanpackage_t_count 8
|
||||
#define spanpackage_t_ptex 12
|
||||
#define spanpackage_t_sfrac 16
|
||||
#define spanpackage_t_tfrac 20
|
||||
#define spanpackage_t_light 24
|
||||
#define spanpackage_t_zi 28
|
||||
#define spanpackage_t_size 32
|
||||
|
||||
// edge_t structure
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define et_u 0
|
||||
#define et_u_step 4
|
||||
#define et_prev 8
|
||||
#define et_next 12
|
||||
#define et_surfs 16
|
||||
#define et_nextremove 20
|
||||
#define et_nearzi 24
|
||||
#define et_owner 28
|
||||
#define et_size 32
|
||||
|
||||
// surf_t structure
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define SURF_T_SHIFT 6
|
||||
#define st_next 0
|
||||
#define st_prev 4
|
||||
#define st_spans 8
|
||||
#define st_key 12
|
||||
#define st_last_u 16
|
||||
#define st_spanstate 20
|
||||
#define st_flags 24
|
||||
#define st_data 28
|
||||
#define st_entity 32
|
||||
#define st_nearzi 36
|
||||
#define st_insubmodel 40
|
||||
#define st_d_ziorigin 44
|
||||
#define st_d_zistepu 48
|
||||
#define st_d_zistepv 52
|
||||
#define st_pad 56
|
||||
#define st_size 64
|
||||
|
||||
// clipplane_t structure
|
||||
// !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
#define cp_normal 0
|
||||
#define cp_dist 12
|
||||
#define cp_next 16
|
||||
#define cp_leftedge 20
|
||||
#define cp_rightedge 21
|
||||
#define cp_reserved 22
|
||||
#define cp_size 24
|
||||
|
||||
// medge_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
#define me_v 0
|
||||
#define me_cachededgeoffset 4
|
||||
|
||||
// mvertex_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
#define mv_position 0
|
||||
#define mv_size 12
|
||||
|
||||
// refdef_t structure
|
||||
// !!! if this is changed, it must be changed in render.h too !!!
|
||||
#define rd_vrect 0
|
||||
#define rd_aliasvrect 20
|
||||
#define rd_vrectright 40
|
||||
#define rd_vrectbottom 44
|
||||
#define rd_aliasvrectright 48
|
||||
#define rd_aliasvrectbottom 52
|
||||
#define rd_vrectrightedge 56
|
||||
#define rd_fvrectx 60
|
||||
#define rd_fvrecty 64
|
||||
#define rd_fvrectx_adj 68
|
||||
#define rd_fvrecty_adj 72
|
||||
#define rd_vrect_x_adj_shift20 76
|
||||
#define rd_vrectright_adj_shift20 80
|
||||
#define rd_fvrectright_adj 84
|
||||
#define rd_fvrectbottom_adj 88
|
||||
#define rd_fvrectright 92
|
||||
#define rd_fvrectbottom 96
|
||||
#define rd_horizontalFieldOfView 100
|
||||
#define rd_xOrigin 104
|
||||
#define rd_yOrigin 108
|
||||
#define rd_vieworg 112
|
||||
#define rd_viewangles 124
|
||||
//fox x, fov y
|
||||
#define rd_ambientlight 144
|
||||
#define rd_flags 148
|
||||
#define rd_currentplayernum 152
|
||||
#define rd_size 156
|
||||
|
||||
// mtriangle_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
#define mtri_vertindex 0
|
||||
#define mtri_stindex 12
|
||||
#define mtri_size 32 // !!! if this changes, array indexing in !!!
|
||||
// !!! d_polysa.s must be changed to match !!!
|
||||
#define mtri_shift 5
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
LEnter16_16:
|
||||
movb (%esi),%al
|
||||
movb (%esi,%ebx,),%cl
|
||||
movb %dh,%ah
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
leal (%esi,%ebx,2),%esi
|
||||
movw 0x12345678(,%eax,2),%ax
|
||||
LBPatch0:
|
||||
addl %ebp,%edx
|
||||
movw %ax,(%edi)
|
||||
movw 0x12345678(,%ecx,2),%cx
|
||||
LBPatch1:
|
||||
movw %cx,2(%edi)
|
||||
addl $0x4,%edi
|
||||
|
||||
movb (%esi),%al
|
||||
movb (%esi,%ebx,),%cl
|
||||
movb %dh,%ah
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
leal (%esi,%ebx,2),%esi
|
||||
movw 0x12345678(,%eax,2),%ax
|
||||
LBPatch2:
|
||||
addl %ebp,%edx
|
||||
movw %ax,(%edi)
|
||||
movw 0x12345678(,%ecx,2),%cx
|
||||
LBPatch3:
|
||||
movw %cx,2(%edi)
|
||||
addl $0x4,%edi
|
||||
|
||||
movb (%esi),%al
|
||||
movb (%esi,%ebx,),%cl
|
||||
movb %dh,%ah
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
leal (%esi,%ebx,2),%esi
|
||||
movw 0x12345678(,%eax,2),%ax
|
||||
LBPatch4:
|
||||
addl %ebp,%edx
|
||||
movw %ax,(%edi)
|
||||
movw 0x12345678(,%ecx,2),%cx
|
||||
LBPatch5:
|
||||
movw %cx,2(%edi)
|
||||
addl $0x4,%edi
|
||||
|
||||
movb (%esi),%al
|
||||
movb (%esi,%ebx,),%cl
|
||||
movb %dh,%ah
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
leal (%esi,%ebx,2),%esi
|
||||
movw 0x12345678(,%eax,2),%ax
|
||||
LBPatch6:
|
||||
addl %ebp,%edx
|
||||
movw %ax,(%edi)
|
||||
movw 0x12345678(,%ecx,2),%cx
|
||||
LBPatch7:
|
||||
movw %cx,2(%edi)
|
||||
addl $0x4,%edi
|
||||
|
||||
LEnter8_16:
|
||||
movb (%esi),%al
|
||||
movb (%esi,%ebx,),%cl
|
||||
movb %dh,%ah
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
leal (%esi,%ebx,2),%esi
|
||||
movw 0x12345678(,%eax,2),%ax
|
||||
LBPatch8:
|
||||
addl %ebp,%edx
|
||||
movw %ax,(%edi)
|
||||
movw 0x12345678(,%ecx,2),%cx
|
||||
LBPatch9:
|
||||
movw %cx,2(%edi)
|
||||
addl $0x4,%edi
|
||||
|
||||
movb (%esi),%al
|
||||
movb (%esi,%ebx,),%cl
|
||||
movb %dh,%ah
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
leal (%esi,%ebx,2),%esi
|
||||
movw 0x12345678(,%eax,2),%ax
|
||||
LBPatch10:
|
||||
addl %ebp,%edx
|
||||
movw %ax,(%edi)
|
||||
movw 0x12345678(,%ecx,2),%cx
|
||||
LBPatch11:
|
||||
movw %cx,2(%edi)
|
||||
addl $0x4,%edi
|
||||
|
||||
LEnter4_16:
|
||||
movb (%esi),%al
|
||||
movb (%esi,%ebx,),%cl
|
||||
movb %dh,%ah
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
leal (%esi,%ebx,2),%esi
|
||||
movw 0x12345678(,%eax,2),%ax
|
||||
LBPatch12:
|
||||
addl %ebp,%edx
|
||||
movw %ax,(%edi)
|
||||
movw 0x12345678(,%ecx,2),%cx
|
||||
LBPatch13:
|
||||
movw %cx,2(%edi)
|
||||
addl $0x4,%edi
|
||||
|
||||
LEnter2_16:
|
||||
movb (%esi),%al
|
||||
movb (%esi,%ebx,),%cl
|
||||
movb %dh,%ah
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
leal (%esi,%ebx,2),%esi
|
||||
movw 0x12345678(,%eax,2),%ax
|
||||
LBPatch14:
|
||||
addl %ebp,%edx
|
||||
movw %ax,(%edi)
|
||||
movw 0x12345678(,%ecx,2),%cx
|
||||
LBPatch15:
|
||||
movw %cx,2(%edi)
|
||||
addl $0x4,%edi
|
1037
engine/sw/d_draw.s
1037
engine/sw/d_draw.s
File diff suppressed because it is too large
Load diff
|
@ -1,974 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_draw16.s
|
||||
// x86 assembly-language horizontal 16-bpp span-drawing code, with 16-pixel
|
||||
// subdivision.
|
||||
//
|
||||
#define SWQUAKE
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp horizontal span drawing code for polygons, with no transparency and
|
||||
// 16-pixel subdivision.
|
||||
//
|
||||
// Assumes there is at least one span in pspans, and that every span
|
||||
// contains at least one pixel
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.data
|
||||
|
||||
.text
|
||||
|
||||
// out-of-line, rarely-needed clamping code
|
||||
|
||||
LClampHigh0:
|
||||
movl C(bbextents),%esi
|
||||
jmp LClampReentry0
|
||||
LClampHighOrLow0:
|
||||
jg LClampHigh0
|
||||
xorl %esi,%esi
|
||||
jmp LClampReentry0
|
||||
|
||||
LClampHigh1:
|
||||
movl C(bbextentt),%edx
|
||||
jmp LClampReentry1
|
||||
LClampHighOrLow1:
|
||||
jg LClampHigh1
|
||||
xorl %edx,%edx
|
||||
jmp LClampReentry1
|
||||
|
||||
LClampLow2:
|
||||
movl $4096,%ebp
|
||||
jmp LClampReentry2
|
||||
LClampHigh2:
|
||||
movl C(bbextents),%ebp
|
||||
jmp LClampReentry2
|
||||
|
||||
LClampLow3:
|
||||
movl $4096,%ecx
|
||||
jmp LClampReentry3
|
||||
LClampHigh3:
|
||||
movl C(bbextentt),%ecx
|
||||
jmp LClampReentry3
|
||||
|
||||
LClampLow4:
|
||||
movl $4096,%eax
|
||||
jmp LClampReentry4
|
||||
LClampHigh4:
|
||||
movl C(bbextents),%eax
|
||||
jmp LClampReentry4
|
||||
|
||||
LClampLow5:
|
||||
movl $4096,%ebx
|
||||
jmp LClampReentry5
|
||||
LClampHigh5:
|
||||
movl C(bbextentt),%ebx
|
||||
jmp LClampReentry5
|
||||
|
||||
|
||||
#define pspans 4+16
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawSpans8SubDiv16)
|
||||
C(D_DrawSpans8SubDiv16):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
//
|
||||
// set up scaled-by-16 steps, for 16-long segments; also set up cacheblock
|
||||
// and span list pointers
|
||||
//
|
||||
// TODO: any overlap from rearranging?
|
||||
flds C(d_sdivzstepu)
|
||||
fmuls fp_16
|
||||
movl C(cacheblock),%edx
|
||||
flds C(d_tdivzstepu)
|
||||
fmuls fp_16
|
||||
movl pspans(%esp),%ebx // point to the first span descriptor
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_16
|
||||
movl %edx,pbase // pbase = cacheblock
|
||||
fstps zi16stepu
|
||||
fstps tdivz16stepu
|
||||
fstps sdivz16stepu
|
||||
|
||||
LSpanLoop:
|
||||
//
|
||||
// set up the initial s/z, t/z, and 1/z on the FP stack, and generate the
|
||||
// initial s and t values
|
||||
//
|
||||
// FIXME: pipeline FILD?
|
||||
fildl espan_t_v(%ebx)
|
||||
fildl espan_t_u(%ebx)
|
||||
|
||||
fld %st(1) // dv | du | dv
|
||||
fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv
|
||||
fld %st(1) // du | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
faddp %st(0),%st(2) // du*d_tdivzstepu |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fmuls C(d_tdivzstepv) // dv*d_tdivzstepv |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// dv*d_tdivzstepv | du*d_tdivzstepu | du | dv
|
||||
fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv +
|
||||
// du*d_sdivzstepu; stays in %st(2) at end
|
||||
fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du |
|
||||
// s/z
|
||||
fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
faddp %st(0),%st(2) // dv*d_zistepv |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z
|
||||
fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fmuls C(d_zistepu) // du*d_zistepu |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// du*d_zistepu | dv*d_zistepv | s/z
|
||||
fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv +
|
||||
// du*d_tdivzstepu; stays in %st(1) at end
|
||||
fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z
|
||||
faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
|
||||
flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z
|
||||
fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv +
|
||||
// du*d_zistepu; stays in %st(0) at end
|
||||
// 1/z | fp_64k | t/z | s/z
|
||||
//
|
||||
// calculate and clamp s & t
|
||||
//
|
||||
fdivr %st(0),%st(1) // 1/z | z*64k | t/z | s/z
|
||||
|
||||
//
|
||||
// point %edi to the first pixel in the span
|
||||
//
|
||||
movl C(d_viewbuffer),%ecx
|
||||
movl espan_t_v(%ebx),%eax
|
||||
movl %ebx,pspantemp // preserve spans pointer
|
||||
|
||||
movl C(tadjust),%edx
|
||||
movl C(sadjust),%esi
|
||||
movl C(d_scantable)(,%eax,4),%edi // v * screenwidth
|
||||
addl %ecx,%edi
|
||||
movl espan_t_u(%ebx),%ecx
|
||||
addl %ecx,%edi // pdest = &pdestspan[scans->u];
|
||||
movl espan_t_count(%ebx),%ecx
|
||||
|
||||
//
|
||||
// now start the FDIV for the end of the span
|
||||
//
|
||||
cmpl $16,%ecx
|
||||
ja LSetupNotLast1
|
||||
|
||||
decl %ecx
|
||||
jz LCleanup1 // if only one pixel, no need to start an FDIV
|
||||
movl %ecx,spancountminus1
|
||||
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_tdivzstepu) // C(d_tdivzstepu) | spancountminus1
|
||||
flds C(d_zistepu) // C(d_zistepu) | C(d_tdivzstepu) | spancountminus1
|
||||
fmul %st(2),%st(0) // C(d_zistepu)*scm1 | C(d_tdivzstepu) | scm1
|
||||
fxch %st(1) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1
|
||||
fmul %st(2),%st(0) // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1
|
||||
fxch %st(2) // scm1 | C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1
|
||||
fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_zistepu)*scm1 |
|
||||
// C(d_tdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_zistepu)*scm1 | C(d_sdivzstepu)*scm1 |
|
||||
// C(d_tdivzstepu)*scm1
|
||||
faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1
|
||||
faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1
|
||||
faddp %st(0),%st(3)
|
||||
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
LCleanup1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
.align 4
|
||||
LSetupNotLast1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fadds zi16stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz16stepu
|
||||
fxch %st(2)
|
||||
flds tdivz16stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight1:
|
||||
|
||||
addl s,%esi
|
||||
addl t,%edx
|
||||
movl C(bbextents),%ebx
|
||||
movl C(bbextentt),%ebp
|
||||
cmpl %ebx,%esi
|
||||
ja LClampHighOrLow0
|
||||
LClampReentry0:
|
||||
movl %esi,s
|
||||
movl pbase,%ebx
|
||||
shll $16,%esi
|
||||
cmpl %ebp,%edx
|
||||
movl %esi,sfracf
|
||||
ja LClampHighOrLow1
|
||||
LClampReentry1:
|
||||
movl %edx,t
|
||||
movl s,%esi // sfrac = scans->sfrac;
|
||||
shll $16,%edx
|
||||
movl t,%eax // tfrac = scans->tfrac;
|
||||
sarl $16,%esi
|
||||
movl %edx,tfracf
|
||||
|
||||
//
|
||||
// calculate the texture starting address
|
||||
//
|
||||
sarl $16,%eax
|
||||
movl C(cachewidth),%edx
|
||||
imull %edx,%eax // (tfrac >> 16) * cachewidth
|
||||
addl %ebx,%esi
|
||||
addl %eax,%esi // psource = pbase + (sfrac >> 16) +
|
||||
// ((tfrac >> 16) * cachewidth);
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $16,%ecx
|
||||
jna LLastSegment
|
||||
|
||||
//
|
||||
// not the last segment; do full 16-wide segment
|
||||
//
|
||||
LNotLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there
|
||||
//
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
movl snext,%eax
|
||||
movl tnext,%edx
|
||||
|
||||
movb (%esi),%bl // get first source texel
|
||||
subl $16,%ecx // count off this segments' pixels
|
||||
movl C(sadjust),%ebp
|
||||
movl %ecx,counttemp // remember count of remaining pixels
|
||||
|
||||
movl C(tadjust),%ecx
|
||||
movb %bl,(%edi) // store first dest pixel
|
||||
|
||||
addl %eax,%ebp
|
||||
addl %edx,%ecx
|
||||
|
||||
movl C(bbextents),%eax
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $4096,%ebp
|
||||
jl LClampLow2
|
||||
cmpl %eax,%ebp
|
||||
ja LClampHigh2
|
||||
LClampReentry2:
|
||||
|
||||
cmpl $4096,%ecx
|
||||
jl LClampLow3
|
||||
cmpl %edx,%ecx
|
||||
ja LClampHigh3
|
||||
LClampReentry3:
|
||||
|
||||
movl %ebp,snext
|
||||
movl %ecx,tnext
|
||||
|
||||
subl s,%ebp
|
||||
subl t,%ecx
|
||||
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl %ecx,%eax
|
||||
movl %ebp,%edx
|
||||
sarl $20,%eax // tstep >>= 16;
|
||||
jz LZero
|
||||
sarl $20,%edx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
imull %ebx,%eax
|
||||
jmp LSetUp1
|
||||
|
||||
LZero:
|
||||
sarl $20,%edx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
|
||||
LSetUp1:
|
||||
|
||||
addl %edx,%eax // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%edx
|
||||
movl %eax,advancetable+4 // advance base in t
|
||||
addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $12,%ebp // left-justify sstep fractional part
|
||||
movl sfracf,%ebx
|
||||
shll $12,%ecx // left-justify tstep fractional part
|
||||
movl %eax,advancetable // advance extra in t
|
||||
|
||||
movl %ecx,tstep
|
||||
addl %ecx,%edx // advance tfrac fractional part by tstep frac
|
||||
|
||||
sbbl %ecx,%ecx // turn tstep carry into -1 (0 if none)
|
||||
addl %ebp,%ebx // advance sfrac fractional part by sstep frac
|
||||
adcl advancetable+4(,%ecx,4),%esi // point to next source texel
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb (%esi),%al
|
||||
addl %ebp,%ebx
|
||||
movb %al,1(%edi)
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,2(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,3(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,4(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,5(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,6(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,7(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
|
||||
//
|
||||
// start FDIV for end of next segment in flight, so it can overlap
|
||||
//
|
||||
movl counttemp,%ecx
|
||||
cmpl $16,%ecx // more than one segment after this?
|
||||
ja LSetupNotLast2 // yes
|
||||
|
||||
decl %ecx
|
||||
jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV
|
||||
movl %ecx,spancountminus1
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_zistepu) // C(d_zistepu) | spancountminus1
|
||||
fmul %st(1),%st(0) // C(d_zistepu)*scm1 | scm1
|
||||
flds C(d_tdivzstepu) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1
|
||||
fmul %st(2),%st(0) // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1
|
||||
fxch %st(1) // C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1 | scm1
|
||||
faddp %st(0),%st(3) // C(d_tdivzstepu)*scm1 | scm1
|
||||
fxch %st(1) // scm1 | C(d_tdivzstepu)*scm1
|
||||
fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1
|
||||
faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1
|
||||
flds fp_64k // 64k | C(d_sdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_sdivzstepu)*scm1 | 64k
|
||||
faddp %st(0),%st(4) // 64k
|
||||
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight2
|
||||
|
||||
.align 4
|
||||
LSetupNotLast2:
|
||||
fadds zi16stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz16stepu
|
||||
fxch %st(2)
|
||||
flds tdivz16stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight2:
|
||||
movl %ecx,counttemp
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,8(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,9(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,10(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,11(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,12(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,13(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,14(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl $16,%edi
|
||||
movl %edx,tfracf
|
||||
movl snext,%edx
|
||||
movl %ebx,sfracf
|
||||
movl tnext,%ebx
|
||||
movl %edx,s
|
||||
movl %ebx,t
|
||||
|
||||
movl counttemp,%ecx // retrieve count
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $16,%ecx // are there multiple segments remaining?
|
||||
movb %al,-1(%edi)
|
||||
ja LNotLastSegment // yes
|
||||
|
||||
//
|
||||
// last segment of scan
|
||||
//
|
||||
LLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there. The number of pixels left is variable, and we want to land on the
|
||||
// last pixel, not step one past it, so we can't run into arithmetic problems
|
||||
//
|
||||
testl %ecx,%ecx
|
||||
jz LNoSteps // just draw the last pixel and we're done
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
|
||||
movb (%esi),%al // load first texel in segment
|
||||
movl C(tadjust),%ebx
|
||||
movb %al,(%edi) // store first pixel in segment
|
||||
movl C(sadjust),%eax
|
||||
|
||||
addl snext,%eax
|
||||
addl tnext,%ebx
|
||||
|
||||
movl C(bbextents),%ebp
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $4096,%eax
|
||||
jl LClampLow4
|
||||
cmpl %ebp,%eax
|
||||
ja LClampHigh4
|
||||
LClampReentry4:
|
||||
movl %eax,snext
|
||||
|
||||
cmpl $4096,%ebx
|
||||
jl LClampLow5
|
||||
cmpl %edx,%ebx
|
||||
ja LClampHigh5
|
||||
LClampReentry5:
|
||||
|
||||
cmpl $1,%ecx // don't bother
|
||||
je LOnlyOneStep // if two pixels in segment, there's only one step,
|
||||
// of the segment length
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
|
||||
addl %eax,%eax // convert to 15.17 format so multiply by 1.31
|
||||
addl %ebx,%ebx // reciprocal yields 16.48
|
||||
|
||||
imull reciprocal_table_16-8(,%ecx,4) // sstep = (snext - s) /
|
||||
// (spancount-1)
|
||||
movl %edx,%ebp
|
||||
|
||||
movl %ebx,%eax
|
||||
imull reciprocal_table_16-8(,%ecx,4) // tstep = (tnext - t) /
|
||||
// (spancount-1)
|
||||
LSetEntryvec:
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl entryvec_table_16(,%ecx,4),%ebx
|
||||
movl %edx,%eax
|
||||
movl %ebx,jumptemp // entry point into code for RET later
|
||||
movl %ebp,%ecx
|
||||
sarl $16,%edx // tstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $16,%ecx // sstep >>= 16;
|
||||
imull %ebx,%edx
|
||||
|
||||
addl %ecx,%edx // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%ecx
|
||||
movl %edx,advancetable+4 // advance base in t
|
||||
addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $16,%ebp // left-justify sstep fractional part
|
||||
movl sfracf,%ebx
|
||||
shll $16,%eax // left-justify tstep fractional part
|
||||
movl %edx,advancetable // advance extra in t
|
||||
|
||||
movl %eax,tstep
|
||||
movl %ecx,%edx
|
||||
addl %eax,%edx
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
jmp *jumptemp // jump to the number-of-pixels handler
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
LNoSteps:
|
||||
movb (%esi),%al // load first texel in segment
|
||||
subl $15,%edi // adjust for hardwired offset
|
||||
jmp LEndSpan
|
||||
|
||||
|
||||
LOnlyOneStep:
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
movl %eax,%ebp
|
||||
movl %ebx,%edx
|
||||
jmp LSetEntryvec
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Entry2_16, Entry3_16, Entry4_16, Entry5_16
|
||||
.globl Entry6_16, Entry7_16, Entry8_16, Entry9_16
|
||||
.globl Entry10_16, Entry11_16, Entry12_16, Entry13_16
|
||||
.globl Entry14_16, Entry15_16, Entry16_16
|
||||
|
||||
Entry2_16:
|
||||
subl $14,%edi // adjust for hardwired offsets
|
||||
movb (%esi),%al
|
||||
jmp LEntry2_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry3_16:
|
||||
subl $13,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
jmp LEntry3_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry4_16:
|
||||
subl $12,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry4_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry5_16:
|
||||
subl $11,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry5_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry6_16:
|
||||
subl $10,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry6_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry7_16:
|
||||
subl $9,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry7_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry8_16:
|
||||
subl $8,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry8_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry9_16:
|
||||
subl $7,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry9_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry10_16:
|
||||
subl $6,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry10_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry11_16:
|
||||
subl $5,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry11_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry12_16:
|
||||
subl $4,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry12_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry13_16:
|
||||
subl $3,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry13_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry14_16:
|
||||
subl $2,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry14_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry15_16:
|
||||
decl %edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry15_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry16_16:
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,1(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry15_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,2(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry14_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,3(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry13_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,4(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry12_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,5(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry11_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,6(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry10_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,7(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry9_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,8(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry8_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,9(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry7_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,10(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry6_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,11(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry5_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,12(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry4_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,13(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
LEntry3_16:
|
||||
movb %al,14(%edi)
|
||||
movb (%esi),%al
|
||||
LEntry2_16:
|
||||
|
||||
LEndSpan:
|
||||
|
||||
//
|
||||
// clear s/z, t/z, 1/z from FP stack
|
||||
//
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
|
||||
movl pspantemp,%ebx // restore spans pointer
|
||||
movl espan_t_pnext(%ebx),%ebx // point to next span
|
||||
testl %ebx,%ebx // any more spans?
|
||||
movb %al,15(%edi)
|
||||
jnz LSpanLoop // more spans
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
#endif // id386
|
|
@ -1,455 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// d_edge.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
|
||||
static int miplevel;
|
||||
|
||||
float scale_for_mip;
|
||||
int screenwidth;
|
||||
int ubasestep, errorterm, erroradjustup, erroradjustdown;
|
||||
int vstartscan;
|
||||
int r_wallindex, r_floorindex, r_skycolorindex;
|
||||
|
||||
// FIXME: should go away
|
||||
extern void R_RotateBmodel (void);
|
||||
extern void R_TransformFrustum (void);
|
||||
|
||||
vec3_t transformed_modelorg;
|
||||
|
||||
/*
|
||||
==============
|
||||
D_DrawPoly
|
||||
|
||||
==============
|
||||
*/
|
||||
void D_DrawPoly (void)
|
||||
{
|
||||
// this driver takes spans, not polygons
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
D_MipLevelForScale
|
||||
=============
|
||||
*/
|
||||
int D_MipLevelForScale (float scale)
|
||||
{
|
||||
int lmiplevel;
|
||||
|
||||
if (scale >= d_scalemip[0] )
|
||||
lmiplevel = 0;
|
||||
else if (scale >= d_scalemip[1] )
|
||||
lmiplevel = 1;
|
||||
else if (scale >= d_scalemip[2] )
|
||||
lmiplevel = 2;
|
||||
else
|
||||
lmiplevel = 3;
|
||||
|
||||
if (lmiplevel < d_minmip)
|
||||
lmiplevel = d_minmip;
|
||||
|
||||
return lmiplevel;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
D_DrawSolidSurface
|
||||
==============
|
||||
*/
|
||||
|
||||
// FIXME: clean this up
|
||||
void D_DrawSolidSurface (surf_t *surf, int color)
|
||||
{
|
||||
espan_t *span;
|
||||
qbyte *pdest;
|
||||
int u, u2, pix;
|
||||
|
||||
if (r_pixbytes == 4)
|
||||
{
|
||||
unsigned int *p32dest;
|
||||
pix = d_8to32table[color];
|
||||
for (span=surf->spans ; span ; span=span->pnext)
|
||||
{
|
||||
p32dest = (unsigned int *)d_viewbuffer + screenwidth*span->v;
|
||||
u = span->u;
|
||||
u2 = span->u + span->count - 1;
|
||||
p32dest[u] = pix;
|
||||
|
||||
for ( ; u <= u2 ; u++)
|
||||
p32dest[u] = pix;
|
||||
}
|
||||
}
|
||||
else if (r_pixbytes == 2)
|
||||
{
|
||||
unsigned short *p16dest;
|
||||
pix = vid.colormap16[color];
|
||||
for (span=surf->spans ; span ; span=span->pnext)
|
||||
{
|
||||
p16dest = (unsigned short *)d_viewbuffer + screenwidth*span->v;
|
||||
u = span->u;
|
||||
u2 = span->u + span->count - 1;
|
||||
p16dest[u] = pix;
|
||||
|
||||
for ( ; u <= u2 ; u++)
|
||||
p16dest[u] = pix;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pix = (color<<24) | (color<<16) | (color<<8) | color;
|
||||
for (span=surf->spans ; span ; span=span->pnext)
|
||||
{
|
||||
pdest = (qbyte *)d_viewbuffer + screenwidth*span->v;
|
||||
u = span->u;
|
||||
u2 = span->u + span->count - 1;
|
||||
((qbyte *)pdest)[u] = pix;
|
||||
|
||||
if (u2 - u < 8)
|
||||
{
|
||||
for (u++ ; u <= u2 ; u++)
|
||||
((qbyte *)pdest)[u] = pix;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u++ ; u & 3 ; u++)
|
||||
((qbyte *)pdest)[u] = pix;
|
||||
|
||||
u2 -= 3;
|
||||
for ( ; u <= u2 ; u+=4)
|
||||
*(int *)((qbyte *)pdest + u) = pix;
|
||||
u2 += 3;
|
||||
for ( ; u <= u2 ; u++)
|
||||
((qbyte *)pdest)[u] = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
D_CalcGradients
|
||||
==============
|
||||
*/
|
||||
void D_CalcGradients (msurface_t *pface)
|
||||
{
|
||||
mplane_t *pplane;
|
||||
float mipscale;
|
||||
vec3_t p_temp1;
|
||||
vec3_t p_saxis, p_taxis;
|
||||
float t;
|
||||
|
||||
pplane = pface->plane;
|
||||
|
||||
mipscale = 1.0 / (float)(1 << miplevel);
|
||||
|
||||
TransformVector (pface->texinfo->vecs[0], p_saxis);
|
||||
TransformVector (pface->texinfo->vecs[1], p_taxis);
|
||||
|
||||
t = xscaleinv * mipscale;
|
||||
d_sdivzstepu = p_saxis[0] * t;
|
||||
d_tdivzstepu = p_taxis[0] * t;
|
||||
|
||||
t = yscaleinv * mipscale;
|
||||
d_sdivzstepv = -p_saxis[1] * t;
|
||||
d_tdivzstepv = -p_taxis[1] * t;
|
||||
|
||||
d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
|
||||
ycenter * d_sdivzstepv;
|
||||
d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
|
||||
ycenter * d_tdivzstepv;
|
||||
|
||||
VectorScale (transformed_modelorg, mipscale, p_temp1);
|
||||
|
||||
t = 0x10000*mipscale;
|
||||
sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
|
||||
((pface->texturemins[0] << 16) >> miplevel)
|
||||
+ pface->texinfo->vecs[0][3]*t;
|
||||
tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
|
||||
((pface->texturemins[1] << 16) >> miplevel)
|
||||
+ pface->texinfo->vecs[1][3]*t;
|
||||
|
||||
//
|
||||
// -1 (-epsilon) so we never wander off the edge of the texture
|
||||
//
|
||||
bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
|
||||
bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
|
||||
}
|
||||
|
||||
void SWR_Drawflat_Callback(struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
D_FlushCaches();
|
||||
}
|
||||
|
||||
void SWR_Floorcolour_Callback(struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
r_floorindex = fbremapidx(SCR_StringToPalIndex(var->string, 255));
|
||||
D_FlushCaches();
|
||||
}
|
||||
|
||||
void SWR_Wallcolour_Callback(struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
r_wallindex = fbremapidx(SCR_StringToPalIndex(var->string, 255));
|
||||
D_FlushCaches();
|
||||
}
|
||||
|
||||
void SWR_Fastskycolour_Callback(struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
r_skycolorindex = SCR_StringToPalIndex(var->string, 255);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
D_DrawSurfaces
|
||||
==============
|
||||
*/
|
||||
void D_DrawSurfaces (void)
|
||||
{
|
||||
void D_DrawSpans32 (espan_t *pspan);
|
||||
surf_t *s;
|
||||
msurface_t *pface;
|
||||
surfcache_t *pcurrentcache;
|
||||
vec3_t world_transformed_modelorg;
|
||||
vec3_t local_modelorg;
|
||||
extern int r_dosirds;
|
||||
extern cvar_t r_fastsky, r_fastskycolour, r_drawflat;
|
||||
|
||||
currententity = &r_worldentity;
|
||||
TransformVector (modelorg, transformed_modelorg);
|
||||
VectorCopy (transformed_modelorg, world_transformed_modelorg);
|
||||
|
||||
if (r_dosirds) //depth only
|
||||
{
|
||||
for (s = &surfaces[1] ; s<surface_p ; s++)
|
||||
{
|
||||
if (!s->spans)
|
||||
continue;
|
||||
|
||||
d_zistepu = s->d_zistepu;
|
||||
d_zistepv = s->d_zistepv;
|
||||
d_ziorigin = s->d_ziorigin;
|
||||
D_DrawZSpans (s->spans);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (s = &surfaces[1] ; s<surface_p ; s++)
|
||||
{
|
||||
if (!s->spans)
|
||||
continue;
|
||||
|
||||
r_drawnpolycount++;
|
||||
|
||||
d_zistepu = s->d_zistepu;
|
||||
d_zistepv = s->d_zistepv;
|
||||
d_ziorigin = s->d_ziorigin;
|
||||
|
||||
if (s->flags & SURF_DRAWSKY)
|
||||
{
|
||||
if (r_fastsky.value || r_worldentity.model->fromgame != fg_quake)
|
||||
{
|
||||
D_DrawSolidSurface (s, r_skycolorindex & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!r_skymade)
|
||||
{
|
||||
R_MakeSky ();
|
||||
}
|
||||
|
||||
if (r_pixbytes == 4)
|
||||
D_DrawSkyScans32 (s->spans);
|
||||
else if (r_pixbytes == 2)
|
||||
D_DrawSkyScans16 (s->spans);
|
||||
else
|
||||
D_DrawSkyScans8 (s->spans);
|
||||
}
|
||||
D_DrawZSpans (s->spans);
|
||||
}
|
||||
else if (s->flags & SURF_DRAWSKYBOX)
|
||||
{
|
||||
pface = s->data;
|
||||
miplevel = 0;
|
||||
if (!pface->texinfo->texture)
|
||||
{
|
||||
d_zistepu = 0;
|
||||
d_zistepv = 0;
|
||||
d_ziorigin = -0.9;
|
||||
|
||||
D_DrawSolidSurface (s, r_skycolorindex & 0xFF);
|
||||
D_DrawZSpans (s->spans);
|
||||
continue;
|
||||
}
|
||||
cacheblock = (qbyte *)pface->texinfo->texture + pface->texinfo->texture->offsets[0];
|
||||
cachewidth = 256;
|
||||
cacheheight = 256;
|
||||
|
||||
d_zistepu = s->d_zistepu;
|
||||
d_zistepv = s->d_zistepv;
|
||||
d_ziorigin = s->d_ziorigin;
|
||||
|
||||
D_CalcGradients (pface);
|
||||
|
||||
if (r_pixbytes == 2)
|
||||
D_DrawSpans16From8(s->spans);
|
||||
else
|
||||
(*d_drawspans) (s->spans);
|
||||
|
||||
// set up a gradient for the background surface that places it
|
||||
// effectively at infinity distance from the viewpoint
|
||||
d_zistepu = 0;
|
||||
d_zistepv = 0;
|
||||
d_ziorigin = -0.9;
|
||||
|
||||
D_DrawZSpans (s->spans);
|
||||
}
|
||||
else if (s->flags & SURF_DRAWBACKGROUND)
|
||||
{
|
||||
// set up a gradient for the background surface that places it
|
||||
// effectively at infinity distance from the viewpoint
|
||||
d_zistepu = 0;
|
||||
d_zistepv = 0;
|
||||
d_ziorigin = -0.9;
|
||||
|
||||
D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF);
|
||||
D_DrawZSpans (s->spans);
|
||||
}
|
||||
else if (s->flags & SURF_DRAWTURB)
|
||||
{
|
||||
pface = s->data;
|
||||
miplevel = 0;
|
||||
cacheblock = (pixel_t *)
|
||||
((qbyte *)pface->texinfo->texture +
|
||||
pface->texinfo->texture->offsets[0]);
|
||||
cachewidth = 64;
|
||||
cacheheight = 64;
|
||||
|
||||
if (s->insubmodel)
|
||||
{
|
||||
// FIXME: we don't want to do all this for every polygon!
|
||||
// TODO: store once at start of frame
|
||||
currententity = s->entity; //FIXME: make this passed in to
|
||||
// R_RotateBmodel ()
|
||||
VectorSubtract (r_origin, currententity->origin,
|
||||
local_modelorg);
|
||||
TransformVector (local_modelorg, transformed_modelorg);
|
||||
|
||||
R_RotateBmodel (); // FIXME: don't mess with the frustum,
|
||||
// make entity passed in
|
||||
}
|
||||
|
||||
D_CalcGradients (pface);
|
||||
|
||||
if (r_pixbytes == 4)
|
||||
Turbulent32 (s->spans);
|
||||
else if (r_pixbytes == 2)
|
||||
Turbulent16 (s->spans);
|
||||
else
|
||||
Turbulent8 (s->spans);
|
||||
D_DrawZSpans (s->spans);
|
||||
|
||||
if (s->insubmodel)
|
||||
{
|
||||
//
|
||||
// restore the old drawing state
|
||||
// FIXME: we don't want to do this every time!
|
||||
// TODO: speed up
|
||||
//
|
||||
currententity = &r_worldentity;
|
||||
VectorCopy (world_transformed_modelorg,
|
||||
transformed_modelorg);
|
||||
VectorCopy (base_vpn, vpn);
|
||||
VectorCopy (base_vup, vup);
|
||||
VectorCopy (base_vright, vright);
|
||||
VectorCopy (base_modelorg, modelorg);
|
||||
R_TransformFrustum ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s->insubmodel)
|
||||
{
|
||||
// FIXME: we don't want to do all this for every polygon!
|
||||
// TODO: store once at start of frame
|
||||
currententity = s->entity; //FIXME: make this passed in to
|
||||
// R_RotateBmodel ()
|
||||
VectorSubtract (r_origin, currententity->origin, local_modelorg);
|
||||
TransformVector (local_modelorg, transformed_modelorg);
|
||||
|
||||
R_RotateBmodel (); // FIXME: don't mess with the frustum,
|
||||
// make entity passed in
|
||||
}
|
||||
|
||||
pface = s->data;
|
||||
|
||||
if (pface->flags & SURF_BULLETEN)
|
||||
{
|
||||
miplevel = 0;
|
||||
if (pface->cachespots[miplevel])
|
||||
pface->cachespots[miplevel]->texture = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
|
||||
* pface->texinfo->mipadjust);
|
||||
}
|
||||
|
||||
// FIXME: make this passed in to D_CacheSurface
|
||||
pcurrentcache = D_CacheSurface (pface, miplevel);
|
||||
|
||||
cacheblock = (pixel_t *)pcurrentcache->data;
|
||||
cachewidth = pcurrentcache->width;
|
||||
|
||||
cacheheight = pcurrentcache->height;
|
||||
|
||||
// if (s->entity == &r_worldentity) //temporary
|
||||
// {
|
||||
D_CalcGradients (pface);
|
||||
(*d_drawspans) (s->spans);
|
||||
|
||||
if (d_drawspans != D_DrawSpans32)
|
||||
D_DrawZSpans (s->spans);
|
||||
// }
|
||||
|
||||
if (s->insubmodel)
|
||||
{
|
||||
//
|
||||
// restore the old drawing state
|
||||
// FIXME: we don't want to do this every time!
|
||||
// TODO: speed up
|
||||
//
|
||||
VectorCopy (world_transformed_modelorg,
|
||||
transformed_modelorg);
|
||||
VectorCopy (base_vpn, vpn);
|
||||
VectorCopy (base_vup, vup);
|
||||
VectorCopy (base_vright, vright);
|
||||
VectorCopy (base_modelorg, modelorg);
|
||||
R_TransformFrustum ();
|
||||
currententity = &r_worldentity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// d_clear: clears a specified rectangle to the specified color
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
D_FillRect
|
||||
================
|
||||
*/
|
||||
void D_FillRect (vrect_t *rect, int color)
|
||||
{
|
||||
int rx, ry, rwidth, rheight;
|
||||
unsigned char *dest;
|
||||
unsigned *ldest;
|
||||
|
||||
rx = rect->x;
|
||||
ry = rect->y;
|
||||
rwidth = rect->width;
|
||||
rheight = rect->height;
|
||||
|
||||
if (rx < 0)
|
||||
{
|
||||
rwidth += rx;
|
||||
rx = 0;
|
||||
}
|
||||
if (ry < 0)
|
||||
{
|
||||
rheight += ry;
|
||||
ry = 0;
|
||||
}
|
||||
if (rx+rwidth > vid.width)
|
||||
rwidth = vid.width - rx;
|
||||
if (ry+rheight > vid.height)
|
||||
rheight = vid.height - rx;
|
||||
|
||||
if (rwidth < 1 || rheight < 1)
|
||||
return;
|
||||
|
||||
dest = ((qbyte *)vid.buffer + ry*vid.rowbytes + rx);
|
||||
|
||||
if (((rwidth & 0x03) == 0) && (((long)dest & 0x03) == 0))
|
||||
{
|
||||
// faster aligned dword clear
|
||||
ldest = (unsigned *)dest;
|
||||
color += color << 16;
|
||||
|
||||
rwidth >>= 2;
|
||||
color += color << 8;
|
||||
|
||||
for (ry=0 ; ry<rheight ; ry++)
|
||||
{
|
||||
for (rx=0 ; rx<rwidth ; rx++)
|
||||
ldest[rx] = color;
|
||||
ldest = (unsigned *)((qbyte*)ldest + vid.rowbytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// slower byte-by-byte clear for unaligned cases
|
||||
for (ry=0 ; ry<rheight ; ry++)
|
||||
{
|
||||
for (rx=0 ; rx<rwidth ; rx++)
|
||||
dest[rx] = color;
|
||||
dest += vid.rowbytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,232 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// d_iface.h: interface header file for rasterization driver modules
|
||||
|
||||
#define WARP_WIDTH 320
|
||||
#define WARP_HEIGHT 200
|
||||
|
||||
#define MAX_LBM_HEIGHT 480
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float u, v;
|
||||
float s, t;
|
||||
float zi;
|
||||
} emitpoint_t;
|
||||
|
||||
#include "particles.h"
|
||||
|
||||
typedef struct polyvert_s {
|
||||
float u, v, zi, s, t;
|
||||
} polyvert_t;
|
||||
|
||||
typedef struct polydesc_s {
|
||||
int numverts;
|
||||
float nearzi;
|
||||
msurface_t *pcurrentface;
|
||||
polyvert_t *pverts;
|
||||
} polydesc_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
typedef struct finalvert_s {
|
||||
int v[6]; // u, v, s, t, l, 1/z
|
||||
int flags;
|
||||
float reserved;
|
||||
} finalvert_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
typedef struct
|
||||
{
|
||||
void *pskin;
|
||||
maliasskindesc_t *pskindesc;
|
||||
int skinwidth;
|
||||
int skinheight;
|
||||
mtriangle_t *ptriangles;
|
||||
finalvert_t *pfinalverts;
|
||||
int numtriangles;
|
||||
int drawtype;
|
||||
mstvert_t *pstverts;
|
||||
//int seamfixupX16;
|
||||
} affinetridesc_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
typedef struct {
|
||||
float u, v, zi, color;
|
||||
} screenpart_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int nump;
|
||||
emitpoint_t *pverts; // there's room for an extra element at [nump],
|
||||
// if the driver wants to duplicate element [0] at
|
||||
// element [nump] to avoid dealing with wrapping
|
||||
mspriteframe_t *pspriteframe;
|
||||
vec3_t vup, vright, vpn; // in worldspace
|
||||
float nearzi;
|
||||
} spritedesc_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int u, v;
|
||||
float zi;
|
||||
int color;
|
||||
} zpointdesc_t;
|
||||
|
||||
extern int d_spanpixcount;
|
||||
extern int r_framecount; // sequence # of current frame since Quake
|
||||
// started
|
||||
extern qboolean r_drawpolys; // 1 if driver wants clipped polygons
|
||||
// rather than a span list
|
||||
extern qboolean r_drawculledpolys; // 1 if driver wants clipped polygons that
|
||||
// have been culled by the edge list
|
||||
extern qboolean r_worldpolysbacktofront; // 1 if driver wants polygons
|
||||
// delivered back to front rather
|
||||
// than front to back
|
||||
extern qboolean r_recursiveaffinetriangles; // true if a driver wants to use
|
||||
// recursive triangular subdivison
|
||||
// and vertex drawing via
|
||||
// D_PolysetDrawFinalVerts() past
|
||||
// a certain distance (normally
|
||||
// only used by the software
|
||||
// driver)
|
||||
extern float r_aliasuvscale; // scale-up factor for screen u and v
|
||||
// on Alias vertices passed to driver
|
||||
|
||||
//16 bit rendering.
|
||||
extern int redbits, redshift;
|
||||
extern int greenbits, greenshift;
|
||||
extern int bluebits, blueshift;
|
||||
|
||||
|
||||
extern int r_pixbytes;
|
||||
extern qboolean r_dowarp;
|
||||
|
||||
extern affinetridesc_t r_affinetridesc;
|
||||
extern spritedesc_t r_spritedesc;
|
||||
extern zpointdesc_t r_zpointdesc;
|
||||
extern polydesc_t r_polydesc;
|
||||
|
||||
extern int d_con_indirect; // if 0, Quake will draw console directly
|
||||
// to vid.buffer; if 1, Quake will
|
||||
// draw console via D_DrawRect. Must be
|
||||
// defined by driver
|
||||
|
||||
extern vec3_t r_pright, r_pup, r_ppn;
|
||||
|
||||
|
||||
void D_Aff8Patch (void *pcolormap, qbyte *ppalremap);
|
||||
void GLD_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height);
|
||||
void SWD_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height);
|
||||
void D_DisableBackBufferAccess (void);
|
||||
void GLD_EndDirectRect (int x, int y, int width, int height);
|
||||
void SWD_EndDirectRect (int x, int y, int width, int height);
|
||||
void D_PolysetDrawAsm (void);
|
||||
void D_PolysetDrawC (void); //C version supports transparency
|
||||
void D_PolysetDraw16 (void);
|
||||
void D_PolysetDraw32 (void);
|
||||
void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts);
|
||||
void D_PolysetDrawFinalVerts32Trans (finalvert_t *fv, int numverts);
|
||||
void D_DrawParticle8S (vec3_t porg, float palpha, float pscale, unsigned int pcolour); //in asm
|
||||
void D_DrawPoly (void);
|
||||
void D_DrawSprite (void);
|
||||
void D_DrawSurfaces (void);
|
||||
void D_DrawZPoint (void);
|
||||
void D_ClearDepth(void);
|
||||
void D_EnableBackBufferAccess (void);
|
||||
void D_EndParticles (void);
|
||||
void D_Init (void);
|
||||
void D_ViewChanged (void);
|
||||
void D_SetupFrame (void);
|
||||
void D_StartParticles (void);
|
||||
void D_TurnZOn (void);
|
||||
void D_WarpScreen (void);
|
||||
|
||||
void D_FillRect (vrect_t *vrect, int color);
|
||||
void D_DrawRect (void);
|
||||
void D_UpdateRects (vrect_t *prect);
|
||||
|
||||
// currently for internal use only, and should be a do-nothing function in
|
||||
// hardware drivers
|
||||
// FIXME: this should go away
|
||||
void D_PolysetUpdateTables (void);
|
||||
|
||||
// these are currently for internal use only, and should not be used by drivers
|
||||
extern int r_skydirect;
|
||||
extern qbyte *r_skysource;
|
||||
|
||||
// transparency types for D_DrawRect ()
|
||||
#define DR_SOLID 0
|
||||
#define DR_TRANSPARENT 1
|
||||
|
||||
// !!! must be kept the same as in quakeasm.h !!!
|
||||
#define TRANSPARENT_COLOR 0xFF
|
||||
|
||||
extern void *acolormap; // FIXME: should go away
|
||||
extern qbyte *apalremap;
|
||||
|
||||
//=======================================================================//
|
||||
|
||||
// callbacks to Quake
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pixel_t *surfdat; // destination for generated surface
|
||||
int rowbytes; // destination logical width in bytes
|
||||
msurface_t *surf; // description for surface to generate
|
||||
fixed8_t lightadj[MAXLIGHTMAPS];
|
||||
// adjust for lightmap levels for dynamic lighting
|
||||
texture_t *texture; // corrected for animating textures
|
||||
int surfmip; // mipmapped ratio of surface texels / world pixels
|
||||
int surfwidth; // in mipmapped texels
|
||||
int surfheight; // in mipmapped texels
|
||||
} drawsurf_t;
|
||||
|
||||
extern drawsurf_t r_drawsurf;
|
||||
|
||||
void R_DrawSurface (void);
|
||||
void R_DrawSurface32 (void);
|
||||
void R_GenTile (msurface_t *psurf, void *pdest);
|
||||
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
#define TURB_TEX_SIZE 64 // base turbulent texture size
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
#define CYCLE 128 // turbulent cycle size
|
||||
|
||||
#define TILE_SIZE 128 // size of textures generated by R_GenTiledSurf
|
||||
|
||||
#define SKYSHIFT 7
|
||||
#define SKYSIZE (1 << SKYSHIFT)
|
||||
#define SKYMASK (SKYSIZE - 1)
|
||||
|
||||
extern float skyspeed, skyspeed2;
|
||||
extern float skytime;
|
||||
|
||||
extern int c_surf;
|
||||
extern vrect_t scr_vrect;
|
||||
|
||||
extern qbyte *r_warpbuffer;
|
||||
|
||||
|
||||
struct palremap_s *D_IdentityRemap(void);
|
||||
struct palremap_s *D_GetPaletteRemap(int red, int green, int blue, qboolean desaturate, qboolean fullbrights, int topcolor, int bottomcolor);
|
||||
void D_DereferenceRemap(struct palremap_s *palremap);
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_ifacea.h
|
||||
//
|
||||
// Include file for asm driver interface.
|
||||
//
|
||||
|
||||
//
|
||||
// !!! note that this file must match the corresponding C structures in
|
||||
// d_iface.h at all times !!!
|
||||
//
|
||||
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
//#define ALIAS_ONSEAM 0x0020
|
||||
|
||||
// !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
#define TURB_TEX_SIZE 64 // base turbulent texture size
|
||||
|
||||
// !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
#define CYCLE 128
|
||||
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define MAXHEIGHT 1024
|
||||
|
||||
// !!! if this is changed, it must be changed in quakedef.h too !!!
|
||||
#define CACHE_SIZE 32 // used to align key data structures
|
||||
|
||||
// particle_t structure
|
||||
// !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
// driver-usable fields
|
||||
//#define pt_org 8
|
||||
//#define pt_color 20
|
||||
// drivers never touch the following fields
|
||||
/*#define pt_next 16
|
||||
#define pt_vel 20
|
||||
#define pt_ramp 32
|
||||
#define pt_die 36
|
||||
#define pt_type 40
|
||||
#define pt_size 44*/
|
||||
|
||||
#define PARTICLE_Z_CLIP 8.0
|
||||
|
||||
// finalvert_t structure
|
||||
// !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
#define fv_v 0 // !!! if this is moved, cases where the !!!
|
||||
// !!! address of this field is pushed in !!!
|
||||
// !!! d_polysa.s must be changed !!!
|
||||
#define fv_flags 24
|
||||
#define fv_reserved 28
|
||||
#define fv_size 32
|
||||
#define fv_shift 5
|
||||
|
||||
|
||||
// stvert_t structure
|
||||
// !!! if this is changed, it must be changed in modelgen.h too !!!
|
||||
#define stv_s 0
|
||||
#define stv_t 4
|
||||
#define stv_size 8
|
||||
#define stv_shift 3
|
||||
|
||||
|
||||
// trivertx_t structure
|
||||
// !!! if this is changed, it must be changed in modelgen.h too !!!
|
||||
#define tv_v 0
|
||||
#define tv_lightnormalindex 3
|
||||
#define tv_size 4
|
||||
|
||||
// affinetridesc_t structure
|
||||
// !!! if this is changed, it must be changed in d_iface.h too !!!
|
||||
#define atd_pskin 0
|
||||
#define atd_pskindesc 4
|
||||
#define atd_skinwidth 8
|
||||
#define atd_skinheight 12
|
||||
#define atd_ptriangles 16
|
||||
#define atd_pfinalverts 20
|
||||
#define atd_numtriangles 24
|
||||
#define atd_drawtype 28
|
||||
#define atd_pstverts 32
|
||||
//#define atd_seamfixupX16 32
|
||||
#define atd_size 36
|
|
@ -1,198 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// d_init.c: rasterization driver initialization
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
|
||||
#define NUM_MIPS 4
|
||||
|
||||
cvar_t d_subdiv16 = SCVAR("d_subdiv16", "1");
|
||||
cvar_t d_mipcap = SCVAR("d_mipcap", "0");
|
||||
cvar_t d_mipscale = SCVAR("d_mipscale", "0.5");
|
||||
extern cvar_t d_smooth;
|
||||
|
||||
surfcache_t *d_initial_rover;
|
||||
qboolean d_roverwrapped;
|
||||
int d_minmip;
|
||||
float d_scalemip[NUM_MIPS-1];
|
||||
|
||||
static float basemip[NUM_MIPS-1] = {1.0, 0.5*0.8, 0.25*0.8};
|
||||
|
||||
void (*d_drawspans) (espan_t *pspan);
|
||||
|
||||
void D_DrawSpans32 (espan_t *pspan);
|
||||
void D_DrawSpans32From8 (espan_t *pspan);
|
||||
void D_DrawSpans32_Smooth (espan_t *pspan);
|
||||
|
||||
void D_Shutdown (void)
|
||||
{
|
||||
D_ShutdownTrans();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
D_Init
|
||||
===============
|
||||
*/
|
||||
void D_Init (void)
|
||||
{
|
||||
|
||||
r_skydirect = 1;
|
||||
|
||||
r_drawpolys = false;
|
||||
r_worldpolysbacktofront = false;
|
||||
r_recursiveaffinetriangles = true;
|
||||
|
||||
if (!r_pixbytes)
|
||||
r_pixbytes = 1;
|
||||
r_aliasuvscale = 1.0;
|
||||
|
||||
#ifdef PEXT_TRANS
|
||||
D_InitTrans();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_CopyRects
|
||||
===============
|
||||
*/
|
||||
void D_CopyRects (vrect_t *prects, int transparent)
|
||||
{
|
||||
|
||||
// this function is only required if the CPU doesn't have direct access to the
|
||||
// back buffer, and there's some driver interface function that the driver
|
||||
// doesn't support and requires Quake to do in software (such as drawing the
|
||||
// console); Quake will then draw into wherever the driver points vid.buffer
|
||||
// and will call this function before swapping buffers
|
||||
|
||||
UNUSED(prects);
|
||||
UNUSED(transparent);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_EnableBackBufferAccess
|
||||
===============
|
||||
*/
|
||||
void D_EnableBackBufferAccess (void)
|
||||
{
|
||||
|
||||
VID_LockBuffer ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_TurnZOn
|
||||
===============
|
||||
*/
|
||||
void D_TurnZOn (void)
|
||||
{
|
||||
// not needed for software version
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_DisableBackBufferAccess
|
||||
===============
|
||||
*/
|
||||
void D_DisableBackBufferAccess (void)
|
||||
{
|
||||
VID_UnlockBuffer ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_SetupFrame
|
||||
===============
|
||||
*/
|
||||
void D_SetupFrame (void)
|
||||
{
|
||||
extern qboolean r_usinglits;
|
||||
int i;
|
||||
|
||||
if (r_dowarp)
|
||||
d_viewbuffer = r_warpbuffer;
|
||||
else
|
||||
d_viewbuffer = (void *)(qbyte *)vid.buffer;
|
||||
|
||||
if (r_dowarp)
|
||||
screenwidth = WARP_WIDTH;
|
||||
else
|
||||
screenwidth = vid.rowbytes;
|
||||
|
||||
d_roverwrapped = false;
|
||||
d_initial_rover = sc_rover;
|
||||
|
||||
d_minmip = d_mipcap.value;
|
||||
if (d_minmip > 3)
|
||||
d_minmip = 3;
|
||||
else if (d_minmip < 0)
|
||||
d_minmip = 0;
|
||||
|
||||
for (i=0 ; i<(NUM_MIPS-1) ; i++)
|
||||
d_scalemip[i] = basemip[i] * d_mipscale.value;
|
||||
|
||||
#if id386
|
||||
if (r_pixbytes == 4)
|
||||
d_drawspans = d_smooth.value?D_DrawSpans32_Smooth:D_DrawSpans32;
|
||||
else if (r_pixbytes == 2)
|
||||
d_drawspans = D_DrawSpans16;
|
||||
else if (d_smooth.value)//override's subdiv16 (bigger impact)
|
||||
d_drawspans = D_DrawSpans8_Smooth;
|
||||
else if (d_subdiv16.value)
|
||||
d_drawspans = D_DrawSpans8SubDiv16;
|
||||
else
|
||||
d_drawspans = D_DrawSpans8;
|
||||
#else
|
||||
if (r_pixbytes == 4)
|
||||
{
|
||||
if (r_usinglits)
|
||||
d_drawspans = d_smooth.value?D_DrawSpans32_Smooth:D_DrawSpans32;
|
||||
else
|
||||
d_drawspans = D_DrawSpans32From8;
|
||||
}
|
||||
else if (r_pixbytes == 2)
|
||||
d_drawspans = D_DrawSpans16;
|
||||
else
|
||||
d_drawspans = d_smooth.value?D_DrawSpans8_Smooth:D_DrawSpans8;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
D_UpdateRects
|
||||
===============
|
||||
*/
|
||||
void D_UpdateRects (vrect_t *prect)
|
||||
{
|
||||
|
||||
// the software driver draws these directly to the vid buffer
|
||||
|
||||
UNUSED(prect);
|
||||
}
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// d_local.h: private rasterization driver defs
|
||||
|
||||
#include "r_shared.h"
|
||||
|
||||
//
|
||||
// TODO: fine-tune this; it's based on providing some overage even if there
|
||||
// is a 2k-wide scan, with subdivision every 8, for 256 spans of 12 bytes each
|
||||
//
|
||||
#define SCANBUFFERPAD 0x1000
|
||||
|
||||
#define R_SKY_SMASK 0x007F0000
|
||||
#define R_SKY_TMASK 0x007F0000
|
||||
|
||||
#define DS_SPAN_LIST_END -128
|
||||
|
||||
#define SURFCACHE_SIZE_AT_320X200 600*1024
|
||||
|
||||
typedef struct surfcache_s
|
||||
{
|
||||
struct surfcache_s *next;
|
||||
struct surfcache_s **owner; // NULL is an empty chunk of memory
|
||||
int lightadj[MAXLIGHTMAPS]; // checked for strobe flush
|
||||
int dlight;
|
||||
int size; // including header
|
||||
unsigned width;
|
||||
unsigned height; // DEBUG only needed for debug
|
||||
float mipscale;
|
||||
struct texture_s *texture; // checked for animating textures
|
||||
int bytesperpix;
|
||||
int fcache;
|
||||
qbyte data[4]; // width*height elements
|
||||
} surfcache_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct sspan_s
|
||||
{
|
||||
int u, v, count;
|
||||
} sspan_t;
|
||||
|
||||
extern cvar_t d_subdiv16;
|
||||
|
||||
extern float scale_for_mip;
|
||||
|
||||
extern qboolean d_roverwrapped;
|
||||
extern surfcache_t *sc_rover;
|
||||
extern surfcache_t *d_initial_rover;
|
||||
|
||||
extern float d_sdivzstepu, d_tdivzstepu, d_zistepu;
|
||||
extern float d_sdivzstepv, d_tdivzstepv, d_zistepv;
|
||||
extern float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
|
||||
|
||||
fixed16_t sadjust, tadjust;
|
||||
fixed16_t bbextents, bbextentt;
|
||||
|
||||
|
||||
void D_DrawSpans8_Smooth (espan_t *pspan);
|
||||
void D_DrawSpans8 (espan_t *pspans);
|
||||
void D_DrawSpans16 (espan_t *pspans);
|
||||
void D_DrawSpans8SubDiv16 (espan_t *pspans);
|
||||
void D_DrawSpans16From8 (espan_t *pspan); //skybox in 16 bit renderer (fixme - load tgas with more colourdepth).
|
||||
void D_DrawZSpans (espan_t *pspans);
|
||||
void Turbulent8 (espan_t *pspan);
|
||||
void Turbulent16 (espan_t *pspan);
|
||||
void Turbulent32 (espan_t *pspan);
|
||||
void D_SpriteDrawSpans (sspan_t *pspan);
|
||||
|
||||
void D_DrawSkyScans8 (espan_t *pspan);
|
||||
void D_DrawSkyScans16 (espan_t *pspan);
|
||||
void D_DrawSkyScans32 (espan_t *pspan);
|
||||
|
||||
void R_ShowSubDiv (void);
|
||||
void (*prealspandrawer)(void);
|
||||
surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel);
|
||||
|
||||
extern int D_MipLevelForScale (float scale);
|
||||
|
||||
#if id386
|
||||
extern void D_PolysetAff8Start (void);
|
||||
extern void D_PolysetAff8End (void);
|
||||
#endif
|
||||
|
||||
extern short *d_pzbuffer;
|
||||
extern unsigned int d_zrowbytes, d_zwidth;
|
||||
|
||||
extern int *d_pscantable;
|
||||
extern int d_scantable[MAXHEIGHT];
|
||||
|
||||
extern int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
|
||||
|
||||
extern int d_y_aspect_shift, d_pix_min, d_pix_max, d_pix_shift;
|
||||
|
||||
extern pixel_t *d_viewbuffer;
|
||||
|
||||
extern short *zspantable[MAXHEIGHT];
|
||||
|
||||
extern int d_minmip;
|
||||
extern float d_scalemip[3];
|
||||
|
||||
extern void (*d_drawspans) (espan_t *pspan);
|
||||
|
||||
#ifdef PEXT_TRANS
|
||||
#define PAL555_SIZE 32*32*32
|
||||
#define TRANS_LEVELS 65
|
||||
#define TRANS_MAX (TRANS_LEVELS - 1)
|
||||
|
||||
#define TRANS_UPPER_CAP (TRANS_MAX / (TRANS_LEVELS + 0.0))
|
||||
#define TRANS_LOWER_CAP (1.0 / TRANS_LEVELS)
|
||||
|
||||
#define REMAP_MAX 64
|
||||
|
||||
// palette remap cache
|
||||
typedef struct palremap_s {
|
||||
int r;
|
||||
int g;
|
||||
int b;
|
||||
int key;
|
||||
int references;
|
||||
qbyte pal[256];
|
||||
} palremap_t;
|
||||
|
||||
palremap_t *palremaps;
|
||||
int palremapsize;
|
||||
|
||||
#define fbremapidx(x) palremaps[1].pal[x]
|
||||
|
||||
#define identityremap palremaps[0]
|
||||
#define fullbrightremap palremaps[1]
|
||||
|
||||
palremap_t *D_GetPaletteRemap(int red, int green, int blue, qboolean desaturate, qboolean fullbrights, int topcolor, int bottomcolor);
|
||||
qbyte *D_GetMenuTintPal(void);
|
||||
struct palremap_s *D_IdentityRemap(void);
|
||||
void D_DereferenceRemap(palremap_t *palremap);
|
||||
|
||||
void D_InitTrans(void);
|
||||
// void Set_TransLevelI(int level);
|
||||
void D_SetTransLevel(float level, blendmode_t blend);
|
||||
extern qbyte Trans(qbyte p, qbyte p2);
|
||||
extern qbyte AddBlend(qbyte p, qbyte p2);
|
||||
|
||||
extern qbyte *pal555to8;
|
||||
|
||||
void D_ShutdownTrans(void);
|
||||
#endif
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// d_modech.c: called when mode has just changed
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
|
||||
int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
|
||||
|
||||
int d_y_aspect_shift, d_pix_min, d_pix_max, d_pix_shift;
|
||||
|
||||
int d_scantable[MAXHEIGHT];
|
||||
short *zspantable[MAXHEIGHT];
|
||||
|
||||
/*
|
||||
================
|
||||
D_Patch
|
||||
================
|
||||
*/
|
||||
void D_Patch (void)
|
||||
{
|
||||
#if id386
|
||||
|
||||
static qboolean protectset8 = false;
|
||||
|
||||
if (!protectset8)
|
||||
{
|
||||
Sys_MakeCodeWriteable ((int)D_PolysetAff8Start,
|
||||
(int)D_PolysetAff8End - (int)D_PolysetAff8Start);
|
||||
protectset8 = true;
|
||||
}
|
||||
|
||||
#endif // id386
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
D_ViewChanged
|
||||
================
|
||||
*/
|
||||
void D_ViewChanged (void)
|
||||
{
|
||||
int rowbytes;
|
||||
|
||||
if (r_dowarp)
|
||||
rowbytes = WARP_WIDTH;
|
||||
else
|
||||
rowbytes = vid.rowbytes;
|
||||
|
||||
scale_for_mip = xscale;
|
||||
if (yscale > xscale)
|
||||
scale_for_mip = yscale;
|
||||
|
||||
d_zrowbytes = vid.width * 2;
|
||||
d_zwidth = vid.width;
|
||||
|
||||
d_pix_min = r_refdef.vrect.width / 320;
|
||||
if (d_pix_min < 1)
|
||||
d_pix_min = 1;
|
||||
|
||||
d_pix_max = (int)((float)r_refdef.vrect.width / (320.0 / 4.0) + 0.5);
|
||||
d_pix_max*=2;
|
||||
d_pix_shift = 8 - (int)((float)r_refdef.vrect.width / 320.0 + 0.5);
|
||||
if (d_pix_max < 1)
|
||||
d_pix_max = 1;
|
||||
|
||||
if (pixelAspect > 1.4)
|
||||
d_y_aspect_shift = 1;
|
||||
else
|
||||
d_y_aspect_shift = 0;
|
||||
|
||||
d_vrectx = r_refdef.vrect.x;
|
||||
d_vrecty = r_refdef.vrect.y;
|
||||
d_vrectright_particle = r_refdef.vrectright - d_pix_max;
|
||||
d_vrectbottom_particle =
|
||||
r_refdef.vrectbottom - (d_pix_max << d_y_aspect_shift);
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<vid.height; i++)
|
||||
{
|
||||
d_scantable[i] = i*rowbytes;
|
||||
zspantable[i] = d_pzbuffer + i*d_zwidth;
|
||||
}
|
||||
}
|
||||
|
||||
D_Patch ();
|
||||
|
||||
// D_FlushCaches();
|
||||
}
|
||||
|
|
@ -1,957 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// d_part.c: software driver module for drawing particles
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
#include "r_local.h"
|
||||
|
||||
vec3_t r_pright, r_pup, r_ppn;
|
||||
|
||||
//Spike: Particles are depth sorted. So why depth write? They are the last to be drawn anyway.
|
||||
#define PARTICLEFACTOR 0x8000 // Change DP_Partfac in ASM to match this
|
||||
|
||||
/*
|
||||
==============
|
||||
D_EndParticles
|
||||
==============
|
||||
*/
|
||||
void D_EndParticles (void)
|
||||
{
|
||||
// not used by software driver
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
D_StartParticles
|
||||
==============
|
||||
*/
|
||||
void D_StartParticles (void)
|
||||
{
|
||||
// not used by software driver
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
D_DrawParticle
|
||||
==============
|
||||
*/
|
||||
#if !id386
|
||||
|
||||
void D_DrawParticle8S (vec3_t porg, float palpha, float pscale, unsigned int pcolour)
|
||||
{
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
qbyte *pdest;
|
||||
short *pz;
|
||||
int i, izi, pix, count, u, v;
|
||||
|
||||
// transform point
|
||||
VectorSubtract (porg, r_origin, local);
|
||||
|
||||
transformed[0] = DotProduct(local, r_pright);
|
||||
transformed[1] = DotProduct(local, r_pup);
|
||||
transformed[2] = DotProduct(local, r_ppn);
|
||||
|
||||
if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
return;
|
||||
|
||||
// project the point
|
||||
// FIXME: preadjust xcenter and ycenter
|
||||
zi = 1.0 / transformed[2];
|
||||
u = (int)(xcenter + zi * transformed[0] + 0.5);
|
||||
v = (int)(ycenter - zi * transformed[1] + 0.5);
|
||||
|
||||
if ((v > d_vrectbottom_particle) ||
|
||||
(u > d_vrectright_particle) ||
|
||||
(v < d_vrecty) ||
|
||||
(u < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * v) + u;
|
||||
pdest = d_viewbuffer + d_scantable[v] + u;
|
||||
izi = (int)(zi * PARTICLEFACTOR);
|
||||
|
||||
pix = izi >> d_pix_shift;
|
||||
pix *= pscale;
|
||||
|
||||
if (pix < d_pix_min)
|
||||
pix = d_pix_min;
|
||||
else if (pix > d_pix_max)
|
||||
pix = d_pix_max;
|
||||
|
||||
switch (pix)
|
||||
{
|
||||
case 1:
|
||||
count = 1 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
pdest[0] = pcolour;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
count = 2 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
pdest[0] = pcolour;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
// pz[1] = izi;
|
||||
pdest[1] = pcolour;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
count = 3 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
pdest[0] = pcolour;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
// pz[1] = izi;
|
||||
pdest[1] = pcolour;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi)
|
||||
{
|
||||
// pz[2] = izi;
|
||||
pdest[2] = pcolour;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
count = 4 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
pdest[0] = pcolour;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
// pz[1] = izi;
|
||||
pdest[1] = pcolour;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi)
|
||||
{
|
||||
// pz[2] = izi;
|
||||
pdest[2] = pcolour;
|
||||
}
|
||||
|
||||
if (pz[3] <= izi)
|
||||
{
|
||||
// pz[3] = izi;
|
||||
pdest[3] = pcolour;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
count = pix << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
// pz[i] = izi;
|
||||
pdest[i] = pcolour;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
||||
void D_DrawParticle16S (vec3_t porg, float palpha, float pscale, unsigned int pcolour)
|
||||
{
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
unsigned short *pdest;
|
||||
int a;
|
||||
short *pz;
|
||||
int i, izi, pix, count, u, v;
|
||||
|
||||
if (palpha <= 0.2)
|
||||
return;
|
||||
|
||||
// transform point
|
||||
VectorSubtract (porg, r_origin, local);
|
||||
|
||||
transformed[0] = DotProduct(local, r_pright);
|
||||
transformed[1] = DotProduct(local, r_pup);
|
||||
transformed[2] = DotProduct(local, r_ppn);
|
||||
|
||||
if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
return;
|
||||
|
||||
// project the point
|
||||
// FIXME: preadjust xcenter and ycenter
|
||||
zi = 1.0 / transformed[2];
|
||||
u = (int)(xcenter + zi * transformed[0] + 0.5);
|
||||
v = (int)(ycenter - zi * transformed[1] + 0.5);
|
||||
|
||||
if ((v > d_vrectbottom_particle) ||
|
||||
(u > d_vrectright_particle) ||
|
||||
(v < d_vrecty) ||
|
||||
(u < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * v) + u;
|
||||
izi = (int)(zi * PARTICLEFACTOR);
|
||||
|
||||
pix = ((int)(izi*pscale));
|
||||
|
||||
if (pix < d_pix_min)
|
||||
pix = d_pix_min;
|
||||
else if (pix > d_pix_max)
|
||||
pix = d_pix_max;
|
||||
|
||||
u -= pix/2;
|
||||
v -= pix/2;
|
||||
if (u < 0) u = 0;
|
||||
if (v < 0) v = 0;
|
||||
pdest = (unsigned short *)d_viewbuffer + ((d_scantable[v] + u));
|
||||
|
||||
a = 255*palpha;
|
||||
|
||||
switch (pix)
|
||||
{
|
||||
default:
|
||||
count = pix << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
// pz[i] = izi;
|
||||
pdest[i] = d_8to16table[pcolour];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma message("fixme: D_DrawParticle16T is not implemented")
|
||||
#define D_DrawParticle16T D_DrawParticle16S
|
||||
|
||||
|
||||
void D_DrawParticle32T (vec3_t porg, float palpha, float pscale, unsigned int pcolour)
|
||||
{
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
qbyte *pdest;
|
||||
qbyte *pal;
|
||||
int a;
|
||||
short *pz;
|
||||
int i, izi, pix, count, u, v;
|
||||
|
||||
if (palpha <= 0.0)
|
||||
return;
|
||||
|
||||
// transform point
|
||||
VectorSubtract (porg, r_origin, local);
|
||||
|
||||
transformed[0] = DotProduct(local, r_pright);
|
||||
transformed[1] = DotProduct(local, r_pup);
|
||||
transformed[2] = DotProduct(local, r_ppn);
|
||||
|
||||
if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
return;
|
||||
|
||||
// project the point
|
||||
// FIXME: preadjust xcenter and ycenter
|
||||
zi = 1.0 / transformed[2];
|
||||
u = (int)(xcenter + zi * transformed[0] + 0.5);
|
||||
v = (int)(ycenter - zi * transformed[1] + 0.5);
|
||||
|
||||
if ((v > d_vrectbottom_particle) ||
|
||||
(u > d_vrectright_particle) ||
|
||||
(v < d_vrecty) ||
|
||||
(u < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * v) + u;
|
||||
izi = (int)(zi * PARTICLEFACTOR);
|
||||
|
||||
pix = ((int)(izi*pscale)) >> d_pix_shift;
|
||||
|
||||
if (pix < d_pix_min)
|
||||
pix = d_pix_min;
|
||||
else if (pix > d_pix_max)
|
||||
pix = d_pix_max;
|
||||
|
||||
u -= pix/2;
|
||||
v -= pix/2;
|
||||
if (u < 0) u = 0;
|
||||
if (v < 0) v = 0;
|
||||
pdest = d_viewbuffer + ((d_scantable[v] + u)<<2);
|
||||
pal = (qbyte *)&d_8to32table[pcolour];
|
||||
|
||||
a = 255*palpha;
|
||||
|
||||
switch (pix)
|
||||
{
|
||||
default:
|
||||
count = pix << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth<<2)
|
||||
{
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
// pz[i] = izi;
|
||||
pdest[(i<<2)+0] = (pdest[(i<<2)+0]*(255-a) + pal[0]*a) / 255;
|
||||
pdest[(i<<2)+1] = (pdest[(i<<2)+1]*(255-a) + pal[1]*a) / 255;
|
||||
pdest[(i<<2)+2] = (pdest[(i<<2)+2]*(255-a) + pal[2]*a) / 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define draw(x, y) x=Trans((qbyte)x,(qbyte)y)
|
||||
#define addblend(x, y) x=AddBlend((qbyte)x,(qbyte)y)
|
||||
void D_DrawParticleTrans (vec3_t porg, float palpha, float pscale, unsigned int pcolour, blendmode_t blendmode)
|
||||
{
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
qbyte *pdest;
|
||||
short *pz;
|
||||
int i, izi, pix, count, u, v;
|
||||
|
||||
if (r_pixbytes == 4)
|
||||
{
|
||||
D_DrawParticle32T(porg, palpha, pscale, pcolour);
|
||||
return;
|
||||
}
|
||||
if (r_pixbytes == 2)
|
||||
{
|
||||
D_DrawParticle16T(porg, palpha, pscale, pcolour);
|
||||
return;
|
||||
}
|
||||
|
||||
if (palpha < TRANS_LOWER_CAP)
|
||||
return;
|
||||
|
||||
if (palpha > TRANS_UPPER_CAP && blendmode == BM_BLEND)
|
||||
{
|
||||
D_DrawParticle8S(porg, palpha, pscale, pcolour);
|
||||
return;
|
||||
}
|
||||
|
||||
D_SetTransLevel(palpha, blendmode);
|
||||
|
||||
// transform point
|
||||
VectorSubtract (porg, r_origin, local);
|
||||
|
||||
transformed[0] = DotProduct(local, r_pright);
|
||||
transformed[1] = DotProduct(local, r_pup);
|
||||
transformed[2] = DotProduct(local, r_ppn);
|
||||
|
||||
if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
return;
|
||||
|
||||
// project the point
|
||||
// FIXME: preadjust xcenter and ycenter
|
||||
zi = 1.0 / transformed[2];
|
||||
u = (int)(xcenter + zi * transformed[0] + 0.5);
|
||||
v = (int)(ycenter - zi * transformed[1] + 0.5);
|
||||
|
||||
if ((v > d_vrectbottom_particle) ||
|
||||
(u > d_vrectright_particle) ||
|
||||
(v < d_vrecty) ||
|
||||
(u < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * v) + u;
|
||||
izi = (int)(zi * PARTICLEFACTOR);
|
||||
|
||||
pix = ((int)(izi*pscale)) >> d_pix_shift;
|
||||
|
||||
if (pix < d_pix_min)
|
||||
pix = d_pix_min;
|
||||
else if (pix > d_pix_max)
|
||||
pix = d_pix_max;
|
||||
|
||||
u -= pix/2;
|
||||
v -= pix/2;
|
||||
if (u < 0) u = 0;
|
||||
if (v < 0) v = 0;
|
||||
pdest = d_viewbuffer + d_scantable[v] + u;
|
||||
|
||||
if (blendmode == BM_ADD) // additive drawing
|
||||
{
|
||||
switch (pix)
|
||||
{
|
||||
case 1:
|
||||
count = 1 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
addblend(pdest[0], pcolour);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
count = 2 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
addblend(pdest[0], pcolour);
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
// pz[1] = izi;
|
||||
addblend(pdest[1], pcolour);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
count = 3 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
addblend(pdest[0], pcolour);
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
// pz[1] = izi;
|
||||
addblend(pdest[1], pcolour);
|
||||
}
|
||||
|
||||
if (pz[2] <= izi)
|
||||
{
|
||||
// pz[2] = izi;
|
||||
addblend(pdest[2], pcolour);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
count = 4 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
addblend(pdest[0], pcolour);
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
// pz[1] = izi;
|
||||
addblend(pdest[1], pcolour);
|
||||
}
|
||||
|
||||
if (pz[2] <= izi)
|
||||
{
|
||||
// pz[2] = izi;
|
||||
addblend(pdest[2], pcolour);
|
||||
}
|
||||
|
||||
if (pz[3] <= izi)
|
||||
{
|
||||
// pz[3] = izi;
|
||||
addblend(pdest[3], pcolour);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
count = pix << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
// pz[i] = izi;
|
||||
addblend(pdest[i], pcolour);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // merge drawing
|
||||
{
|
||||
switch (pix)
|
||||
{
|
||||
case 1:
|
||||
count = 1 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
draw(pdest[0], pcolour);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
count = 2 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
draw(pdest[0], pcolour);
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
// pz[1] = izi;
|
||||
draw(pdest[1], pcolour);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
count = 3 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
draw(pdest[0], pcolour);
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
// pz[1] = izi;
|
||||
draw(pdest[1], pcolour);
|
||||
}
|
||||
|
||||
if (pz[2] <= izi)
|
||||
{
|
||||
// pz[2] = izi;
|
||||
draw(pdest[2], pcolour);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
count = 4 << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
if (pz[0] <= izi)
|
||||
{
|
||||
// pz[0] = izi;
|
||||
draw(pdest[0], pcolour);
|
||||
}
|
||||
|
||||
if (pz[1] <= izi)
|
||||
{
|
||||
// pz[1] = izi;
|
||||
draw(pdest[1], pcolour);
|
||||
}
|
||||
|
||||
if (pz[2] <= izi)
|
||||
{
|
||||
// pz[2] = izi;
|
||||
draw(pdest[2], pcolour);
|
||||
}
|
||||
|
||||
if (pz[3] <= izi)
|
||||
{
|
||||
// pz[3] = izi;
|
||||
draw(pdest[3], pcolour);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
count = pix << d_y_aspect_shift;
|
||||
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
{
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
// pz[i] = izi;
|
||||
draw(pdest[i], pcolour);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void D_2dPos(vec3_t pos, int *u, int *v, int *z)
|
||||
{
|
||||
float zi;
|
||||
vec3_t local, transformed;
|
||||
|
||||
// transform point
|
||||
VectorSubtract (pos, r_origin, local);
|
||||
|
||||
transformed[2] = DotProduct(local, r_ppn);
|
||||
|
||||
if (transformed[2] < PARTICLE_Z_CLIP) //near clip
|
||||
{
|
||||
*u = -1; //send it off the side intentionally.
|
||||
return;
|
||||
}
|
||||
|
||||
transformed[0] = DotProduct(local, r_pright);
|
||||
transformed[1] = DotProduct(local, r_pup);
|
||||
|
||||
// project the point
|
||||
zi = 1.0 / transformed[2];
|
||||
*u = (int)(xcenter + zi * transformed[0] + 0.5);
|
||||
*v = (int)(ycenter - zi * transformed[1] + 0.5);
|
||||
|
||||
*z = (int)(zi * 0x8000);
|
||||
}
|
||||
vec_t VI2Length(int x, int y)
|
||||
{
|
||||
float length;
|
||||
length = (float)x*x + (float)y*y;
|
||||
length = sqrt (length);
|
||||
return length;
|
||||
}
|
||||
void D_DrawSpark32T (vec3_t src, vec3_t dest, float palpha, unsigned int pcolour) //draw a line in 3d space
|
||||
{
|
||||
/*
|
||||
Finds 2d coords for the points, then draws a line between them with an appropriate alpha
|
||||
*/
|
||||
unsigned char *pdest;
|
||||
unsigned char *pal;
|
||||
short *pz;
|
||||
int count, u1, v1, z1, a1, a, ia;
|
||||
int u2, v2, z2;
|
||||
|
||||
int du, dv, dz, da;
|
||||
|
||||
if (palpha <= 0.0)
|
||||
return;
|
||||
|
||||
D_2dPos(src, &u1, &v1, &z1);
|
||||
D_2dPos(dest, &u2, &v2, &z2);
|
||||
|
||||
if ((v1 > d_vrectbottom_particle) ||
|
||||
(u1 > d_vrectright_particle) ||
|
||||
(v1 < d_vrecty) ||
|
||||
(u1 < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((v2 > d_vrectbottom_particle) ||
|
||||
(u2 > d_vrectright_particle) ||
|
||||
(v2 < d_vrecty) ||
|
||||
(u2 < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
pal = (qbyte *)(d_8to32table + pcolour);
|
||||
a1 = 255 * palpha;
|
||||
|
||||
du = u2 - u1;
|
||||
dv = v2 - v1;
|
||||
dz = z2 - z1;
|
||||
da = 0 - a1;
|
||||
|
||||
if (!du && !dv)
|
||||
count = 1;
|
||||
else
|
||||
{
|
||||
count = VI2Length(du, dv);
|
||||
if (!count)
|
||||
count = 1;
|
||||
}
|
||||
|
||||
du *= 256*256;
|
||||
dv *= 256*256;
|
||||
dz *= 256*256;
|
||||
da *= 256*256;
|
||||
u1 = u1<<16;
|
||||
v1 = v1<<16;
|
||||
z1 = z1<<16;
|
||||
a1 = a1<<16;
|
||||
{
|
||||
du /= count;
|
||||
dv /= count;
|
||||
dz /= count;
|
||||
da /= count;
|
||||
}
|
||||
do
|
||||
{
|
||||
pz = d_pzbuffer + (d_zwidth * (v1>>16)) + (u1>>16);
|
||||
|
||||
if (*pz <= z1>>16)
|
||||
{
|
||||
// *pz = z1>>16;
|
||||
|
||||
a = a1>>16;
|
||||
ia = 255-a;
|
||||
pdest = (qbyte *)((unsigned int *)d_viewbuffer + ((d_scantable[v1>>16] + (u1>>16))));
|
||||
pdest[0] = (pdest[0]*((ia)) + pal[0]*(a))/255;
|
||||
pdest[1] = (pdest[1]*((ia)) + pal[1]*(a))/255;
|
||||
pdest[2] = (pdest[2]*((ia)) + pal[2]*(a))/255;
|
||||
}
|
||||
|
||||
u1 += du;
|
||||
v1 += dv;
|
||||
z1 += dz;
|
||||
a1 += da;
|
||||
} while (count--);
|
||||
}
|
||||
|
||||
void D_DrawSpark16S (vec3_t src, vec3_t dest, float palpha, unsigned int pcolour) //draw a line in 3d space, 8bpp
|
||||
{
|
||||
unsigned short *pdest;
|
||||
short *pz;
|
||||
int count, u1, v1, z1;
|
||||
int u2, v2, z2;
|
||||
|
||||
int du, dv, dz;
|
||||
|
||||
if (palpha <= 0.0)
|
||||
return;
|
||||
|
||||
D_2dPos(src, &u1, &v1, &z1);
|
||||
D_2dPos(dest, &u2, &v2, &z2);
|
||||
|
||||
if ((v1 > d_vrectbottom_particle) ||
|
||||
(u1 > d_vrectright_particle) ||
|
||||
(v1 < d_vrecty) ||
|
||||
(u1 < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((v2 > d_vrectbottom_particle) ||
|
||||
(u2 > d_vrectright_particle) ||
|
||||
(v2 < d_vrecty) ||
|
||||
(u2 < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
du = u2 - u1;
|
||||
dv = v2 - v1;
|
||||
dz = z2 - z1;
|
||||
|
||||
if (!du && !dv)
|
||||
count = 1;
|
||||
else
|
||||
{
|
||||
count = VI2Length(du, dv);
|
||||
if (!count)
|
||||
count = 1;
|
||||
}
|
||||
|
||||
du *= 256*256;
|
||||
dv *= 256*256;
|
||||
dz *= 256*256;
|
||||
u1 = u1<<16;
|
||||
v1 = v1<<16;
|
||||
z1 = z1<<16;
|
||||
{
|
||||
du /= count;
|
||||
dv /= count;
|
||||
dz /= count;
|
||||
}
|
||||
do
|
||||
{
|
||||
pz = d_pzbuffer + (d_zwidth * (v1>>16)) + (u1>>16);
|
||||
|
||||
if (*pz <= z1>>16)
|
||||
{
|
||||
// *pz = z1>>16;
|
||||
|
||||
pdest = (unsigned short*)d_viewbuffer + d_scantable[v1>>16] + (u1>>16);
|
||||
*pdest = d_8to16table[pcolour];
|
||||
}
|
||||
|
||||
u1 += du;
|
||||
v1 += dv;
|
||||
z1 += dz;
|
||||
} while (count--);
|
||||
}
|
||||
#pragma message("fixme: D_DrawSpark16T is not implemented")
|
||||
#define D_DrawSpark16T D_DrawSpark16S
|
||||
|
||||
void D_DrawSparkTrans (vec3_t src, vec3_t dest, float palpha, unsigned int pcolour, blendmode_t blendmode) //draw a line in 3d space, 8bpp
|
||||
{
|
||||
qbyte *pdest;
|
||||
short *pz;
|
||||
int count, u1, v1, z1;
|
||||
int u2, v2, z2;
|
||||
|
||||
int du, dv, dz;
|
||||
|
||||
if (r_pixbytes == 4)
|
||||
{
|
||||
D_DrawSpark32T(src, dest, palpha, pcolour);
|
||||
return;
|
||||
}
|
||||
if (r_pixbytes == 2)
|
||||
{
|
||||
D_DrawSpark16T(src, dest, palpha, pcolour);
|
||||
return;
|
||||
}
|
||||
|
||||
D_SetTransLevel(palpha, blendmode);
|
||||
|
||||
D_2dPos(src, &u1, &v1, &z1);
|
||||
D_2dPos(dest, &u2, &v2, &z2);
|
||||
|
||||
if ((v1 > d_vrectbottom_particle) ||
|
||||
(u1 > d_vrectright_particle) ||
|
||||
(v1 < d_vrecty) ||
|
||||
(u1 < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((v2 > d_vrectbottom_particle) ||
|
||||
(u2 > d_vrectright_particle) ||
|
||||
(v2 < d_vrecty) ||
|
||||
(u2 < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
du = u2 - u1;
|
||||
dv = v2 - v1;
|
||||
dz = z2 - z1;
|
||||
|
||||
if (!du && !dv)
|
||||
count = 1;
|
||||
else
|
||||
{
|
||||
count = VI2Length(du, dv);
|
||||
if (!count)
|
||||
count = 1;
|
||||
}
|
||||
|
||||
du *= 256*256;
|
||||
dv *= 256*256;
|
||||
dz *= 256*256;
|
||||
u1 = u1<<16;
|
||||
v1 = v1<<16;
|
||||
z1 = z1<<16;
|
||||
du /= count;
|
||||
dv /= count;
|
||||
dz /= count;
|
||||
|
||||
if (blendmode == BM_ADD) // additive
|
||||
{
|
||||
do
|
||||
{
|
||||
pz = d_pzbuffer + (d_zwidth * (v1>>16)) + (u1>>16);
|
||||
|
||||
if (*pz <= z1>>16)
|
||||
{
|
||||
// *pz = z1>>16;
|
||||
pdest = d_viewbuffer + d_scantable[v1>>16] + (u1>>16);
|
||||
addblend(*pdest, (qbyte)pcolour);
|
||||
}
|
||||
|
||||
u1 += du;
|
||||
v1 += dv;
|
||||
z1 += dz;
|
||||
} while (count--);
|
||||
}
|
||||
else // merge blend
|
||||
{
|
||||
do
|
||||
{
|
||||
pz = d_pzbuffer + (d_zwidth * (v1>>16)) + (u1>>16);
|
||||
|
||||
if (*pz <= z1>>16)
|
||||
{
|
||||
// *pz = z1>>16;
|
||||
pdest = d_viewbuffer + d_scantable[v1>>16] + (u1>>16);
|
||||
draw(*pdest, (qbyte)pcolour);
|
||||
}
|
||||
|
||||
u1 += du;
|
||||
v1 += dv;
|
||||
z1 += dz;
|
||||
} while (count--);
|
||||
}
|
||||
}
|
|
@ -1,485 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_parta.s
|
||||
// x86 assembly-language 8-bpp particle-drawing code.
|
||||
//
|
||||
#define SWQUAKE
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "d_ifacea.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#if id386
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp particle drawing code.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//FIXME: comments, full optimization
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp particle queueing code.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
|
||||
#define P0 12+4
|
||||
#define P1 12+8
|
||||
#define P2 12+12
|
||||
#define P3 12+16
|
||||
|
||||
//void D_DrawParticle8S (vec3_t porg, float palpha, float pscale, unsigned int pcolour)
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawParticle8S)
|
||||
C(D_DrawParticle8S):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
movl P0(%esp),%edi
|
||||
|
||||
// FIXME: better FP overlap in general here
|
||||
|
||||
// transform point
|
||||
// VectorSubtract (p->org, r_origin, local);
|
||||
flds C(r_origin)
|
||||
fsubrs 0(%edi)
|
||||
flds 4(%edi)
|
||||
fsubs C(r_origin)+4
|
||||
flds 8(%edi)
|
||||
fsubs C(r_origin)+8
|
||||
fxch %st(2) // local[0] | local[1] | local[2]
|
||||
|
||||
// transformed[2] = DotProduct(local, r_ppn);
|
||||
flds C(r_ppn) // r_ppn[0] | local[0] | local[1] | local[2]
|
||||
fmul %st(1),%st(0) // dot0 | local[0] | local[1] | local[2]
|
||||
flds C(r_ppn)+4 // r_ppn[1] | dot0 | local[0] | local[1] | local[2]
|
||||
fmul %st(3),%st(0) // dot1 | dot0 | local[0] | local[1] | local[2]
|
||||
flds C(r_ppn)+8 // r_ppn[2] | dot1 | dot0 | local[0] |
|
||||
// local[1] | local[2]
|
||||
fmul %st(5),%st(0) // dot2 | dot1 | dot0 | local[0] | local[1] | local[2]
|
||||
fxch %st(2) // dot0 | dot1 | dot2 | local[0] | local[1] | local[2]
|
||||
faddp %st(0),%st(1) // dot0 + dot1 | dot2 | local[0] | local[1] |
|
||||
// local[2]
|
||||
faddp %st(0),%st(1) // z | local[0] | local[1] | local[2]
|
||||
fld %st(0) // z | z | local[0] | local[1] |
|
||||
// local[2]
|
||||
fdivrs float_1 // 1/z | z | local[0] | local[1] | local[2]
|
||||
fxch %st(1) // z | 1/z | local[0] | local[1] | local[2]
|
||||
|
||||
// if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
// return;
|
||||
fcomps float_particle_z_clip // 1/z | local[0] | local[1] | local[2]
|
||||
fxch %st(3) // local[2] | local[0] | local[1] | 1/z
|
||||
|
||||
flds C(r_pup) // r_pup[0] | local[2] | local[0] | local[1] | 1/z
|
||||
fmul %st(2),%st(0) // dot0 | local[2] | local[0] | local[1] | 1/z
|
||||
flds C(r_pup)+4 // r_pup[1] | dot0 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jnz LPop6AndDone
|
||||
|
||||
// transformed[1] = DotProduct(local, r_pup);
|
||||
fmul %st(4),%st(0) // dot1 | dot0 | local[2] | local[0] | local[1] | 1/z
|
||||
flds C(r_pup)+8 // r_pup[2] | dot1 | dot0 | local[2] |
|
||||
// local[0] | local[1] | 1/z
|
||||
fmul %st(3),%st(0) // dot2 | dot1 | dot0 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
fxch %st(2) // dot0 | dot1 | dot2 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
faddp %st(0),%st(1) // dot0 + dot1 | dot2 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
faddp %st(0),%st(1) // y | local[2] | local[0] | local[1] | 1/z
|
||||
fxch %st(3) // local[1] | local[2] | local[0] | y | 1/z
|
||||
|
||||
// transformed[0] = DotProduct(local, r_pright);
|
||||
fmuls C(r_pright)+4 // dot1 | local[2] | local[0] | y | 1/z
|
||||
fxch %st(2) // local[0] | local[2] | dot1 | y | 1/z
|
||||
fmuls C(r_pright) // dot0 | local[2] | dot1 | y | 1/z
|
||||
fxch %st(1) // local[2] | dot0 | dot1 | y | 1/z
|
||||
fmuls C(r_pright)+8 // dot2 | dot0 | dot1 | y | 1/z
|
||||
fxch %st(2) // dot1 | dot0 | dot2 | y | 1/z
|
||||
faddp %st(0),%st(1) // dot1 + dot0 | dot2 | y | 1/z
|
||||
|
||||
faddp %st(0),%st(1) // x | y | 1/z
|
||||
fxch %st(1) // y | x | 1/z
|
||||
|
||||
// project the point
|
||||
fmul %st(2),%st(0) // y/z | x | 1/z
|
||||
fxch %st(1) // x | y/z | 1/z
|
||||
fmul %st(2),%st(0) // x/z | y/z | 1/z
|
||||
fxch %st(1) // y/z | x/z | 1/z
|
||||
fsubrs C(ycenter) // v | x/z | 1/z
|
||||
fxch %st(1) // x/z | v | 1/z
|
||||
fadds C(xcenter) // u | v | 1/z
|
||||
// FIXME: preadjust xcenter and ycenter
|
||||
fxch %st(1) // v | u | 1/z
|
||||
fadds float_point5 // v | u | 1/z
|
||||
fxch %st(1) // u | v | 1/z
|
||||
fadds float_point5 // u | v | 1/z
|
||||
fxch %st(2) // 1/z | v | u
|
||||
fmuls DP_Partfac // 1/z * 0x8000 | v | u
|
||||
fxch %st(2) // u | v | 1/z * 0x8000
|
||||
|
||||
// FIXME: use Terje's fp->int trick here?
|
||||
// FIXME: check we're getting proper rounding here
|
||||
fistpl DP_u // v | 1/z * 0x8000
|
||||
fistpl DP_v // 1/z * 0x8000
|
||||
|
||||
movl DP_u,%eax
|
||||
movl DP_v,%edx
|
||||
|
||||
// if ((v > d_vrectbottom_particle) ||
|
||||
// (u > d_vrectright_particle) ||
|
||||
// (v < d_vrecty) ||
|
||||
// (u < d_vrectx))
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
movl C(d_vrectbottom_particle),%ebx
|
||||
movl C(d_vrectright_particle),%ecx
|
||||
cmpl %ebx,%edx
|
||||
jg LPop1AndDone
|
||||
cmpl %ecx,%eax
|
||||
jg LPop1AndDone
|
||||
movl C(d_vrecty),%ebx
|
||||
movl C(d_vrectx),%ecx
|
||||
cmpl %ebx,%edx
|
||||
jl LPop1AndDone
|
||||
|
||||
cmpl %ecx,%eax
|
||||
jl LPop1AndDone
|
||||
|
||||
movl P3(%esp),%edi
|
||||
movl %edi,DP_Color
|
||||
|
||||
// flds P3(%esp) // color | 1/z * 0x8000
|
||||
// FIXME: use Terje's fast fp->int trick?
|
||||
// fistpl DP_Color // 1/z * 0x8000
|
||||
|
||||
movl C(d_viewbuffer),%ebx
|
||||
|
||||
addl %eax,%ebx
|
||||
movl C(d_scantable)(,%edx,4),%edi // point to the pixel
|
||||
|
||||
imull C(d_zrowbytes),%edx // point to the z pixel
|
||||
|
||||
leal (%edx,%eax,2),%edx
|
||||
movl C(d_pzbuffer),%eax
|
||||
|
||||
fistpl izi
|
||||
|
||||
addl %ebx,%edi
|
||||
addl %eax,%edx
|
||||
|
||||
// pix = izi >> d_pix_shift;
|
||||
|
||||
movl izi,%eax
|
||||
movl C(d_pix_shift),%ecx
|
||||
shrl %cl,%eax
|
||||
movl izi,%ebp
|
||||
|
||||
// if (pix < d_pix_min)
|
||||
// pix = d_pix_min;
|
||||
// else if (pix > d_pix_max)
|
||||
// pix = d_pix_max;
|
||||
|
||||
movl C(d_pix_min),%ebx
|
||||
movl C(d_pix_max),%ecx
|
||||
cmpl %ebx,%eax
|
||||
jnl LTestPixMax
|
||||
movl %ebx,%eax
|
||||
jmp LTestDone
|
||||
|
||||
LTestPixMax:
|
||||
cmpl %ecx,%eax
|
||||
jng LTestDone
|
||||
movl %ecx,%eax
|
||||
LTestDone:
|
||||
|
||||
movb DP_Color,%ch
|
||||
|
||||
movl C(d_y_aspect_shift),%ebx
|
||||
testl %ebx,%ebx
|
||||
jnz LDefault
|
||||
|
||||
cmpl $4,%eax
|
||||
ja LDefault
|
||||
|
||||
jmp DP_EntryTable-4(,%eax,4)
|
||||
|
||||
// 1x1
|
||||
.globl DP_1x1
|
||||
DP_1x1:
|
||||
cmpw %bp,(%edx) // just one pixel to do
|
||||
jg LDone
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
jmp LDone
|
||||
|
||||
// 2x2
|
||||
.globl DP_2x2
|
||||
DP_2x2:
|
||||
pushl %esi
|
||||
movl C(screenwidth),%ebx
|
||||
movl C(d_zrowbytes),%esi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L2x2_1
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L2x2_1:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L2x2_2
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L2x2_2:
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L2x2_3
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L2x2_3:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L2x2_4
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L2x2_4:
|
||||
|
||||
popl %esi
|
||||
jmp LDone
|
||||
|
||||
// 3x3
|
||||
.globl DP_3x3
|
||||
DP_3x3:
|
||||
pushl %esi
|
||||
movl C(screenwidth),%ebx
|
||||
movl C(d_zrowbytes),%esi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L3x3_1
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L3x3_1:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L3x3_2
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L3x3_2:
|
||||
cmpw %bp,4(%edx)
|
||||
jg L3x3_3
|
||||
movw %bp,4(%edx)
|
||||
movb %ch,2(%edi)
|
||||
L3x3_3:
|
||||
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L3x3_4
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L3x3_4:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L3x3_5
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L3x3_5:
|
||||
cmpw %bp,4(%edx,%esi,1)
|
||||
jg L3x3_6
|
||||
movw %bp,4(%edx,%esi,1)
|
||||
movb %ch,2(%edi,%ebx,1)
|
||||
L3x3_6:
|
||||
|
||||
cmpw %bp,(%edx,%esi,2)
|
||||
jg L3x3_7
|
||||
movw %bp,(%edx,%esi,2)
|
||||
movb %ch,(%edi,%ebx,2)
|
||||
L3x3_7:
|
||||
cmpw %bp,2(%edx,%esi,2)
|
||||
jg L3x3_8
|
||||
movw %bp,2(%edx,%esi,2)
|
||||
movb %ch,1(%edi,%ebx,2)
|
||||
L3x3_8:
|
||||
cmpw %bp,4(%edx,%esi,2)
|
||||
jg L3x3_9
|
||||
movw %bp,4(%edx,%esi,2)
|
||||
movb %ch,2(%edi,%ebx,2)
|
||||
L3x3_9:
|
||||
|
||||
popl %esi
|
||||
jmp LDone
|
||||
|
||||
|
||||
// 4x4
|
||||
.globl DP_4x4
|
||||
DP_4x4:
|
||||
pushl %esi
|
||||
movl C(screenwidth),%ebx
|
||||
movl C(d_zrowbytes),%esi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L4x4_1
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L4x4_1:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L4x4_2
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L4x4_2:
|
||||
cmpw %bp,4(%edx)
|
||||
jg L4x4_3
|
||||
movw %bp,4(%edx)
|
||||
movb %ch,2(%edi)
|
||||
L4x4_3:
|
||||
cmpw %bp,6(%edx)
|
||||
jg L4x4_4
|
||||
movw %bp,6(%edx)
|
||||
movb %ch,3(%edi)
|
||||
L4x4_4:
|
||||
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L4x4_5
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L4x4_5:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L4x4_6
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L4x4_6:
|
||||
cmpw %bp,4(%edx,%esi,1)
|
||||
jg L4x4_7
|
||||
movw %bp,4(%edx,%esi,1)
|
||||
movb %ch,2(%edi,%ebx,1)
|
||||
L4x4_7:
|
||||
cmpw %bp,6(%edx,%esi,1)
|
||||
jg L4x4_8
|
||||
movw %bp,6(%edx,%esi,1)
|
||||
movb %ch,3(%edi,%ebx,1)
|
||||
L4x4_8:
|
||||
|
||||
leal (%edx,%esi,2),%edx
|
||||
leal (%edi,%ebx,2),%edi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L4x4_9
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L4x4_9:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L4x4_10
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L4x4_10:
|
||||
cmpw %bp,4(%edx)
|
||||
jg L4x4_11
|
||||
movw %bp,4(%edx)
|
||||
movb %ch,2(%edi)
|
||||
L4x4_11:
|
||||
cmpw %bp,6(%edx)
|
||||
jg L4x4_12
|
||||
movw %bp,6(%edx)
|
||||
movb %ch,3(%edi)
|
||||
L4x4_12:
|
||||
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L4x4_13
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L4x4_13:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L4x4_14
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L4x4_14:
|
||||
cmpw %bp,4(%edx,%esi,1)
|
||||
jg L4x4_15
|
||||
movw %bp,4(%edx,%esi,1)
|
||||
movb %ch,2(%edi,%ebx,1)
|
||||
L4x4_15:
|
||||
cmpw %bp,6(%edx,%esi,1)
|
||||
jg L4x4_16
|
||||
movw %bp,6(%edx,%esi,1)
|
||||
movb %ch,3(%edi,%ebx,1)
|
||||
L4x4_16:
|
||||
|
||||
popl %esi
|
||||
jmp LDone
|
||||
|
||||
// default case, handling any size particle
|
||||
LDefault:
|
||||
|
||||
// count = pix << d_y_aspect_shift;
|
||||
|
||||
movl %eax,%ebx
|
||||
movl %eax,DP_Pix
|
||||
movb C(d_y_aspect_shift),%cl
|
||||
shll %cl,%ebx
|
||||
|
||||
// for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
// {
|
||||
// for (i=0 ; i<pix ; i++)
|
||||
// {
|
||||
// if (pz[i] <= izi)
|
||||
// {
|
||||
// pz[i] = izi;
|
||||
// pdest[i] = color;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
LGenRowLoop:
|
||||
movl DP_Pix,%eax
|
||||
|
||||
LGenColLoop:
|
||||
cmpw %bp,-2(%edx,%eax,2)
|
||||
jg LGSkip
|
||||
movw %bp,-2(%edx,%eax,2)
|
||||
movb %ch,-1(%edi,%eax,1)
|
||||
LGSkip:
|
||||
decl %eax // --pix
|
||||
jnz LGenColLoop
|
||||
|
||||
addl C(d_zrowbytes),%edx
|
||||
addl C(screenwidth),%edi
|
||||
|
||||
decl %ebx // --count
|
||||
jnz LGenRowLoop
|
||||
|
||||
LDone:
|
||||
popl %ebx // restore register variables
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
LPop6AndDone:
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
LPop1AndDone:
|
||||
fstp %st(0)
|
||||
jmp LDone
|
||||
|
||||
#endif // id386
|
1786
engine/sw/d_polysa.s
1786
engine/sw/d_polysa.s
File diff suppressed because it is too large
Load diff
2633
engine/sw/d_polyse.c
2633
engine/sw/d_polyse.c
File diff suppressed because it is too large
Load diff
1727
engine/sw/d_scan.c
1727
engine/sw/d_scan.c
File diff suppressed because it is too large
Load diff
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_scana.s
|
||||
// x86 assembly-language turbulent texture mapping code
|
||||
//
|
||||
#define SWQUAKE
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
|
||||
.text
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// turbulent texture mapping code
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawTurbulent8Span)
|
||||
C(D_DrawTurbulent8Span):
|
||||
pushl %ebp // preserve caller's stack frame pointer
|
||||
pushl %esi // preserve register variables
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
|
||||
movl C(r_turb_s),%esi
|
||||
movl C(r_turb_t),%ecx
|
||||
movl C(r_turb_pdest),%edi
|
||||
movl C(r_turb_spancount),%ebx
|
||||
|
||||
Llp:
|
||||
movl %ecx,%eax
|
||||
movl %esi,%edx
|
||||
sarl $16,%eax
|
||||
movl C(r_turb_turb),%ebp
|
||||
sarl $16,%edx
|
||||
andl $(CYCLE-1),%eax
|
||||
andl $(CYCLE-1),%edx
|
||||
movl (%ebp,%eax,4),%eax
|
||||
movl (%ebp,%edx,4),%edx
|
||||
addl %esi,%eax
|
||||
sarl $16,%eax
|
||||
addl %ecx,%edx
|
||||
sarl $16,%edx
|
||||
andl $(TURB_TEX_SIZE-1),%eax
|
||||
andl $(TURB_TEX_SIZE-1),%edx
|
||||
shll $6,%edx
|
||||
movl C(r_turb_pbase),%ebp
|
||||
addl %eax,%edx
|
||||
incl %edi
|
||||
addl C(r_turb_sstep),%esi
|
||||
addl C(r_turb_tstep),%ecx
|
||||
movb (%ebp,%edx,1),%dl
|
||||
decl %ebx
|
||||
movb %dl,-1(%edi)
|
||||
jnz Llp
|
||||
|
||||
movl %edi,C(r_turb_pdest)
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebp // restore caller's stack frame pointer
|
||||
ret
|
||||
|
||||
#endif // id386
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// d_sky.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
#include "d_local.h"
|
||||
|
||||
#define SKY_SPAN_SHIFT 5
|
||||
#define SKY_SPAN_MAX (1 << SKY_SPAN_SHIFT)
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
D_Sky_uv_To_st
|
||||
=================
|
||||
*/
|
||||
void D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t)
|
||||
{
|
||||
float wu, wv, temp;
|
||||
vec3_t end;
|
||||
|
||||
if (r_refdef.vrect.width >= r_refdef.vrect.height)
|
||||
temp = (float)r_refdef.vrect.width;
|
||||
else
|
||||
temp = (float)r_refdef.vrect.height;
|
||||
|
||||
wu = 8192.0 * (float)(u-((int)vid.width>>1)) / temp;
|
||||
wv = 8192.0 * (float)(((int)vid.height>>1)-v) / temp;
|
||||
|
||||
end[0] = 4096*vpn[0] + wu*vright[0] + wv*vup[0];
|
||||
end[1] = 4096*vpn[1] + wu*vright[1] + wv*vup[1];
|
||||
end[2] = 4096*vpn[2] + wu*vright[2] + wv*vup[2];
|
||||
end[2] *= 3;
|
||||
VectorNormalize (end);
|
||||
|
||||
temp = skytime*skyspeed; // TODO: add D_SetupFrame & set this there
|
||||
*s = (int)((temp + 6*(SKYSIZE/2-1)*end[0]) * 0x10000);
|
||||
*t = (int)((temp + 6*(SKYSIZE/2-1)*end[1]) * 0x10000);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
D_DrawSkyScans8
|
||||
=================
|
||||
*/
|
||||
void D_DrawSkyScans8 (espan_t *pspan)
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
unsigned char *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
int spancountminus1;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
do
|
||||
{
|
||||
pdest = (unsigned char *)((qbyte *)d_viewbuffer +
|
||||
(screenwidth * pspan->v) + pspan->u);
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
// calculate the initial s & t
|
||||
u = pspan->u;
|
||||
v = pspan->v;
|
||||
D_Sky_uv_To_st (u, v, &s, &t);
|
||||
|
||||
do
|
||||
{
|
||||
if (count >= SKY_SPAN_MAX)
|
||||
spancount = SKY_SPAN_MAX;
|
||||
else
|
||||
spancount = count;
|
||||
|
||||
count -= spancount;
|
||||
|
||||
if (count)
|
||||
{
|
||||
u += spancount;
|
||||
|
||||
// calculate s and t at far end of span,
|
||||
// calculate s and t steps across span by shifting
|
||||
D_Sky_uv_To_st (u, v, &snext, &tnext);
|
||||
|
||||
sstep = (snext - s) >> SKY_SPAN_SHIFT;
|
||||
tstep = (tnext - t) >> SKY_SPAN_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate s and t at last pixel in span,
|
||||
// calculate s and t steps across span by division
|
||||
spancountminus1 = (float)(spancount - 1);
|
||||
|
||||
if (spancountminus1 > 0)
|
||||
{
|
||||
u += spancountminus1;
|
||||
D_Sky_uv_To_st (u, v, &snext, &tnext);
|
||||
|
||||
sstep = (snext - s) / spancountminus1;
|
||||
tstep = (tnext - t) / spancountminus1;
|
||||
}
|
||||
else
|
||||
{
|
||||
snext = 0;
|
||||
tnext = 0;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
*pdest++ = r_skysource[((t & R_SKY_TMASK) >> 8) +
|
||||
((s & R_SKY_SMASK) >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
|
||||
void D_DrawSkyScans16 (espan_t *pspan)
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
unsigned short *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
int spancountminus1;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
do
|
||||
{
|
||||
pdest = ((unsigned short *)d_viewbuffer +
|
||||
(screenwidth * pspan->v) + pspan->u);
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
// calculate the initial s & t
|
||||
u = pspan->u;
|
||||
v = pspan->v;
|
||||
D_Sky_uv_To_st (u, v, &s, &t);
|
||||
|
||||
do
|
||||
{
|
||||
if (count >= SKY_SPAN_MAX)
|
||||
spancount = SKY_SPAN_MAX;
|
||||
else
|
||||
spancount = count;
|
||||
|
||||
count -= spancount;
|
||||
|
||||
if (count)
|
||||
{
|
||||
u += spancount;
|
||||
|
||||
// calculate s and t at far end of span,
|
||||
// calculate s and t steps across span by shifting
|
||||
D_Sky_uv_To_st (u, v, &snext, &tnext);
|
||||
|
||||
sstep = (snext - s) >> SKY_SPAN_SHIFT;
|
||||
tstep = (tnext - t) >> SKY_SPAN_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate s and t at last pixel in span,
|
||||
// calculate s and t steps across span by division
|
||||
spancountminus1 = (float)(spancount - 1);
|
||||
|
||||
if (spancountminus1 > 0)
|
||||
{
|
||||
u += spancountminus1;
|
||||
D_Sky_uv_To_st (u, v, &snext, &tnext);
|
||||
|
||||
sstep = (snext - s) / spancountminus1;
|
||||
tstep = (tnext - t) / spancountminus1;
|
||||
}
|
||||
else
|
||||
{
|
||||
snext=0;
|
||||
tnext=0;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
*pdest++ = d_8to16table[r_skysource[((t & R_SKY_TMASK) >> 8) +
|
||||
((s & R_SKY_SMASK) >> 16)]];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
|
||||
void D_DrawSkyScans32 (espan_t *pspan)
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
unsigned int *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
int spancountminus1;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
do
|
||||
{
|
||||
pdest = ((unsigned int *)d_viewbuffer +
|
||||
(screenwidth * pspan->v) + pspan->u);
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
// calculate the initial s & t
|
||||
u = pspan->u;
|
||||
v = pspan->v;
|
||||
D_Sky_uv_To_st (u, v, &s, &t);
|
||||
|
||||
do
|
||||
{
|
||||
if (count >= SKY_SPAN_MAX)
|
||||
spancount = SKY_SPAN_MAX;
|
||||
else
|
||||
spancount = count;
|
||||
|
||||
count -= spancount;
|
||||
|
||||
if (count)
|
||||
{
|
||||
u += spancount;
|
||||
|
||||
// calculate s and t at far end of span,
|
||||
// calculate s and t steps across span by shifting
|
||||
D_Sky_uv_To_st (u, v, &snext, &tnext);
|
||||
|
||||
sstep = (snext - s) >> SKY_SPAN_SHIFT;
|
||||
tstep = (tnext - t) >> SKY_SPAN_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate s and t at last pixel in span,
|
||||
// calculate s and t steps across span by division
|
||||
spancountminus1 = (float)(spancount - 1);
|
||||
|
||||
if (spancountminus1 > 0)
|
||||
{
|
||||
u += spancountminus1;
|
||||
D_Sky_uv_To_st (u, v, &snext, &tnext);
|
||||
|
||||
sstep = (snext - s) / spancountminus1;
|
||||
tstep = (tnext - t) / spancountminus1;
|
||||
}
|
||||
else
|
||||
{
|
||||
snext=0;
|
||||
tnext=0;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
*pdest++ = d_8to32table[r_skysource[((t & R_SKY_TMASK) >> 8) +
|
||||
((s & R_SKY_SMASK) >> 16)]];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
|
|
@ -1,900 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_spr8.s
|
||||
// x86 assembly-language horizontal 8-bpp transparent span-drawing code.
|
||||
//
|
||||
#define SWQUAKE
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#if id386
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp horizontal span drawing code for polygons, with transparency.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
|
||||
// out-of-line, rarely-needed clamping code
|
||||
|
||||
LClampHigh0:
|
||||
movl C(bbextents),%esi
|
||||
jmp LClampReentry0
|
||||
LClampHighOrLow0:
|
||||
jg LClampHigh0
|
||||
xorl %esi,%esi
|
||||
jmp LClampReentry0
|
||||
|
||||
LClampHigh1:
|
||||
movl C(bbextentt),%edx
|
||||
jmp LClampReentry1
|
||||
LClampHighOrLow1:
|
||||
jg LClampHigh1
|
||||
xorl %edx,%edx
|
||||
jmp LClampReentry1
|
||||
|
||||
LClampLow2:
|
||||
movl $2048,%ebp
|
||||
jmp LClampReentry2
|
||||
LClampHigh2:
|
||||
movl C(bbextents),%ebp
|
||||
jmp LClampReentry2
|
||||
|
||||
LClampLow3:
|
||||
movl $2048,%ecx
|
||||
jmp LClampReentry3
|
||||
LClampHigh3:
|
||||
movl C(bbextentt),%ecx
|
||||
jmp LClampReentry3
|
||||
|
||||
LClampLow4:
|
||||
movl $2048,%eax
|
||||
jmp LClampReentry4
|
||||
LClampHigh4:
|
||||
movl C(bbextents),%eax
|
||||
jmp LClampReentry4
|
||||
|
||||
LClampLow5:
|
||||
movl $2048,%ebx
|
||||
jmp LClampReentry5
|
||||
LClampHigh5:
|
||||
movl C(bbextentt),%ebx
|
||||
jmp LClampReentry5
|
||||
|
||||
|
||||
#define pspans 4+16
|
||||
|
||||
.align 4
|
||||
.globl C(D_SpriteDrawSpans)
|
||||
C(D_SpriteDrawSpans):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
//
|
||||
// set up scaled-by-8 steps, for 8-long segments; also set up cacheblock
|
||||
// and span list pointers, and 1/z step in 0.32 fixed-point
|
||||
//
|
||||
// FIXME: any overlap from rearranging?
|
||||
flds C(d_sdivzstepu)
|
||||
fmuls fp_8
|
||||
movl C(cacheblock),%edx
|
||||
flds C(d_tdivzstepu)
|
||||
fmuls fp_8
|
||||
movl pspans(%esp),%ebx // point to the first span descriptor
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_8
|
||||
movl %edx,pbase // pbase = cacheblock
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_64kx64k
|
||||
fxch %st(3)
|
||||
fstps sdivz8stepu
|
||||
fstps zi8stepu
|
||||
fstps tdivz8stepu
|
||||
fistpl izistep
|
||||
movl izistep,%eax
|
||||
rorl $16,%eax // put upper 16 bits in low word
|
||||
movl sspan_t_count(%ebx),%ecx
|
||||
movl %eax,izistep
|
||||
|
||||
cmpl $0,%ecx
|
||||
jle LNextSpan
|
||||
|
||||
LSpanLoop:
|
||||
|
||||
//
|
||||
// set up the initial s/z, t/z, and 1/z on the FP stack, and generate the
|
||||
// initial s and t values
|
||||
//
|
||||
// FIXME: pipeline FILD?
|
||||
fildl sspan_t_v(%ebx)
|
||||
fildl sspan_t_u(%ebx)
|
||||
|
||||
fld %st(1) // dv | du | dv
|
||||
fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv
|
||||
fld %st(1) // du | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
faddp %st(0),%st(2) // du*d_tdivzstepu |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fmuls C(d_tdivzstepv) // dv*d_tdivzstepv |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// dv*d_tdivzstepv | du*d_tdivzstepu | du | dv
|
||||
fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv +
|
||||
// du*d_sdivzstepu; stays in %st(2) at end
|
||||
fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du |
|
||||
// s/z
|
||||
fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
faddp %st(0),%st(2) // dv*d_zistepv |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z
|
||||
fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fmuls C(d_zistepu) // du*d_zistepu |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// du*d_zistepu | dv*d_zistepv | s/z
|
||||
fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv +
|
||||
// du*d_tdivzstepu; stays in %st(1) at end
|
||||
fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z
|
||||
faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
|
||||
flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z
|
||||
fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv +
|
||||
// du*d_zistepu; stays in %st(0) at end
|
||||
// 1/z | fp_64k | t/z | s/z
|
||||
|
||||
fld %st(0) // FIXME: get rid of stall on FMUL?
|
||||
fmuls fp_64kx64k
|
||||
fxch %st(1)
|
||||
|
||||
//
|
||||
// calculate and clamp s & t
|
||||
//
|
||||
fdivr %st(0),%st(2) // 1/z | z*64k | t/z | s/z
|
||||
fxch %st(1)
|
||||
|
||||
fistpl izi // 0.32 fixed-point 1/z
|
||||
movl izi,%ebp
|
||||
|
||||
//
|
||||
// set pz to point to the first z-buffer pixel in the span
|
||||
//
|
||||
rorl $16,%ebp // put upper 16 bits in low word
|
||||
movl sspan_t_v(%ebx),%eax
|
||||
movl %ebp,izi
|
||||
movl sspan_t_u(%ebx),%ebp
|
||||
imull C(d_zrowbytes)
|
||||
shll $1,%ebp // a word per pixel
|
||||
addl C(d_pzbuffer),%eax
|
||||
addl %ebp,%eax
|
||||
movl %eax,pz
|
||||
|
||||
//
|
||||
// point %edi to the first pixel in the span
|
||||
//
|
||||
movl C(d_viewbuffer),%ebp
|
||||
movl sspan_t_v(%ebx),%eax
|
||||
pushl %ebx // preserve spans pointer
|
||||
movl C(tadjust),%edx
|
||||
movl C(sadjust),%esi
|
||||
movl C(d_scantable)(,%eax,4),%edi // v * screenwidth
|
||||
addl %ebp,%edi
|
||||
movl sspan_t_u(%ebx),%ebp
|
||||
addl %ebp,%edi // pdest = &pdestspan[scans->u];
|
||||
|
||||
//
|
||||
// now start the FDIV for the end of the span
|
||||
//
|
||||
cmpl $8,%ecx
|
||||
ja LSetupNotLast1
|
||||
|
||||
decl %ecx
|
||||
jz LCleanup1 // if only one pixel, no need to start an FDIV
|
||||
movl %ecx,spancountminus1
|
||||
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_tdivzstepu) // _d_tdivzstepu | spancountminus1
|
||||
flds C(d_zistepu) // _d_zistepu | _d_tdivzstepu | spancountminus1
|
||||
fmul %st(2),%st(0) // _d_zistepu*scm1 | _d_tdivzstepu | scm1
|
||||
fxch %st(1) // _d_tdivzstepu | _d_zistepu*scm1 | scm1
|
||||
fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1
|
||||
fxch %st(2) // scm1 | _d_zistepu*scm1 | _d_tdivzstepu*scm1
|
||||
fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_zistepu*scm1 |
|
||||
// _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_zistepu*scm1 | _d_sdivzstepu*scm1 |
|
||||
// _d_tdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3)
|
||||
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
LCleanup1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
.align 4
|
||||
LSetupNotLast1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fadds zi8stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz8stepu
|
||||
fxch %st(2)
|
||||
flds tdivz8stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight1:
|
||||
|
||||
addl s,%esi
|
||||
addl t,%edx
|
||||
movl C(bbextents),%ebx
|
||||
movl C(bbextentt),%ebp
|
||||
cmpl %ebx,%esi
|
||||
ja LClampHighOrLow0
|
||||
LClampReentry0:
|
||||
movl %esi,s
|
||||
movl pbase,%ebx
|
||||
shll $16,%esi
|
||||
cmpl %ebp,%edx
|
||||
movl %esi,sfracf
|
||||
ja LClampHighOrLow1
|
||||
LClampReentry1:
|
||||
movl %edx,t
|
||||
movl s,%esi // sfrac = scans->sfrac;
|
||||
shll $16,%edx
|
||||
movl t,%eax // tfrac = scans->tfrac;
|
||||
sarl $16,%esi
|
||||
movl %edx,tfracf
|
||||
|
||||
//
|
||||
// calculate the texture starting address
|
||||
//
|
||||
sarl $16,%eax
|
||||
addl %ebx,%esi
|
||||
imull C(cachewidth),%eax // (tfrac >> 16) * cachewidth
|
||||
addl %eax,%esi // psource = pbase + (sfrac >> 16) +
|
||||
// ((tfrac >> 16) * cachewidth);
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $8,%ecx
|
||||
jna LLastSegment
|
||||
|
||||
//
|
||||
// not the last segment; do full 8-wide segment
|
||||
//
|
||||
LNotLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there
|
||||
//
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
movl snext,%eax
|
||||
movl tnext,%edx
|
||||
|
||||
subl $8,%ecx // count off this segments' pixels
|
||||
movl C(sadjust),%ebp
|
||||
pushl %ecx // remember count of remaining pixels
|
||||
movl C(tadjust),%ecx
|
||||
|
||||
addl %eax,%ebp
|
||||
addl %edx,%ecx
|
||||
|
||||
movl C(bbextents),%eax
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $2048,%ebp
|
||||
jl LClampLow2
|
||||
cmpl %eax,%ebp
|
||||
ja LClampHigh2
|
||||
LClampReentry2:
|
||||
|
||||
cmpl $2048,%ecx
|
||||
jl LClampLow3
|
||||
cmpl %edx,%ecx
|
||||
ja LClampHigh3
|
||||
LClampReentry3:
|
||||
|
||||
movl %ebp,snext
|
||||
movl %ecx,tnext
|
||||
|
||||
subl s,%ebp
|
||||
subl t,%ecx
|
||||
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl %ecx,%eax
|
||||
movl %ebp,%edx
|
||||
sarl $19,%edx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $19,%eax // tstep >>= 16;
|
||||
jz LIsZero
|
||||
imull %ebx,%eax // (tstep >> 16) * cachewidth;
|
||||
LIsZero:
|
||||
addl %edx,%eax // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%edx
|
||||
movl %eax,advancetable+4 // advance base in t
|
||||
addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $13,%ebp // left-justify sstep fractional part
|
||||
movl %ebp,sstep
|
||||
movl sfracf,%ebx
|
||||
shll $13,%ecx // left-justify tstep fractional part
|
||||
movl %eax,advancetable // advance extra in t
|
||||
movl %ecx,tstep
|
||||
|
||||
movl pz,%ecx
|
||||
movl izi,%ebp
|
||||
|
||||
cmpw (%ecx),%bp
|
||||
jl Lp1
|
||||
movb (%esi),%al // get first source texel
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp1
|
||||
movw %bp,(%ecx)
|
||||
movb %al,(%edi) // store first dest pixel
|
||||
Lp1:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx // advance tfrac fractional part by tstep frac
|
||||
|
||||
sbbl %eax,%eax // turn tstep carry into -1 (0 if none)
|
||||
addl sstep,%ebx // advance sfrac fractional part by sstep frac
|
||||
adcl advancetable+4(,%eax,4),%esi // point to next source texel
|
||||
|
||||
cmpw 2(%ecx),%bp
|
||||
jl Lp2
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp2
|
||||
movw %bp,2(%ecx)
|
||||
movb %al,1(%edi)
|
||||
Lp2:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 4(%ecx),%bp
|
||||
jl Lp3
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp3
|
||||
movw %bp,4(%ecx)
|
||||
movb %al,2(%edi)
|
||||
Lp3:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 6(%ecx),%bp
|
||||
jl Lp4
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp4
|
||||
movw %bp,6(%ecx)
|
||||
movb %al,3(%edi)
|
||||
Lp4:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 8(%ecx),%bp
|
||||
jl Lp5
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp5
|
||||
movw %bp,8(%ecx)
|
||||
movb %al,4(%edi)
|
||||
Lp5:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
//
|
||||
// start FDIV for end of next segment in flight, so it can overlap
|
||||
//
|
||||
popl %eax
|
||||
cmpl $8,%eax // more than one segment after this?
|
||||
ja LSetupNotLast2 // yes
|
||||
|
||||
decl %eax
|
||||
jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV
|
||||
movl %eax,spancountminus1
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_zistepu) // _d_zistepu | spancountminus1
|
||||
fmul %st(1),%st(0) // _d_zistepu*scm1 | scm1
|
||||
flds C(d_tdivzstepu) // _d_tdivzstepu | _d_zistepu*scm1 | scm1
|
||||
fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1
|
||||
fxch %st(1) // _d_zistepu*scm1 | _d_tdivzstepu*scm1 | scm1
|
||||
faddp %st(0),%st(3) // _d_tdivzstepu*scm1 | scm1
|
||||
fxch %st(1) // scm1 | _d_tdivzstepu*scm1
|
||||
fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1
|
||||
flds fp_64k // 64k | _d_sdivzstepu*scm1
|
||||
fxch %st(1) // _d_sdivzstepu*scm1 | 64k
|
||||
faddp %st(0),%st(4) // 64k
|
||||
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight2
|
||||
|
||||
.align 4
|
||||
LSetupNotLast2:
|
||||
fadds zi8stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz8stepu
|
||||
fxch %st(2)
|
||||
flds tdivz8stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight2:
|
||||
pushl %eax
|
||||
|
||||
cmpw 10(%ecx),%bp
|
||||
jl Lp6
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp6
|
||||
movw %bp,10(%ecx)
|
||||
movb %al,5(%edi)
|
||||
Lp6:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 12(%ecx),%bp
|
||||
jl Lp7
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp7
|
||||
movw %bp,12(%ecx)
|
||||
movb %al,6(%edi)
|
||||
Lp7:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 14(%ecx),%bp
|
||||
jl Lp8
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp8
|
||||
movw %bp,14(%ecx)
|
||||
movb %al,7(%edi)
|
||||
Lp8:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
addl $8,%edi
|
||||
addl $16,%ecx
|
||||
movl %edx,tfracf
|
||||
movl snext,%edx
|
||||
movl %ebx,sfracf
|
||||
movl tnext,%ebx
|
||||
movl %edx,s
|
||||
movl %ebx,t
|
||||
|
||||
movl %ecx,pz
|
||||
movl %ebp,izi
|
||||
|
||||
popl %ecx // retrieve count
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $8,%ecx // are there multiple segments remaining?
|
||||
ja LNotLastSegment // yes
|
||||
|
||||
//
|
||||
// last segment of scan
|
||||
//
|
||||
LLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there. The number of pixels left is variable, and we want to land on the
|
||||
// last pixel, not step one past it, so we can't run into arithmetic problems
|
||||
//
|
||||
testl %ecx,%ecx
|
||||
jz LNoSteps // just draw the last pixel and we're done
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
|
||||
movl C(tadjust),%ebx
|
||||
movl C(sadjust),%eax
|
||||
|
||||
addl snext,%eax
|
||||
addl tnext,%ebx
|
||||
|
||||
movl C(bbextents),%ebp
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $2048,%eax
|
||||
jl LClampLow4
|
||||
cmpl %ebp,%eax
|
||||
ja LClampHigh4
|
||||
LClampReentry4:
|
||||
movl %eax,snext
|
||||
|
||||
cmpl $2048,%ebx
|
||||
jl LClampLow5
|
||||
cmpl %edx,%ebx
|
||||
ja LClampHigh5
|
||||
LClampReentry5:
|
||||
|
||||
cmpl $1,%ecx // don't bother
|
||||
je LOnlyOneStep // if two pixels in segment, there's only one step,
|
||||
// of the segment length
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
|
||||
addl %eax,%eax // convert to 15.17 format so multiply by 1.31
|
||||
addl %ebx,%ebx // reciprocal yields 16.48
|
||||
imull reciprocal_table-8(,%ecx,4) // sstep = (snext - s) / (spancount-1)
|
||||
movl %edx,%ebp
|
||||
|
||||
movl %ebx,%eax
|
||||
imull reciprocal_table-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1)
|
||||
|
||||
LSetEntryvec:
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl spr8entryvec_table(,%ecx,4),%ebx
|
||||
movl %edx,%eax
|
||||
pushl %ebx // entry point into code for RET later
|
||||
movl %ebp,%ecx
|
||||
sarl $16,%ecx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $16,%edx // tstep >>= 16;
|
||||
jz LIsZeroLast
|
||||
imull %ebx,%edx // (tstep >> 16) * cachewidth;
|
||||
LIsZeroLast:
|
||||
addl %ecx,%edx // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%ecx
|
||||
movl %edx,advancetable+4 // advance base in t
|
||||
addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $16,%ebp // left-justify sstep fractional part
|
||||
movl sfracf,%ebx
|
||||
shll $16,%eax // left-justify tstep fractional part
|
||||
movl %edx,advancetable // advance extra in t
|
||||
|
||||
movl %eax,tstep
|
||||
movl %ebp,sstep
|
||||
movl %ecx,%edx
|
||||
|
||||
movl pz,%ecx
|
||||
movl izi,%ebp
|
||||
|
||||
ret // jump to the number-of-pixels handler
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
LNoSteps:
|
||||
movl pz,%ecx
|
||||
subl $7,%edi // adjust for hardwired offset
|
||||
subl $14,%ecx
|
||||
jmp LEndSpan
|
||||
|
||||
|
||||
LOnlyOneStep:
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
movl %eax,%ebp
|
||||
movl %ebx,%edx
|
||||
jmp LSetEntryvec
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry2_8
|
||||
Spr8Entry2_8:
|
||||
subl $6,%edi // adjust for hardwired offsets
|
||||
subl $12,%ecx
|
||||
movb (%esi),%al
|
||||
jmp LLEntry2_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry3_8
|
||||
Spr8Entry3_8:
|
||||
subl $5,%edi // adjust for hardwired offsets
|
||||
subl $10,%ecx
|
||||
jmp LLEntry3_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry4_8
|
||||
Spr8Entry4_8:
|
||||
subl $4,%edi // adjust for hardwired offsets
|
||||
subl $8,%ecx
|
||||
jmp LLEntry4_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry5_8
|
||||
Spr8Entry5_8:
|
||||
subl $3,%edi // adjust for hardwired offsets
|
||||
subl $6,%ecx
|
||||
jmp LLEntry5_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry6_8
|
||||
Spr8Entry6_8:
|
||||
subl $2,%edi // adjust for hardwired offsets
|
||||
subl $4,%ecx
|
||||
jmp LLEntry6_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry7_8
|
||||
Spr8Entry7_8:
|
||||
decl %edi // adjust for hardwired offsets
|
||||
subl $2,%ecx
|
||||
jmp LLEntry7_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry8_8
|
||||
Spr8Entry8_8:
|
||||
cmpw (%ecx),%bp
|
||||
jl Lp9
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp9
|
||||
movw %bp,(%ecx)
|
||||
movb %al,(%edi)
|
||||
Lp9:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry7_8:
|
||||
cmpw 2(%ecx),%bp
|
||||
jl Lp10
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp10
|
||||
movw %bp,2(%ecx)
|
||||
movb %al,1(%edi)
|
||||
Lp10:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry6_8:
|
||||
cmpw 4(%ecx),%bp
|
||||
jl Lp11
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp11
|
||||
movw %bp,4(%ecx)
|
||||
movb %al,2(%edi)
|
||||
Lp11:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry5_8:
|
||||
cmpw 6(%ecx),%bp
|
||||
jl Lp12
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp12
|
||||
movw %bp,6(%ecx)
|
||||
movb %al,3(%edi)
|
||||
Lp12:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry4_8:
|
||||
cmpw 8(%ecx),%bp
|
||||
jl Lp13
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp13
|
||||
movw %bp,8(%ecx)
|
||||
movb %al,4(%edi)
|
||||
Lp13:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry3_8:
|
||||
cmpw 10(%ecx),%bp
|
||||
jl Lp14
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp14
|
||||
movw %bp,10(%ecx)
|
||||
movb %al,5(%edi)
|
||||
Lp14:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry2_8:
|
||||
cmpw 12(%ecx),%bp
|
||||
jl Lp15
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp15
|
||||
movw %bp,12(%ecx)
|
||||
movb %al,6(%edi)
|
||||
Lp15:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
LEndSpan:
|
||||
cmpw 14(%ecx),%bp
|
||||
jl Lp16
|
||||
movb (%esi),%al // load first texel in segment
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp16
|
||||
movw %bp,14(%ecx)
|
||||
movb %al,7(%edi)
|
||||
Lp16:
|
||||
|
||||
//
|
||||
// clear s/z, t/z, 1/z from FP stack
|
||||
//
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
|
||||
popl %ebx // restore spans pointer
|
||||
LNextSpan:
|
||||
addl $(sspan_t_size),%ebx // point to next span
|
||||
movl sspan_t_count(%ebx),%ecx
|
||||
cmpl $0,%ecx // any more spans?
|
||||
jg LSpanLoop // yes
|
||||
jz LNextSpan // yes, but this one's empty
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
#endif // id386
|
1091
engine/sw/d_sprite.c
1091
engine/sw/d_sprite.c
File diff suppressed because it is too large
Load diff
|
@ -1,329 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// d_surf.c: rasterization driver surface heap manager
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
#include "r_local.h"
|
||||
|
||||
float surfscale;
|
||||
qboolean r_cache_thrash; // set if surface cache is thrashing
|
||||
|
||||
int r_flushcache;
|
||||
|
||||
int sc_size;
|
||||
surfcache_t *sc_rover, *sc_base;
|
||||
|
||||
#define GUARDSIZE 4
|
||||
|
||||
|
||||
int D_SurfaceCacheForRes (int width, int height, int bpp)
|
||||
{
|
||||
extern cvar_t sw_surfcachesize;
|
||||
int size, pix;
|
||||
|
||||
if (COM_CheckParm ("-surfcachesize"))
|
||||
{
|
||||
size = Q_atoi(com_argv[COM_CheckParm("-surfcachesize")+1]) * 1024;
|
||||
return size;
|
||||
}
|
||||
|
||||
if (sw_surfcachesize.value >= 512*1024) // force minimum of 512k
|
||||
{
|
||||
return (int)sw_surfcachesize.value;
|
||||
}
|
||||
|
||||
size = 4096*1024;//SURFCACHE_SIZE_AT_320X200;
|
||||
|
||||
pix = width*height;
|
||||
if (pix > 64000)
|
||||
size += (pix-64000)*4;
|
||||
|
||||
size*=8;
|
||||
if (bpp)
|
||||
return size*bpp;
|
||||
return size;
|
||||
}
|
||||
|
||||
void D_CheckCacheGuard (void)
|
||||
{
|
||||
qbyte *s;
|
||||
int i;
|
||||
|
||||
s = (qbyte *)sc_base + sc_size;
|
||||
for (i=0 ; i<GUARDSIZE ; i++)
|
||||
if (s[i] != (qbyte)i)
|
||||
Sys_Error ("D_CheckCacheGuard: failed");
|
||||
}
|
||||
|
||||
void D_ClearCacheGuard (void)
|
||||
{
|
||||
qbyte *s;
|
||||
int i;
|
||||
|
||||
s = (qbyte *)sc_base + sc_size;
|
||||
for (i=0 ; i<GUARDSIZE ; i++)
|
||||
s[i] = (qbyte)i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
D_InitCaches
|
||||
|
||||
================
|
||||
*/
|
||||
void D_InitCaches (void *buffer, int size)
|
||||
{
|
||||
// Con_Printf(S_NOTICE "Using %i KB for SW surface cache\n", size / 1024);
|
||||
|
||||
sc_size = size - GUARDSIZE;
|
||||
sc_base = (surfcache_t *)buffer;
|
||||
sc_rover = sc_base;
|
||||
|
||||
sc_base->next = NULL;
|
||||
sc_base->owner = NULL;
|
||||
sc_base->size = sc_size;
|
||||
|
||||
D_ClearCacheGuard ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
D_FlushCaches
|
||||
==================
|
||||
*/
|
||||
void D_FlushCaches (void)
|
||||
{
|
||||
surfcache_t *c;
|
||||
|
||||
if (!sc_base)
|
||||
return;
|
||||
|
||||
for (c = sc_base ; c ; c = c->next)
|
||||
{
|
||||
if (c->owner)
|
||||
*c->owner = NULL;
|
||||
}
|
||||
|
||||
sc_rover = sc_base;
|
||||
sc_base->next = NULL;
|
||||
sc_base->owner = NULL;
|
||||
sc_base->size = sc_size;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
D_SCAlloc
|
||||
=================
|
||||
*/
|
||||
surfcache_t *D_SCAlloc (int width, int bpp, int size)
|
||||
{
|
||||
surfcache_t *newsc;
|
||||
qboolean wrapped_this_time;
|
||||
|
||||
// if ((width < 0) || (width > 256))
|
||||
// Sys_Error ("D_SCAlloc: bad cache width %d\n", width);
|
||||
|
||||
// if ((size <= 0) || (size > 0x10000*bpp))
|
||||
// Sys_Error ("D_SCAlloc: bad cache size %d\n", size);
|
||||
|
||||
#ifdef __alpha__
|
||||
size = (int)((long)&((surfcache_t *)0)->data[size]);
|
||||
#else
|
||||
size = (int)&((surfcache_t *)0)->data[size];
|
||||
#endif
|
||||
size = (size + 3) & ~3;
|
||||
if (size > sc_size)
|
||||
Sys_Error ("D_SCAlloc: %i > cache size",size);
|
||||
|
||||
// if there is not size bytes after the rover, reset to the start
|
||||
wrapped_this_time = false;
|
||||
|
||||
if ( !sc_rover || (qbyte *)sc_rover - (qbyte *)sc_base > sc_size - size)
|
||||
{
|
||||
if (sc_rover)
|
||||
{
|
||||
wrapped_this_time = true;
|
||||
}
|
||||
sc_rover = sc_base;
|
||||
}
|
||||
|
||||
// colect and free surfcache_t blocks until the rover block is large enough
|
||||
newsc = sc_rover;
|
||||
if (sc_rover->owner)
|
||||
*sc_rover->owner = NULL;
|
||||
|
||||
while (newsc->size < size)
|
||||
{
|
||||
// free another
|
||||
sc_rover = sc_rover->next;
|
||||
if (!sc_rover)
|
||||
Sys_Error ("D_SCAlloc: hit the end of memory");
|
||||
if (sc_rover->owner)
|
||||
*sc_rover->owner = NULL;
|
||||
|
||||
newsc->size += sc_rover->size;
|
||||
newsc->next = sc_rover->next;
|
||||
}
|
||||
|
||||
// create a fragment out of any leftovers
|
||||
if (newsc->size - size > 256)
|
||||
{
|
||||
sc_rover = (surfcache_t *)( (qbyte *)newsc + size);
|
||||
sc_rover->size = newsc->size - size;
|
||||
sc_rover->next = newsc->next;
|
||||
sc_rover->width = 0;
|
||||
sc_rover->owner = NULL;
|
||||
newsc->next = sc_rover;
|
||||
newsc->size = size;
|
||||
}
|
||||
else
|
||||
sc_rover = newsc->next;
|
||||
|
||||
newsc->width = width;
|
||||
// DEBUG
|
||||
if (width > 0)
|
||||
newsc->height = (size - sizeof(*newsc) + sizeof(newsc->data)) / (width*bpp);
|
||||
|
||||
newsc->bytesperpix = bpp;
|
||||
|
||||
newsc->owner = NULL; // should be set properly after return
|
||||
|
||||
if (d_roverwrapped)
|
||||
{
|
||||
if (wrapped_this_time || (sc_rover >= d_initial_rover))
|
||||
r_cache_thrash = true;
|
||||
}
|
||||
else if (wrapped_this_time)
|
||||
{
|
||||
d_roverwrapped = true;
|
||||
}
|
||||
|
||||
D_CheckCacheGuard (); // DEBUG
|
||||
return newsc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
D_SCDump
|
||||
=================
|
||||
*/
|
||||
void D_SCDump (void)
|
||||
{
|
||||
surfcache_t *test;
|
||||
|
||||
for (test = sc_base ; test ; test = test->next)
|
||||
{
|
||||
if (test == sc_rover)
|
||||
Sys_Printf ("ROVER:\n");
|
||||
Sys_Printf ("%p : %i bytes %i width\n",test, test->size, test->width);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
D_CacheSurface
|
||||
================
|
||||
*/
|
||||
surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel)
|
||||
{
|
||||
surfcache_t *cache;
|
||||
int bpp;
|
||||
|
||||
//
|
||||
// if the surface is animating or flashing, flush the cache
|
||||
//
|
||||
r_drawsurf.texture = SWR_TextureAnimation (surface->texinfo->texture);
|
||||
r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]];
|
||||
r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]];
|
||||
r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]];
|
||||
r_drawsurf.lightadj[3] = d_lightstylevalue[surface->styles[3]];
|
||||
|
||||
//
|
||||
// see if the cache holds apropriate data
|
||||
//
|
||||
cache = surface->cachespots[miplevel];
|
||||
|
||||
if (cache && !cache->dlight && surface->dlightframe != r_framecount
|
||||
&& cache->texture == r_drawsurf.texture && cache->fcache == r_flushcache //extra part added to flush caches over a group of frames on palette change...
|
||||
&& cache->lightadj[0] == r_drawsurf.lightadj[0]
|
||||
&& cache->lightadj[1] == r_drawsurf.lightadj[1]
|
||||
&& cache->lightadj[2] == r_drawsurf.lightadj[2]
|
||||
&& cache->lightadj[3] == r_drawsurf.lightadj[3] )
|
||||
return cache;
|
||||
|
||||
//
|
||||
// determine shape of surface
|
||||
//
|
||||
surfscale = 1.0 / (1<<miplevel);
|
||||
|
||||
r_drawsurf.surfmip = miplevel;
|
||||
r_drawsurf.surfwidth = surface->extents[0] >> miplevel;
|
||||
r_drawsurf.rowbytes = r_drawsurf.surfwidth;
|
||||
r_drawsurf.surfheight = surface->extents[1] >> miplevel;
|
||||
|
||||
bpp = r_pixbytes;
|
||||
//
|
||||
// allocate memory if needed
|
||||
//
|
||||
if (!cache) // if a texture just animated, don't reallocate it
|
||||
{
|
||||
cache = D_SCAlloc (r_drawsurf.surfwidth, bpp,
|
||||
r_drawsurf.surfwidth * r_drawsurf.surfheight * bpp);
|
||||
surface->cachespots[miplevel] = cache;
|
||||
cache->owner = &surface->cachespots[miplevel];
|
||||
cache->mipscale = surfscale;
|
||||
}
|
||||
|
||||
if (surface->dlightframe == r_framecount)
|
||||
cache->dlight = 1;
|
||||
else
|
||||
cache->dlight = 0;
|
||||
|
||||
cache->fcache = r_flushcache;
|
||||
|
||||
r_drawsurf.surfdat = (pixel_t *)cache->data;
|
||||
|
||||
cache->texture = r_drawsurf.texture;
|
||||
cache->lightadj[0] = r_drawsurf.lightadj[0];
|
||||
cache->lightadj[1] = r_drawsurf.lightadj[1];
|
||||
cache->lightadj[2] = r_drawsurf.lightadj[2];
|
||||
cache->lightadj[3] = r_drawsurf.lightadj[3];
|
||||
|
||||
//
|
||||
// draw and light the surface texture
|
||||
//
|
||||
r_drawsurf.surf = surface;
|
||||
|
||||
c_surf++;
|
||||
if (cache->bytesperpix==4 && r_usinglits)
|
||||
R_DrawSurface32 ();
|
||||
else
|
||||
R_DrawSurface ();
|
||||
|
||||
return surface->cachespots[miplevel];
|
||||
}
|
||||
|
||||
|
|
@ -1,765 +0,0 @@
|
|||
//contains routines for blending images (as well as blitting 32bit to 8bit type stuff)
|
||||
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
#include "r_local.h"
|
||||
|
||||
void MakeVideoPalette(void);
|
||||
void MakeSwizzledPalette(void);
|
||||
void MakePaletteRemaps(void);
|
||||
|
||||
int *srctable;
|
||||
int *dsttable;
|
||||
qbyte *pal555to8;
|
||||
|
||||
int swzpal[TRANS_LEVELS][256];
|
||||
|
||||
// menutint
|
||||
palremap_t *mtpalremap;
|
||||
|
||||
// IB remap
|
||||
palremap_t *ib_remap;
|
||||
|
||||
#define palette host_basepal
|
||||
#define _abs(x) ((x)*(x))
|
||||
|
||||
void D_ShutdownTrans(void)
|
||||
{
|
||||
if (pal555to8)
|
||||
{
|
||||
BZ_Free(pal555to8);
|
||||
pal555to8 = NULL;
|
||||
}
|
||||
|
||||
if (palremaps)
|
||||
{
|
||||
BZ_Free(palremaps);
|
||||
palremapsize = 0;
|
||||
palremaps = NULL;
|
||||
}
|
||||
|
||||
mtpalremap = NULL;
|
||||
ib_remap = NULL;
|
||||
}
|
||||
|
||||
void D_InitTrans(void)
|
||||
{
|
||||
// create pal555to8 and swizzled palette
|
||||
MakeVideoPalette();
|
||||
MakeSwizzledPalette();
|
||||
MakePaletteRemaps();
|
||||
|
||||
srctable = swzpal[0];
|
||||
dsttable = swzpal[TRANS_MAX];
|
||||
ib_remap = D_IdentityRemap();
|
||||
}
|
||||
|
||||
// TODO: INLINE THESE FUNCTIONS
|
||||
qbyte Trans(qbyte p, qbyte p2)
|
||||
{
|
||||
int x;
|
||||
|
||||
x = (srctable[p] + dsttable[p2]) | 0x01F07C1F;
|
||||
return pal555to8[x & (x >> 15)];
|
||||
|
||||
}
|
||||
|
||||
qbyte AddBlend(qbyte p, qbyte p2)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
||||
x = (srctable[p] + dsttable[p2]);
|
||||
y = x & 0x40100400; // overflow bits
|
||||
x = (x | 0x01F07C1F) & 0x3FFFFFFF;
|
||||
y = y - (y >> 5);
|
||||
x = x | y;
|
||||
return pal555to8[x & (x >> 15)];
|
||||
}
|
||||
|
||||
/*
|
||||
void Set_TransLevelI(int level)
|
||||
{
|
||||
t_curtable = level/(100.0f/(t_numtables-1));
|
||||
t_curlookupp = t_lookup[t_curtable];
|
||||
}
|
||||
*/
|
||||
|
||||
void D_SetTransLevel(float level, blendmode_t blend)
|
||||
{
|
||||
int ilvl;
|
||||
|
||||
// cap and set level
|
||||
ilvl = (bound(0, level, 1) * (TRANS_MAX + 0.99));
|
||||
|
||||
// set blending tables
|
||||
switch (blend)
|
||||
{
|
||||
case BM_ADD:
|
||||
dsttable = swzpal[ilvl];
|
||||
srctable = swzpal[TRANS_MAX];
|
||||
break;
|
||||
default:
|
||||
dsttable = swzpal[ilvl];
|
||||
srctable = swzpal[TRANS_MAX - ilvl];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define _abs(x) ((x)*(x))
|
||||
qbyte FindIndexFromRGB(int red, int green, int blue)
|
||||
{
|
||||
int i, best=15;
|
||||
int bestdif=256*256*256, curdif;
|
||||
extern qbyte *host_basepal;
|
||||
qbyte *pa;
|
||||
|
||||
pa = host_basepal;
|
||||
for (i = 0; i < 256; i++, pa+=3)
|
||||
{
|
||||
curdif = _abs(red - pa[0]) + _abs(green - pa[1]) + _abs(blue - pa[2]);
|
||||
if (curdif < bestdif)
|
||||
{
|
||||
if (curdif<1)
|
||||
return i;
|
||||
bestdif = curdif;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
qbyte FindIndexFromRGBNoFB(int red, int green, int blue)
|
||||
{
|
||||
int i, best=15;
|
||||
int bestdif=256*256*256, curdif;
|
||||
extern qbyte *host_basepal;
|
||||
qbyte *pa;
|
||||
|
||||
pa = host_basepal;
|
||||
for (i = 0; i < 256 - vid.fullbright; i++, pa+=3)
|
||||
{
|
||||
curdif = _abs(red - pa[0]) + _abs(green - pa[1]) + _abs(blue - pa[2]);
|
||||
if (curdif < bestdif)
|
||||
{
|
||||
if (curdif<1)
|
||||
return i;
|
||||
bestdif = curdif;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
#define FindPalette(r,g,b) pal555to8[((r&0xF8)>>3)|((g&0xF8)<<2)|((b&0xF8)<<7)]
|
||||
qbyte GetPaletteIndex(int red, int green, int blue)
|
||||
{
|
||||
if (pal555to8) //fast precalculated method
|
||||
return FindPalette(red,green,blue);
|
||||
else //slow, horrible method.
|
||||
return FindIndexFromRGB(red, green, blue);
|
||||
}
|
||||
|
||||
qbyte GetPaletteNoFB(int red, int green, int blue)
|
||||
{
|
||||
if (pal555to8) //fast precalculated (but ugly) method
|
||||
return fbremapidx(FindPalette(red,green,blue));
|
||||
else //slow, horrible (but accurate) method.
|
||||
return FindIndexFromRGBNoFB(red, green, blue);
|
||||
}
|
||||
|
||||
void MakeVideoPalette(void)
|
||||
{
|
||||
vfsfile_t *f;
|
||||
int r, g, b;
|
||||
|
||||
// allocate memory
|
||||
if (!pal555to8)
|
||||
pal555to8 = BZ_Malloc(PAL555_SIZE);
|
||||
// pal555to8 = Hunk_AllocName(PAL555_SIZE, "RGB data");
|
||||
|
||||
// load in previously created table
|
||||
if ((f = FS_OpenVFS("pal555.pal", "rb", FS_GAME)))
|
||||
{
|
||||
VFS_READ(f, pal555to8, PAL555_SIZE);
|
||||
VFS_CLOSE(f);
|
||||
return;
|
||||
}
|
||||
|
||||
// create palette conversion table
|
||||
for (b = 0; b < 32; b++)
|
||||
for (g = 0; g < 32; g++)
|
||||
for (r = 0; r < 32; r++)
|
||||
pal555to8[r | (g << 5) | (b << 10)] =
|
||||
FindIndexFromRGB(r<<3|r>>2, g<<3|g>>2, b<<3|b>>2);
|
||||
|
||||
// write palette conversion table
|
||||
if (d_palconvwrite.value)
|
||||
COM_WriteFile("pal555.pal", pal555to8, PAL555_SIZE);
|
||||
}
|
||||
|
||||
void MakeSwizzledPalette(void)
|
||||
{
|
||||
int idx, lvl;
|
||||
qbyte *pa;
|
||||
|
||||
// create swizzled palettes
|
||||
for (lvl = 0; lvl < TRANS_LEVELS; lvl++)
|
||||
{
|
||||
pa = host_basepal;
|
||||
for (idx = 0; idx < 256; idx++)
|
||||
{
|
||||
// create a b10r10g10 table for each alpha level
|
||||
// may need some hacking due to the tendancy of
|
||||
// identity merges becoming darker
|
||||
swzpal[lvl][idx] = ( (pa[0] * lvl) >> 4 ) << 10; // red
|
||||
swzpal[lvl][idx] |= ( (pa[1] * lvl) >> 4 ); // green
|
||||
swzpal[lvl][idx] |= ( (pa[2] * lvl) >> 4 ) << 20; // blue
|
||||
swzpal[lvl][idx] = swzpal[lvl][idx] & 0x3feffbff;
|
||||
pa += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// colormap functions
|
||||
// REMAPKEY macro defines the palette remap key
|
||||
// d = desaturate (0/1), f = fullbrights (0/1), t = top color, b = bottom color
|
||||
#define REMAPKEY(d, f, t, b) (0x1 ^ (d<<1) ^ (f<<2) ^ (t<<3) ^ (b<<7))
|
||||
#define DEREFDEFAULT -2147483647 // lowest negative 32-bit number (without MSVC being stupid)
|
||||
|
||||
void MakePaletteRemaps(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
palremapsize = d_palremapsize.value;
|
||||
|
||||
if (palremapsize < 4)
|
||||
{
|
||||
Con_Printf("Invalid size for d_palremapsize, defaulting to 4.\n");
|
||||
palremapsize = 4;
|
||||
}
|
||||
|
||||
palremaps = BZ_Malloc(sizeof(palremap_t)*palremapsize);
|
||||
|
||||
// build identity remap
|
||||
palremaps[0].r = palremaps[0].g = palremaps[0].b = 255;
|
||||
palremaps[0].key = REMAPKEY(0, 1, TOP_DEFAULT, BOTTOM_DEFAULT);
|
||||
palremaps[0].references = 999;
|
||||
for (i = 0; i < 256; i++)
|
||||
palremaps[0].pal[i] = i;
|
||||
|
||||
// build fullbright remap
|
||||
palremaps[1].r = palremaps[1].g = palremaps[1].b = 255;
|
||||
palremaps[1].key = REMAPKEY(0, 0, TOP_DEFAULT, BOTTOM_DEFAULT);
|
||||
palremaps[1].references = 999;
|
||||
for (i = 0; i < 256 - vid.fullbright; i++)
|
||||
palremaps[1].pal[i] = i;
|
||||
for (i = 256 - vid.fullbright; i < 256; i++)
|
||||
palremaps[1].pal[i] = FindIndexFromRGBNoFB(host_basepal[i*3], host_basepal[i*3+1], host_basepal[i*3+2]);
|
||||
|
||||
for (i = 2; i < palremapsize; i++)
|
||||
{
|
||||
palremaps[i].key = 0;
|
||||
palremaps[i].references = DEREFDEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
void BuildModulatedPalette(qbyte *indexes, int red, int green, int blue, qboolean desaturate, qboolean fullbrights, int topcolor, int bottomcolor)
|
||||
{
|
||||
qbyte *rgb = host_basepal;
|
||||
unsigned int r, g, b, x, invmask = 0;
|
||||
|
||||
if (red < 0 || green < 0 || blue < 0)
|
||||
invmask = 0xff;
|
||||
|
||||
// generate palette remap
|
||||
if (desaturate)
|
||||
{
|
||||
int s;
|
||||
|
||||
for (x = 0; x < 256; x++)
|
||||
{
|
||||
s = rgb[0]*76 + rgb[1]*151 + rgb[2]*29 + 128;
|
||||
r = abs((127*256 + s*red) >> 16);
|
||||
g = abs((127*256 + s*green) >> 16);
|
||||
b = abs((127*256 + s*blue) >> 16);
|
||||
|
||||
if (r > 255)
|
||||
r = 255;
|
||||
if (g > 255)
|
||||
g = 255;
|
||||
if (b > 255)
|
||||
b = 255;
|
||||
|
||||
if (fullbrights) // relying on branch prediction here...
|
||||
indexes[x] = GetPaletteIndex(r^invmask, g^invmask, b^invmask);
|
||||
else
|
||||
indexes[x] = GetPaletteNoFB(r^invmask, g^invmask, b^invmask);
|
||||
rgb += 3;
|
||||
}
|
||||
}
|
||||
else if (red == 255 && green == 255 && blue == 255)
|
||||
{
|
||||
// identity merge
|
||||
if (fullbrights)
|
||||
memcpy(indexes, identityremap.pal, sizeof(identityremap.pal));
|
||||
else
|
||||
memcpy(indexes, fullbrightremap.pal, sizeof(fullbrightremap.pal));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = 0; x < 256; x++)
|
||||
{
|
||||
// modulus math
|
||||
r = abs((127 + rgb[0]*red) >> 8);
|
||||
g = abs((127 + rgb[1]*green) >> 8);
|
||||
b = abs((127 + rgb[2]*blue) >> 8);
|
||||
|
||||
if (r > 255)
|
||||
r = 255;
|
||||
if (g > 255)
|
||||
g = 255;
|
||||
if (b > 255)
|
||||
b = 255;
|
||||
|
||||
if (fullbrights) // relying on branch prediction here...
|
||||
indexes[x] = GetPaletteIndex(r^invmask, g^invmask, b^invmask);
|
||||
else
|
||||
indexes[x] = GetPaletteNoFB(r^invmask, g^invmask, b^invmask);
|
||||
rgb += 3;
|
||||
}
|
||||
}
|
||||
|
||||
// handle top/bottom remap
|
||||
if (topcolor == TOP_DEFAULT && bottomcolor == BOTTOM_DEFAULT)
|
||||
return;
|
||||
|
||||
{
|
||||
qbyte topcolors[16];
|
||||
qbyte bottomcolors[16];
|
||||
|
||||
topcolor = topcolor * 16;
|
||||
bottomcolor = bottomcolor * 16;
|
||||
|
||||
for (x = 0; x < 16; x++)
|
||||
{
|
||||
if (topcolor < 128)
|
||||
topcolors[x] = indexes[topcolor + x];
|
||||
else
|
||||
topcolors[x] = indexes[topcolor + 15 - x];
|
||||
|
||||
if (bottomcolor < 128)
|
||||
bottomcolors[x] = indexes[bottomcolor + x];
|
||||
else
|
||||
bottomcolors[x] = indexes[bottomcolor + 15 - x];
|
||||
}
|
||||
|
||||
for (x = 0; x < 16; x++)
|
||||
{
|
||||
indexes[TOP_RANGE + x] = topcolors[x];
|
||||
indexes[BOTTOM_RANGE + x] = bottomcolors[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
palremap_t *D_GetPaletteRemap(int red, int green, int blue, qboolean desaturate, qboolean fullbrights, int topcolor, int bottomcolor)
|
||||
{
|
||||
int i, key, deref = -1, dereflast = 1;
|
||||
|
||||
topcolor = topcolor & 0xf;
|
||||
bottomcolor = bottomcolor & 0xf;
|
||||
|
||||
key = REMAPKEY(desaturate, fullbrights, topcolor, bottomcolor);
|
||||
|
||||
for (i = 0; i < palremapsize; i++)
|
||||
{
|
||||
if (palremaps[i].r == red &&
|
||||
palremaps[i].g == green &&
|
||||
palremaps[i].b == blue &&
|
||||
palremaps[i].key == key)
|
||||
{
|
||||
if (palremaps[i].references < 1)
|
||||
palremaps[i].references = 1;
|
||||
else
|
||||
palremaps[i].references++;
|
||||
return palremaps + i;
|
||||
}
|
||||
else if (palremaps[i].references < dereflast)
|
||||
{
|
||||
deref = i;
|
||||
dereflast = palremaps[i].references;
|
||||
}
|
||||
}
|
||||
|
||||
if (deref < 2) // no remaps found and all maps are referenced
|
||||
return palremaps; // identity remap
|
||||
|
||||
// return non-referenced map
|
||||
BuildModulatedPalette(palremaps[deref].pal, red, green, blue, desaturate, fullbrights, topcolor, bottomcolor);
|
||||
if (palremaps[deref].references < 1)
|
||||
palremaps[deref].references = 1;
|
||||
else
|
||||
palremaps[deref].references++;
|
||||
palremaps[deref].r = red;
|
||||
palremaps[deref].g = green;
|
||||
palremaps[deref].b = blue;
|
||||
palremaps[deref].key = key;
|
||||
return palremaps + deref;
|
||||
}
|
||||
|
||||
palremap_t *RebuildMenuTint(struct cvar_s *var)
|
||||
{
|
||||
vec3_t rgb;
|
||||
|
||||
if (var->string[0])
|
||||
SCR_StringToRGB(var->string, rgb, 1);
|
||||
else
|
||||
return NULL;
|
||||
|
||||
return D_GetPaletteRemap(rgb[0]*255, rgb[1]*255, rgb[2]*255, true, true, TOP_DEFAULT, BOTTOM_DEFAULT);
|
||||
}
|
||||
|
||||
void D_DereferenceRemap(palremap_t *palremap)
|
||||
{
|
||||
static int dereftime;
|
||||
|
||||
if (palremap && palremap >= palremaps+2)
|
||||
{
|
||||
if (palremap->references < 2)
|
||||
{
|
||||
if (dereftime >= 0)
|
||||
dereftime = DEREFDEFAULT;
|
||||
palremap->references = dereftime;
|
||||
dereftime++;
|
||||
}
|
||||
else
|
||||
palremap->references--;
|
||||
}
|
||||
}
|
||||
|
||||
void SWR_Menutint_Callback(struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
if (mtpalremap)
|
||||
D_DereferenceRemap(mtpalremap);
|
||||
|
||||
mtpalremap = RebuildMenuTint(var);
|
||||
}
|
||||
|
||||
qbyte *D_GetMenuTintPal(void)
|
||||
{
|
||||
if (mtpalremap && mtpalremap != palremaps)
|
||||
return mtpalremap->pal;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct palremap_s *D_IdentityRemap(void) // TODO: explicitly inline this
|
||||
{
|
||||
return palremaps;
|
||||
}
|
||||
|
||||
#undef REMAPKEY
|
||||
#undef DEREFDEFAULT
|
||||
|
||||
void MediaSW_ShowFrame8bit(qbyte *framedata, int inwidth, int inheight, qbyte *palette)
|
||||
{
|
||||
int y, x;
|
||||
|
||||
D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly
|
||||
if (r_pixbytes == 1)
|
||||
{
|
||||
qbyte *dest, *src;
|
||||
int lines=vid.conheight;
|
||||
int v;
|
||||
int f, fstep;
|
||||
|
||||
dest = vid.conbuffer;
|
||||
|
||||
for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
|
||||
{
|
||||
v = (vid.conheight - lines + y)*inheight/vid.conheight;
|
||||
src = framedata + v*inwidth;
|
||||
{
|
||||
f = 0;
|
||||
fstep = (inwidth<<16)/vid.conwidth;
|
||||
for (x=0 ; x<vid.conwidth ; x+=4)
|
||||
{
|
||||
dest[x] = FindPalette(palette[src[(f>>16)]*3], palette[src[(f>>16)]*3+1], palette[src[(f>>16)]*3+2]);
|
||||
f += fstep;
|
||||
dest[x+1] = FindPalette(palette[src[(f>>16)]*3], palette[src[(f>>16)]*3+1], palette[src[(f>>16)]*3+2]);
|
||||
f += fstep;
|
||||
dest[x+2] = FindPalette(palette[src[(f>>16)]*3], palette[src[(f>>16)]*3+1], palette[src[(f>>16)]*3+2]);
|
||||
f += fstep;
|
||||
dest[x+3] = FindPalette(palette[src[(f>>16)]*3], palette[src[(f>>16)]*3+1], palette[src[(f>>16)]*3+2]);
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (r_pixbytes == 2)
|
||||
{
|
||||
/* this still expects 32bit input
|
||||
extern int redbits, redshift;
|
||||
extern int greenbits, greenshift;
|
||||
extern int bluebits, blueshift;
|
||||
|
||||
unsigned short *dest;
|
||||
qbyte *src;
|
||||
int lines=vid.conheight;
|
||||
int v;
|
||||
int f, fstep;
|
||||
|
||||
dest = (unsigned short *)vid.conbuffer;
|
||||
|
||||
for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
|
||||
{
|
||||
v = (vid.conheight - lines + y)*inheight/vid.conheight;
|
||||
src = framedata + v*inwidth*4;
|
||||
{
|
||||
f = 0;
|
||||
fstep = ((inwidth)*0x10000)/vid.conwidth;
|
||||
for (x=0 ; x<vid.conwidth; x++) //sw 32 bit rendering is bgrx
|
||||
{
|
||||
dest[x] = (((src[(f>>16)*4]*(1<<redbits))/256)<<redshift) + (((src[(f>>16)*4+1]*(1<<greenbits))/256)<<greenshift) + (((src[(f>>16)*4+2]*(1<<bluebits))/256)<<blueshift);
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if (r_pixbytes == 4)
|
||||
{
|
||||
qbyte *dest, *src;
|
||||
int lines=vid.conheight;
|
||||
int v;
|
||||
int f, fstep;
|
||||
|
||||
dest = vid.conbuffer;
|
||||
|
||||
for (y=0 ; y<lines ; y++, dest += vid.conrowbytes*4)
|
||||
{
|
||||
v = (vid.conheight - lines + y)*inheight/vid.conheight;
|
||||
src = framedata + v*inwidth;
|
||||
{
|
||||
f = 0;
|
||||
fstep = ((inwidth)*0x10000)/vid.conwidth;
|
||||
for (x=0 ; x<vid.conwidth*4 ; x+=4) //sw 32 bit rendering is bgrx
|
||||
{
|
||||
dest[x] = palette[src[(f>>16)]*3+2];
|
||||
dest[x+1] = palette[src[(f>>16)]*3+1];
|
||||
dest[x+2] = palette[src[(f>>16)]*3];
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
Sys_Error("24 bit rendering?");
|
||||
|
||||
D_DisableBackBufferAccess (); // for adapters that can't stay mapped in
|
||||
|
||||
SCR_SetUpToDrawConsole();
|
||||
if (scr_con_current)
|
||||
SCR_DrawConsole (false);
|
||||
|
||||
M_Draw(0);
|
||||
}
|
||||
|
||||
void MediaSW_ShowFrameRGBA_32(qbyte *framedata, int inwidth, int inheight) //top down
|
||||
{
|
||||
int y, x;
|
||||
|
||||
D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly
|
||||
if (r_pixbytes == 1)
|
||||
{
|
||||
qbyte *dest, *src;
|
||||
int lines=vid.conheight;
|
||||
int v;
|
||||
int f, fstep;
|
||||
|
||||
dest = vid.conbuffer;
|
||||
|
||||
for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
|
||||
{
|
||||
v = (vid.conheight - lines + y)*inheight/vid.conheight;
|
||||
src = framedata + v*inwidth*4;
|
||||
{
|
||||
f = 0;
|
||||
fstep = ((inwidth)*0x10000)/vid.conwidth;
|
||||
for (x=0 ; x<vid.conwidth ; x+=4)
|
||||
{
|
||||
dest[x] = FindPalette(src[(f>>16)*4], src[(f>>16)*4+1], src[(f>>16)*4+2]);
|
||||
f += fstep;
|
||||
dest[x+1] = FindPalette(src[(f>>16)*4], src[(f>>16)*4+1], src[(f>>16)*4+2]);
|
||||
f += fstep;
|
||||
dest[x+2] = FindPalette(src[(f>>16)*4], src[(f>>16)*4+1], src[(f>>16)*4+2]);
|
||||
f += fstep;
|
||||
dest[x+3] = FindPalette(src[(f>>16)*4], src[(f>>16)*4+1], src[(f>>16)*4+2]);
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (r_pixbytes == 2)
|
||||
{
|
||||
extern int redbits, redshift;
|
||||
extern int greenbits, greenshift;
|
||||
extern int bluebits, blueshift;
|
||||
|
||||
unsigned short *dest;
|
||||
qbyte *src;
|
||||
int lines=vid.conheight;
|
||||
int v;
|
||||
int f, fstep;
|
||||
|
||||
dest = (unsigned short *)vid.conbuffer;
|
||||
|
||||
for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
|
||||
{
|
||||
v = (vid.conheight - lines + y)*inheight/vid.conheight;
|
||||
src = framedata + v*inwidth*4;
|
||||
{
|
||||
f = 0;
|
||||
fstep = ((inwidth)*0x10000)/vid.conwidth;
|
||||
for (x=0 ; x<vid.conwidth; x++) //sw 32 bit rendering is bgrx
|
||||
{
|
||||
dest[x] = (((src[(f>>16)*4]*(1<<redbits))/256)<<redshift) + (((src[(f>>16)*4+1]*(1<<greenbits))/256)<<greenshift) + (((src[(f>>16)*4+2]*(1<<bluebits))/256)<<blueshift);
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (r_pixbytes == 4)
|
||||
{
|
||||
qbyte *dest, *src;
|
||||
int lines=vid.conheight;
|
||||
int v;
|
||||
int f, fstep;
|
||||
|
||||
dest = vid.conbuffer;
|
||||
|
||||
for (y=0 ; y<lines ; y++, dest += vid.conrowbytes*4)
|
||||
{
|
||||
v = (vid.conheight - lines + y)*inheight/vid.conheight;
|
||||
src = framedata + v*inwidth*4;
|
||||
{
|
||||
f = 0;
|
||||
fstep = ((inwidth)*0x10000)/vid.conwidth;
|
||||
for (x=0 ; x<vid.conwidth*4 ; x+=4) //sw 32 bit rendering is bgrx
|
||||
{
|
||||
dest[x] = src[(f>>16)*4+2];
|
||||
dest[x+1] = src[(f>>16)*4+1];
|
||||
dest[x+2] = src[(f>>16)*4];
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
Sys_Error("24 bit rendering?");
|
||||
|
||||
D_DisableBackBufferAccess (); // for adapters that can't stay mapped in
|
||||
|
||||
SCR_SetUpToDrawConsole();
|
||||
if (scr_con_current)
|
||||
SCR_DrawConsole (false);
|
||||
}
|
||||
|
||||
void MediaSW_ShowFrameBGR_24_Flip(qbyte *framedata, int inwidth, int inheight) //input is bottom up...
|
||||
{
|
||||
int y, x;
|
||||
|
||||
D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly
|
||||
if (r_pixbytes == 1)
|
||||
{
|
||||
qbyte *dest, *src;
|
||||
int lines=vid.conheight;
|
||||
int v;
|
||||
int f, fstep;
|
||||
|
||||
dest = vid.conbuffer;
|
||||
|
||||
for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
|
||||
{
|
||||
v = (lines - y)*inheight/vid.conheight;
|
||||
src = framedata + v*inwidth*3;
|
||||
{
|
||||
f = 0;
|
||||
fstep = ((inwidth)*0x10000)/vid.conwidth;
|
||||
for (x=0 ; x<vid.conwidth ; x+=4)
|
||||
{
|
||||
dest[x] = FindPalette(src[(f>>16)*3+2], src[(f>>16)*3+1], src[(f>>16)*3]);
|
||||
f += fstep;
|
||||
dest[x+1] = FindPalette(src[(f>>16)*3+2], src[(f>>16)*3+1], src[(f>>16)*3]);
|
||||
f += fstep;
|
||||
dest[x+2] = FindPalette(src[(f>>16)*3+2], src[(f>>16)*3+1], src[(f>>16)*3]);
|
||||
f += fstep;
|
||||
dest[x+3] = FindPalette(src[(f>>16)*3+2], src[(f>>16)*3+1], src[(f>>16)*3]);
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (r_pixbytes == 2)
|
||||
{
|
||||
extern int redbits, redshift;
|
||||
extern int greenbits, greenshift;
|
||||
extern int bluebits, blueshift;
|
||||
|
||||
unsigned short *dest;
|
||||
qbyte *src;
|
||||
int lines=vid.conheight;
|
||||
int v;
|
||||
int f, fstep;
|
||||
|
||||
dest = (unsigned short *)vid.conbuffer;
|
||||
|
||||
for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
|
||||
{
|
||||
v = (lines - y)*inheight/vid.conheight;
|
||||
src = framedata + v*inwidth*3;
|
||||
{
|
||||
f = 0;
|
||||
fstep = ((inwidth)*0x10000)/vid.conwidth;
|
||||
for (x=0 ; x<vid.conwidth; x++) //sw 32 bit rendering is bgrx
|
||||
{
|
||||
dest[x] = (((src[(f>>16)*3+2]*(1<<redbits))/256)<<redshift) + (((src[(f>>16)*3+1]*(1<<greenbits))/256)<<greenshift) + (((src[(f>>16)*3+0]*(1<<bluebits))/256)<<blueshift);
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (r_pixbytes == 4)
|
||||
{
|
||||
unsigned int *dest;
|
||||
qbyte *src;
|
||||
int lines=vid.conheight;
|
||||
int v;
|
||||
int f, fstep;
|
||||
|
||||
dest = (unsigned int *)vid.conbuffer;
|
||||
|
||||
for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
|
||||
{
|
||||
v = (lines - y)*inheight/vid.conheight;
|
||||
src = framedata + v*inwidth*3;
|
||||
{
|
||||
f = 0;
|
||||
fstep = ((inwidth)*0x10000)/vid.conwidth;
|
||||
for (x=0 ; x<vid.conwidth ; x++) //sw 32 bit rendering is bgrx
|
||||
{
|
||||
*(dest+x) = *(int *)(src + (f>>16)*3);
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
Sys_Error("24 bit rendering?");
|
||||
|
||||
D_DisableBackBufferAccess (); // for adapters that can't stay mapped in
|
||||
|
||||
SCR_SetUpToDrawConsole();
|
||||
if (scr_con_current)
|
||||
SCR_DrawConsole (false);
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_vars.c: global refresh variables
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
//#if !id386
|
||||
|
||||
// all global and static refresh variables are collected in a contiguous block
|
||||
// to avoid cache conflicts.
|
||||
|
||||
//-------------------------------------------------------
|
||||
// global refresh variables
|
||||
//-------------------------------------------------------
|
||||
|
||||
// FIXME: make into one big structure, like cl or sv
|
||||
// FIXME: do separately for refresh engine and driver
|
||||
|
||||
float d_sdivzstepu, d_tdivzstepu, d_zistepu;
|
||||
float d_sdivzstepv, d_tdivzstepv, d_zistepv;
|
||||
float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
|
||||
|
||||
fixed16_t sadjust, tadjust, bbextents, bbextentt;
|
||||
|
||||
pixel_t *cacheblock;
|
||||
int cachewidth;
|
||||
int cacheheight;
|
||||
pixel_t *d_viewbuffer;
|
||||
short *d_pzbuffer;
|
||||
unsigned int d_zrowbytes;
|
||||
unsigned int d_zwidth;
|
||||
|
||||
//#endif // !id386
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// d_varsa.s
|
||||
//
|
||||
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
|
||||
//-------------------------------------------------------
|
||||
// global refresh variables
|
||||
//-------------------------------------------------------
|
||||
|
||||
// FIXME: put all refresh variables into one contiguous block. Make into one
|
||||
// big structure, like cl or sv?
|
||||
|
||||
.align 4
|
||||
.globl C(d_sdivzstepu)
|
||||
.globl C(d_tdivzstepu)
|
||||
.globl C(d_zistepu)
|
||||
.globl C(d_sdivzstepv)
|
||||
.globl C(d_tdivzstepv)
|
||||
.globl C(d_zistepv)
|
||||
.globl C(d_sdivzorigin)
|
||||
.globl C(d_tdivzorigin)
|
||||
.globl C(d_ziorigin)
|
||||
C(d_sdivzstepu): .single 0
|
||||
C(d_tdivzstepu): .single 0
|
||||
C(d_zistepu): .single 0
|
||||
C(d_sdivzstepv): .single 0
|
||||
C(d_tdivzstepv): .single 0
|
||||
C(d_zistepv): .single 0
|
||||
C(d_sdivzorigin): .single 0
|
||||
C(d_tdivzorigin): .single 0
|
||||
C(d_ziorigin): .single 0
|
||||
|
||||
.globl C(sadjust)
|
||||
.globl C(tadjust)
|
||||
.globl C(bbextents)
|
||||
.globl C(bbextentt)
|
||||
C(sadjust): .long 0
|
||||
C(tadjust): .long 0
|
||||
C(bbextents): .long 0
|
||||
C(bbextentt): .long 0
|
||||
|
||||
.globl C(cacheblock)
|
||||
.globl C(d_viewbuffer)
|
||||
.globl C(cachewidth)
|
||||
.globl C(d_pzbuffer)
|
||||
.globl C(d_zrowbytes)
|
||||
.globl C(d_zwidth)
|
||||
C(cacheblock): .long 0
|
||||
C(cachewidth): .long 0
|
||||
C(d_viewbuffer): .long 0
|
||||
C(d_pzbuffer): .long 0
|
||||
C(d_zrowbytes): .long 0
|
||||
C(d_zwidth): .long 0
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// ASM-only variables
|
||||
//-------------------------------------------------------
|
||||
.globl izi
|
||||
izi: .long 0
|
||||
|
||||
.globl pbase, s, t, sfracf, tfracf, snext, tnext
|
||||
.globl spancountminus1, zi16stepu, sdivz16stepu, tdivz16stepu
|
||||
.globl zi8stepu, sdivz8stepu, tdivz8stepu, pz
|
||||
s: .long 0
|
||||
t: .long 0
|
||||
snext: .long 0
|
||||
tnext: .long 0
|
||||
sfracf: .long 0
|
||||
tfracf: .long 0
|
||||
pbase: .long 0
|
||||
zi8stepu: .long 0
|
||||
sdivz8stepu: .long 0
|
||||
tdivz8stepu: .long 0
|
||||
zi16stepu: .long 0
|
||||
sdivz16stepu: .long 0
|
||||
tdivz16stepu: .long 0
|
||||
spancountminus1: .long 0
|
||||
pz: .long 0
|
||||
|
||||
.globl izistep
|
||||
izistep: .long 0
|
||||
|
||||
//-------------------------------------------------------
|
||||
// local variables for d_draw16.s
|
||||
//-------------------------------------------------------
|
||||
|
||||
.globl reciprocal_table_16, entryvec_table_16
|
||||
// 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13,
|
||||
// 1/14, and 1/15 in 0.32 form
|
||||
reciprocal_table_16: .long 0x40000000, 0x2aaaaaaa, 0x20000000
|
||||
.long 0x19999999, 0x15555555, 0x12492492
|
||||
.long 0x10000000, 0xe38e38e, 0xccccccc, 0xba2e8ba
|
||||
.long 0xaaaaaaa, 0x9d89d89, 0x9249249, 0x8888888
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Entry2_16
|
||||
.extern Entry3_16
|
||||
.extern Entry4_16
|
||||
.extern Entry5_16
|
||||
.extern Entry6_16
|
||||
.extern Entry7_16
|
||||
.extern Entry8_16
|
||||
.extern Entry9_16
|
||||
.extern Entry10_16
|
||||
.extern Entry11_16
|
||||
.extern Entry12_16
|
||||
.extern Entry13_16
|
||||
.extern Entry14_16
|
||||
.extern Entry15_16
|
||||
.extern Entry16_16
|
||||
#endif
|
||||
|
||||
entryvec_table_16: .long 0, Entry2_16, Entry3_16, Entry4_16
|
||||
.long Entry5_16, Entry6_16, Entry7_16, Entry8_16
|
||||
.long Entry9_16, Entry10_16, Entry11_16, Entry12_16
|
||||
.long Entry13_16, Entry14_16, Entry15_16, Entry16_16
|
||||
|
||||
//-------------------------------------------------------
|
||||
// local variables for d_parta.s
|
||||
//-------------------------------------------------------
|
||||
.globl DP_Count, DP_u, DP_v, DP_Partfac, DP_Color, DP_Pix, DP_EntryTable
|
||||
DP_Count: .long 0
|
||||
DP_u: .long 0
|
||||
DP_v: .long 0
|
||||
DP_Partfac: .single 32768.0
|
||||
DP_Color: .long 0
|
||||
DP_Pix: .long 0
|
||||
|
||||
|
||||
#ifndef NeXT
|
||||
.extern DP_1x1
|
||||
.extern DP_2x2
|
||||
.extern DP_3x3
|
||||
.extern DP_4x4
|
||||
#endif
|
||||
|
||||
DP_EntryTable: .long DP_1x1, DP_2x2, DP_3x3, DP_4x4
|
||||
|
||||
//
|
||||
// advancetable is 8 bytes, but points to the middle of that range so negative
|
||||
// offsets will work
|
||||
//
|
||||
.globl advancetable, sstep, tstep, pspantemp, counttemp, jumptemp
|
||||
advancetable: .long 0, 0
|
||||
sstep: .long 0
|
||||
tstep: .long 0
|
||||
|
||||
pspantemp: .long 0
|
||||
counttemp: .long 0
|
||||
jumptemp: .long 0
|
||||
|
||||
// 1/2, 1/3, 1/4, 1/5, 1/6, and 1/7 in 0.32 form
|
||||
.globl reciprocal_table, entryvec_table
|
||||
reciprocal_table: .long 0x40000000, 0x2aaaaaaa, 0x20000000
|
||||
.long 0x19999999, 0x15555555, 0x12492492
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Entry2_8
|
||||
.extern Entry3_8
|
||||
.extern Entry4_8
|
||||
.extern Entry5_8
|
||||
.extern Entry6_8
|
||||
.extern Entry7_8
|
||||
.extern Entry8_8
|
||||
#endif
|
||||
|
||||
entryvec_table: .long 0, Entry2_8, Entry3_8, Entry4_8
|
||||
.long Entry5_8, Entry6_8, Entry7_8, Entry8_8
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Spr8Entry2_8
|
||||
.extern Spr8Entry3_8
|
||||
.extern Spr8Entry4_8
|
||||
.extern Spr8Entry5_8
|
||||
.extern Spr8Entry6_8
|
||||
.extern Spr8Entry7_8
|
||||
.extern Spr8Entry8_8
|
||||
#endif
|
||||
|
||||
.globl spr8entryvec_table
|
||||
spr8entryvec_table: .long 0, Spr8Entry2_8, Spr8Entry3_8, Spr8Entry4_8
|
||||
.long Spr8Entry5_8, Spr8Entry6_8, Spr8Entry7_8, Spr8Entry8_8
|
||||
|
||||
#endif // id386
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// d_zpoint.c: software driver module for drawing z-buffered points
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
D_DrawZPoint
|
||||
=====================
|
||||
*/
|
||||
void D_DrawZPoint (void)
|
||||
{
|
||||
qbyte *pdest;
|
||||
short *pz;
|
||||
int izi;
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * r_zpointdesc.v) + r_zpointdesc.u;
|
||||
pdest = d_viewbuffer + d_scantable[r_zpointdesc.v] + r_zpointdesc.u;
|
||||
izi = (int)(r_zpointdesc.zi * 0x8000);
|
||||
|
||||
if (*pz <= izi)
|
||||
{
|
||||
*pz = izi;
|
||||
*pdest = r_zpointdesc.color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void D_ClearDepth(void)
|
||||
{
|
||||
memset(d_pzbuffer, 0, sizeof(*d_pzbuffer)*vid.width*vid.height);
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// nonintel.c: code for non-Intel processors only
|
||||
//
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
================
|
||||
R_Surf8Patch
|
||||
================
|
||||
*/
|
||||
void R_Surf8Patch ()
|
||||
{
|
||||
// we only patch code on Intel
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_Surf16Patch
|
||||
================
|
||||
*/
|
||||
void R_Surf16Patch ()
|
||||
{
|
||||
// we only patch code on Intel
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_SurfacePatch
|
||||
================
|
||||
*/
|
||||
void R_SurfacePatch (void)
|
||||
{
|
||||
// we only patch code on Intel
|
||||
}
|
||||
|
||||
|
||||
#endif // !id386
|
||||
|
|
@ -1,363 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_aclip.c: clip routines for drawing Alias models directly to the screen
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
#include "d_local.h"
|
||||
|
||||
static finalvert_t fv[2][8];
|
||||
static auxvert_t av[8];
|
||||
|
||||
void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av);
|
||||
void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out);
|
||||
void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out);
|
||||
void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out);
|
||||
void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out);
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_Alias_clip_z
|
||||
|
||||
pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
|
||||
================
|
||||
*/
|
||||
void R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
auxvert_t *pav0, *pav1, avout;
|
||||
|
||||
pav0 = &av[pfv0 - &fv[0][0]];
|
||||
pav1 = &av[pfv1 - &fv[0][0]];
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1])
|
||||
{
|
||||
scale = (ALIAS_Z_CLIP_PLANE - pav0->fv[2]) /
|
||||
(pav1->fv[2] - pav0->fv[2]);
|
||||
|
||||
avout.fv[0] = pav0->fv[0] + (pav1->fv[0] - pav0->fv[0]) * scale;
|
||||
avout.fv[1] = pav0->fv[1] + (pav1->fv[1] - pav0->fv[1]) * scale;
|
||||
avout.fv[2] = ALIAS_Z_CLIP_PLANE;
|
||||
|
||||
out->v[2] = pfv0->v[2] + (pfv1->v[2] - pfv0->v[2]) * scale;
|
||||
out->v[3] = pfv0->v[3] + (pfv1->v[3] - pfv0->v[3]) * scale;
|
||||
out->v[4] = pfv0->v[4] + (pfv1->v[4] - pfv0->v[4]) * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (ALIAS_Z_CLIP_PLANE - pav1->fv[2]) /
|
||||
(pav0->fv[2] - pav1->fv[2]);
|
||||
|
||||
avout.fv[0] = pav1->fv[0] + (pav0->fv[0] - pav1->fv[0]) * scale;
|
||||
avout.fv[1] = pav1->fv[1] + (pav0->fv[1] - pav1->fv[1]) * scale;
|
||||
avout.fv[2] = ALIAS_Z_CLIP_PLANE;
|
||||
|
||||
out->v[2] = pfv1->v[2] + (pfv0->v[2] - pfv1->v[2]) * scale;
|
||||
out->v[3] = pfv1->v[3] + (pfv0->v[3] - pfv1->v[3]) * scale;
|
||||
out->v[4] = pfv1->v[4] + (pfv0->v[4] - pfv1->v[4]) * scale;
|
||||
}
|
||||
|
||||
R_AliasProjectFinalVert (out, &avout);
|
||||
|
||||
if (out->v[0] < r_refdef.aliasvrect.x)
|
||||
out->flags |= ALIAS_LEFT_CLIP;
|
||||
if (out->v[1] < r_refdef.aliasvrect.y)
|
||||
out->flags |= ALIAS_TOP_CLIP;
|
||||
if (out->v[0] > r_refdef.aliasvrectright)
|
||||
out->flags |= ALIAS_RIGHT_CLIP;
|
||||
if (out->v[1] > r_refdef.aliasvrectbottom)
|
||||
out->flags |= ALIAS_BOTTOM_CLIP;
|
||||
}
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1])
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.x - pfv0->v[0]) /
|
||||
(pfv1->v[0] - pfv0->v[0]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.x - pfv1->v[0]) /
|
||||
(pfv0->v[0] - pfv1->v[0]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1])
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectright - pfv0->v[0]) /
|
||||
(pfv1->v[0] - pfv0->v[0]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectright - pfv1->v[0]) /
|
||||
(pfv0->v[0] - pfv1->v[0]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1])
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.y - pfv0->v[1]) /
|
||||
(pfv1->v[1] - pfv0->v[1]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrect.y - pfv1->v[1]) /
|
||||
(pfv0->v[1] - pfv1->v[1]);
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1])
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectbottom - pfv0->v[1]) /
|
||||
(pfv1->v[1] - pfv0->v[1]);
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (float)(r_refdef.aliasvrectbottom - pfv1->v[1]) /
|
||||
(pfv0->v[1] - pfv1->v[1]);
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
|
||||
void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) )
|
||||
{
|
||||
int i,j,k;
|
||||
int flags, oldflags;
|
||||
|
||||
j = count-1;
|
||||
k = 0;
|
||||
for (i=0 ; i<count ; j = i, i++)
|
||||
{
|
||||
oldflags = in[j].flags & flag;
|
||||
flags = in[i].flags & flag;
|
||||
|
||||
if (flags && oldflags)
|
||||
continue;
|
||||
if (oldflags ^ flags)
|
||||
{
|
||||
clip (&in[j], &in[i], &out[k]);
|
||||
out[k].flags = 0;
|
||||
if (out[k].v[0] < r_refdef.aliasvrect.x)
|
||||
out[k].flags |= ALIAS_LEFT_CLIP;
|
||||
if (out[k].v[1] < r_refdef.aliasvrect.y)
|
||||
out[k].flags |= ALIAS_TOP_CLIP;
|
||||
if (out[k].v[0] > r_refdef.aliasvrectright)
|
||||
out[k].flags |= ALIAS_RIGHT_CLIP;
|
||||
if (out[k].v[1] > r_refdef.aliasvrectbottom)
|
||||
out[k].flags |= ALIAS_BOTTOM_CLIP;
|
||||
k++;
|
||||
}
|
||||
if (!flags)
|
||||
{
|
||||
out[k] = in[i];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasClipTriangle
|
||||
================
|
||||
*/
|
||||
void R_AliasClipTriangle (mtriangle_t *ptri, void (*drawfnc) (void))
|
||||
{
|
||||
int i, k, pingpong;
|
||||
mtriangle_t mtri;
|
||||
unsigned clipflags;
|
||||
|
||||
mstvert_t tst[3]; //temp st
|
||||
|
||||
mstvert_t *pst = r_affinetridesc.pstverts;
|
||||
|
||||
|
||||
// copy vertexes and fix seam texture coordinates
|
||||
fv[0][0] = pfinalverts[ptri->xyz_index[0]];
|
||||
fv[0][1] = pfinalverts[ptri->xyz_index[1]];
|
||||
fv[0][2] = pfinalverts[ptri->xyz_index[2]];
|
||||
|
||||
fv[0][0].v[2] = pst[ptri->st_index[0]].s;
|
||||
fv[0][0].v[3] = pst[ptri->st_index[0]].t;
|
||||
|
||||
fv[0][1].v[2] = pst[ptri->st_index[1]].s;
|
||||
fv[0][1].v[3] = pst[ptri->st_index[1]].t;
|
||||
|
||||
fv[0][2].v[2] = pst[ptri->st_index[2]].s;
|
||||
fv[0][2].v[3] = pst[ptri->st_index[2]].t;
|
||||
|
||||
// clip
|
||||
clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags;
|
||||
|
||||
if (clipflags & ALIAS_Z_CLIP)
|
||||
{
|
||||
for (i=0 ; i<3 ; i++)
|
||||
av[i] = pauxverts[ptri->xyz_index[i]];
|
||||
|
||||
k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong = 1;
|
||||
clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
pingpong = 0;
|
||||
k = 3;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_LEFT_CLIP)
|
||||
{
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_LEFT_CLIP, k, R_Alias_clip_left);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_RIGHT_CLIP)
|
||||
{
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_RIGHT_CLIP, k, R_Alias_clip_right);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_BOTTOM_CLIP)
|
||||
{
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_TOP_CLIP)
|
||||
{
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_TOP_CLIP, k, R_Alias_clip_top);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
for (i=0 ; i<k ; i++)
|
||||
{
|
||||
if (fv[pingpong][i].v[0] < r_refdef.aliasvrect.x)
|
||||
fv[pingpong][i].v[0] = r_refdef.aliasvrect.x;
|
||||
else if (fv[pingpong][i].v[0] > r_refdef.aliasvrectright)
|
||||
fv[pingpong][i].v[0] = r_refdef.aliasvrectright;
|
||||
|
||||
if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y)
|
||||
fv[pingpong][i].v[1] = r_refdef.aliasvrect.y;
|
||||
else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom)
|
||||
fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom;
|
||||
|
||||
fv[pingpong][i].flags = 0;
|
||||
}
|
||||
|
||||
// draw triangles
|
||||
r_affinetridesc.ptriangles = &mtri;
|
||||
r_affinetridesc.pfinalverts = fv[pingpong];
|
||||
r_affinetridesc.pstverts = tst;
|
||||
|
||||
// FIXME: do all at once as trifan?
|
||||
mtri.xyz_index[0] = 0;
|
||||
mtri.st_index[0] = 0;
|
||||
tst[0].s = fv[pingpong][0].v[2];
|
||||
tst[0].t = fv[pingpong][0].v[3];
|
||||
|
||||
for (i=1 ; i<k-1 ; i++)
|
||||
{
|
||||
mtri.xyz_index[1] = i;
|
||||
mtri.st_index[1] = 1;
|
||||
tst[1].s = fv[pingpong][i].v[2];
|
||||
tst[1].t = fv[pingpong][i].v[3];
|
||||
|
||||
mtri.xyz_index[2] = i+1;
|
||||
mtri.st_index[2] = 2;
|
||||
tst[2].s = fv[pingpong][i+1].v[2];
|
||||
tst[2].t = fv[pingpong][i+1].v[3];
|
||||
drawfnc ();
|
||||
}
|
||||
r_affinetridesc.pstverts = pst;
|
||||
}
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// r_aliasa.s
|
||||
// x86 assembly-language Alias model transform and project code.
|
||||
//
|
||||
#define SWQUAKE
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
Ltemp0: .long 0
|
||||
Ltemp1: .long 0
|
||||
|
||||
.text
|
||||
|
||||
#define pfv0 8+4
|
||||
#define pfv1 8+8
|
||||
#define out 8+12
|
||||
|
||||
.globl C(R_Alias_clip_bottom)
|
||||
C(R_Alias_clip_bottom):
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
movl pfv0(%esp),%esi
|
||||
movl pfv1(%esp),%edi
|
||||
|
||||
movl C(r_refdef)+rd_aliasvrectbottom,%eax
|
||||
|
||||
LDoForwardOrBackward:
|
||||
|
||||
movl fv_v+4(%esi),%edx
|
||||
movl fv_v+4(%edi),%ecx
|
||||
|
||||
cmpl %ecx,%edx
|
||||
jl LDoForward
|
||||
|
||||
movl fv_v+4(%esi),%ecx
|
||||
movl fv_v+4(%edi),%edx
|
||||
movl pfv0(%esp),%edi
|
||||
movl pfv1(%esp),%esi
|
||||
|
||||
LDoForward:
|
||||
|
||||
subl %edx,%ecx
|
||||
subl %edx,%eax
|
||||
movl %ecx,Ltemp1
|
||||
movl %eax,Ltemp0
|
||||
fildl Ltemp1
|
||||
fildl Ltemp0
|
||||
movl out(%esp),%edx
|
||||
movl $2,%eax
|
||||
|
||||
fdivp %st(0),%st(1) // scale
|
||||
|
||||
LDo3Forward:
|
||||
fildl fv_v+0(%esi) // fv0v0 | scale
|
||||
fildl fv_v+0(%edi) // fv1v0 | fv0v0 | scale
|
||||
fildl fv_v+4(%esi) // fv0v1 | fv1v0 | fv0v0 | scale
|
||||
fildl fv_v+4(%edi) // fv1v1 | fv0v1 | fv1v0 | fv0v0 | scale
|
||||
fildl fv_v+8(%esi) // fv0v2 | fv1v1 | fv0v1 | fv1v0 | fv0v0 | scale
|
||||
fildl fv_v+8(%edi) // fv1v2 | fv0v2 | fv1v1 | fv0v1 | fv1v0 | fv0v0 |
|
||||
// scale
|
||||
fxch %st(5) // fv0v0 | fv0v2 | fv1v1 | fv0v1 | fv1v0 | fv1v2 |
|
||||
// scale
|
||||
fsubr %st(0),%st(4) // fv0v0 | fv0v2 | fv1v1 | fv0v1 | fv1v0-fv0v0 |
|
||||
// fv1v2 | scale
|
||||
fxch %st(3) // fv0v1 | fv0v2 | fv1v1 | fv0v0 | fv1v0-fv0v0 |
|
||||
// fv1v2 | scale
|
||||
fsubr %st(0),%st(2) // fv0v1 | fv0v2 | fv1v1-fv0v1 | fv0v0 |
|
||||
// fv1v0-fv0v0 | fv1v2 | scale
|
||||
fxch %st(1) // fv0v2 | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
// fv1v0-fv0v0 | fv1v2 | scale
|
||||
fsubr %st(0),%st(5) // fv0v2 | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
// fv1v0-fv0v0 | fv1v2-fv0v2 | scale
|
||||
fxch %st(6) // scale | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
// fv1v0-fv0v0 | fv1v2-fv0v2 | fv0v2
|
||||
fmul %st(0),%st(4) // scale | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
// (fv1v0-fv0v0)*scale | fv1v2-fv0v2 | fv0v2
|
||||
addl $12,%edi
|
||||
fmul %st(0),%st(2) // scale | fv0v1 | (fv1v1-fv0v1)*scale | fv0v0 |
|
||||
// (fv1v0-fv0v0)*scale | fv1v2-fv0v2 | fv0v2
|
||||
addl $12,%esi
|
||||
addl $12,%edx
|
||||
fmul %st(0),%st(5) // scale | fv0v1 | (fv1v1-fv0v1)*scale | fv0v0 |
|
||||
// (fv1v0-fv0v0)*scale | (fv1v2-fv0v2)*scale |
|
||||
// fv0v2
|
||||
fxch %st(3) // fv0v0 | fv0v1 | (fv1v1-fv0v1)*scale | scale |
|
||||
// (fv1v0-fv0v0)*scale | (fv1v2-fv0v2)*scale |
|
||||
// fv0v2
|
||||
faddp %st(0),%st(4) // fv0v1 | (fv1v1-fv0v1)*scale | scale |
|
||||
// fv0v0+(fv1v0-fv0v0)*scale |
|
||||
// (fv1v2-fv0v2)*scale | fv0v2
|
||||
faddp %st(0),%st(1) // fv0v1+(fv1v1-fv0v1)*scale | scale |
|
||||
// fv0v0+(fv1v0-fv0v0)*scale |
|
||||
// (fv1v2-fv0v2)*scale | fv0v2
|
||||
fxch %st(4) // fv0v2 | scale | fv0v0+(fv1v0-fv0v0)*scale |
|
||||
// (fv1v2-fv0v2)*scale | fv0v1+(fv1v1-fv0v1)*scale
|
||||
faddp %st(0),%st(3) // scale | fv0v0+(fv1v0-fv0v0)*scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale |
|
||||
// fv0v1+(fv1v1-fv0v1)*scale
|
||||
fxch %st(1) // fv0v0+(fv1v0-fv0v0)*scale | scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale |
|
||||
// fv0v1+(fv1v1-fv0v1)*scale
|
||||
fadds float_point5
|
||||
fxch %st(3) // fv0v1+(fv1v1-fv0v1)*scale | scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale |
|
||||
// fv0v0+(fv1v0-fv0v0)*scale
|
||||
fadds float_point5
|
||||
fxch %st(2) // fv0v2+(fv1v2-fv0v2)*scale | scale |
|
||||
// fv0v1+(fv1v1-fv0v1)*scale |
|
||||
// fv0v0+(fv1v0-fv0v0)*scale
|
||||
fadds float_point5
|
||||
fxch %st(3) // fv0v0+(fv1v0-fv0v0)*scale | scale |
|
||||
// fv0v1+(fv1v1-fv0v1)*scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale
|
||||
fistpl fv_v+0-12(%edx) // scale | fv0v1+(fv1v1-fv0v1)*scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale
|
||||
fxch %st(1) // fv0v1+(fv1v1-fv0v1)*scale | scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale | scale
|
||||
fistpl fv_v+4-12(%edx) // scale | fv0v2+(fv1v2-fv0v2)*scale
|
||||
fxch %st(1) // fv0v2+(fv1v2-fv0v2)*sc | scale
|
||||
fistpl fv_v+8-12(%edx) // scale
|
||||
|
||||
decl %eax
|
||||
jnz LDo3Forward
|
||||
|
||||
fstp %st(0)
|
||||
|
||||
popl %edi
|
||||
popl %esi
|
||||
|
||||
ret
|
||||
|
||||
|
||||
.globl C(R_Alias_clip_top)
|
||||
C(R_Alias_clip_top):
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
movl pfv0(%esp),%esi
|
||||
movl pfv1(%esp),%edi
|
||||
|
||||
movl C(r_refdef)+rd_aliasvrect+4,%eax
|
||||
jmp LDoForwardOrBackward
|
||||
|
||||
|
||||
|
||||
.globl C(R_Alias_clip_right)
|
||||
C(R_Alias_clip_right):
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
movl pfv0(%esp),%esi
|
||||
movl pfv1(%esp),%edi
|
||||
|
||||
movl C(r_refdef)+rd_aliasvrectright,%eax
|
||||
|
||||
LRightLeftEntry:
|
||||
|
||||
|
||||
movl fv_v+4(%esi),%edx
|
||||
movl fv_v+4(%edi),%ecx
|
||||
|
||||
cmpl %ecx,%edx
|
||||
movl fv_v+0(%esi),%edx
|
||||
|
||||
movl fv_v+0(%edi),%ecx
|
||||
jl LDoForward2
|
||||
|
||||
movl fv_v+0(%esi),%ecx
|
||||
movl fv_v+0(%edi),%edx
|
||||
movl pfv0(%esp),%edi
|
||||
movl pfv1(%esp),%esi
|
||||
|
||||
LDoForward2:
|
||||
|
||||
jmp LDoForward
|
||||
|
||||
|
||||
.globl C(R_Alias_clip_left)
|
||||
C(R_Alias_clip_left):
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
movl pfv0(%esp),%esi
|
||||
movl pfv1(%esp),%edi
|
||||
|
||||
movl C(r_refdef)+rd_aliasvrect+0,%eax
|
||||
jmp LRightLeftEntry
|
||||
|
||||
|
||||
#endif // id386
|
||||
|
|
@ -1,950 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_alias.c: routines for setting up to draw alias models
|
||||
|
||||
//changes include stvertexes now being seperatly number from the triangles.
|
||||
//this allows q2 models to be supported.
|
||||
//lerping is also available.
|
||||
|
||||
//future aims include better skin management.
|
||||
|
||||
//the asm code cannot handle alias models anymore.
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
#include "d_local.h" // FIXME: shouldn't be needed (is needed for patch
|
||||
// right now, but that should move)
|
||||
|
||||
#define Q2RF_DEPTHHACK 16 // for view weapon Z crunching
|
||||
|
||||
#define LIGHT_MIN 5 // lowest light value we'll allow, to avoid the
|
||||
// need for inner-loop light clamping
|
||||
|
||||
mtriangle_t *ptriangles;
|
||||
affinetridesc_t r_affinetridesc;
|
||||
|
||||
void *acolormap; // FIXME: should go away
|
||||
qbyte *apalremap;
|
||||
|
||||
dtrivertx_t *r_apoldverts;
|
||||
dtrivertx_t *r_apnewverts;
|
||||
vec3_t r_afrntlerp;
|
||||
vec3_t r_abacklerp;
|
||||
vec3_t r_amovelerp;
|
||||
|
||||
// TODO: these probably will go away with optimized rasterization
|
||||
mmdl_t *pmdl;
|
||||
vec3_t r_plightvec;
|
||||
int r_ambientlight;
|
||||
float r_shadelight;
|
||||
aliashdr_t *paliashdr;
|
||||
finalvert_t *pfinalverts;
|
||||
auxvert_t *pauxverts;
|
||||
static float ziscale;
|
||||
static model_t *pmodel;
|
||||
|
||||
extern int cl_playerindex;
|
||||
|
||||
static maliasskindesc_t *pskindesc;
|
||||
|
||||
int r_amodels_drawn;
|
||||
int a_skinwidth;
|
||||
int r_anumverts;
|
||||
|
||||
float aliastransform[3][4];
|
||||
|
||||
typedef struct {
|
||||
int index0;
|
||||
int index1;
|
||||
} aedge_t;
|
||||
|
||||
static aedge_t aedges[12] = {
|
||||
{0, 1}, {1, 2}, {2, 3}, {3, 0},
|
||||
{4, 5}, {5, 6}, {6, 7}, {7, 4},
|
||||
{0, 5}, {1, 4}, {2, 7}, {3, 6}
|
||||
};
|
||||
|
||||
#define NUMVERTEXNORMALS 162
|
||||
|
||||
extern float r_avertexnormals[NUMVERTEXNORMALS][3];
|
||||
|
||||
void R_AliasTransformAndProjectFinalVerts (finalvert_t *fv);//,
|
||||
//mstvert_t *pstverts);
|
||||
void R_AliasSetUpTransform (int trivial_accept);
|
||||
void R_AliasTransformVector (vec3_t in, vec3_t out);
|
||||
void R_AliasTransformFinalVert (finalvert_t *fv, auxvert_t *av,
|
||||
dtrivertx_t *pnewverts, dtrivertx_t *poldverts);//, mstvert_t *pstverts);
|
||||
void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av);
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasCheckBBox
|
||||
================
|
||||
*/
|
||||
qboolean R_AliasCheckBBox (void)
|
||||
{
|
||||
int i, flags, nframe, oframe, numv;
|
||||
aliashdr_t *pahdr;
|
||||
float zi, basepts[8][3], v0, v1, frac;
|
||||
finalvert_t *pv0, *pv1, viewpts[16];
|
||||
auxvert_t *pa0, *pa1, viewaux[16];
|
||||
maliasframedesc_t *pnewframedesc, *poldframedesc;
|
||||
qboolean zclipped, zfullyclipped;
|
||||
unsigned anyclip, allclip;
|
||||
int minz;
|
||||
float a, b;
|
||||
vec3_t min, max;
|
||||
|
||||
|
||||
// expand, rotate, and translate points into worldspace
|
||||
|
||||
currententity->trivial_accept = 0;
|
||||
pmodel = currententity->model;
|
||||
pahdr = SWMod_Extradata (pmodel);
|
||||
pmdl = (mmdl_t *)((qbyte *)pahdr + pahdr->model);
|
||||
|
||||
R_AliasSetUpTransform (0);
|
||||
|
||||
// construct the base bounding box for this frame
|
||||
nframe = currententity->framestate.g[FS_REG].frame[0];
|
||||
// TODO: don't repeat this check when drawing?
|
||||
if ((nframe >= pmdl->numframes) || (nframe < 0))
|
||||
{
|
||||
Con_DPrintf ("No such frame %d %s\n", nframe,
|
||||
pmodel->name);
|
||||
nframe = 0;
|
||||
}
|
||||
|
||||
// construct the base bounding box for this frame
|
||||
oframe = currententity->framestate.g[FS_REG].frame[1];
|
||||
// TODO: don't repeat this check when drawing?
|
||||
if ((oframe >= pmdl->numframes) || (oframe < 0))
|
||||
{
|
||||
Con_DPrintf ("No such frame %d %s\n", oframe,
|
||||
pmodel->name);
|
||||
oframe = 0;
|
||||
}
|
||||
|
||||
pnewframedesc = &pahdr->frames[nframe];
|
||||
poldframedesc = &pahdr->frames[oframe];
|
||||
|
||||
for (i = 0; i < 3; i++) //choose the most outward of the two.
|
||||
{
|
||||
a = poldframedesc->scale_origin[i] + poldframedesc->bboxmin.v[i]*poldframedesc->scale[i];
|
||||
b = pnewframedesc->scale_origin[i] + pnewframedesc->bboxmin.v[i]*pnewframedesc->scale[i];
|
||||
min[i] = a>b?b:a;
|
||||
|
||||
a = poldframedesc->scale_origin[i] + poldframedesc->bboxmax.v[i]*poldframedesc->scale[i];
|
||||
b = pnewframedesc->scale_origin[i] + pnewframedesc->bboxmax.v[i]*pnewframedesc->scale[i];
|
||||
max[i] = a>b?a:b;
|
||||
}
|
||||
|
||||
// x worldspace coordinates
|
||||
basepts[0][0] = basepts[1][0] = basepts[2][0] = basepts[3][0] = min[0];
|
||||
basepts[4][0] = basepts[5][0] = basepts[6][0] = basepts[7][0] = max[0];
|
||||
|
||||
// y worldspace coordinates
|
||||
basepts[0][1] = basepts[3][1] = basepts[5][1] = basepts[6][1] = min[1];
|
||||
basepts[1][1] = basepts[2][1] = basepts[4][1] = basepts[7][1] = max[1];
|
||||
|
||||
// z worldspace coordinates
|
||||
basepts[0][2] = basepts[1][2] = basepts[4][2] = basepts[5][2] = min[2];
|
||||
basepts[2][2] = basepts[3][2] = basepts[6][2] = basepts[7][2] = max[2];
|
||||
|
||||
zclipped = false;
|
||||
zfullyclipped = true;
|
||||
|
||||
minz = 9999;
|
||||
for (i=0; i<8 ; i++)
|
||||
{
|
||||
R_AliasTransformVector (&basepts[i][0], &viewaux[i].fv[0]);
|
||||
|
||||
if (viewaux[i].fv[2] < ALIAS_Z_CLIP_PLANE)
|
||||
{
|
||||
// we must clip points that are closer than the near clip plane
|
||||
viewpts[i].flags = ALIAS_Z_CLIP;
|
||||
zclipped = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (viewaux[i].fv[2] < minz)
|
||||
minz = viewaux[i].fv[2];
|
||||
viewpts[i].flags = 0;
|
||||
zfullyclipped = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (zfullyclipped)
|
||||
{
|
||||
return false; // everything was near-z-clipped
|
||||
}
|
||||
|
||||
numv = 8;
|
||||
|
||||
if (zclipped)
|
||||
{
|
||||
// organize points by edges, use edges to get new points (possible trivial
|
||||
// reject)
|
||||
for (i=0 ; i<12 ; i++)
|
||||
{
|
||||
// edge endpoints
|
||||
pv0 = &viewpts[aedges[i].index0];
|
||||
pv1 = &viewpts[aedges[i].index1];
|
||||
pa0 = &viewaux[aedges[i].index0];
|
||||
pa1 = &viewaux[aedges[i].index1];
|
||||
|
||||
// if one end is clipped and the other isn't, make a new point
|
||||
if (pv0->flags ^ pv1->flags)
|
||||
{
|
||||
frac = (ALIAS_Z_CLIP_PLANE - pa0->fv[2]) /
|
||||
(pa1->fv[2] - pa0->fv[2]);
|
||||
viewaux[numv].fv[0] = pa0->fv[0] +
|
||||
(pa1->fv[0] - pa0->fv[0]) * frac;
|
||||
viewaux[numv].fv[1] = pa0->fv[1] +
|
||||
(pa1->fv[1] - pa0->fv[1]) * frac;
|
||||
viewaux[numv].fv[2] = ALIAS_Z_CLIP_PLANE;
|
||||
viewpts[numv].flags = 0;
|
||||
numv++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// project the vertices that remain after clipping
|
||||
anyclip = 0;
|
||||
allclip = ALIAS_XY_CLIP_MASK;
|
||||
|
||||
// TODO: probably should do this loop in ASM, especially if we use floats
|
||||
for (i=0 ; i<numv ; i++)
|
||||
{
|
||||
// we don't need to bother with vertices that were z-clipped
|
||||
if (viewpts[i].flags & ALIAS_Z_CLIP)
|
||||
continue;
|
||||
|
||||
zi = 1.0 / viewaux[i].fv[2];
|
||||
|
||||
// FIXME: do with chop mode in ASM, or convert to float
|
||||
v0 = (viewaux[i].fv[0] * xscale * zi) + xcenter;
|
||||
v1 = (viewaux[i].fv[1] * yscale * zi) + ycenter;
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (v0 < r_refdef.fvrectx)
|
||||
flags |= ALIAS_LEFT_CLIP;
|
||||
if (v1 < r_refdef.fvrecty)
|
||||
flags |= ALIAS_TOP_CLIP;
|
||||
if (v0 > r_refdef.fvrectright)
|
||||
flags |= ALIAS_RIGHT_CLIP;
|
||||
if (v1 > r_refdef.fvrectbottom)
|
||||
flags |= ALIAS_BOTTOM_CLIP;
|
||||
|
||||
anyclip |= flags;
|
||||
allclip &= flags;
|
||||
}
|
||||
|
||||
if (allclip)
|
||||
return false; // trivial reject off one side
|
||||
|
||||
currententity->trivial_accept = !anyclip & !zclipped;
|
||||
|
||||
if (currententity->trivial_accept)
|
||||
{
|
||||
if (minz > (r_aliastransition + (pmdl->size * r_resfudge)))
|
||||
{
|
||||
currententity->trivial_accept |= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasTransformVector
|
||||
================
|
||||
*/
|
||||
void R_AliasTransformVector (vec3_t in, vec3_t out)
|
||||
{
|
||||
out[0] = DotProduct(in, aliastransform[0]) + aliastransform[0][3];
|
||||
out[1] = DotProduct(in, aliastransform[1]) + aliastransform[1][3];
|
||||
out[2] = DotProduct(in, aliastransform[2]) + aliastransform[2][3];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasPreparePoints
|
||||
|
||||
General clipped case
|
||||
================
|
||||
*/
|
||||
mstvert_t *stc;
|
||||
mtriangle_t *tn;
|
||||
void R_AliasPreparePoints (void)
|
||||
{
|
||||
void (*drawfnc) (void);
|
||||
int i;
|
||||
mstvert_t *pstverts;
|
||||
finalvert_t *fv;
|
||||
auxvert_t *av;
|
||||
mtriangle_t *ptri;
|
||||
finalvert_t *pfv[3];
|
||||
|
||||
r_anumverts = pmdl->numverts;
|
||||
fv = pfinalverts;
|
||||
av = pauxverts;
|
||||
|
||||
if (r_pixbytes == 4)
|
||||
drawfnc = D_PolysetDraw32;
|
||||
else if (r_pixbytes == 2)
|
||||
drawfnc = D_PolysetDraw16;
|
||||
else
|
||||
{
|
||||
#if id386
|
||||
drawfnc = D_PolysetDrawAsm;
|
||||
#else
|
||||
drawfnc = D_PolysetDrawC;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i=0 ; i<r_anumverts ; i++, fv++, av++, r_apnewverts++, r_apoldverts++)
|
||||
{
|
||||
R_AliasTransformFinalVert (fv, av, r_apnewverts, r_apoldverts);
|
||||
if (av->fv[2] < ALIAS_Z_CLIP_PLANE)
|
||||
fv->flags |= ALIAS_Z_CLIP;
|
||||
else
|
||||
{
|
||||
R_AliasProjectFinalVert (fv, av);
|
||||
|
||||
if (fv->v[0] < r_refdef.aliasvrect.x)
|
||||
fv->flags |= ALIAS_LEFT_CLIP;
|
||||
if (fv->v[1] < r_refdef.aliasvrect.y)
|
||||
fv->flags |= ALIAS_TOP_CLIP;
|
||||
if (fv->v[0] > r_refdef.aliasvrectright)
|
||||
fv->flags |= ALIAS_RIGHT_CLIP;
|
||||
if (fv->v[1] > r_refdef.aliasvrectbottom)
|
||||
fv->flags |= ALIAS_BOTTOM_CLIP;
|
||||
}
|
||||
}
|
||||
|
||||
stc = pstverts = (mstvert_t *)((qbyte *)paliashdr + paliashdr->stverts);
|
||||
//
|
||||
// clip and draw all triangles
|
||||
//
|
||||
r_affinetridesc.numtriangles = 1;
|
||||
|
||||
ptri = (mtriangle_t *)((qbyte *)paliashdr + paliashdr->triangles);
|
||||
for (i=0 ; i<pmdl->numtris ; i++, ptri++)
|
||||
{
|
||||
pfv[0] = &pfinalverts[ptri->xyz_index[0]];
|
||||
pfv[1] = &pfinalverts[ptri->xyz_index[1]];
|
||||
pfv[2] = &pfinalverts[ptri->xyz_index[2]];
|
||||
|
||||
if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags & (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP) )
|
||||
continue; // completely clipped
|
||||
|
||||
if ( ! ( (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) &
|
||||
(ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP) ) )
|
||||
{ // totally unclipped
|
||||
r_affinetridesc.pfinalverts = pfinalverts;
|
||||
r_affinetridesc.ptriangles = ptri;
|
||||
|
||||
drawfnc ();
|
||||
}
|
||||
else
|
||||
{ // partially clipped
|
||||
R_AliasClipTriangle (ptri, drawfnc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasSetUpTransform
|
||||
================
|
||||
*/
|
||||
void R_AliasSetUpTransform (int trivial_accept)
|
||||
{
|
||||
int i;
|
||||
float rotationmatrix[3][4], t2matrix[3][4];
|
||||
static float viewmatrix[3][4];
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
rotationmatrix[i][0] = currententity->axis[0][i]*currententity->scale;
|
||||
rotationmatrix[i][1] = currententity->axis[1][i]*currententity->scale;
|
||||
rotationmatrix[i][2] = currententity->axis[2][i]*currententity->scale;
|
||||
}
|
||||
|
||||
rotationmatrix[0][3] = -modelorg[0];
|
||||
rotationmatrix[1][3] = -modelorg[1];
|
||||
rotationmatrix[2][3] = -modelorg[2];
|
||||
|
||||
|
||||
// TODO: should be global, set when vright, etc., set
|
||||
VectorCopy (vright, viewmatrix[0]);
|
||||
VectorCopy (vup, viewmatrix[1]);
|
||||
VectorInverse (viewmatrix[1]);
|
||||
VectorCopy (vpn, viewmatrix[2]);
|
||||
|
||||
// viewmatrix[0][3] = 0;
|
||||
// viewmatrix[1][3] = 0;
|
||||
// viewmatrix[2][3] = 0;
|
||||
|
||||
if (currententity->flags & Q2RF_WEAPONMODEL)
|
||||
{ //rotate viewmodel to view first
|
||||
float vmmatrix[3][4];
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
t2matrix[i][0] = cl.viewent[r_refdef.currentplayernum].axis[0][i];
|
||||
t2matrix[i][1] = cl.viewent[r_refdef.currentplayernum].axis[1][i];
|
||||
t2matrix[i][2] = cl.viewent[r_refdef.currentplayernum].axis[2][i];
|
||||
}
|
||||
|
||||
t2matrix[0][3] = cl.viewent[r_refdef.currentplayernum].origin[0];
|
||||
t2matrix[1][3] = cl.viewent[r_refdef.currentplayernum].origin[1];
|
||||
t2matrix[2][3] = cl.viewent[r_refdef.currentplayernum].origin[2];
|
||||
|
||||
R_ConcatTransforms (rotationmatrix, t2matrix, vmmatrix);
|
||||
R_ConcatTransforms (viewmatrix, vmmatrix, aliastransform);
|
||||
}
|
||||
else
|
||||
R_ConcatTransforms (viewmatrix, rotationmatrix, aliastransform);
|
||||
|
||||
|
||||
// do the scaling up of x and y to screen coordinates as part of the transform
|
||||
// for the unclipped case (it would mess up clipping in the clipped case).
|
||||
// Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y
|
||||
// correspondingly so the projected x and y come out right
|
||||
// FIXME: make this work for clipped case too?
|
||||
if (trivial_accept)
|
||||
{
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
aliastransform[0][i] *= aliasxscale *
|
||||
(1.0 / ((float)0x8000 * 0x10000));
|
||||
aliastransform[1][i] *= aliasyscale *
|
||||
(1.0 / ((float)0x8000 * 0x10000));
|
||||
aliastransform[2][i] *= 1.0 / ((float)0x8000 * 0x10000);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasTransformFinalVert
|
||||
================
|
||||
*/
|
||||
void R_AliasTransformFinalVert (finalvert_t *fv, auxvert_t *av,
|
||||
dtrivertx_t *pnewverts, dtrivertx_t *poldverts)//, mstvert_t *pstverts)
|
||||
{
|
||||
int temp;
|
||||
float lightcos, *plightnormal;
|
||||
|
||||
vec3_t lerp_org;
|
||||
|
||||
lerp_org[0] = r_amovelerp[0] + pnewverts->v[0]*r_afrntlerp[0] + poldverts->v[0]*r_abacklerp[0];
|
||||
lerp_org[1] = r_amovelerp[1] + pnewverts->v[1]*r_afrntlerp[1] + poldverts->v[1]*r_abacklerp[1];
|
||||
lerp_org[2] = r_amovelerp[2] + pnewverts->v[2]*r_afrntlerp[2] + poldverts->v[2]*r_abacklerp[2];
|
||||
|
||||
av->fv[0] = DotProduct(lerp_org, aliastransform[0]) +
|
||||
aliastransform[0][3];
|
||||
av->fv[1] = DotProduct(lerp_org, aliastransform[1]) +
|
||||
aliastransform[1][3];
|
||||
av->fv[2] = DotProduct(lerp_org, aliastransform[2]) +
|
||||
aliastransform[2][3];
|
||||
|
||||
fv->v[2] = 0;
|
||||
fv->v[3] = 0;
|
||||
|
||||
fv->flags = 0;
|
||||
|
||||
// lighting
|
||||
plightnormal = r_avertexnormals[pnewverts->lightnormalindex];
|
||||
lightcos = DotProduct (plightnormal, r_plightvec);
|
||||
temp = r_ambientlight;
|
||||
|
||||
if (lightcos < 0)
|
||||
{
|
||||
temp += (int)(r_shadelight * lightcos);
|
||||
|
||||
// clamp; because we limited the minimum ambient and shading light, we
|
||||
// don't have to clamp low light, just bright
|
||||
if (temp < 0)
|
||||
temp = 0;
|
||||
}
|
||||
|
||||
fv->v[4] = temp;
|
||||
}
|
||||
|
||||
|
||||
//#if !id386 //since stvert_t was changed.
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasTransformAndProjectFinalVerts
|
||||
================
|
||||
*/
|
||||
void R_AliasTransformAndProjectFinalVerts (finalvert_t *fv)//, stvert_t *pstverts)
|
||||
{
|
||||
int i, temp;
|
||||
float lightcos, *plightnormal, zi;
|
||||
dtrivertx_t *pnewverts, *poldverts;
|
||||
|
||||
vec3_t lerp_org;
|
||||
|
||||
pnewverts = r_apnewverts;
|
||||
poldverts = r_apoldverts;
|
||||
|
||||
for (i=0 ; i<r_anumverts ; i++, fv++, pnewverts++, poldverts++)
|
||||
{
|
||||
lerp_org[0] = r_amovelerp[0] + pnewverts->v[0]*r_afrntlerp[0] + poldverts->v[0]*r_abacklerp[0];
|
||||
lerp_org[1] = r_amovelerp[1] + pnewverts->v[1]*r_afrntlerp[1] + poldverts->v[1]*r_abacklerp[1];
|
||||
lerp_org[2] = r_amovelerp[2] + pnewverts->v[2]*r_afrntlerp[2] + poldverts->v[2]*r_abacklerp[2];
|
||||
|
||||
// transform and project
|
||||
zi = 1.0 / (DotProduct(lerp_org, aliastransform[2]) +
|
||||
aliastransform[2][3]);
|
||||
|
||||
// x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is
|
||||
// scaled up by 1/2**31, and the scaling cancels out for x and y in the
|
||||
// projection
|
||||
fv->v[5] = zi;
|
||||
|
||||
fv->v[0] = ((DotProduct(lerp_org, aliastransform[0]) +
|
||||
aliastransform[0][3]) * zi) + aliasxcenter;
|
||||
fv->v[1] = ((DotProduct(lerp_org, aliastransform[1]) +
|
||||
aliastransform[1][3]) * zi) + aliasycenter;
|
||||
|
||||
fv->v[2] = 0;//pstverts->s;
|
||||
fv->v[3] = 0;//pstverts->t;
|
||||
fv->flags = 0;
|
||||
|
||||
// lighting
|
||||
plightnormal = r_avertexnormals[pnewverts->lightnormalindex]; //don't bother lerping light.
|
||||
lightcos = DotProduct (plightnormal, r_plightvec);
|
||||
temp = r_ambientlight;
|
||||
|
||||
if (lightcos < 0)
|
||||
{
|
||||
temp += (int)(r_shadelight * lightcos);
|
||||
|
||||
// clamp; because we limited the minimum ambient and shading light, we
|
||||
// don't have to clamp low light, just bright
|
||||
if (temp < 0)
|
||||
temp = 0;
|
||||
}
|
||||
|
||||
fv->v[4] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
//#endif
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasProjectFinalVert
|
||||
================
|
||||
*/
|
||||
void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av)
|
||||
{
|
||||
float zi;
|
||||
|
||||
// project points
|
||||
zi = 1.0 / av->fv[2];
|
||||
|
||||
fv->v[5] = zi * ziscale;
|
||||
|
||||
fv->v[0] = (av->fv[0] * aliasxscale * zi) + aliasxcenter;
|
||||
fv->v[1] = (av->fv[1] * aliasyscale * zi) + aliasycenter;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasPrepareUnclippedPoints
|
||||
================
|
||||
*/
|
||||
void R_AliasPrepareUnclippedPoints (void)
|
||||
{
|
||||
r_anumverts = pmdl->numverts;
|
||||
|
||||
R_AliasTransformAndProjectFinalVerts (pfinalverts);
|
||||
/*
|
||||
if (r_affinetridesc.drawtype)
|
||||
{
|
||||
if (r_pixbytes == 4)
|
||||
D_PolysetDrawFinalVerts32Trans (pfinalverts, r_anumverts);
|
||||
else if (r_pixbytes == 2)
|
||||
D_PolysetDrawFinalVerts16C (pfinalverts, r_anumverts);
|
||||
#if 0//id386
|
||||
else if (t_state & TT_ONE)
|
||||
D_PolysetDrawFinalVertsAsm (pfinalverts, r_anumverts);
|
||||
#endif
|
||||
else
|
||||
D_PolysetDrawFinalVertsC (pfinalverts, r_anumverts);
|
||||
}
|
||||
*/
|
||||
r_affinetridesc.pfinalverts = pfinalverts;
|
||||
r_affinetridesc.ptriangles = (mtriangle_t *)
|
||||
((qbyte *)paliashdr + paliashdr->triangles);
|
||||
r_affinetridesc.numtriangles = pmdl->numtris;
|
||||
|
||||
if (r_pixbytes == 4)
|
||||
D_PolysetDraw32 ();
|
||||
#if 0//id386
|
||||
else if (t_state & TT_ONE)
|
||||
D_PolysetDrawAsm ();
|
||||
#endif
|
||||
else
|
||||
D_PolysetDrawC ();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_AliasSetupSkin
|
||||
===============
|
||||
*/
|
||||
void R_AliasSetupSkin (void)
|
||||
{
|
||||
int skinnum;
|
||||
int i, numskins;
|
||||
maliasskingroup_t *paliasskingroup;
|
||||
float *pskinintervals, fullskininterval;
|
||||
float skintargettime, skintime;
|
||||
|
||||
skinnum = currententity->skinnum;
|
||||
if ((skinnum >= pmdl->numskins) || (skinnum < 0))
|
||||
{
|
||||
Con_DPrintf ("R_AliasSetupSkin: no such skin # %d\n", skinnum);
|
||||
skinnum = 0;
|
||||
}
|
||||
|
||||
pskindesc = ((maliasskindesc_t *)
|
||||
((qbyte *)paliashdr + paliashdr->skindesc)) + skinnum;
|
||||
a_skinwidth = pmdl->skinwidth;
|
||||
|
||||
if (pskindesc->type == ALIAS_SKIN_GROUP)
|
||||
{
|
||||
paliasskingroup = (maliasskingroup_t *)((qbyte *)paliashdr +
|
||||
pskindesc->skin);
|
||||
pskinintervals = (float *)
|
||||
((qbyte *)paliashdr + paliasskingroup->intervals);
|
||||
numskins = paliasskingroup->numskins;
|
||||
fullskininterval = pskinintervals[numskins-1];
|
||||
|
||||
skintime = cl.time;// + currententity->syncbase;
|
||||
|
||||
// when loading in Mod_LoadAliasSkinGroup, we guaranteed all interval
|
||||
// values are positive, so we don't have to worry about division by 0
|
||||
skintargettime = skintime -
|
||||
((int)(skintime / fullskininterval)) * fullskininterval;
|
||||
|
||||
for (i=0 ; i<(numskins-1) ; i++)
|
||||
{
|
||||
if (pskinintervals[i] > skintargettime)
|
||||
break;
|
||||
}
|
||||
|
||||
pskindesc = &paliasskingroup->skindescs[i];
|
||||
}
|
||||
|
||||
r_affinetridesc.pskindesc = pskindesc;
|
||||
r_affinetridesc.pskin = (void *)((qbyte *)paliashdr + pskindesc->skin);
|
||||
r_affinetridesc.skinwidth = a_skinwidth;
|
||||
r_affinetridesc.skinheight = pmdl->skinheight;
|
||||
|
||||
if (currententity->model != cl.model_precache[cl_playerindex])
|
||||
return;
|
||||
//alternate player skins.
|
||||
if (currententity->scoreboard && r_pixbytes == 1)
|
||||
{
|
||||
qbyte *base;
|
||||
skin_t *skin;
|
||||
|
||||
if (!currententity->scoreboard->skin)
|
||||
Skin_Find (currententity->scoreboard);
|
||||
base = Skin_Cache8 (currententity->scoreboard->skin);
|
||||
skin = currententity->scoreboard->skin;
|
||||
if (base && skin->cachedbpp == r_pixbytes*8)
|
||||
{
|
||||
r_affinetridesc.pskin = base;
|
||||
r_affinetridesc.skinwidth = skin->width;
|
||||
r_affinetridesc.skinheight = skin->height;
|
||||
}
|
||||
}
|
||||
else if (currententity->scoreboard && r_pixbytes == 4)
|
||||
{
|
||||
qbyte *base;
|
||||
skin_t *skin;
|
||||
|
||||
if (!currententity->scoreboard->skin)
|
||||
Skin_Find (currententity->scoreboard);
|
||||
base = Skin_Cache32 (currententity->scoreboard->skin);
|
||||
skin = currententity->scoreboard->skin;
|
||||
if (base && skin->cachedbpp == r_pixbytes*8)
|
||||
{
|
||||
r_affinetridesc.pskin = base;
|
||||
r_affinetridesc.skinwidth = skin->width;
|
||||
r_affinetridesc.skinheight = skin->height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasSetupLighting
|
||||
================
|
||||
*/
|
||||
void R_AliasSetupLighting (alight_t *plighting)
|
||||
{
|
||||
|
||||
if (r_pixbytes == 4)
|
||||
{ //fixes inverse lighting in sw 32.
|
||||
//we fix it here so the lighting code doesn't have to have lots of extra minuses, as they are multiplied out
|
||||
plighting->ambientlight=(128-plighting->ambientlight);
|
||||
plighting->shadelight=(128-plighting->shadelight);
|
||||
}
|
||||
|
||||
// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have
|
||||
// to clamp off the bottom
|
||||
r_ambientlight = plighting->ambientlight;
|
||||
|
||||
r_shadelight = plighting->shadelight;
|
||||
|
||||
if (r_ambientlight < LIGHT_MIN)
|
||||
r_ambientlight = LIGHT_MIN;
|
||||
|
||||
r_ambientlight = (255 - r_ambientlight) << VID_CBITS;
|
||||
|
||||
if (r_ambientlight < LIGHT_MIN)
|
||||
r_ambientlight = LIGHT_MIN;
|
||||
|
||||
if (r_shadelight < 0)
|
||||
r_shadelight = 0;
|
||||
|
||||
r_shadelight *= VID_GRADES;
|
||||
|
||||
// rotate the lighting vector into the model's frame of reference
|
||||
r_plightvec[0] = DotProduct (plighting->plightvec, currententity->axis[0]);
|
||||
r_plightvec[1] = DotProduct (plighting->plightvec, currententity->axis[1]);
|
||||
r_plightvec[2] = DotProduct (plighting->plightvec, currententity->axis[2]);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_AliasSetupFrame
|
||||
|
||||
set r_apverts
|
||||
=================
|
||||
*/
|
||||
void R_AliasSetupFrame (void)
|
||||
{
|
||||
int frame, oframe;
|
||||
int i, numframes;
|
||||
maliasgroup_t *paliasgroup;
|
||||
float *pintervals, fullinterval, targettime, time;
|
||||
|
||||
// float *min1, *min2;
|
||||
// vec3_t max1, max2;
|
||||
float fl, bl;
|
||||
|
||||
frame = currententity->framestate.g[FS_REG].frame[0];
|
||||
if ((frame >= pmdl->numframes) || (frame < 0))
|
||||
{
|
||||
Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
|
||||
frame = 0;
|
||||
}
|
||||
oframe = currententity->framestate.g[FS_REG].frame[1];
|
||||
if ((oframe >= pmdl->numframes) || (oframe < 0))
|
||||
{
|
||||
// Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", oframe); //pointless
|
||||
oframe = 0;
|
||||
}
|
||||
|
||||
bl = currententity->framestate.g[FS_REG].lerpfrac;
|
||||
if (bl < 0)
|
||||
bl = 0;
|
||||
else if (bl > 1)
|
||||
bl = 1;
|
||||
fl = 1.0 - bl;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
r_abacklerp[i] = paliashdr->frames[oframe].scale[i]*bl;
|
||||
r_afrntlerp[i] = paliashdr->frames[frame].scale[i]*fl;
|
||||
r_amovelerp[i] = paliashdr->frames[frame].scale_origin[i]*fl + paliashdr->frames[oframe].scale_origin[i]*bl;
|
||||
}
|
||||
|
||||
if (paliashdr->frames[frame].type == ALIAS_SINGLE)
|
||||
{
|
||||
r_apnewverts = (dtrivertx_t *)
|
||||
((qbyte *)paliashdr + paliashdr->frames[frame].frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
paliasgroup = (maliasgroup_t *)
|
||||
((qbyte *)paliashdr + paliashdr->frames[frame].frame);
|
||||
pintervals = (float *)((qbyte *)paliashdr + paliasgroup->intervals);
|
||||
numframes = paliasgroup->numframes;
|
||||
fullinterval = pintervals[numframes-1];
|
||||
|
||||
time = currententity->framestate.g[FS_REG].frametime[0];
|
||||
|
||||
//
|
||||
// when loading in Mod_LoadAliasGroup, we guaranteed all interval values
|
||||
// are positive, so we don't have to worry about division by 0
|
||||
//
|
||||
targettime = time - ((int)(time / fullinterval)) * fullinterval;
|
||||
|
||||
for (i=0 ; i<(numframes-1) ; i++)
|
||||
{
|
||||
if (pintervals[i] > targettime)
|
||||
break;
|
||||
}
|
||||
|
||||
r_apnewverts = (dtrivertx_t *)
|
||||
((qbyte *)paliashdr + paliasgroup->frames[i].frame);
|
||||
}
|
||||
|
||||
if (paliashdr->frames[oframe].type == ALIAS_SINGLE) //things could go haywire here...
|
||||
{
|
||||
r_apoldverts = (dtrivertx_t *)
|
||||
((qbyte *)paliashdr + paliashdr->frames[oframe].frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
paliasgroup = (maliasgroup_t *)
|
||||
((qbyte *)paliashdr + paliashdr->frames[oframe].frame);
|
||||
pintervals = (float *)((qbyte *)paliashdr + paliasgroup->intervals);
|
||||
numframes = paliasgroup->numframes;
|
||||
fullinterval = pintervals[numframes-1];
|
||||
|
||||
time = currententity->framestate.g[FS_REG].frametime[1];
|
||||
|
||||
//
|
||||
// when loading in Mod_LoadAliasGroup, we guaranteed all interval values
|
||||
// are positive, so we don't have to worry about division by 0
|
||||
//
|
||||
targettime = time - ((int)(time / fullinterval)) * fullinterval;
|
||||
|
||||
for (i=0 ; i<(numframes-1) ; i++)
|
||||
{
|
||||
if (pintervals[i] > targettime)
|
||||
break;
|
||||
}
|
||||
|
||||
r_apoldverts = (dtrivertx_t *)
|
||||
((qbyte *)paliashdr + paliasgroup->frames[i].frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_AliasDrawModel
|
||||
================
|
||||
*/
|
||||
void R_AliasDrawModel (alight_t *plighting)
|
||||
{
|
||||
finalvert_t finalverts[MAXALIASVERTS +
|
||||
((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 1];
|
||||
auxvert_t auxverts[MAXALIASVERTS];
|
||||
|
||||
extern qbyte transfactor;
|
||||
extern qbyte transbackfac;
|
||||
|
||||
if (r_pixbytes == 1)
|
||||
{
|
||||
if (currententity->shaderRGBAf[3] < TRANS_LOWER_CAP)
|
||||
return;
|
||||
|
||||
if (currententity->shaderRGBAf[3] > TRANS_UPPER_CAP)
|
||||
{
|
||||
transbackfac = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_SetTransLevel(currententity->shaderRGBAf[3], BM_BLEND);
|
||||
transbackfac = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
transfactor = currententity->shaderRGBAf[3]*255;
|
||||
transbackfac = 255 - transfactor;
|
||||
}
|
||||
|
||||
r_amodels_drawn++;
|
||||
|
||||
// cache align
|
||||
pfinalverts = (finalvert_t *)
|
||||
(((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
||||
pauxverts = &auxverts[0];
|
||||
|
||||
paliashdr = (aliashdr_t *)SWMod_Extradata (currententity->model);
|
||||
pmdl = (mmdl_t *)((qbyte *)paliashdr + paliashdr->model);
|
||||
|
||||
R_AliasSetupSkin ();
|
||||
R_AliasSetUpTransform (currententity->trivial_accept);
|
||||
R_AliasSetupLighting (plighting);
|
||||
R_AliasSetupFrame ();
|
||||
|
||||
if (!currententity->palremap)
|
||||
currententity->palremap = D_IdentityRemap();
|
||||
// Sys_Error ("R_AliasDrawModel: !currententity->colormap");
|
||||
|
||||
r_affinetridesc.drawtype = (currententity->trivial_accept == 3) &&
|
||||
r_recursiveaffinetriangles;
|
||||
|
||||
r_affinetridesc.pstverts = (mstvert_t *)((qbyte *)paliashdr + paliashdr->stverts);
|
||||
|
||||
apalremap = currententity->palremap->pal;
|
||||
acolormap = vid.colormap;
|
||||
if (r_pixbytes == 2)
|
||||
acolormap = vid.colormap16;
|
||||
|
||||
if (r_affinetridesc.drawtype)
|
||||
{
|
||||
D_PolysetUpdateTables (); // FIXME: precalc...
|
||||
}
|
||||
else
|
||||
{
|
||||
#if id386
|
||||
D_Aff8Patch (acolormap, apalremap);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (currententity == &cl.viewent[r_refdef.currentplayernum] || currententity->flags & Q2RF_DEPTHHACK)
|
||||
ziscale = (float)0x8000 * (float)0x10000 * 3.0;
|
||||
else
|
||||
ziscale = (float)0x8000 * (float)0x10000;
|
||||
|
||||
if (currententity->trivial_accept)
|
||||
R_AliasPrepareUnclippedPoints ();
|
||||
else
|
||||
R_AliasPreparePoints ();
|
||||
}
|
||||
|
|
@ -1,244 +0,0 @@
|
|||
/*
|
||||
r_aliasa.S
|
||||
|
||||
(description)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
// r_aliasa.s
|
||||
// x86 assembly-language Alias model transform and project code.
|
||||
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if 0 //def id386
|
||||
|
||||
.data
|
||||
|
||||
Lfloat_1: .single 1.0
|
||||
Ltemp: .long 0
|
||||
Lcoords: .long 0, 0, 0
|
||||
|
||||
.text
|
||||
|
||||
#define fv 12+4
|
||||
#define pstverts 12+8
|
||||
|
||||
.globl C(R_AliasTransformAndProjectFinalVerts)
|
||||
C(R_AliasTransformAndProjectFinalVerts):
|
||||
// pushl %ebp //Spike was here. // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
|
||||
// int i, temp;
|
||||
// float lightcos, *plightnormal, zi;
|
||||
// trivertx_t *pverts;
|
||||
|
||||
// pverts = r_apnewverts;
|
||||
movl C(r_apnewverts),%esi
|
||||
|
||||
// for (i=0 ; i<r_anumverts ; i++, fv++, pverts++, pstverts++)
|
||||
// {
|
||||
// movl pstverts(%esp),%ebp //Spike was here.
|
||||
movl fv(%esp),%edi
|
||||
movl C(r_anumverts),%ecx
|
||||
subl %edx,%edx
|
||||
|
||||
Lloop:
|
||||
|
||||
// // transform and project
|
||||
// zi = 1.0 / (DotProduct(pverts->v, aliastransform[2]) +
|
||||
// aliastransform[2][3]);
|
||||
movb (%esi),%dl
|
||||
movb %dl,Lcoords
|
||||
fildl Lcoords // v[0]
|
||||
movb 1(%esi),%dl
|
||||
movb %dl,Lcoords+4
|
||||
fildl Lcoords+4 // v[1] | v[0]
|
||||
movb 2(%esi),%dl
|
||||
movb %dl,Lcoords+8
|
||||
fildl Lcoords+8 // v[2] | v[1] | v[0]
|
||||
|
||||
fld %st(2) // v[0] | v[2] | v[1] | v[0]
|
||||
fmuls C(aliastransform)+32 // accum | v[2] | v[1] | v[0]
|
||||
fld %st(2) // v[1] | accum | v[2] | v[1] | v[0]
|
||||
fmuls C(aliastransform)+36 // accum2 | accum | v[2] | v[1] | v[0]
|
||||
fxch %st(1) // accum | accum2 | v[2] | v[1] | v[0]
|
||||
fadds C(aliastransform)+44 // accum | accum2 | v[2] | v[1] | v[0]
|
||||
fld %st(2) // v[2] | accum | accum2 | v[2] | v[1] | v[0]
|
||||
fmuls C(aliastransform)+40 // accum3 | accum | accum2 | v[2] | v[1] |
|
||||
// v[0]
|
||||
fxch %st(1) // accum | accum3 | accum2 | v[2] | v[1] | v[0]
|
||||
faddp %st(0),%st(2) // accum3 | accum | v[2] | v[1] | v[0]
|
||||
movb tv_lightnormalindex(%esi),%dl
|
||||
// movl stv_s(%ebp),%eax //Spike was here.
|
||||
// movl %eax,fv_v+8(%edi) //Spike was here.
|
||||
movl $0,fv_v+8(%edi) //Spike was here.
|
||||
faddp %st(0),%st(1) // z | v[2] | v[1] | v[0]
|
||||
|
||||
// movl stv_t(%ebp),%eax //Spike was here.
|
||||
// movl %eax,fv_v+12(%edi) //Spike was here.
|
||||
movl $0,fv_v+12(%edi) //Spike was here.
|
||||
|
||||
// // lighting
|
||||
// plightnormal = r_avertexnormals[pverts->lightnormalindex];
|
||||
|
||||
fdivrs Lfloat_1 // zi | v[2] | v[1] | v[0]
|
||||
|
||||
// fv->v[2] = pstverts->s;
|
||||
// fv->v[3] = pstverts->t;
|
||||
// fv->flags = pstverts->onseam;
|
||||
// movl stv_onseam(%ebp),%eax //Spike was here.
|
||||
// movl %eax,fv_flags(%edi) //Spike was here.
|
||||
movl $0,fv_flags(%edi) //Spike was here.
|
||||
|
||||
// movl fv_size(%edi),%eax //Spike was here.
|
||||
// movl stv_size(%ebp),%eax //Spike was here.
|
||||
movl 4(%esi),%eax
|
||||
|
||||
leal (%edx,%edx,2),%eax // index*3
|
||||
|
||||
fxch %st(3) // v[0] | v[2] | v[1] | zi
|
||||
|
||||
// lightcos = DotProduct (plightnormal, r_plightvec);
|
||||
flds C(r_avertexnormals)(,%eax,4)
|
||||
fmuls C(r_plightvec)
|
||||
flds C(r_avertexnormals)+4(,%eax,4)
|
||||
fmuls C(r_plightvec)+4
|
||||
flds C(r_avertexnormals)+8(,%eax,4)
|
||||
fmuls C(r_plightvec)+8
|
||||
fxch %st(1)
|
||||
faddp %st(0),%st(2)
|
||||
fld %st(2) // v[0] | laccum | laccum2 | v[0] | v[2] |
|
||||
// v[1] | zi
|
||||
fmuls C(aliastransform)+0 // xaccum | laccum | laccum2 | v[0] | v[2] |
|
||||
// v[1] | zi
|
||||
fxch %st(2) // laccum2 | laccum | xaccum | v[0] | v[2] |
|
||||
// v[1] | zi
|
||||
faddp %st(0),%st(1) // laccum | xaccum | v[0] | v[2] | v[1] | zi
|
||||
|
||||
// temp = r_ambientlight;
|
||||
// if (lightcos < 0)
|
||||
// {
|
||||
fsts Ltemp
|
||||
movl C(r_ambientlight),%eax
|
||||
movb Ltemp+3,%dl
|
||||
testb $0x80,%dl
|
||||
jz Lsavelight // no need to clamp if only ambient lit, because
|
||||
// r_ambientlight is preclamped
|
||||
|
||||
// temp += (int)(r_shadelight * lightcos);
|
||||
fmuls C(r_shadelight)
|
||||
// FIXME: fast float->int conversion?
|
||||
fistpl Ltemp
|
||||
addl Ltemp,%eax
|
||||
|
||||
// // clamp; because we limited the minimum ambient and shading light, we
|
||||
// // don't have to clamp low light, just bright
|
||||
// if (temp < 0)
|
||||
// temp = 0;
|
||||
jns Lp1
|
||||
subl %eax,%eax
|
||||
|
||||
// }
|
||||
|
||||
Lp1:
|
||||
|
||||
// fv->v[4] = temp;
|
||||
//
|
||||
// // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is
|
||||
// // scaled up by 1/2**31, and the scaling cancels out for x and y in the
|
||||
// // projection
|
||||
// fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) +
|
||||
// aliastransform[0][3]) * zi) + aliasxcenter;
|
||||
// fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) +
|
||||
// aliastransform[1][3]) * zi) + aliasycenter;
|
||||
// fv->v[5] = zi;
|
||||
fxch %st(1) // v[0] | xaccum | v[2] | v[1] | zi
|
||||
fmuls C(aliastransform)+16 // yaccum | xaccum | v[2] | v[1] | zi
|
||||
fxch %st(3) // v[1] | xaccum | v[2] | yaccum | zi
|
||||
fld %st(0) // v[1] | v[1] | xaccum | v[2] | yaccum | zi
|
||||
fmuls C(aliastransform)+4 // xaccum2 | v[1] | xaccum | v[2] | yaccum |zi
|
||||
fxch %st(1) // v[1] | xaccum2 | xaccum | v[2] | yaccum |zi
|
||||
movl %eax,fv_v+16(%edi)
|
||||
fmuls C(aliastransform)+20 // yaccum2 | xaccum2 | xaccum | v[2] | yaccum|
|
||||
// zi
|
||||
fxch %st(2) // xaccum | xaccum2 | yaccum2 | v[2] | yaccum|
|
||||
// zi
|
||||
fadds C(aliastransform)+12 // xaccum | xaccum2 | yaccum2 | v[2] | yaccum|
|
||||
// zi
|
||||
fxch %st(4) // yaccum | xaccum2 | yaccum2 | v[2] | xaccum|
|
||||
// zi
|
||||
fadds C(aliastransform)+28 // yaccum | xaccum2 | yaccum2 | v[2] | xaccum|
|
||||
// zi
|
||||
fxch %st(3) // v[2] | xaccum2 | yaccum2 | yaccum | xaccum|
|
||||
// zi
|
||||
fld %st(0) // v[2] | v[2] | xaccum2 | yaccum2 | yaccum |
|
||||
// xaccum | zi
|
||||
fmuls C(aliastransform)+8 // xaccum3 | v[2] | xaccum2 | yaccum2 |yaccum|
|
||||
// xaccum | zi
|
||||
fxch %st(1) // v[2] | xaccum3 | xaccum2 | yaccum2 |yaccum|
|
||||
// xaccum | zi
|
||||
fmuls C(aliastransform)+24 // yaccum3 | xaccum3 | xaccum2 | yaccum2 |
|
||||
// yaccum | xaccum | zi
|
||||
fxch %st(5) // xaccum | xaccum3 | xaccum2 | yaccum2 |
|
||||
// yaccum | yaccum3 | zi
|
||||
faddp %st(0),%st(2) // xaccum3 | xaccum | yaccum2 | yaccum |
|
||||
// yaccum3 | zi
|
||||
fxch %st(3) // yaccum | xaccum | yaccum2 | xaccum3 |
|
||||
// yaccum3 | zi
|
||||
faddp %st(0),%st(2) // xaccum | yaccum | xaccum3 | yaccum3 | zi
|
||||
addl $(tv_size),%esi
|
||||
faddp %st(0),%st(2) // yaccum | x | yaccum3 | zi
|
||||
faddp %st(0),%st(2) // x | y | zi
|
||||
// addl $(stv_size),%ebp //Spike was here
|
||||
fmul %st(2),%st(0) // x/z | y | zi
|
||||
fxch %st(1) // y | x/z | zi
|
||||
fmul %st(2),%st(0) // y/z | x/z | zi
|
||||
fxch %st(1) // x/z | y/z | zi
|
||||
fadds C(aliasxcenter) // u | y/z | zi
|
||||
fxch %st(1) // y/z | u | zi
|
||||
fadds C(aliasycenter) // v | u | zi
|
||||
fxch %st(2) // zi | u | v
|
||||
// FIXME: fast float->int conversion?
|
||||
fistpl fv_v+20(%edi) // u | v
|
||||
fistpl fv_v+0(%edi) // v
|
||||
fistpl fv_v+4(%edi)
|
||||
|
||||
// }
|
||||
|
||||
addl $(fv_size),%edi
|
||||
decl %ecx
|
||||
jnz Lloop
|
||||
|
||||
popl %esi // restore register variables
|
||||
popl %edi
|
||||
// popl %ebp //Spike was here. // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
Lsavelight:
|
||||
fstp %st(0)
|
||||
jmp Lp1
|
||||
|
||||
#endif // id386
|
|
@ -1,918 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_bsp.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
|
||||
//
|
||||
// current entity info
|
||||
//
|
||||
qboolean insubmodel;
|
||||
entity_t *currententity;
|
||||
vec3_t modelorg, base_modelorg;
|
||||
// modelorg is the viewpoint reletive to
|
||||
// the currently rendering entity
|
||||
vec3_t r_entorigin; // the currently rendering entity in world
|
||||
// coordinates
|
||||
|
||||
float entity_rotation[3][3];
|
||||
|
||||
vec3_t r_worldmodelorg;
|
||||
|
||||
int r_currentbkey;
|
||||
|
||||
typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t;
|
||||
|
||||
#define MAX_BMODEL_VERTS 500 // 6K
|
||||
#define MAX_BMODEL_EDGES 1000 // 12K
|
||||
|
||||
static mvertex_t *pbverts;
|
||||
static bedge_t *pbedges;
|
||||
static int numbverts, numbedges;
|
||||
|
||||
static mvertex_t *pfrontenter, *pfrontexit;
|
||||
|
||||
static qboolean makeclippededge;
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
R_EntityRotate
|
||||
================
|
||||
*/
|
||||
void R_EntityRotate (vec3_t vec)
|
||||
{
|
||||
vec3_t tvec;
|
||||
|
||||
VectorCopy (vec, tvec);
|
||||
vec[0] = DotProduct (entity_rotation[0], tvec);
|
||||
vec[1] = DotProduct (entity_rotation[1], tvec);
|
||||
vec[2] = DotProduct (entity_rotation[2], tvec);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RotateBmodel
|
||||
================
|
||||
*/
|
||||
void R_RotateBmodel (void)
|
||||
{
|
||||
float angle, s, c, temp1[3][3], temp2[3][3], temp3[3][3];
|
||||
|
||||
// TODO: should use a look-up table
|
||||
// TODO: should really be stored with the entity instead of being reconstructed
|
||||
// TODO: could cache lazily, stored in the entity
|
||||
// TODO: share work with R_SetUpAliasTransform
|
||||
|
||||
// yaw
|
||||
angle = currententity->angles[YAW];
|
||||
angle = angle * M_PI*2 / 360;
|
||||
s = sin(angle);
|
||||
c = cos(angle);
|
||||
|
||||
temp1[0][0] = c;
|
||||
temp1[0][1] = s;
|
||||
temp1[0][2] = 0;
|
||||
temp1[1][0] = -s;
|
||||
temp1[1][1] = c;
|
||||
temp1[1][2] = 0;
|
||||
temp1[2][0] = 0;
|
||||
temp1[2][1] = 0;
|
||||
temp1[2][2] = 1;
|
||||
|
||||
|
||||
// pitch
|
||||
angle = currententity->angles[PITCH];
|
||||
angle = angle * M_PI*2 / 360;
|
||||
s = sin(angle);
|
||||
c = cos(angle);
|
||||
|
||||
temp2[0][0] = c;
|
||||
temp2[0][1] = 0;
|
||||
temp2[0][2] = -s;
|
||||
temp2[1][0] = 0;
|
||||
temp2[1][1] = 1;
|
||||
temp2[1][2] = 0;
|
||||
temp2[2][0] = s;
|
||||
temp2[2][1] = 0;
|
||||
temp2[2][2] = c;
|
||||
|
||||
R_ConcatRotations (temp2, temp1, temp3);
|
||||
|
||||
// roll
|
||||
angle = currententity->angles[ROLL];
|
||||
angle = angle * M_PI*2 / 360;
|
||||
s = sin(angle);
|
||||
c = cos(angle);
|
||||
|
||||
temp1[0][0] = 1;
|
||||
temp1[0][1] = 0;
|
||||
temp1[0][2] = 0;
|
||||
temp1[1][0] = 0;
|
||||
temp1[1][1] = c;
|
||||
temp1[1][2] = s;
|
||||
temp1[2][0] = 0;
|
||||
temp1[2][1] = -s;
|
||||
temp1[2][2] = c;
|
||||
|
||||
R_ConcatRotations (temp1, temp3, entity_rotation);
|
||||
|
||||
//
|
||||
// rotate modelorg and the transformation matrix
|
||||
//
|
||||
R_EntityRotate (modelorg);
|
||||
R_EntityRotate (vpn);
|
||||
R_EntityRotate (vright);
|
||||
R_EntityRotate (vup);
|
||||
|
||||
R_TransformFrustum ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RecursiveClipBPoly
|
||||
================
|
||||
*/
|
||||
void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf)
|
||||
{
|
||||
bedge_t *psideedges[2], *pnextedge, *ptedge;
|
||||
int i, side, lastside;
|
||||
float dist, frac, lastdist;
|
||||
mplane_t *splitplane, tplane;
|
||||
mvertex_t *pvert, *plastvert, *ptvert;
|
||||
mnode_t *pn;
|
||||
|
||||
psideedges[0] = psideedges[1] = NULL;
|
||||
|
||||
makeclippededge = false;
|
||||
|
||||
// transform the BSP plane into model space
|
||||
// FIXME: cache these?
|
||||
splitplane = pnode->plane;
|
||||
if (!splitplane)
|
||||
return;
|
||||
tplane.dist = splitplane->dist -
|
||||
DotProduct(r_entorigin, splitplane->normal);
|
||||
tplane.normal[0] = DotProduct (entity_rotation[0], splitplane->normal);
|
||||
tplane.normal[1] = DotProduct (entity_rotation[1], splitplane->normal);
|
||||
tplane.normal[2] = DotProduct (entity_rotation[2], splitplane->normal);
|
||||
|
||||
// clip edges to BSP plane
|
||||
for ( ; pedges ; pedges = pnextedge)
|
||||
{
|
||||
pnextedge = pedges->pnext;
|
||||
|
||||
// set the status for the last point as the previous point
|
||||
// FIXME: cache this stuff somehow?
|
||||
plastvert = pedges->v[0];
|
||||
lastdist = DotProduct (plastvert->position, tplane.normal) -
|
||||
tplane.dist;
|
||||
|
||||
if (lastdist > 0)
|
||||
lastside = 0;
|
||||
else
|
||||
lastside = 1;
|
||||
|
||||
pvert = pedges->v[1];
|
||||
|
||||
dist = DotProduct (pvert->position, tplane.normal) - tplane.dist;
|
||||
|
||||
if (dist > 0)
|
||||
side = 0;
|
||||
else
|
||||
side = 1;
|
||||
|
||||
if (side != lastside)
|
||||
{
|
||||
// clipped
|
||||
if (numbverts >= MAX_BMODEL_VERTS)
|
||||
return;
|
||||
|
||||
// generate the clipped vertex
|
||||
frac = lastdist / (lastdist - dist);
|
||||
ptvert = &pbverts[numbverts++];
|
||||
ptvert->position[0] = plastvert->position[0] +
|
||||
frac * (pvert->position[0] -
|
||||
plastvert->position[0]);
|
||||
ptvert->position[1] = plastvert->position[1] +
|
||||
frac * (pvert->position[1] -
|
||||
plastvert->position[1]);
|
||||
ptvert->position[2] = plastvert->position[2] +
|
||||
frac * (pvert->position[2] -
|
||||
plastvert->position[2]);
|
||||
|
||||
// split into two edges, one on each side, and remember entering
|
||||
// and exiting points
|
||||
// FIXME: share the clip edge by having a winding direction flag?
|
||||
if (numbedges >= (MAX_BMODEL_EDGES - 1))
|
||||
{
|
||||
Con_Printf ("Out of edges for bmodel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ptedge = &pbedges[numbedges];
|
||||
ptedge->pnext = psideedges[lastside];
|
||||
psideedges[lastside] = ptedge;
|
||||
ptedge->v[0] = plastvert;
|
||||
ptedge->v[1] = ptvert;
|
||||
|
||||
ptedge = &pbedges[numbedges + 1];
|
||||
ptedge->pnext = psideedges[side];
|
||||
psideedges[side] = ptedge;
|
||||
ptedge->v[0] = ptvert;
|
||||
ptedge->v[1] = pvert;
|
||||
|
||||
numbedges += 2;
|
||||
|
||||
if (side == 0)
|
||||
{
|
||||
// entering for front, exiting for back
|
||||
pfrontenter = ptvert;
|
||||
makeclippededge = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pfrontexit = ptvert;
|
||||
makeclippededge = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add the edge to the appropriate side
|
||||
pedges->pnext = psideedges[side];
|
||||
psideedges[side] = pedges;
|
||||
}
|
||||
}
|
||||
|
||||
// if anything was clipped, reconstitute and add the edges along the clip
|
||||
// plane to both sides (but in opposite directions)
|
||||
if (makeclippededge)
|
||||
{
|
||||
if (numbedges >= (MAX_BMODEL_EDGES - 2))
|
||||
{
|
||||
Con_Printf ("Out of edges for bmodel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ptedge = &pbedges[numbedges];
|
||||
ptedge->pnext = psideedges[0];
|
||||
psideedges[0] = ptedge;
|
||||
ptedge->v[0] = pfrontexit;
|
||||
ptedge->v[1] = pfrontenter;
|
||||
|
||||
ptedge = &pbedges[numbedges + 1];
|
||||
ptedge->pnext = psideedges[1];
|
||||
psideedges[1] = ptedge;
|
||||
ptedge->v[0] = pfrontenter;
|
||||
ptedge->v[1] = pfrontexit;
|
||||
|
||||
numbedges += 2;
|
||||
}
|
||||
|
||||
// draw or recurse further
|
||||
for (i=0 ; i<2 ; i++)
|
||||
{
|
||||
if (psideedges[i])
|
||||
{
|
||||
// draw if we've reached a non-solid leaf, done if all that's left is a
|
||||
// solid leaf, and continue down the tree if it's not a leaf
|
||||
pn = pnode->children[i];
|
||||
|
||||
// we're done with this branch if the node or leaf isn't in the PVS
|
||||
if (pn->visframe == r_visframecount)
|
||||
{
|
||||
if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3)
|
||||
{
|
||||
if (pn->contents != -1)
|
||||
{
|
||||
if (pn->contents != Q2CONTENTS_SOLID)
|
||||
{
|
||||
r_currentbkey = ((mleaf_t *)pn)->key;
|
||||
R_RenderBmodelFace (psideedges[i], psurf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RecursiveClipBPoly (psideedges[i], pnode->children[i],
|
||||
psurf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pn->contents < 0)
|
||||
{
|
||||
if (pn->contents != Q1CONTENTS_SOLID)
|
||||
{
|
||||
r_currentbkey = ((mleaf_t *)pn)->key;
|
||||
R_RenderBmodelFace (psideedges[i], psurf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RecursiveClipBPoly (psideedges[i], pnode->children[i],
|
||||
psurf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawSolidClippedSubmodelPolygons
|
||||
================
|
||||
*/
|
||||
void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel)
|
||||
{
|
||||
int i, j, lindex;
|
||||
vec_t dot;
|
||||
msurface_t *psurf;
|
||||
int numsurfaces;
|
||||
mplane_t *pplane;
|
||||
mvertex_t bverts[MAX_BMODEL_VERTS];
|
||||
bedge_t bedges[MAX_BMODEL_EDGES], *pbedge;
|
||||
medge_t *pedge, *pedges;
|
||||
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
|
||||
psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
|
||||
numsurfaces = pmodel->nummodelsurfaces;
|
||||
pedges = pmodel->edges;
|
||||
|
||||
for (i=0 ; i<numsurfaces ; i++, psurf++)
|
||||
{
|
||||
// find which side of the node we are on
|
||||
pplane = psurf->plane;
|
||||
|
||||
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
|
||||
|
||||
// draw the polygon
|
||||
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
||||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
|
||||
{
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
|
||||
// copy the edges to bedges, flipping if necessary so always
|
||||
// clockwise winding
|
||||
// FIXME: if edges and vertices get caches, these assignments must move
|
||||
// outside the loop, and overflow checking must be done here
|
||||
pbverts = bverts;
|
||||
pbedges = bedges;
|
||||
numbverts = numbedges = 0;
|
||||
|
||||
if (psurf->numedges > 0)
|
||||
{
|
||||
pbedge = &bedges[numbedges];
|
||||
numbedges += psurf->numedges;
|
||||
|
||||
for (j=0 ; j<psurf->numedges ; j++)
|
||||
{
|
||||
lindex = pmodel->surfedges[psurf->firstedge+j];
|
||||
|
||||
if (lindex > 0)
|
||||
{
|
||||
pedge = &pedges[lindex];
|
||||
pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]];
|
||||
pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]];
|
||||
}
|
||||
else
|
||||
{
|
||||
lindex = -lindex;
|
||||
pedge = &pedges[lindex];
|
||||
pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]];
|
||||
pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]];
|
||||
}
|
||||
|
||||
pbedge[j].pnext = &pbedge[j+1];
|
||||
}
|
||||
|
||||
pbedge[j-1].pnext = NULL; // mark end of edges
|
||||
|
||||
R_RecursiveClipBPoly (pbedge, currententity->topnode, psurf);
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Error ("no edges in bmodel");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawSubmodelPolygons
|
||||
================
|
||||
*/
|
||||
void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags)
|
||||
{
|
||||
int i;
|
||||
vec_t dot;
|
||||
msurface_t *psurf;
|
||||
int numsurfaces, sflags;
|
||||
mplane_t *pplane;
|
||||
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
|
||||
psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
|
||||
numsurfaces = pmodel->nummodelsurfaces;
|
||||
|
||||
if (!cl.worldmodel->submodels || pmodel->submodels != cl.worldmodel->submodels)
|
||||
sflags = SURF_NOFLAT;
|
||||
else
|
||||
sflags = 0;
|
||||
|
||||
for (i=0 ; i<numsurfaces ; i++, psurf++)
|
||||
{
|
||||
// find which side of the node we are on
|
||||
pplane = psurf->plane;
|
||||
|
||||
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
|
||||
|
||||
// draw the polygon
|
||||
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
||||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
|
||||
{
|
||||
r_currentkey = ((mleaf_t *)currententity->topnode)->key;
|
||||
|
||||
psurf->flags |= sflags;
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
R_RenderFace (psurf, clipflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RecursiveWorldNode
|
||||
================
|
||||
*/
|
||||
void SWR_RecursiveWorldNode (mnode_t *node, int clipflags)
|
||||
{
|
||||
int i, c, side, *pindex;
|
||||
vec3_t acceptpt, rejectpt;
|
||||
mplane_t *plane;
|
||||
msurface_t *surf, **mark;
|
||||
mleaf_t *pleaf;
|
||||
double d, dot;
|
||||
|
||||
if (node->contents == Q1CONTENTS_SOLID)
|
||||
return; // solid
|
||||
|
||||
if (node->visframe != r_visframecount)
|
||||
return;
|
||||
|
||||
// cull the clipping planes if not trivial accept
|
||||
// FIXME: the compiler is doing a lousy job of optimizing here; it could be
|
||||
// twice as fast in ASM
|
||||
if (clipflags)
|
||||
{
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
if (! (clipflags & (1<<i)) )
|
||||
continue; // don't need to clip against it
|
||||
|
||||
// generate accept and reject points
|
||||
// FIXME: do with fast look-ups or integer tests based on the sign bit
|
||||
// of the floating point values
|
||||
|
||||
pindex = pfrustum_indexes[i];
|
||||
|
||||
rejectpt[0] = (float)node->minmaxs[pindex[0]];
|
||||
rejectpt[1] = (float)node->minmaxs[pindex[1]];
|
||||
rejectpt[2] = (float)node->minmaxs[pindex[2]];
|
||||
|
||||
d = DotProduct (rejectpt, view_clipplanes[i].normal);
|
||||
d -= view_clipplanes[i].dist;
|
||||
|
||||
if (d <= 0)
|
||||
return;
|
||||
|
||||
acceptpt[0] = (float)node->minmaxs[pindex[3+0]];
|
||||
acceptpt[1] = (float)node->minmaxs[pindex[3+1]];
|
||||
acceptpt[2] = (float)node->minmaxs[pindex[3+2]];
|
||||
|
||||
d = DotProduct (acceptpt, view_clipplanes[i].normal);
|
||||
d -= view_clipplanes[i].dist;
|
||||
|
||||
if (d >= 0)
|
||||
clipflags &= ~(1<<i); // node is entirely on screen
|
||||
}
|
||||
}
|
||||
|
||||
// if a leaf node, draw stuff
|
||||
if (node->contents < 0)
|
||||
{
|
||||
pleaf = (mleaf_t *)node;
|
||||
|
||||
mark = pleaf->firstmarksurface;
|
||||
c = pleaf->nummarksurfaces;
|
||||
|
||||
if (c)
|
||||
{
|
||||
do
|
||||
{
|
||||
(*mark)->visframe = r_framecount;
|
||||
mark++;
|
||||
} while (--c);
|
||||
}
|
||||
|
||||
// deal with model fragments in this leaf
|
||||
if (pleaf->efrags)
|
||||
{
|
||||
R_StoreEfrags (&pleaf->efrags);
|
||||
}
|
||||
|
||||
pleaf->key = r_currentkey;
|
||||
r_currentkey++; // all bmodels in a leaf share the same key
|
||||
}
|
||||
else
|
||||
{
|
||||
// node is just a decision point, so go down the apropriate sides
|
||||
|
||||
// find which side of the node we are on
|
||||
plane = node->plane;
|
||||
|
||||
switch (plane->type)
|
||||
{
|
||||
case PLANE_X:
|
||||
dot = modelorg[0] - plane->dist;
|
||||
break;
|
||||
case PLANE_Y:
|
||||
dot = modelorg[1] - plane->dist;
|
||||
break;
|
||||
case PLANE_Z:
|
||||
dot = modelorg[2] - plane->dist;
|
||||
break;
|
||||
default:
|
||||
dot = DotProduct (modelorg, plane->normal) - plane->dist;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dot >= 0)
|
||||
side = 0;
|
||||
else
|
||||
side = 1;
|
||||
|
||||
// recurse down the children, front side first
|
||||
SWR_RecursiveWorldNode (node->children[side], clipflags);
|
||||
|
||||
// draw stuff
|
||||
c = node->numsurfaces;
|
||||
|
||||
if (c)
|
||||
{
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
|
||||
if (dot < -BACKFACE_EPSILON)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((surf->flags & SURF_PLANEBACK) &&
|
||||
(surf->visframe == r_framecount))
|
||||
{
|
||||
if (r_drawpolys)
|
||||
{
|
||||
if (r_worldpolysbacktofront)
|
||||
{
|
||||
if (numbtofpolys < MAX_BTOFPOLYS)
|
||||
{
|
||||
pbtofpolys[numbtofpolys].clipflags =
|
||||
clipflags;
|
||||
pbtofpolys[numbtofpolys].psurf = surf;
|
||||
numbtofpolys++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RenderPoly (surf, clipflags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RenderFace (surf, clipflags);
|
||||
}
|
||||
}
|
||||
|
||||
surf++;
|
||||
} while (--c);
|
||||
}
|
||||
else if (dot > BACKFACE_EPSILON)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!(surf->flags & SURF_PLANEBACK) &&
|
||||
(surf->visframe == r_framecount))
|
||||
{
|
||||
if (r_drawpolys)
|
||||
{
|
||||
if (r_worldpolysbacktofront)
|
||||
{
|
||||
if (numbtofpolys < MAX_BTOFPOLYS)
|
||||
{
|
||||
pbtofpolys[numbtofpolys].clipflags =
|
||||
clipflags;
|
||||
pbtofpolys[numbtofpolys].psurf = surf;
|
||||
numbtofpolys++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RenderPoly (surf, clipflags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RenderFace (surf, clipflags);
|
||||
}
|
||||
}
|
||||
|
||||
surf++;
|
||||
} while (--c);
|
||||
}
|
||||
|
||||
// all surfaces on the same node share the same sequence number
|
||||
r_currentkey++;
|
||||
}
|
||||
|
||||
// recurse down the back side
|
||||
SWR_RecursiveWorldNode (node->children[!side], clipflags);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q2BSPS
|
||||
qbyte areabits[MAX_Q2MAP_AREAS/8];
|
||||
void SWR_RecursiveQ2WorldNode (mnode_t *node, int clipflags)
|
||||
{
|
||||
int i, c, side, *pindex;
|
||||
vec3_t acceptpt, rejectpt;
|
||||
mplane_t *plane;
|
||||
msurface_t *surf, **mark;
|
||||
mleaf_t *pleaf;
|
||||
double d, dot;
|
||||
|
||||
if (node->contents == Q2CONTENTS_SOLID)
|
||||
return; // solid
|
||||
|
||||
if (node->visframe != r_visframecount)
|
||||
return;
|
||||
|
||||
// cull the clipping planes if not trivial accept
|
||||
// FIXME: the compiler is doing a lousy job of optimizing here; it could be
|
||||
// twice as fast in ASM
|
||||
if (clipflags)
|
||||
{
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
if (! (clipflags & (1<<i)) )
|
||||
continue; // don't need to clip against it
|
||||
|
||||
// generate accept and reject points
|
||||
// FIXME: do with fast look-ups or integer tests based on the sign bit
|
||||
// of the floating point values
|
||||
|
||||
pindex = pfrustum_indexes[i];
|
||||
|
||||
rejectpt[0] = (float)node->minmaxs[pindex[0]];
|
||||
rejectpt[1] = (float)node->minmaxs[pindex[1]];
|
||||
rejectpt[2] = (float)node->minmaxs[pindex[2]];
|
||||
|
||||
d = DotProduct (rejectpt, view_clipplanes[i].normal);
|
||||
d -= view_clipplanes[i].dist;
|
||||
|
||||
if (d <= 0)
|
||||
return;
|
||||
|
||||
acceptpt[0] = (float)node->minmaxs[pindex[3+0]];
|
||||
acceptpt[1] = (float)node->minmaxs[pindex[3+1]];
|
||||
acceptpt[2] = (float)node->minmaxs[pindex[3+2]];
|
||||
|
||||
d = DotProduct (acceptpt, view_clipplanes[i].normal);
|
||||
d -= view_clipplanes[i].dist;
|
||||
|
||||
if (d >= 0)
|
||||
clipflags &= ~(1<<i); // node is entirely on screen
|
||||
}
|
||||
}
|
||||
|
||||
// if a leaf node, draw stuff
|
||||
if (node->contents != -1)
|
||||
{
|
||||
pleaf = (mleaf_t *)node;
|
||||
|
||||
// check for door connected areas
|
||||
// if (areabits)
|
||||
// {
|
||||
if (! (areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
|
||||
return; // not visible
|
||||
// }
|
||||
|
||||
mark = pleaf->firstmarksurface;
|
||||
c = pleaf->nummarksurfaces;
|
||||
|
||||
if (c)
|
||||
{
|
||||
do
|
||||
{
|
||||
(*mark)->visframe = r_framecount;
|
||||
mark++;
|
||||
} while (--c);
|
||||
}
|
||||
|
||||
pleaf->key = r_currentkey;
|
||||
r_currentkey++; // all bmodels in a leaf share the same key
|
||||
}
|
||||
else
|
||||
{
|
||||
// node is just a decision point, so go down the apropriate sides
|
||||
|
||||
// find which side of the node we are on
|
||||
plane = node->plane;
|
||||
|
||||
switch (plane->type)
|
||||
{
|
||||
case PLANE_X:
|
||||
dot = modelorg[0] - plane->dist;
|
||||
break;
|
||||
case PLANE_Y:
|
||||
dot = modelorg[1] - plane->dist;
|
||||
break;
|
||||
case PLANE_Z:
|
||||
dot = modelorg[2] - plane->dist;
|
||||
break;
|
||||
default:
|
||||
dot = DotProduct (modelorg, plane->normal) - plane->dist;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dot >= 0)
|
||||
side = 0;
|
||||
else
|
||||
side = 1;
|
||||
|
||||
// recurse down the children, front side first
|
||||
SWR_RecursiveQ2WorldNode (node->children[side], clipflags);
|
||||
|
||||
// draw stuff
|
||||
c = node->numsurfaces;
|
||||
|
||||
if (c)
|
||||
{
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
|
||||
if (dot < -BACKFACE_EPSILON)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((surf->flags & SURF_PLANEBACK) &&
|
||||
(surf->visframe == r_framecount))
|
||||
{
|
||||
if (r_drawpolys)
|
||||
{
|
||||
if (r_worldpolysbacktofront)
|
||||
{
|
||||
if (numbtofpolys < MAX_BTOFPOLYS)
|
||||
{
|
||||
pbtofpolys[numbtofpolys].clipflags =
|
||||
clipflags;
|
||||
pbtofpolys[numbtofpolys].psurf = surf;
|
||||
numbtofpolys++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RenderPoly (surf, clipflags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RenderFace (surf, clipflags);
|
||||
}
|
||||
}
|
||||
|
||||
surf++;
|
||||
} while (--c);
|
||||
}
|
||||
else if (dot > BACKFACE_EPSILON)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!(surf->flags & SURF_PLANEBACK) &&
|
||||
(surf->visframe == r_framecount))
|
||||
{
|
||||
if (r_drawpolys)
|
||||
{
|
||||
if (r_worldpolysbacktofront)
|
||||
{
|
||||
if (numbtofpolys < MAX_BTOFPOLYS)
|
||||
{
|
||||
pbtofpolys[numbtofpolys].clipflags =
|
||||
clipflags;
|
||||
pbtofpolys[numbtofpolys].psurf = surf;
|
||||
numbtofpolys++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RenderPoly (surf, clipflags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RenderFace (surf, clipflags);
|
||||
}
|
||||
}
|
||||
|
||||
surf++;
|
||||
} while (--c);
|
||||
}
|
||||
|
||||
// all surfaces on the same node share the same sequence number
|
||||
r_currentkey++;
|
||||
}
|
||||
|
||||
// recurse down the back side
|
||||
SWR_RecursiveQ2WorldNode (node->children[!side], clipflags);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
================
|
||||
R_RenderWorld
|
||||
================
|
||||
*/
|
||||
void R_RenderWorld (void)
|
||||
{
|
||||
int i;
|
||||
model_t *clmodel;
|
||||
btofpoly_t btofpolys[MAX_BTOFPOLYS];
|
||||
|
||||
pbtofpolys = btofpolys;
|
||||
|
||||
currententity = &r_worldentity;
|
||||
VectorCopy (r_origin, modelorg);
|
||||
clmodel = currententity->model;
|
||||
r_pcurrentvertbase = clmodel->vertexes;
|
||||
|
||||
#ifdef Q2BSPS
|
||||
if (clmodel->fromgame == fg_quake2)
|
||||
{
|
||||
int leafnum;
|
||||
int clientarea;
|
||||
|
||||
#ifdef Q2CLIENT
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
memcpy(areabits, cl.q2frame.areabits, sizeof(areabits));
|
||||
else
|
||||
#endif
|
||||
{
|
||||
leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg);
|
||||
clientarea = CM_LeafArea (cl.worldmodel, leafnum);
|
||||
CM_WriteAreaBits(cl.worldmodel, areabits, clientarea);
|
||||
}
|
||||
|
||||
SWR_RecursiveQ2WorldNode (clmodel->nodes, 15);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
SWR_RecursiveWorldNode (clmodel->nodes, 15);
|
||||
|
||||
// if the driver wants the polygons back to front, play the visible ones back
|
||||
// in that order
|
||||
|
||||
if (r_worldpolysbacktofront)
|
||||
{
|
||||
for (i=numbtofpolys-1 ; i>=0 ; i--)
|
||||
{
|
||||
R_RenderPoly (btofpolys[i].psurf, btofpolys[i].clipflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
2320
engine/sw/r_draw.c
2320
engine/sw/r_draw.c
File diff suppressed because it is too large
Load diff
|
@ -1,887 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// r_drawa.s
|
||||
// x86 assembly-language edge clipping and emission code
|
||||
//
|
||||
|
||||
#define SWQUAKE
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
// !!! if these are changed, they must be changed in r_draw.c too !!!
|
||||
#define FULLY_CLIPPED_CACHED 0x80000000
|
||||
#define FRAMECOUNT_MASK 0x7FFFFFFF
|
||||
|
||||
.data
|
||||
|
||||
Ld0: .single 0.0
|
||||
Ld1: .single 0.0
|
||||
Lstack: .long 0
|
||||
Lfp_near_clip: .single NEAR_CLIP
|
||||
Lceilv0: .long 0
|
||||
Lv: .long 0
|
||||
Lu0: .long 0
|
||||
Lv0: .long 0
|
||||
Lzi0: .long 0
|
||||
|
||||
.text
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// edge clipping code
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#define pv0 4+12
|
||||
#define pv1 8+12
|
||||
#define clip 12+12
|
||||
|
||||
.align 4
|
||||
.globl C(R_ClipEdge)
|
||||
C(R_ClipEdge):
|
||||
pushl %esi // preserve register variables
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
movl %esp,Lstack // for clearing the stack later
|
||||
|
||||
// float d0, d1, f;
|
||||
// mvertex_t clipvert;
|
||||
|
||||
movl clip(%esp),%ebx
|
||||
movl pv0(%esp),%esi
|
||||
movl pv1(%esp),%edx
|
||||
|
||||
// if (clip)
|
||||
// {
|
||||
testl %ebx,%ebx
|
||||
jz Lemit
|
||||
|
||||
// do
|
||||
// {
|
||||
|
||||
Lcliploop:
|
||||
|
||||
// d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
|
||||
// d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
|
||||
flds mv_position+0(%esi)
|
||||
fmuls cp_normal+0(%ebx)
|
||||
flds mv_position+4(%esi)
|
||||
fmuls cp_normal+4(%ebx)
|
||||
flds mv_position+8(%esi)
|
||||
fmuls cp_normal+8(%ebx)
|
||||
fxch %st(1)
|
||||
faddp %st(0),%st(2) // d0mul2 | d0add0
|
||||
|
||||
flds mv_position+0(%edx)
|
||||
fmuls cp_normal+0(%ebx)
|
||||
flds mv_position+4(%edx)
|
||||
fmuls cp_normal+4(%ebx)
|
||||
flds mv_position+8(%edx)
|
||||
fmuls cp_normal+8(%ebx)
|
||||
fxch %st(1)
|
||||
faddp %st(0),%st(2) // d1mul2 | d1add0 | d0mul2 | d0add0
|
||||
fxch %st(3) // d0add0 | d1add0 | d0mul2 | d1mul2
|
||||
|
||||
faddp %st(0),%st(2) // d1add0 | dot0 | d1mul2
|
||||
faddp %st(0),%st(2) // dot0 | dot1
|
||||
|
||||
fsubs cp_dist(%ebx) // d0 | dot1
|
||||
fxch %st(1) // dot1 | d0
|
||||
fsubs cp_dist(%ebx) // d1 | d0
|
||||
fxch %st(1)
|
||||
fstps Ld0
|
||||
fstps Ld1
|
||||
|
||||
// if (d0 >= 0)
|
||||
// {
|
||||
movl Ld0,%eax
|
||||
movl Ld1,%ecx
|
||||
orl %eax,%ecx
|
||||
js Lp2
|
||||
|
||||
// both points are unclipped
|
||||
|
||||
Lcontinue:
|
||||
|
||||
//
|
||||
// R_ClipEdge (&clipvert, pv1, clip->next);
|
||||
// return;
|
||||
// }
|
||||
// } while ((clip = clip->next) != NULL);
|
||||
movl cp_next(%ebx),%ebx
|
||||
testl %ebx,%ebx
|
||||
jnz Lcliploop
|
||||
|
||||
// }
|
||||
|
||||
//// add the edge
|
||||
// R_EmitEdge (pv0, pv1);
|
||||
Lemit:
|
||||
|
||||
//
|
||||
// set integer rounding to ceil mode, set to single precision
|
||||
//
|
||||
// FIXME: do away with by manually extracting integers from floats?
|
||||
// FIXME: set less often
|
||||
fldcw ceil_cw
|
||||
|
||||
// edge_t *edge, *pcheck;
|
||||
// int u_check;
|
||||
// float u, u_step;
|
||||
// vec3_t local, transformed;
|
||||
// float *world;
|
||||
// int v, v2, ceilv0;
|
||||
// float scale, lzi0, u0, v0;
|
||||
// int side;
|
||||
|
||||
// if (r_lastvertvalid)
|
||||
// {
|
||||
cmpl $0,C(r_lastvertvalid)
|
||||
jz LCalcFirst
|
||||
|
||||
// u0 = r_u1;
|
||||
// v0 = r_v1;
|
||||
// lzi0 = r_lzi1;
|
||||
// ceilv0 = r_ceilv1;
|
||||
movl C(r_lzi1),%eax
|
||||
movl C(r_u1),%ecx
|
||||
movl %eax,Lzi0
|
||||
movl %ecx,Lu0
|
||||
movl C(r_v1),%ecx
|
||||
movl C(r_ceilv1),%eax
|
||||
movl %ecx,Lv0
|
||||
movl %eax,Lceilv0
|
||||
jmp LCalcSecond
|
||||
|
||||
// }
|
||||
|
||||
LCalcFirst:
|
||||
|
||||
// else
|
||||
// {
|
||||
// world = &pv0->position[0];
|
||||
|
||||
call LTransformAndProject // v0 | lzi0 | u0
|
||||
|
||||
fsts Lv0
|
||||
fxch %st(2) // u0 | lzi0 | v0
|
||||
fstps Lu0 // lzi0 | v0
|
||||
fstps Lzi0 // v0
|
||||
|
||||
// ceilv0 = (int)(v0 - 2000) + 2000; // ceil(v0);
|
||||
fistpl Lceilv0
|
||||
|
||||
// }
|
||||
|
||||
LCalcSecond:
|
||||
|
||||
// world = &pv1->position[0];
|
||||
movl %edx,%esi
|
||||
|
||||
call LTransformAndProject // v1 | lzi1 | u1
|
||||
|
||||
flds Lu0 // u0 | v1 | lzi1 | u1
|
||||
fxch %st(3) // u1 | v1 | lzi1 | u0
|
||||
flds Lzi0 // lzi0 | u1 | v1 | lzi1 | u0
|
||||
fxch %st(3) // lzi1 | u1 | v1 | lzi0 | u0
|
||||
flds Lv0 // v0 | lzi1 | u1 | v1 | lzi0 | u0
|
||||
fxch %st(3) // v1 | lzi1 | u1 | v0 | lzi0 | u0
|
||||
|
||||
// r_ceilv1 = (int)(r_v1 - 2000) + 2000; // ceil(r_v1);
|
||||
fistl C(r_ceilv1)
|
||||
|
||||
fldcw single_cw // put back normal floating-point state
|
||||
|
||||
fsts C(r_v1)
|
||||
fxch %st(4) // lzi0 | lzi1 | u1 | v0 | v1 | u0
|
||||
|
||||
// if (r_lzi1 > lzi0)
|
||||
// lzi0 = r_lzi1;
|
||||
fcom %st(1)
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jz LP0
|
||||
fstp %st(0)
|
||||
fld %st(0)
|
||||
LP0:
|
||||
|
||||
fxch %st(1) // lzi1 | lzi0 | u1 | v0 | v1 | u0
|
||||
fstps C(r_lzi1) // lzi0 | u1 | v0 | v1 | u0
|
||||
fxch %st(1)
|
||||
fsts C(r_u1)
|
||||
fxch %st(1)
|
||||
|
||||
// if (lzi0 > r_nearzi) // for mipmap finding
|
||||
// r_nearzi = lzi0;
|
||||
fcoms C(r_nearzi)
|
||||
fnstsw %ax
|
||||
testb $0x45,%ah
|
||||
jnz LP1
|
||||
fsts C(r_nearzi)
|
||||
LP1:
|
||||
|
||||
// // for right edges, all we want is the effect on 1/z
|
||||
// if (r_nearzionly)
|
||||
// return;
|
||||
movl C(r_nearzionly),%eax
|
||||
testl %eax,%eax
|
||||
jz LP2
|
||||
LPop5AndDone:
|
||||
movl C(cacheoffset),%eax
|
||||
movl C(r_framecount),%edx
|
||||
cmpl $0x7FFFFFFF,%eax
|
||||
jz LDoPop
|
||||
andl $(FRAMECOUNT_MASK),%edx
|
||||
orl $(FULLY_CLIPPED_CACHED),%edx
|
||||
movl %edx,C(cacheoffset)
|
||||
|
||||
LDoPop:
|
||||
fstp %st(0) // u1 | v0 | v1 | u0
|
||||
fstp %st(0) // v0 | v1 | u0
|
||||
fstp %st(0) // v1 | u0
|
||||
fstp %st(0) // u0
|
||||
fstp %st(0)
|
||||
jmp Ldone
|
||||
|
||||
LP2:
|
||||
|
||||
// // create the edge
|
||||
// if (ceilv0 == r_ceilv1)
|
||||
// return; // horizontal edge
|
||||
movl Lceilv0,%ebx
|
||||
movl C(edge_p),%edi
|
||||
movl C(r_ceilv1),%ecx
|
||||
movl %edi,%edx
|
||||
movl C(r_pedge),%esi
|
||||
addl $(et_size),%edx
|
||||
cmpl %ecx,%ebx
|
||||
jz LPop5AndDone
|
||||
|
||||
movl C(r_pedge),%eax
|
||||
movl %eax,et_owner(%edi)
|
||||
|
||||
// side = ceilv0 > r_ceilv1;
|
||||
//
|
||||
// edge->nearzi = lzi0;
|
||||
fstps et_nearzi(%edi) // u1 | v0 | v1 | u0
|
||||
|
||||
// if (side == 1)
|
||||
// {
|
||||
jc LSide0
|
||||
|
||||
LSide1:
|
||||
|
||||
// // leading edge (go from p2 to p1)
|
||||
|
||||
// u_step = ((u0 - r_u1) / (v0 - r_v1));
|
||||
fsubrp %st(0),%st(3) // v0 | v1 | u0-u1
|
||||
fsub %st(1),%st(0) // v0-v1 | v1 | u0-u1
|
||||
fdivrp %st(0),%st(2) // v1 | ustep
|
||||
|
||||
// r_emitted = 1;
|
||||
movl $1,C(r_emitted)
|
||||
|
||||
// edge = edge_p++;
|
||||
movl %edx,C(edge_p)
|
||||
|
||||
// pretouch next edge
|
||||
movl (%edx),%eax
|
||||
|
||||
// v2 = ceilv0 - 1;
|
||||
// v = r_ceilv1;
|
||||
movl %ecx,%eax
|
||||
leal -1(%ebx),%ecx
|
||||
movl %eax,%ebx
|
||||
|
||||
// edge->surfs[0] = 0;
|
||||
// edge->surfs[1] = surface_p - surfaces;
|
||||
movl C(surface_p),%eax
|
||||
movl C(surfaces),%esi
|
||||
subl %edx,%edx
|
||||
subl %esi,%eax
|
||||
shrl $(SURF_T_SHIFT),%eax
|
||||
movl %edx,et_surfs(%edi)
|
||||
movl %eax,et_surfs+2(%edi)
|
||||
|
||||
subl %esi,%esi
|
||||
|
||||
// u = r_u1 + ((float)v - r_v1) * u_step;
|
||||
movl %ebx,Lv
|
||||
fildl Lv // v | v1 | ustep
|
||||
fsubp %st(0),%st(1) // v-v1 | ustep
|
||||
fmul %st(1),%st(0) // (v-v1)*ustep | ustep
|
||||
fadds C(r_u1) // u | ustep
|
||||
|
||||
jmp LSideDone
|
||||
|
||||
// }
|
||||
|
||||
LSide0:
|
||||
|
||||
// else
|
||||
// {
|
||||
// // trailing edge (go from p1 to p2)
|
||||
|
||||
// u_step = ((r_u1 - u0) / (r_v1 - v0));
|
||||
fsub %st(3),%st(0) // u1-u0 | v0 | v1 | u0
|
||||
fxch %st(2) // v1 | v0 | u1-u0 | u0
|
||||
fsub %st(1),%st(0) // v1-v0 | v0 | u1-u0 | u0
|
||||
fdivrp %st(0),%st(2) // v0 | ustep | u0
|
||||
|
||||
// r_emitted = 1;
|
||||
movl $1,C(r_emitted)
|
||||
|
||||
// edge = edge_p++;
|
||||
movl %edx,C(edge_p)
|
||||
|
||||
// pretouch next edge
|
||||
movl (%edx),%eax
|
||||
|
||||
// v = ceilv0;
|
||||
// v2 = r_ceilv1 - 1;
|
||||
decl %ecx
|
||||
|
||||
// edge->surfs[0] = surface_p - surfaces;
|
||||
// edge->surfs[1] = 0;
|
||||
movl C(surface_p),%eax
|
||||
movl C(surfaces),%esi
|
||||
subl %edx,%edx
|
||||
subl %esi,%eax
|
||||
shrl $(SURF_T_SHIFT),%eax
|
||||
movl %edx,et_surfs+2(%edi)
|
||||
movl %eax,et_surfs(%edi)
|
||||
|
||||
movl $1,%esi
|
||||
|
||||
// u = u0 + ((float)v - v0) * u_step;
|
||||
movl %ebx,Lv
|
||||
fildl Lv // v | v0 | ustep | u0
|
||||
fsubp %st(0),%st(1) // v-v0 | ustep | u0
|
||||
fmul %st(1),%st(0) // (v-v0)*ustep | ustep | u0
|
||||
faddp %st(0),%st(2) // ustep | u
|
||||
fxch %st(1) // u | ustep
|
||||
|
||||
// }
|
||||
|
||||
LSideDone:
|
||||
|
||||
// edge->u_step = u_step*0x100000;
|
||||
// edge->u = u*0x100000 + 0xFFFFF;
|
||||
|
||||
fmuls fp_1m // u*0x100000 | ustep
|
||||
fxch %st(1) // ustep | u*0x100000
|
||||
fmuls fp_1m // ustep*0x100000 | u*0x100000
|
||||
fxch %st(1) // u*0x100000 | ustep*0x100000
|
||||
fadds fp_1m_minus_1 // u*0x100000 + 0xFFFFF | ustep*0x100000
|
||||
fxch %st(1) // ustep*0x100000 | u*0x100000 + 0xFFFFF
|
||||
fistpl et_u_step(%edi) // u*0x100000 + 0xFFFFF
|
||||
fistpl et_u(%edi)
|
||||
|
||||
// // we need to do this to avoid stepping off the edges if a very nearly
|
||||
// // horizontal edge is less than epsilon above a scan, and numeric error
|
||||
// // causes it to incorrectly extend to the scan, and the extension of the
|
||||
// // line goes off the edge of the screen
|
||||
// // FIXME: is this actually needed?
|
||||
// if (edge->u < r_refdef.vrect_x_adj_shift20)
|
||||
// edge->u = r_refdef.vrect_x_adj_shift20;
|
||||
// if (edge->u > r_refdef.vrectright_adj_shift20)
|
||||
// edge->u = r_refdef.vrectright_adj_shift20;
|
||||
movl et_u(%edi),%eax
|
||||
movl C(r_refdef)+rd_vrect_x_adj_shift20,%edx
|
||||
cmpl %edx,%eax
|
||||
jl LP4
|
||||
movl C(r_refdef)+rd_vrectright_adj_shift20,%edx
|
||||
cmpl %edx,%eax
|
||||
jng LP5
|
||||
LP4:
|
||||
movl %edx,et_u(%edi)
|
||||
movl %edx,%eax
|
||||
LP5:
|
||||
|
||||
// // sort the edge in normally
|
||||
// u_check = edge->u;
|
||||
//
|
||||
// if (edge->surfs[0])
|
||||
// u_check++; // sort trailers after leaders
|
||||
addl %esi,%eax
|
||||
|
||||
// if (!newedges[v] || newedges[v]->u >= u_check)
|
||||
// {
|
||||
movl C(newedges)(,%ebx,4),%esi
|
||||
testl %esi,%esi
|
||||
jz LDoFirst
|
||||
cmpl %eax,et_u(%esi)
|
||||
jl LNotFirst
|
||||
LDoFirst:
|
||||
|
||||
// edge->next = newedges[v];
|
||||
// newedges[v] = edge;
|
||||
movl %esi,et_next(%edi)
|
||||
movl %edi,C(newedges)(,%ebx,4)
|
||||
|
||||
jmp LSetRemove
|
||||
|
||||
// }
|
||||
|
||||
LNotFirst:
|
||||
|
||||
// else
|
||||
// {
|
||||
// pcheck = newedges[v];
|
||||
//
|
||||
// while (pcheck->next && pcheck->next->u < u_check)
|
||||
// pcheck = pcheck->next;
|
||||
LFindInsertLoop:
|
||||
movl %esi,%edx
|
||||
movl et_next(%esi),%esi
|
||||
testl %esi,%esi
|
||||
jz LInsertFound
|
||||
cmpl %eax,et_u(%esi)
|
||||
jl LFindInsertLoop
|
||||
|
||||
LInsertFound:
|
||||
|
||||
// edge->next = pcheck->next;
|
||||
// pcheck->next = edge;
|
||||
movl %esi,et_next(%edi)
|
||||
movl %edi,et_next(%edx)
|
||||
|
||||
// }
|
||||
|
||||
LSetRemove:
|
||||
|
||||
// edge->nextremove = removeedges[v2];
|
||||
// removeedges[v2] = edge;
|
||||
movl C(removeedges)(,%ecx,4),%eax
|
||||
movl %edi,C(removeedges)(,%ecx,4)
|
||||
movl %eax,et_nextremove(%edi)
|
||||
|
||||
Ldone:
|
||||
movl Lstack,%esp // clear temporary variables from stack
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %edi
|
||||
popl %esi
|
||||
ret
|
||||
|
||||
// at least one point is clipped
|
||||
|
||||
Lp2:
|
||||
testl %eax,%eax
|
||||
jns Lp1
|
||||
|
||||
// else
|
||||
// {
|
||||
// // point 0 is clipped
|
||||
|
||||
// if (d1 < 0)
|
||||
// {
|
||||
movl Ld1,%eax
|
||||
testl %eax,%eax
|
||||
jns Lp3
|
||||
|
||||
// // both points are clipped
|
||||
// // we do cache fully clipped edges
|
||||
// if (!leftclipped)
|
||||
movl C(r_leftclipped),%eax
|
||||
movl C(r_pedge),%ecx
|
||||
testl %eax,%eax
|
||||
jnz Ldone
|
||||
|
||||
// r_pedge->framecount = r_framecount;
|
||||
movl C(r_framecount),%eax
|
||||
andl $(FRAMECOUNT_MASK),%eax
|
||||
orl $(FULLY_CLIPPED_CACHED),%eax
|
||||
movl %eax,C(cacheoffset)
|
||||
|
||||
// return;
|
||||
jmp Ldone
|
||||
|
||||
// }
|
||||
|
||||
Lp1:
|
||||
|
||||
// // point 0 is unclipped
|
||||
// if (d1 >= 0)
|
||||
// {
|
||||
// // both points are unclipped
|
||||
// continue;
|
||||
|
||||
// // only point 1 is clipped
|
||||
|
||||
// f = d0 / (d0 - d1);
|
||||
flds Ld0
|
||||
flds Ld1
|
||||
fsubr %st(1),%st(0)
|
||||
|
||||
// // we don't cache partially clipped edges
|
||||
movl $0x7FFFFFFF,C(cacheoffset)
|
||||
|
||||
fdivrp %st(0),%st(1)
|
||||
|
||||
subl $(mv_size),%esp // allocate space for clipvert
|
||||
|
||||
// clipvert.position[0] = pv0->position[0] +
|
||||
// f * (pv1->position[0] - pv0->position[0]);
|
||||
// clipvert.position[1] = pv0->position[1] +
|
||||
// f * (pv1->position[1] - pv0->position[1]);
|
||||
// clipvert.position[2] = pv0->position[2] +
|
||||
// f * (pv1->position[2] - pv0->position[2]);
|
||||
flds mv_position+8(%edx)
|
||||
fsubs mv_position+8(%esi)
|
||||
flds mv_position+4(%edx)
|
||||
fsubs mv_position+4(%esi)
|
||||
flds mv_position+0(%edx)
|
||||
fsubs mv_position+0(%esi) // 0 | 1 | 2
|
||||
|
||||
// replace pv1 with the clip point
|
||||
movl %esp,%edx
|
||||
movl cp_leftedge(%ebx),%eax
|
||||
testb %al,%al
|
||||
|
||||
fmul %st(3),%st(0)
|
||||
fxch %st(1) // 1 | 0 | 2
|
||||
fmul %st(3),%st(0)
|
||||
fxch %st(2) // 2 | 0 | 1
|
||||
fmulp %st(0),%st(3) // 0 | 1 | 2
|
||||
fadds mv_position+0(%esi)
|
||||
fxch %st(1) // 1 | 0 | 2
|
||||
fadds mv_position+4(%esi)
|
||||
fxch %st(2) // 2 | 0 | 1
|
||||
fadds mv_position+8(%esi)
|
||||
fxch %st(1) // 0 | 2 | 1
|
||||
fstps mv_position+0(%esp) // 2 | 1
|
||||
fstps mv_position+8(%esp) // 1
|
||||
fstps mv_position+4(%esp)
|
||||
|
||||
// if (clip->leftedge)
|
||||
// {
|
||||
jz Ltestright
|
||||
|
||||
// r_leftclipped = true;
|
||||
// r_leftexit = clipvert;
|
||||
movl $1,C(r_leftclipped)
|
||||
movl mv_position+0(%esp),%eax
|
||||
movl %eax,C(r_leftexit)+mv_position+0
|
||||
movl mv_position+4(%esp),%eax
|
||||
movl %eax,C(r_leftexit)+mv_position+4
|
||||
movl mv_position+8(%esp),%eax
|
||||
movl %eax,C(r_leftexit)+mv_position+8
|
||||
|
||||
jmp Lcontinue
|
||||
|
||||
// }
|
||||
|
||||
Ltestright:
|
||||
// else if (clip->rightedge)
|
||||
// {
|
||||
testb %ah,%ah
|
||||
jz Lcontinue
|
||||
|
||||
// r_rightclipped = true;
|
||||
// r_rightexit = clipvert;
|
||||
movl $1,C(r_rightclipped)
|
||||
movl mv_position+0(%esp),%eax
|
||||
movl %eax,C(r_rightexit)+mv_position+0
|
||||
movl mv_position+4(%esp),%eax
|
||||
movl %eax,C(r_rightexit)+mv_position+4
|
||||
movl mv_position+8(%esp),%eax
|
||||
movl %eax,C(r_rightexit)+mv_position+8
|
||||
|
||||
// }
|
||||
//
|
||||
// R_ClipEdge (pv0, &clipvert, clip->next);
|
||||
// return;
|
||||
// }
|
||||
jmp Lcontinue
|
||||
|
||||
// }
|
||||
|
||||
Lp3:
|
||||
|
||||
// // only point 0 is clipped
|
||||
// r_lastvertvalid = false;
|
||||
|
||||
movl $0,C(r_lastvertvalid)
|
||||
|
||||
// f = d0 / (d0 - d1);
|
||||
flds Ld0
|
||||
flds Ld1
|
||||
fsubr %st(1),%st(0)
|
||||
|
||||
// // we don't cache partially clipped edges
|
||||
movl $0x7FFFFFFF,C(cacheoffset)
|
||||
|
||||
fdivrp %st(0),%st(1)
|
||||
|
||||
subl $(mv_size),%esp // allocate space for clipvert
|
||||
|
||||
// clipvert.position[0] = pv0->position[0] +
|
||||
// f * (pv1->position[0] - pv0->position[0]);
|
||||
// clipvert.position[1] = pv0->position[1] +
|
||||
// f * (pv1->position[1] - pv0->position[1]);
|
||||
// clipvert.position[2] = pv0->position[2] +
|
||||
// f * (pv1->position[2] - pv0->position[2]);
|
||||
flds mv_position+8(%edx)
|
||||
fsubs mv_position+8(%esi)
|
||||
flds mv_position+4(%edx)
|
||||
fsubs mv_position+4(%esi)
|
||||
flds mv_position+0(%edx)
|
||||
fsubs mv_position+0(%esi) // 0 | 1 | 2
|
||||
|
||||
movl cp_leftedge(%ebx),%eax
|
||||
testb %al,%al
|
||||
|
||||
fmul %st(3),%st(0)
|
||||
fxch %st(1) // 1 | 0 | 2
|
||||
fmul %st(3),%st(0)
|
||||
fxch %st(2) // 2 | 0 | 1
|
||||
fmulp %st(0),%st(3) // 0 | 1 | 2
|
||||
fadds mv_position+0(%esi)
|
||||
fxch %st(1) // 1 | 0 | 2
|
||||
fadds mv_position+4(%esi)
|
||||
fxch %st(2) // 2 | 0 | 1
|
||||
fadds mv_position+8(%esi)
|
||||
fxch %st(1) // 0 | 2 | 1
|
||||
fstps mv_position+0(%esp) // 2 | 1
|
||||
fstps mv_position+8(%esp) // 1
|
||||
fstps mv_position+4(%esp)
|
||||
|
||||
// replace pv0 with the clip point
|
||||
movl %esp,%esi
|
||||
|
||||
// if (clip->leftedge)
|
||||
// {
|
||||
jz Ltestright2
|
||||
|
||||
// r_leftclipped = true;
|
||||
// r_leftenter = clipvert;
|
||||
movl $1,C(r_leftclipped)
|
||||
movl mv_position+0(%esp),%eax
|
||||
movl %eax,C(r_leftenter)+mv_position+0
|
||||
movl mv_position+4(%esp),%eax
|
||||
movl %eax,C(r_leftenter)+mv_position+4
|
||||
movl mv_position+8(%esp),%eax
|
||||
movl %eax,C(r_leftenter)+mv_position+8
|
||||
|
||||
jmp Lcontinue
|
||||
|
||||
// }
|
||||
|
||||
Ltestright2:
|
||||
// else if (clip->rightedge)
|
||||
// {
|
||||
testb %ah,%ah
|
||||
jz Lcontinue
|
||||
|
||||
// r_rightclipped = true;
|
||||
// r_rightenter = clipvert;
|
||||
movl $1,C(r_rightclipped)
|
||||
movl mv_position+0(%esp),%eax
|
||||
movl %eax,C(r_rightenter)+mv_position+0
|
||||
movl mv_position+4(%esp),%eax
|
||||
movl %eax,C(r_rightenter)+mv_position+4
|
||||
movl mv_position+8(%esp),%eax
|
||||
movl %eax,C(r_rightenter)+mv_position+8
|
||||
|
||||
// }
|
||||
jmp Lcontinue
|
||||
|
||||
// %esi = vec3_t point to transform and project
|
||||
// %edx preserved
|
||||
LTransformAndProject:
|
||||
|
||||
// // transform and project
|
||||
// VectorSubtract (world, modelorg, local);
|
||||
flds mv_position+0(%esi)
|
||||
fsubs C(modelorg)+0
|
||||
flds mv_position+4(%esi)
|
||||
fsubs C(modelorg)+4
|
||||
flds mv_position+8(%esi)
|
||||
fsubs C(modelorg)+8
|
||||
fxch %st(2) // local[0] | local[1] | local[2]
|
||||
|
||||
// TransformVector (local, transformed);
|
||||
//
|
||||
// if (transformed[2] < NEAR_CLIP)
|
||||
// transformed[2] = NEAR_CLIP;
|
||||
//
|
||||
// lzi0 = 1.0 / transformed[2];
|
||||
fld %st(0) // local[0] | local[0] | local[1] | local[2]
|
||||
fmuls C(vpn)+0 // zm0 | local[0] | local[1] | local[2]
|
||||
fld %st(1) // local[0] | zm0 | local[0] | local[1] |
|
||||
// local[2]
|
||||
fmuls C(vright)+0 // xm0 | zm0 | local[0] | local[1] | local[2]
|
||||
fxch %st(2) // local[0] | zm0 | xm0 | local[1] | local[2]
|
||||
fmuls C(vup)+0 // ym0 | zm0 | xm0 | local[1] | local[2]
|
||||
fld %st(3) // local[1] | ym0 | zm0 | xm0 | local[1] |
|
||||
// local[2]
|
||||
fmuls C(vpn)+4 // zm1 | ym0 | zm0 | xm0 | local[1] |
|
||||
// local[2]
|
||||
fld %st(4) // local[1] | zm1 | ym0 | zm0 | xm0 |
|
||||
// local[1] | local[2]
|
||||
fmuls C(vright)+4 // xm1 | zm1 | ym0 | zm0 | xm0 |
|
||||
// local[1] | local[2]
|
||||
fxch %st(5) // local[1] | zm1 | ym0 | zm0 | xm0 |
|
||||
// xm1 | local[2]
|
||||
fmuls C(vup)+4 // ym1 | zm1 | ym0 | zm0 | xm0 |
|
||||
// xm1 | local[2]
|
||||
fxch %st(1) // zm1 | ym1 | ym0 | zm0 | xm0 |
|
||||
// xm1 | local[2]
|
||||
faddp %st(0),%st(3) // ym1 | ym0 | zm2 | xm0 | xm1 | local[2]
|
||||
fxch %st(3) // xm0 | ym0 | zm2 | ym1 | xm1 | local[2]
|
||||
faddp %st(0),%st(4) // ym0 | zm2 | ym1 | xm2 | local[2]
|
||||
faddp %st(0),%st(2) // zm2 | ym2 | xm2 | local[2]
|
||||
fld %st(3) // local[2] | zm2 | ym2 | xm2 | local[2]
|
||||
fmuls C(vpn)+8 // zm3 | zm2 | ym2 | xm2 | local[2]
|
||||
fld %st(4) // local[2] | zm3 | zm2 | ym2 | xm2 | local[2]
|
||||
fmuls C(vright)+8 // xm3 | zm3 | zm2 | ym2 | xm2 | local[2]
|
||||
fxch %st(5) // local[2] | zm3 | zm2 | ym2 | xm2 | xm3
|
||||
fmuls C(vup)+8 // ym3 | zm3 | zm2 | ym2 | xm2 | xm3
|
||||
fxch %st(1) // zm3 | ym3 | zm2 | ym2 | xm2 | xm3
|
||||
faddp %st(0),%st(2) // ym3 | zm4 | ym2 | xm2 | xm3
|
||||
fxch %st(4) // xm3 | zm4 | ym2 | xm2 | ym3
|
||||
faddp %st(0),%st(3) // zm4 | ym2 | xm4 | ym3
|
||||
fxch %st(1) // ym2 | zm4 | xm4 | ym3
|
||||
faddp %st(0),%st(3) // zm4 | xm4 | ym4
|
||||
|
||||
fcoms Lfp_near_clip
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jz LNoClip
|
||||
fstp %st(0)
|
||||
flds Lfp_near_clip
|
||||
|
||||
LNoClip:
|
||||
|
||||
fdivrs float_1 // lzi0 | x | y
|
||||
fxch %st(1) // x | lzi0 | y
|
||||
|
||||
// // FIXME: build x/yscale into transform?
|
||||
// scale = xscale * lzi0;
|
||||
// u0 = (xcenter + scale*transformed[0]);
|
||||
flds C(xscale) // xscale | x | lzi0 | y
|
||||
fmul %st(2),%st(0) // scale | x | lzi0 | y
|
||||
fmulp %st(0),%st(1) // scale*x | lzi0 | y
|
||||
fadds C(xcenter) // u0 | lzi0 | y
|
||||
|
||||
// if (u0 < r_refdef.fvrectx_adj)
|
||||
// u0 = r_refdef.fvrectx_adj;
|
||||
// if (u0 > r_refdef.fvrectright_adj)
|
||||
// u0 = r_refdef.fvrectright_adj;
|
||||
// FIXME: use integer compares of floats?
|
||||
fcoms C(r_refdef)+rd_fvrectx_adj
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jz LClampP0
|
||||
fstp %st(0)
|
||||
flds C(r_refdef)+rd_fvrectx_adj
|
||||
LClampP0:
|
||||
fcoms C(r_refdef)+rd_fvrectright_adj
|
||||
fnstsw %ax
|
||||
testb $0x45,%ah
|
||||
jnz LClampP1
|
||||
fstp %st(0)
|
||||
flds C(r_refdef)+rd_fvrectright_adj
|
||||
LClampP1:
|
||||
|
||||
fld %st(1) // lzi0 | u0 | lzi0 | y
|
||||
|
||||
// scale = yscale * lzi0;
|
||||
// v0 = (ycenter - scale*transformed[1]);
|
||||
fmuls C(yscale) // scale | u0 | lzi0 | y
|
||||
fmulp %st(0),%st(3) // u0 | lzi0 | scale*y
|
||||
fxch %st(2) // scale*y | lzi0 | u0
|
||||
fsubrs C(ycenter) // v0 | lzi0 | u0
|
||||
|
||||
// if (v0 < r_refdef.fvrecty_adj)
|
||||
// v0 = r_refdef.fvrecty_adj;
|
||||
// if (v0 > r_refdef.fvrectbottom_adj)
|
||||
// v0 = r_refdef.fvrectbottom_adj;
|
||||
// FIXME: use integer compares of floats?
|
||||
fcoms C(r_refdef)+rd_fvrecty_adj
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jz LClampP2
|
||||
fstp %st(0)
|
||||
flds C(r_refdef)+rd_fvrecty_adj
|
||||
LClampP2:
|
||||
fcoms C(r_refdef)+rd_fvrectbottom_adj
|
||||
fnstsw %ax
|
||||
testb $0x45,%ah
|
||||
jnz LClampP3
|
||||
fstp %st(0)
|
||||
flds C(r_refdef)+rd_fvrectbottom_adj
|
||||
LClampP3:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
#define in 4
|
||||
#define out 8
|
||||
.align 2
|
||||
.globl C(TransformVector)
|
||||
C(TransformVector):
|
||||
movl in(%esp),%eax
|
||||
movl out(%esp),%edx
|
||||
|
||||
flds (%eax) // in[0]
|
||||
fmuls C(vright) // in[0]*vright[0]
|
||||
flds (%eax) // in[0] | in[0]*vright[0]
|
||||
fmuls C(vup) // in[0]*vup[0] | in[0]*vright[0]
|
||||
flds (%eax) // in[0] | in[0]*vup[0] | in[0]*vright[0]
|
||||
fmuls C(vpn) // in[0]*vpn[0] | in[0]*vup[0] | in[0]*vright[0]
|
||||
|
||||
flds 4(%eax) // in[1] | ...
|
||||
fmuls C(vright)+4 // in[1]*vright[1] | ...
|
||||
flds 4(%eax) // in[1] | in[1]*vright[1] | ...
|
||||
fmuls C(vup)+4 // in[1]*vup[1] | in[1]*vright[1] | ...
|
||||
flds 4(%eax) // in[1] | in[1]*vup[1] | in[1]*vright[1] | ...
|
||||
fmuls C(vpn)+4 // in[1]*vpn[1] | in[1]*vup[1] | in[1]*vright[1] | ...
|
||||
fxch %st(2) // in[1]*vright[1] | in[1]*vup[1] | in[1]*vpn[1] | ...
|
||||
|
||||
faddp %st(0),%st(5) // in[1]*vup[1] | in[1]*vpn[1] | ...
|
||||
faddp %st(0),%st(3) // in[1]*vpn[1] | ...
|
||||
faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
|
||||
|
||||
flds 8(%eax) // in[2] | ...
|
||||
fmuls C(vright)+8 // in[2]*vright[2] | ...
|
||||
flds 8(%eax) // in[2] | in[2]*vright[2] | ...
|
||||
fmuls C(vup)+8 // in[2]*vup[2] | in[2]*vright[2] | ...
|
||||
flds 8(%eax) // in[2] | in[2]*vup[2] | in[2]*vright[2] | ...
|
||||
fmuls C(vpn)+8 // in[2]*vpn[2] | in[2]*vup[2] | in[2]*vright[2] | ...
|
||||
fxch %st(2) // in[2]*vright[2] | in[2]*vup[2] | in[2]*vpn[2] | ...
|
||||
|
||||
faddp %st(0),%st(5) // in[2]*vup[2] | in[2]*vpn[2] | ...
|
||||
faddp %st(0),%st(3) // in[2]*vpn[2] | ...
|
||||
faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
|
||||
|
||||
fstps 8(%edx) // out[2]
|
||||
fstps 4(%edx) // out[1]
|
||||
fstps (%edx) // out[0]
|
||||
|
||||
ret
|
||||
|
||||
|
||||
#endif // id386
|
||||
|
|
@ -1,929 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_edge.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
|
||||
#if 0
|
||||
// FIXME
|
||||
the complex cases add new polys on most lines, so dont optimize for keeping them the same
|
||||
have multiple free span lists to try to get better coherence?
|
||||
low depth complexity -- 1 to 3 or so
|
||||
|
||||
this breaks spans at every edge, even hidden ones (bad)
|
||||
|
||||
have a sentinal at both ends?
|
||||
#endif
|
||||
|
||||
|
||||
edge_t *auxedges;
|
||||
edge_t *r_edges, *edge_p, *edge_max;
|
||||
|
||||
surf_t *surfaces, *surface_p, *surf_max;
|
||||
|
||||
// surfaces are generated in back to front order by the bsp, so if a surf
|
||||
// pointer is greater than another one, it should be drawn in front
|
||||
// surfaces[1] is the background, and is used as the active surface stack
|
||||
|
||||
edge_t *newedges[MAXHEIGHT];
|
||||
edge_t *removeedges[MAXHEIGHT];
|
||||
|
||||
espan_t *span_p, *max_span_p;
|
||||
|
||||
int r_currentkey;
|
||||
|
||||
extern int screenwidth;
|
||||
|
||||
int current_iv;
|
||||
|
||||
int edge_head_u_shift20, edge_tail_u_shift20;
|
||||
|
||||
static void (*pdrawfunc)(void);
|
||||
|
||||
edge_t edge_head;
|
||||
edge_t edge_tail;
|
||||
edge_t edge_aftertail;
|
||||
edge_t edge_sentinel;
|
||||
|
||||
float fv;
|
||||
|
||||
void R_GenerateSpans (void);
|
||||
void R_GenerateSpansTrans (void);
|
||||
void R_GenerateSpansBackward (void);
|
||||
|
||||
void R_LeadingEdge (edge_t *edge);
|
||||
void R_LeadingEdgeBackwards (edge_t *edge);
|
||||
void R_TrailingEdge (surf_t *surf, edge_t *edge);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_DrawCulledPolys
|
||||
==============
|
||||
*/
|
||||
void R_DrawCulledPolys (void)
|
||||
{
|
||||
surf_t *s;
|
||||
msurface_t *pface;
|
||||
|
||||
currententity = &r_worldentity;
|
||||
|
||||
if (r_worldpolysbacktofront)
|
||||
{
|
||||
for (s=surface_p-1 ; s>&surfaces[1] ; s--)
|
||||
{
|
||||
if (!s->spans)
|
||||
continue;
|
||||
|
||||
if (!(s->flags & SURF_DRAWBACKGROUND))
|
||||
{
|
||||
pface = (msurface_t *)s->data;
|
||||
R_RenderPoly (pface, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (s = &surfaces[1] ; s<surface_p ; s++)
|
||||
{
|
||||
if (!s->spans)
|
||||
continue;
|
||||
|
||||
if (!(s->flags & SURF_DRAWBACKGROUND))
|
||||
{
|
||||
pface = (msurface_t *)s->data;
|
||||
R_RenderPoly (pface, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_BeginEdgeFrame
|
||||
==============
|
||||
*/
|
||||
void R_BeginEdgeFrame (void)
|
||||
{
|
||||
int v;
|
||||
|
||||
edge_p = r_edges;
|
||||
edge_max = &r_edges[r_numallocatededges];
|
||||
|
||||
surface_p = &surfaces[2]; // background is surface 1,
|
||||
// surface 0 is a dummy
|
||||
surfaces[1].spans = NULL; // no background spans yet
|
||||
surfaces[1].flags = SURF_DRAWBACKGROUND;
|
||||
|
||||
// put the background behind everything in the world
|
||||
if (r_draworder.value)
|
||||
{
|
||||
pdrawfunc = R_GenerateSpansBackward;
|
||||
surfaces[1].key = 0;
|
||||
r_currentkey = 1;
|
||||
}
|
||||
else if (cl.worldmodel->fromgame == fg_halflife)
|
||||
{
|
||||
pdrawfunc = R_GenerateSpansTrans;
|
||||
surfaces[1].key = 0x7FFFFFFF;
|
||||
r_currentkey = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdrawfunc = R_GenerateSpans;
|
||||
surfaces[1].key = 0x7FFFFFFF;
|
||||
r_currentkey = 0;
|
||||
}
|
||||
|
||||
// FIXME: set with memset
|
||||
for (v=r_refdef.vrect.y ; v<r_refdef.vrectbottom ; v++)
|
||||
{
|
||||
newedges[v] = removeedges[v] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
==============
|
||||
R_InsertNewEdges
|
||||
|
||||
Adds the edges in the linked list edgestoadd, adding them to the edges in the
|
||||
linked list edgelist. edgestoadd is assumed to be sorted on u, and non-empty (this is actually newedges[v]). edgelist is assumed to be sorted on u, with a
|
||||
sentinel at the end (actually, this is the active edge table starting at
|
||||
edge_head.next).
|
||||
==============
|
||||
*/
|
||||
void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist)
|
||||
{
|
||||
edge_t *next_edge;
|
||||
|
||||
do
|
||||
{
|
||||
next_edge = edgestoadd->next;
|
||||
edgesearch:
|
||||
if (edgelist->u >= edgestoadd->u)
|
||||
goto addedge;
|
||||
edgelist=edgelist->next;
|
||||
if (edgelist->u >= edgestoadd->u)
|
||||
goto addedge;
|
||||
edgelist=edgelist->next;
|
||||
if (edgelist->u >= edgestoadd->u)
|
||||
goto addedge;
|
||||
edgelist=edgelist->next;
|
||||
if (edgelist->u >= edgestoadd->u)
|
||||
goto addedge;
|
||||
edgelist=edgelist->next;
|
||||
goto edgesearch;
|
||||
|
||||
// insert edgestoadd before edgelist
|
||||
addedge:
|
||||
edgestoadd->next = edgelist;
|
||||
edgestoadd->prev = edgelist->prev;
|
||||
edgelist->prev->next = edgestoadd;
|
||||
edgelist->prev = edgestoadd;
|
||||
} while ((edgestoadd = next_edge) != NULL);
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
==============
|
||||
R_RemoveEdges
|
||||
==============
|
||||
*/
|
||||
void R_RemoveEdges (edge_t *pedge)
|
||||
{
|
||||
|
||||
do
|
||||
{
|
||||
pedge->next->prev = pedge->prev;
|
||||
pedge->prev->next = pedge->next;
|
||||
} while ((pedge = pedge->nextremove) != NULL);
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
==============
|
||||
R_StepActiveU
|
||||
==============
|
||||
*/
|
||||
void R_StepActiveU (edge_t *pedge)
|
||||
{
|
||||
edge_t *pnext_edge, *pwedge;
|
||||
|
||||
while (1)
|
||||
{
|
||||
nextedge:
|
||||
pedge->u += pedge->u_step;
|
||||
if (pedge->u < pedge->prev->u)
|
||||
goto pushback;
|
||||
pedge = pedge->next;
|
||||
|
||||
pedge->u += pedge->u_step;
|
||||
if (pedge->u < pedge->prev->u)
|
||||
goto pushback;
|
||||
pedge = pedge->next;
|
||||
|
||||
pedge->u += pedge->u_step;
|
||||
if (pedge->u < pedge->prev->u)
|
||||
goto pushback;
|
||||
pedge = pedge->next;
|
||||
|
||||
pedge->u += pedge->u_step;
|
||||
if (pedge->u < pedge->prev->u)
|
||||
goto pushback;
|
||||
pedge = pedge->next;
|
||||
|
||||
goto nextedge;
|
||||
|
||||
pushback:
|
||||
if (pedge == &edge_aftertail)
|
||||
return;
|
||||
|
||||
// push it back to keep it sorted
|
||||
pnext_edge = pedge->next;
|
||||
|
||||
// pull the edge out of the edge list
|
||||
pedge->next->prev = pedge->prev;
|
||||
pedge->prev->next = pedge->next;
|
||||
|
||||
// find out where the edge goes in the edge list
|
||||
pwedge = pedge->prev->prev;
|
||||
|
||||
while (pwedge->u > pedge->u)
|
||||
{
|
||||
pwedge = pwedge->prev;
|
||||
}
|
||||
|
||||
// put the edge back into the edge list
|
||||
pedge->next = pwedge->next;
|
||||
pedge->prev = pwedge;
|
||||
pedge->next->prev = pedge;
|
||||
pwedge->next = pedge;
|
||||
|
||||
pedge = pnext_edge;
|
||||
if (pedge == &edge_tail)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_CleanupSpan
|
||||
==============
|
||||
*/
|
||||
void R_CleanupSpan (void)
|
||||
{
|
||||
surf_t *surf;
|
||||
int iu;
|
||||
espan_t *span;
|
||||
|
||||
// now that we've reached the right edge of the screen, we're done with any
|
||||
// unfinished surfaces, so emit a span for whatever's on top
|
||||
surf = surfaces[1].next;
|
||||
iu = edge_tail_u_shift20;
|
||||
if (iu > surf->last_u)
|
||||
{
|
||||
span = span_p++;
|
||||
span->u = surf->last_u;
|
||||
span->count = iu - span->u;
|
||||
span->v = current_iv;
|
||||
span->pnext = surf->spans;
|
||||
surf->spans = span;
|
||||
}
|
||||
|
||||
// reset spanstate for all surfaces in the surface stack
|
||||
do
|
||||
{
|
||||
surf->spanstate = 0;
|
||||
surf = surf->next;
|
||||
} while (surf != &surfaces[1]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_LeadingEdgeBackwards
|
||||
==============
|
||||
*/
|
||||
void R_LeadingEdgeBackwards (edge_t *edge)
|
||||
{
|
||||
espan_t *span;
|
||||
surf_t *surf, *surf2;
|
||||
int iu;
|
||||
|
||||
// it's adding a new surface in, so find the correct place
|
||||
surf = &surfaces[edge->surfs[1]];
|
||||
|
||||
// don't start a span if this is an inverted span, with the end
|
||||
// edge preceding the start edge (that is, we've already seen the
|
||||
// end edge)
|
||||
if (++surf->spanstate == 1)
|
||||
{
|
||||
surf2 = surfaces[1].next;
|
||||
|
||||
if (surf->key > surf2->key)
|
||||
goto newtop;
|
||||
|
||||
// if it's two surfaces on the same plane, the one that's already
|
||||
// active is in front, so keep going unless it's a bmodel
|
||||
if (surf->insubmodel && (surf->key == surf2->key))
|
||||
{
|
||||
// must be two bmodels in the same leaf; don't care, because they'll
|
||||
// never be farthest anyway
|
||||
goto newtop;
|
||||
}
|
||||
|
||||
continue_search:
|
||||
|
||||
do
|
||||
{
|
||||
surf2 = surf2->next;
|
||||
} while (surf->key < surf2->key);
|
||||
|
||||
if (surf->key == surf2->key)
|
||||
{
|
||||
// if it's two surfaces on the same plane, the one that's already
|
||||
// active is in front, so keep going unless it's a bmodel
|
||||
if (!surf->insubmodel)
|
||||
goto continue_search;
|
||||
|
||||
// must be two bmodels in the same leaf; don't care which is really
|
||||
// in front, because they'll never be farthest anyway
|
||||
}
|
||||
|
||||
goto gotposition;
|
||||
|
||||
newtop:
|
||||
// emit a span (obscures current top)
|
||||
iu = edge->u >> 20;
|
||||
|
||||
if (iu > surf2->last_u)
|
||||
{
|
||||
span = span_p++;
|
||||
span->u = surf2->last_u;
|
||||
span->count = iu - span->u;
|
||||
span->v = current_iv;
|
||||
span->pnext = surf2->spans;
|
||||
surf2->spans = span;
|
||||
}
|
||||
|
||||
// set last_u on the new span
|
||||
surf->last_u = iu;
|
||||
|
||||
gotposition:
|
||||
// insert before surf2
|
||||
surf->next = surf2;
|
||||
surf->prev = surf2->prev;
|
||||
surf2->prev->next = surf;
|
||||
surf2->prev = surf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_TrailingEdge
|
||||
==============
|
||||
*/
|
||||
void R_TrailingEdge (surf_t *surf, edge_t *edge)
|
||||
{
|
||||
espan_t *span;
|
||||
int iu;
|
||||
|
||||
// don't generate a span if this is an inverted span, with the end
|
||||
// edge preceding the start edge (that is, we haven't seen the
|
||||
// start edge yet)
|
||||
if (--surf->spanstate == 0)
|
||||
{
|
||||
if (surf->insubmodel)
|
||||
r_bmodelactive--;
|
||||
|
||||
if (surf == surfaces[1].next)
|
||||
{
|
||||
// emit a span (current top going away)
|
||||
iu = edge->u >> 20;
|
||||
if (iu > surf->last_u)
|
||||
{
|
||||
span = span_p++;
|
||||
span->u = surf->last_u;
|
||||
span->count = iu - span->u;
|
||||
span->v = current_iv;
|
||||
span->pnext = surf->spans;
|
||||
surf->spans = span;
|
||||
}
|
||||
|
||||
// set last_u on the surface below
|
||||
surf->next->last_u = iu;
|
||||
}
|
||||
|
||||
surf->prev->next = surf->next;
|
||||
surf->next->prev = surf->prev;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
==============
|
||||
R_LeadingEdge
|
||||
==============
|
||||
*/
|
||||
void R_LeadingEdge (edge_t *edge)
|
||||
{
|
||||
espan_t *span;
|
||||
surf_t *surf, *surf2;
|
||||
int iu;
|
||||
double fu, newzi, testzi, newzitop, newzibottom;
|
||||
|
||||
if (edge->surfs[1])
|
||||
{
|
||||
// it's adding a new surface in, so find the correct place
|
||||
surf = &surfaces[edge->surfs[1]];
|
||||
|
||||
// don't start a span if this is an inverted span, with the end
|
||||
// edge preceding the start edge (that is, we've already seen the
|
||||
// end edge)
|
||||
if (++surf->spanstate == 1)
|
||||
{
|
||||
if (surf->insubmodel)
|
||||
r_bmodelactive++;
|
||||
|
||||
surf2 = surfaces[1].next;
|
||||
|
||||
if (surf->key < surf2->key)
|
||||
goto newtop;
|
||||
|
||||
// if it's two surfaces on the same plane, the one that's already
|
||||
// active is in front, so keep going unless it's a bmodel
|
||||
if (surf->insubmodel && (surf->key == surf2->key))
|
||||
{
|
||||
// must be two bmodels in the same leaf; sort on 1/z
|
||||
fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
|
||||
newzi = surf->d_ziorigin + fv*surf->d_zistepv +
|
||||
fu*surf->d_zistepu;
|
||||
newzibottom = newzi * 0.99;
|
||||
|
||||
testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
|
||||
fu*surf2->d_zistepu;
|
||||
|
||||
if (newzibottom >= testzi)
|
||||
{
|
||||
goto newtop;
|
||||
}
|
||||
|
||||
newzitop = newzi * 1.01;
|
||||
if (newzitop >= testzi)
|
||||
{
|
||||
if (surf->d_zistepu >= surf2->d_zistepu)
|
||||
{
|
||||
goto newtop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continue_search:
|
||||
|
||||
do
|
||||
{
|
||||
surf2 = surf2->next;
|
||||
} while (surf->key > surf2->key);
|
||||
|
||||
if (surf->key == surf2->key)
|
||||
{
|
||||
// if it's two surfaces on the same plane, the one that's already
|
||||
// active is in front, so keep going unless it's a bmodel
|
||||
if (!surf->insubmodel)
|
||||
goto continue_search;
|
||||
|
||||
// must be two bmodels in the same leaf; sort on 1/z
|
||||
fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
|
||||
newzi = surf->d_ziorigin + fv*surf->d_zistepv +
|
||||
fu*surf->d_zistepu;
|
||||
newzibottom = newzi * 0.99;
|
||||
|
||||
testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
|
||||
fu*surf2->d_zistepu;
|
||||
|
||||
if (newzibottom >= testzi)
|
||||
{
|
||||
goto gotposition;
|
||||
}
|
||||
|
||||
newzitop = newzi * 1.01;
|
||||
if (newzitop >= testzi)
|
||||
{
|
||||
if (surf->d_zistepu >= surf2->d_zistepu)
|
||||
{
|
||||
goto gotposition;
|
||||
}
|
||||
}
|
||||
|
||||
goto continue_search;
|
||||
}
|
||||
|
||||
goto gotposition;
|
||||
|
||||
newtop:
|
||||
// emit a span (obscures current top)
|
||||
iu = edge->u >> 20;
|
||||
|
||||
if (iu > surf2->last_u)
|
||||
{
|
||||
span = span_p++;
|
||||
span->u = surf2->last_u;
|
||||
span->count = iu - span->u;
|
||||
span->v = current_iv;
|
||||
span->pnext = surf2->spans;
|
||||
surf2->spans = span;
|
||||
}
|
||||
|
||||
// set last_u on the new span
|
||||
surf->last_u = iu;
|
||||
|
||||
gotposition:
|
||||
// insert before surf2
|
||||
surf->next = surf2;
|
||||
surf->prev = surf2->prev;
|
||||
surf2->prev->next = surf;
|
||||
surf2->prev = surf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_GenerateSpans
|
||||
==============
|
||||
*/
|
||||
void R_GenerateSpans (void)
|
||||
{
|
||||
edge_t *edge;
|
||||
surf_t *surf;
|
||||
|
||||
r_bmodelactive = 0;
|
||||
|
||||
// clear active surfaces to just the background surface
|
||||
surfaces[1].next = surfaces[1].prev = &surfaces[1];
|
||||
surfaces[1].last_u = edge_head_u_shift20;
|
||||
|
||||
// generate spans
|
||||
for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
|
||||
{
|
||||
if (edge->surfs[0])
|
||||
{
|
||||
// it has a left surface, so a surface is going away for this span
|
||||
surf = &surfaces[edge->surfs[0]];
|
||||
|
||||
R_TrailingEdge (surf, edge);
|
||||
|
||||
if (!edge->surfs[1])
|
||||
continue;
|
||||
}
|
||||
|
||||
R_LeadingEdge (edge);
|
||||
}
|
||||
|
||||
R_CleanupSpan ();
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
||||
void R_LeadingTransEdge (edge_t *edge)
|
||||
{
|
||||
espan_t *span;
|
||||
surf_t *surf, *surf2;
|
||||
int iu;
|
||||
double fu, newzi, testzi, newzitop, newzibottom;
|
||||
|
||||
if (edge->surfs[1])
|
||||
{
|
||||
// it's adding a new surface in, so find the correct place
|
||||
surf = &surfaces[edge->surfs[1]];
|
||||
|
||||
// don't start a span if this is an inverted span, with the end
|
||||
// edge preceding the start edge (that is, we've already seen the
|
||||
// end edge)
|
||||
if (++surf->spanstate == 1)
|
||||
{
|
||||
if (surf->insubmodel)
|
||||
r_bmodelactive++;
|
||||
|
||||
surf2 = surfaces[1].next;
|
||||
|
||||
if (surf->key < surf2->key)
|
||||
goto newtop;
|
||||
|
||||
// if it's two surfaces on the same plane, the one that's already
|
||||
// active is in front, so keep going unless it's a bmodel
|
||||
if (surf->insubmodel && (surf->key == surf2->key))
|
||||
{
|
||||
// must be two bmodels in the same leaf; sort on 1/z
|
||||
fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
|
||||
newzi = surf->d_ziorigin + fv*surf->d_zistepv +
|
||||
fu*surf->d_zistepu;
|
||||
newzibottom = newzi * 0.99;
|
||||
|
||||
testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
|
||||
fu*surf2->d_zistepu;
|
||||
|
||||
if (newzibottom >= testzi)
|
||||
{
|
||||
goto newtop;
|
||||
}
|
||||
|
||||
newzitop = newzi * 1.01;
|
||||
if (newzitop >= testzi)
|
||||
{
|
||||
if (surf->d_zistepu >= surf2->d_zistepu)
|
||||
{
|
||||
goto newtop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continue_search:
|
||||
|
||||
do
|
||||
{
|
||||
surf2 = surf2->next;
|
||||
} while (surf->key > surf2->key);
|
||||
|
||||
if (surf->key == surf2->key)
|
||||
{
|
||||
// if it's two surfaces on the same plane, the one that's already
|
||||
// active is in front, so keep going unless it's a bmodel
|
||||
if (!surf->insubmodel)
|
||||
goto continue_search;
|
||||
|
||||
// must be two bmodels in the same leaf; sort on 1/z
|
||||
fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
|
||||
newzi = surf->d_ziorigin + fv*surf->d_zistepv +
|
||||
fu*surf->d_zistepu;
|
||||
newzibottom = newzi * 0.99;
|
||||
|
||||
testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
|
||||
fu*surf2->d_zistepu;
|
||||
|
||||
if (newzibottom >= testzi)
|
||||
{
|
||||
goto gotposition;
|
||||
}
|
||||
|
||||
newzitop = newzi * 1.01;
|
||||
if (newzitop >= testzi)
|
||||
{
|
||||
if (surf->d_zistepu >= surf2->d_zistepu)
|
||||
{
|
||||
goto gotposition;
|
||||
}
|
||||
}
|
||||
|
||||
goto continue_search;
|
||||
}
|
||||
|
||||
goto gotposition;
|
||||
|
||||
newtop:
|
||||
// emit a span (obscures current top)
|
||||
iu = edge->u >> 20;
|
||||
|
||||
if (iu > surf2->last_u)
|
||||
{
|
||||
span = span_p++;
|
||||
span->u = surf2->last_u;
|
||||
span->count = iu - span->u;
|
||||
span->v = current_iv;
|
||||
span->pnext = surf2->spans;
|
||||
surf2->spans = span;
|
||||
}
|
||||
|
||||
// set last_u on the new span
|
||||
surf->last_u = iu;
|
||||
|
||||
gotposition:
|
||||
// insert before surf2
|
||||
surf->next = surf2;
|
||||
surf->prev = surf2->prev;
|
||||
surf2->prev->next = surf;
|
||||
surf2->prev = surf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R_GenerateSpansTrans (void)
|
||||
{
|
||||
edge_t *edge;
|
||||
surf_t *surf;
|
||||
|
||||
r_bmodelactive = 0;
|
||||
|
||||
// clear active surfaces to just the background surface
|
||||
surfaces[1].next = surfaces[1].prev = &surfaces[1];
|
||||
surfaces[1].last_u = edge_head_u_shift20;
|
||||
|
||||
// generate spans
|
||||
for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
|
||||
{
|
||||
if (edge->surfs[0])
|
||||
{
|
||||
// it has a left surface, so a surface is going away for this span
|
||||
surf = &surfaces[edge->surfs[0]];
|
||||
|
||||
R_TrailingEdge (surf, edge);
|
||||
|
||||
if (!edge->surfs[1])
|
||||
continue;
|
||||
}
|
||||
|
||||
R_LeadingTransEdge (edge);
|
||||
}
|
||||
|
||||
R_CleanupSpan ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_GenerateSpansBackward
|
||||
==============
|
||||
*/
|
||||
void R_GenerateSpansBackward (void)
|
||||
{
|
||||
edge_t *edge;
|
||||
|
||||
r_bmodelactive = 0;
|
||||
|
||||
// clear active surfaces to just the background surface
|
||||
surfaces[1].next = surfaces[1].prev = &surfaces[1];
|
||||
surfaces[1].last_u = edge_head_u_shift20;
|
||||
|
||||
// generate spans
|
||||
for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
|
||||
{
|
||||
if (edge->surfs[0])
|
||||
R_TrailingEdge (&surfaces[edge->surfs[0]], edge);
|
||||
|
||||
if (edge->surfs[1])
|
||||
R_LeadingEdgeBackwards (edge);
|
||||
}
|
||||
|
||||
R_CleanupSpan ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_ScanEdges
|
||||
|
||||
Input:
|
||||
newedges[] array
|
||||
this has links to edges, which have links to surfaces
|
||||
|
||||
Output:
|
||||
Each surface has a linked list of its visible spans
|
||||
==============
|
||||
*/
|
||||
void R_ScanEdges (void)
|
||||
{
|
||||
int iv, bottom;
|
||||
qbyte basespans[MAXSPANS*sizeof(espan_t)+CACHE_SIZE];
|
||||
espan_t *basespan_p;
|
||||
surf_t *s;
|
||||
|
||||
basespan_p = (espan_t *)
|
||||
((long)(basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
||||
max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width];
|
||||
|
||||
span_p = basespan_p;
|
||||
|
||||
// clear active edges to just the background edges around the whole screen
|
||||
// FIXME: most of this only needs to be set up once
|
||||
edge_head.u = r_refdef.vrect.x << 20;
|
||||
edge_head_u_shift20 = edge_head.u >> 20;
|
||||
edge_head.u_step = 0;
|
||||
edge_head.prev = NULL;
|
||||
edge_head.next = &edge_tail;
|
||||
edge_head.surfs[0] = 0;
|
||||
edge_head.surfs[1] = 1;
|
||||
|
||||
edge_tail.u = (r_refdef.vrectright << 20) + 0xFFFFF;
|
||||
edge_tail_u_shift20 = edge_tail.u >> 20;
|
||||
edge_tail.u_step = 0;
|
||||
edge_tail.prev = &edge_head;
|
||||
edge_tail.next = &edge_aftertail;
|
||||
edge_tail.surfs[0] = 1;
|
||||
edge_tail.surfs[1] = 0;
|
||||
|
||||
edge_aftertail.u = -1; // force a move
|
||||
edge_aftertail.u_step = 0;
|
||||
edge_aftertail.next = &edge_sentinel;
|
||||
edge_aftertail.prev = &edge_tail;
|
||||
|
||||
// FIXME: do we need this now that we clamp x in r_draw.c?
|
||||
edge_sentinel.u = 2000 << 24; // make sure nothing sorts past this
|
||||
edge_sentinel.prev = &edge_aftertail;
|
||||
|
||||
//
|
||||
// process all scan lines
|
||||
//
|
||||
bottom = r_refdef.vrectbottom - 1;
|
||||
|
||||
for (iv=r_refdef.vrect.y ; iv<bottom ; iv++)
|
||||
{
|
||||
current_iv = iv;
|
||||
fv = (float)iv;
|
||||
|
||||
// mark that the head (background start) span is pre-included
|
||||
surfaces[1].spanstate = 1;
|
||||
|
||||
if (newedges[iv])
|
||||
{
|
||||
R_InsertNewEdges (newedges[iv], edge_head.next);
|
||||
}
|
||||
|
||||
(*pdrawfunc) ();
|
||||
|
||||
// flush the span list if we can't be sure we have enough spans left for
|
||||
// the next scan
|
||||
if (span_p > max_span_p)
|
||||
{
|
||||
S_ExtraUpdate (); // don't let sound get messed up if going slow
|
||||
|
||||
if (r_drawculledpolys)
|
||||
R_DrawCulledPolys ();
|
||||
else
|
||||
D_DrawSurfaces ();
|
||||
|
||||
// clear the surface span pointers
|
||||
for (s = &surfaces[1] ; s<surface_p ; s++)
|
||||
s->spans = NULL;
|
||||
|
||||
span_p = basespan_p;
|
||||
}
|
||||
|
||||
if (removeedges[iv])
|
||||
R_RemoveEdges (removeedges[iv]);
|
||||
|
||||
if (edge_head.next != &edge_tail)
|
||||
R_StepActiveU (edge_head.next);
|
||||
}
|
||||
|
||||
// do the last scan (no need to step or sort or remove on the last scan)
|
||||
|
||||
current_iv = iv;
|
||||
fv = (float)iv;
|
||||
|
||||
// mark that the head (background start) span is pre-included
|
||||
surfaces[1].spanstate = 1;
|
||||
|
||||
if (newedges[iv])
|
||||
R_InsertNewEdges (newedges[iv], edge_head.next);
|
||||
|
||||
(*pdrawfunc) ();
|
||||
|
||||
// draw whatever's left in the span list
|
||||
if (r_drawculledpolys)
|
||||
R_DrawCulledPolys ();
|
||||
else
|
||||
D_DrawSurfaces ();
|
||||
}
|
||||
|
||||
|
|
@ -1,751 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// r_edgea.s
|
||||
// x86 assembly-language edge-processing code.
|
||||
//
|
||||
|
||||
#define SWQUAKE
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
Ltemp: .long 0
|
||||
float_1_div_0100000h: .long 0x35800000 // 1.0/(float)0x100000
|
||||
float_point_999: .single 0.999
|
||||
float_1_point_001: .single 1.001
|
||||
|
||||
.text
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#define edgestoadd 4+8 // note odd stack offsets because of interleaving
|
||||
#define edgelist 8+12 // with pushes
|
||||
|
||||
.globl C(R_EdgeCodeStart)
|
||||
C(R_EdgeCodeStart):
|
||||
|
||||
.globl C(R_InsertNewEdges)
|
||||
C(R_InsertNewEdges):
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
movl edgestoadd(%esp),%edx
|
||||
pushl %ebx
|
||||
movl edgelist(%esp),%ecx
|
||||
|
||||
LDoNextEdge:
|
||||
movl et_u(%edx),%eax
|
||||
movl %edx,%edi
|
||||
|
||||
LContinueSearch:
|
||||
movl et_u(%ecx),%ebx
|
||||
movl et_next(%ecx),%esi
|
||||
cmpl %ebx,%eax
|
||||
jle LAddedge
|
||||
movl et_u(%esi),%ebx
|
||||
movl et_next(%esi),%ecx
|
||||
cmpl %ebx,%eax
|
||||
jle LAddedge2
|
||||
movl et_u(%ecx),%ebx
|
||||
movl et_next(%ecx),%esi
|
||||
cmpl %ebx,%eax
|
||||
jle LAddedge
|
||||
movl et_u(%esi),%ebx
|
||||
movl et_next(%esi),%ecx
|
||||
cmpl %ebx,%eax
|
||||
jg LContinueSearch
|
||||
|
||||
LAddedge2:
|
||||
movl et_next(%edx),%edx
|
||||
movl et_prev(%esi),%ebx
|
||||
movl %esi,et_next(%edi)
|
||||
movl %ebx,et_prev(%edi)
|
||||
movl %edi,et_next(%ebx)
|
||||
movl %edi,et_prev(%esi)
|
||||
movl %esi,%ecx
|
||||
|
||||
cmpl $0,%edx
|
||||
jnz LDoNextEdge
|
||||
jmp LDone
|
||||
|
||||
.align 4
|
||||
LAddedge:
|
||||
movl et_next(%edx),%edx
|
||||
movl et_prev(%ecx),%ebx
|
||||
movl %ecx,et_next(%edi)
|
||||
movl %ebx,et_prev(%edi)
|
||||
movl %edi,et_next(%ebx)
|
||||
movl %edi,et_prev(%ecx)
|
||||
|
||||
cmpl $0,%edx
|
||||
jnz LDoNextEdge
|
||||
|
||||
LDone:
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
|
||||
ret
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#define predge 4+4
|
||||
|
||||
.globl C(R_RemoveEdges)
|
||||
C(R_RemoveEdges):
|
||||
pushl %ebx
|
||||
movl predge(%esp),%eax
|
||||
|
||||
Lre_loop:
|
||||
movl et_next(%eax),%ecx
|
||||
movl et_nextremove(%eax),%ebx
|
||||
movl et_prev(%eax),%edx
|
||||
testl %ebx,%ebx
|
||||
movl %edx,et_prev(%ecx)
|
||||
jz Lre_done
|
||||
movl %ecx,et_next(%edx)
|
||||
|
||||
movl et_next(%ebx),%ecx
|
||||
movl et_prev(%ebx),%edx
|
||||
movl et_nextremove(%ebx),%eax
|
||||
movl %edx,et_prev(%ecx)
|
||||
testl %eax,%eax
|
||||
movl %ecx,et_next(%edx)
|
||||
jnz Lre_loop
|
||||
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
Lre_done:
|
||||
movl %ecx,et_next(%edx)
|
||||
popl %ebx
|
||||
|
||||
ret
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#define pedgelist 4+4 // note odd stack offset because of interleaving
|
||||
// with pushes
|
||||
|
||||
.globl C(R_StepActiveU)
|
||||
C(R_StepActiveU):
|
||||
pushl %edi
|
||||
movl pedgelist(%esp),%edx
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
movl et_prev(%edx),%esi
|
||||
|
||||
LNewEdge:
|
||||
movl et_u(%esi),%edi
|
||||
|
||||
LNextEdge:
|
||||
movl et_u(%edx),%eax
|
||||
movl et_u_step(%edx),%ebx
|
||||
addl %ebx,%eax
|
||||
movl et_next(%edx),%esi
|
||||
movl %eax,et_u(%edx)
|
||||
cmpl %edi,%eax
|
||||
jl LPushBack
|
||||
|
||||
movl et_u(%esi),%edi
|
||||
movl et_u_step(%esi),%ebx
|
||||
addl %ebx,%edi
|
||||
movl et_next(%esi),%edx
|
||||
movl %edi,et_u(%esi)
|
||||
cmpl %eax,%edi
|
||||
jl LPushBack2
|
||||
|
||||
movl et_u(%edx),%eax
|
||||
movl et_u_step(%edx),%ebx
|
||||
addl %ebx,%eax
|
||||
movl et_next(%edx),%esi
|
||||
movl %eax,et_u(%edx)
|
||||
cmpl %edi,%eax
|
||||
jl LPushBack
|
||||
|
||||
movl et_u(%esi),%edi
|
||||
movl et_u_step(%esi),%ebx
|
||||
addl %ebx,%edi
|
||||
movl et_next(%esi),%edx
|
||||
movl %edi,et_u(%esi)
|
||||
cmpl %eax,%edi
|
||||
jnl LNextEdge
|
||||
|
||||
LPushBack2:
|
||||
movl %edx,%ebx
|
||||
movl %edi,%eax
|
||||
movl %esi,%edx
|
||||
movl %ebx,%esi
|
||||
|
||||
LPushBack:
|
||||
// push it back to keep it sorted
|
||||
movl et_prev(%edx),%ecx
|
||||
movl et_next(%edx),%ebx
|
||||
|
||||
// done if the -1 in edge_aftertail triggered this
|
||||
cmpl $(C(edge_aftertail)),%edx
|
||||
jz LUDone
|
||||
|
||||
// pull the edge out of the edge list
|
||||
movl et_prev(%ecx),%edi
|
||||
movl %ecx,et_prev(%esi)
|
||||
movl %ebx,et_next(%ecx)
|
||||
|
||||
// find out where the edge goes in the edge list
|
||||
LPushBackLoop:
|
||||
movl et_prev(%edi),%ecx
|
||||
movl et_u(%edi),%ebx
|
||||
cmpl %ebx,%eax
|
||||
jnl LPushBackFound
|
||||
|
||||
movl et_prev(%ecx),%edi
|
||||
movl et_u(%ecx),%ebx
|
||||
cmpl %ebx,%eax
|
||||
jl LPushBackLoop
|
||||
|
||||
movl %ecx,%edi
|
||||
|
||||
// put the edge back into the edge list
|
||||
LPushBackFound:
|
||||
movl et_next(%edi),%ebx
|
||||
movl %edi,et_prev(%edx)
|
||||
movl %ebx,et_next(%edx)
|
||||
movl %edx,et_next(%edi)
|
||||
movl %edx,et_prev(%ebx)
|
||||
|
||||
movl %esi,%edx
|
||||
movl et_prev(%esi),%esi
|
||||
|
||||
cmpl $(C(edge_tail)),%edx
|
||||
jnz LNewEdge
|
||||
|
||||
LUDone:
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
|
||||
ret
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#define surf 4 // note this is loaded before any pushes
|
||||
|
||||
.align 4
|
||||
TrailingEdge:
|
||||
movl st_spanstate(%esi),%eax // check for edge inversion
|
||||
decl %eax
|
||||
jnz LInverted
|
||||
|
||||
movl %eax,st_spanstate(%esi)
|
||||
movl st_insubmodel(%esi),%ecx
|
||||
movl 0x12345678,%edx // surfaces[1].st_next
|
||||
LPatch0:
|
||||
movl C(r_bmodelactive),%eax
|
||||
subl %ecx,%eax
|
||||
cmpl %esi,%edx
|
||||
movl %eax,C(r_bmodelactive)
|
||||
jnz LNoEmit // surface isn't on top, just remove
|
||||
|
||||
// emit a span (current top going away)
|
||||
movl et_u(%ebx),%eax
|
||||
shrl $20,%eax // iu = integral pixel u
|
||||
movl st_last_u(%esi),%edx
|
||||
movl st_next(%esi),%ecx
|
||||
cmpl %edx,%eax
|
||||
jle LNoEmit2 // iu <= surf->last_u, so nothing to emit
|
||||
|
||||
movl %eax,st_last_u(%ecx) // surf->next->last_u = iu;
|
||||
subl %edx,%eax
|
||||
movl %edx,espan_t_u(%ebp) // span->u = surf->last_u;
|
||||
|
||||
movl %eax,espan_t_count(%ebp) // span->count = iu - span->u;
|
||||
movl C(current_iv),%eax
|
||||
movl %eax,espan_t_v(%ebp) // span->v = current_iv;
|
||||
movl st_spans(%esi),%eax
|
||||
movl %eax,espan_t_pnext(%ebp) // span->pnext = surf->spans;
|
||||
movl %ebp,st_spans(%esi) // surf->spans = span;
|
||||
addl $(espan_t_size),%ebp
|
||||
|
||||
movl st_next(%esi),%edx // remove the surface from the surface
|
||||
movl st_prev(%esi),%esi // stack
|
||||
|
||||
movl %edx,st_next(%esi)
|
||||
movl %esi,st_prev(%edx)
|
||||
ret
|
||||
|
||||
LNoEmit2:
|
||||
movl %eax,st_last_u(%ecx) // surf->next->last_u = iu;
|
||||
movl st_next(%esi),%edx // remove the surface from the surface
|
||||
movl st_prev(%esi),%esi // stack
|
||||
|
||||
movl %edx,st_next(%esi)
|
||||
movl %esi,st_prev(%edx)
|
||||
ret
|
||||
|
||||
LNoEmit:
|
||||
movl st_next(%esi),%edx // remove the surface from the surface
|
||||
movl st_prev(%esi),%esi // stack
|
||||
|
||||
movl %edx,st_next(%esi)
|
||||
movl %esi,st_prev(%edx)
|
||||
ret
|
||||
|
||||
LInverted:
|
||||
movl %eax,st_spanstate(%esi)
|
||||
ret
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// trailing edge only
|
||||
Lgs_trailing:
|
||||
pushl $Lgs_nextedge
|
||||
jmp TrailingEdge
|
||||
|
||||
|
||||
.globl C(R_GenerateSpans)
|
||||
C(R_GenerateSpans):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// clear active surfaces to just the background surface
|
||||
movl C(surfaces),%eax
|
||||
movl C(edge_head_u_shift20),%edx
|
||||
addl $(st_size),%eax
|
||||
// %ebp = span_p throughout
|
||||
movl C(span_p),%ebp
|
||||
|
||||
movl $0,C(r_bmodelactive)
|
||||
|
||||
movl %eax,st_next(%eax)
|
||||
movl %eax,st_prev(%eax)
|
||||
movl %edx,st_last_u(%eax)
|
||||
movl C(edge_head)+et_next,%ebx // edge=edge_head.next
|
||||
|
||||
// generate spans
|
||||
cmpl $(C(edge_tail)),%ebx // done if empty list
|
||||
jz Lgs_lastspan
|
||||
|
||||
Lgs_edgeloop:
|
||||
|
||||
movl et_surfs(%ebx),%edi
|
||||
movl C(surfaces),%eax
|
||||
movl %edi,%esi
|
||||
andl $0xFFFF0000,%edi
|
||||
andl $0xFFFF,%esi
|
||||
jz Lgs_leading // not a trailing edge
|
||||
|
||||
// it has a left surface, so a surface is going away for this span
|
||||
shll $(SURF_T_SHIFT),%esi
|
||||
addl %eax,%esi
|
||||
testl %edi,%edi
|
||||
jz Lgs_trailing
|
||||
|
||||
// both leading and trailing
|
||||
call TrailingEdge
|
||||
movl C(surfaces),%eax
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// handle a leading edge
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
Lgs_leading:
|
||||
shrl $16-SURF_T_SHIFT,%edi
|
||||
movl C(surfaces),%eax
|
||||
addl %eax,%edi
|
||||
movl 0x12345678,%esi // surf2 = surfaces[1].next;
|
||||
LPatch2:
|
||||
movl st_spanstate(%edi),%edx
|
||||
movl st_insubmodel(%edi),%eax
|
||||
testl %eax,%eax
|
||||
jnz Lbmodel_leading
|
||||
|
||||
// handle a leading non-bmodel edge
|
||||
|
||||
// don't start a span if this is an inverted span, with the end edge preceding
|
||||
// the start edge (that is, we've already seen the end edge)
|
||||
testl %edx,%edx
|
||||
jnz Lxl_done
|
||||
|
||||
|
||||
// if (surf->key < surf2->key)
|
||||
// goto newtop;
|
||||
incl %edx
|
||||
movl st_key(%edi),%eax
|
||||
movl %edx,st_spanstate(%edi)
|
||||
movl st_key(%esi),%ecx
|
||||
cmpl %ecx,%eax
|
||||
jl Lnewtop
|
||||
|
||||
// main sorting loop to search through surface stack until insertion point
|
||||
// found. Always terminates because background surface is sentinel
|
||||
// do
|
||||
// {
|
||||
// surf2 = surf2->next;
|
||||
// } while (surf->key >= surf2->key);
|
||||
Lsortloopnb:
|
||||
movl st_next(%esi),%esi
|
||||
movl st_key(%esi),%ecx
|
||||
cmpl %ecx,%eax
|
||||
jge Lsortloopnb
|
||||
|
||||
jmp LInsertAndExit
|
||||
|
||||
|
||||
// handle a leading bmodel edge
|
||||
.align 4
|
||||
Lbmodel_leading:
|
||||
|
||||
// don't start a span if this is an inverted span, with the end edge preceding
|
||||
// the start edge (that is, we've already seen the end edge)
|
||||
testl %edx,%edx
|
||||
jnz Lxl_done
|
||||
|
||||
movl C(r_bmodelactive),%ecx
|
||||
incl %edx
|
||||
incl %ecx
|
||||
movl %edx,st_spanstate(%edi)
|
||||
movl %ecx,C(r_bmodelactive)
|
||||
|
||||
// if (surf->key < surf2->key)
|
||||
// goto newtop;
|
||||
movl st_key(%edi),%eax
|
||||
movl st_key(%esi),%ecx
|
||||
cmpl %ecx,%eax
|
||||
jl Lnewtop
|
||||
|
||||
// if ((surf->key == surf2->key) && surf->insubmodel)
|
||||
// {
|
||||
jz Lzcheck_for_newtop
|
||||
|
||||
// main sorting loop to search through surface stack until insertion point
|
||||
// found. Always terminates because background surface is sentinel
|
||||
// do
|
||||
// {
|
||||
// surf2 = surf2->next;
|
||||
// } while (surf->key > surf2->key);
|
||||
Lsortloop:
|
||||
movl st_next(%esi),%esi
|
||||
movl st_key(%esi),%ecx
|
||||
cmpl %ecx,%eax
|
||||
jg Lsortloop
|
||||
|
||||
jne LInsertAndExit
|
||||
|
||||
// Do 1/z sorting to see if we've arrived in the right position
|
||||
movl et_u(%ebx),%eax
|
||||
subl $0xFFFFF,%eax
|
||||
movl %eax,Ltemp
|
||||
fildl Ltemp
|
||||
|
||||
fmuls float_1_div_0100000h // fu = (float)(edge->u - 0xFFFFF) *
|
||||
// (1.0 / 0x100000);
|
||||
|
||||
fld %st(0) // fu | fu
|
||||
fmuls st_d_zistepu(%edi) // fu*surf->d_zistepu | fu
|
||||
flds C(fv) // fv | fu*surf->d_zistepu | fu
|
||||
fmuls st_d_zistepv(%edi) // fv*surf->d_zistepv | fu*surf->d_zistepu | fu
|
||||
fxch %st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu
|
||||
fadds st_d_ziorigin(%edi) // fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
|
||||
flds st_d_zistepu(%esi) // surf2->d_zistepu |
|
||||
// fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
fmul %st(3),%st(0) // fu*surf2->d_zistepu |
|
||||
// fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
fxch %st(1) // fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fu*surf2->d_zistepu |
|
||||
// fv*surf->d_zistepv | fu
|
||||
faddp %st(0),%st(2) // fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
flds C(fv) // fv | fu*surf2->d_zistepu | newzi | fu
|
||||
fmuls st_d_zistepv(%esi) // fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
fld %st(2) // newzi | fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
fmuls float_point_999 // newzibottom | fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
fxch %st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv |
|
||||
// newzibottom | newzi | fu
|
||||
fadds st_d_ziorigin(%esi) // fu*surf2->d_zistepu + surf2->d_ziorigin |
|
||||
// fv*surf2->d_zistepv | newzibottom | newzi |
|
||||
// fu
|
||||
faddp %st(0),%st(1) // testzi | newzibottom | newzi | fu
|
||||
fxch %st(1) // newzibottom | testzi | newzi | fu
|
||||
|
||||
// if (newzibottom >= testzi)
|
||||
// goto Lgotposition;
|
||||
|
||||
fcomp %st(1) // testzi | newzi | fu
|
||||
|
||||
fxch %st(1) // newzi | testzi | fu
|
||||
fmuls float_1_point_001 // newzitop | testzi | fu
|
||||
fxch %st(1) // testzi | newzitop | fu
|
||||
|
||||
fnstsw %ax
|
||||
testb $0x01,%ah
|
||||
jz Lgotposition_fpop3
|
||||
|
||||
// if (newzitop >= testzi)
|
||||
// {
|
||||
|
||||
fcomp %st(1) // newzitop | fu
|
||||
fnstsw %ax
|
||||
testb $0x45,%ah
|
||||
jz Lsortloop_fpop2
|
||||
|
||||
// if (surf->d_zistepu >= surf2->d_zistepu)
|
||||
// goto newtop;
|
||||
|
||||
flds st_d_zistepu(%edi) // surf->d_zistepu | newzitop| fu
|
||||
fcomps st_d_zistepu(%esi) // newzitop | fu
|
||||
fnstsw %ax
|
||||
testb $0x01,%ah
|
||||
jz Lgotposition_fpop2
|
||||
|
||||
fstp %st(0) // clear the FPstack
|
||||
fstp %st(0)
|
||||
movl st_key(%edi),%eax
|
||||
jmp Lsortloop
|
||||
|
||||
|
||||
Lgotposition_fpop3:
|
||||
fstp %st(0)
|
||||
Lgotposition_fpop2:
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
jmp LInsertAndExit
|
||||
|
||||
|
||||
// emit a span (obscures current top)
|
||||
|
||||
Lnewtop_fpop3:
|
||||
fstp %st(0)
|
||||
Lnewtop_fpop2:
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
movl st_key(%edi),%eax // reload the sorting key
|
||||
|
||||
Lnewtop:
|
||||
movl et_u(%ebx),%eax
|
||||
movl st_last_u(%esi),%edx
|
||||
shrl $20,%eax // iu = integral pixel u
|
||||
movl %eax,st_last_u(%edi) // surf->last_u = iu;
|
||||
cmpl %edx,%eax
|
||||
jle LInsertAndExit // iu <= surf->last_u, so nothing to emit
|
||||
|
||||
subl %edx,%eax
|
||||
movl %edx,espan_t_u(%ebp) // span->u = surf->last_u;
|
||||
|
||||
movl %eax,espan_t_count(%ebp) // span->count = iu - span->u;
|
||||
movl C(current_iv),%eax
|
||||
movl %eax,espan_t_v(%ebp) // span->v = current_iv;
|
||||
movl st_spans(%esi),%eax
|
||||
movl %eax,espan_t_pnext(%ebp) // span->pnext = surf->spans;
|
||||
movl %ebp,st_spans(%esi) // surf->spans = span;
|
||||
addl $(espan_t_size),%ebp
|
||||
|
||||
LInsertAndExit:
|
||||
// insert before surf2
|
||||
movl %esi,st_next(%edi) // surf->next = surf2;
|
||||
movl st_prev(%esi),%eax
|
||||
movl %eax,st_prev(%edi) // surf->prev = surf2->prev;
|
||||
movl %edi,st_prev(%esi) // surf2->prev = surf;
|
||||
movl %edi,st_next(%eax) // surf2->prev->next = surf;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// leading edge done
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// see if there are any more edges
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
Lgs_nextedge:
|
||||
movl et_next(%ebx),%ebx
|
||||
cmpl $(C(edge_tail)),%ebx
|
||||
jnz Lgs_edgeloop
|
||||
|
||||
// clean up at the right edge
|
||||
Lgs_lastspan:
|
||||
|
||||
// now that we've reached the right edge of the screen, we're done with any
|
||||
// unfinished surfaces, so emit a span for whatever's on top
|
||||
movl 0x12345678,%esi // surfaces[1].st_next
|
||||
LPatch3:
|
||||
movl C(edge_tail_u_shift20),%eax
|
||||
xorl %ecx,%ecx
|
||||
movl st_last_u(%esi),%edx
|
||||
subl %edx,%eax
|
||||
jle Lgs_resetspanstate
|
||||
|
||||
movl %edx,espan_t_u(%ebp)
|
||||
movl %eax,espan_t_count(%ebp)
|
||||
movl C(current_iv),%eax
|
||||
movl %eax,espan_t_v(%ebp)
|
||||
movl st_spans(%esi),%eax
|
||||
movl %eax,espan_t_pnext(%ebp)
|
||||
movl %ebp,st_spans(%esi)
|
||||
addl $(espan_t_size),%ebp
|
||||
|
||||
// reset spanstate for all surfaces in the surface stack
|
||||
Lgs_resetspanstate:
|
||||
movl %ecx,st_spanstate(%esi)
|
||||
movl st_next(%esi),%esi
|
||||
cmpl $0x12345678,%esi // &surfaces[1]
|
||||
LPatch4:
|
||||
jnz Lgs_resetspanstate
|
||||
|
||||
// store the final span_p
|
||||
movl %ebp,C(span_p)
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// 1/z sorting for bmodels in the same leaf
|
||||
// ---------------------------------------------------------------
|
||||
.align 4
|
||||
Lxl_done:
|
||||
incl %edx
|
||||
movl %edx,st_spanstate(%edi)
|
||||
|
||||
jmp Lgs_nextedge
|
||||
|
||||
|
||||
.align 4
|
||||
Lzcheck_for_newtop:
|
||||
movl et_u(%ebx),%eax
|
||||
subl $0xFFFFF,%eax
|
||||
movl %eax,Ltemp
|
||||
fildl Ltemp
|
||||
|
||||
fmuls float_1_div_0100000h // fu = (float)(edge->u - 0xFFFFF) *
|
||||
// (1.0 / 0x100000);
|
||||
|
||||
fld %st(0) // fu | fu
|
||||
fmuls st_d_zistepu(%edi) // fu*surf->d_zistepu | fu
|
||||
flds C(fv) // fv | fu*surf->d_zistepu | fu
|
||||
fmuls st_d_zistepv(%edi) // fv*surf->d_zistepv | fu*surf->d_zistepu | fu
|
||||
fxch %st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu
|
||||
fadds st_d_ziorigin(%edi) // fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
|
||||
flds st_d_zistepu(%esi) // surf2->d_zistepu |
|
||||
// fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
fmul %st(3),%st(0) // fu*surf2->d_zistepu |
|
||||
// fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
fxch %st(1) // fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fu*surf2->d_zistepu |
|
||||
// fv*surf->d_zistepv | fu
|
||||
faddp %st(0),%st(2) // fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
flds C(fv) // fv | fu*surf2->d_zistepu | newzi | fu
|
||||
fmuls st_d_zistepv(%esi) // fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
fld %st(2) // newzi | fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
fmuls float_point_999 // newzibottom | fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
fxch %st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv |
|
||||
// newzibottom | newzi | fu
|
||||
fadds st_d_ziorigin(%esi) // fu*surf2->d_zistepu + surf2->d_ziorigin |
|
||||
// fv*surf2->d_zistepv | newzibottom | newzi |
|
||||
// fu
|
||||
faddp %st(0),%st(1) // testzi | newzibottom | newzi | fu
|
||||
fxch %st(1) // newzibottom | testzi | newzi | fu
|
||||
|
||||
// if (newzibottom >= testzi)
|
||||
// goto newtop;
|
||||
|
||||
fcomp %st(1) // testzi | newzi | fu
|
||||
|
||||
fxch %st(1) // newzi | testzi | fu
|
||||
fmuls float_1_point_001 // newzitop | testzi | fu
|
||||
fxch %st(1) // testzi | newzitop | fu
|
||||
|
||||
fnstsw %ax
|
||||
testb $0x01,%ah
|
||||
jz Lnewtop_fpop3
|
||||
|
||||
// if (newzitop >= testzi)
|
||||
// {
|
||||
|
||||
fcomp %st(1) // newzitop | fu
|
||||
fnstsw %ax
|
||||
testb $0x45,%ah
|
||||
jz Lsortloop_fpop2
|
||||
|
||||
// if (surf->d_zistepu >= surf2->d_zistepu)
|
||||
// goto newtop;
|
||||
|
||||
flds st_d_zistepu(%edi) // surf->d_zistepu | newzitop | fu
|
||||
fcomps st_d_zistepu(%esi) // newzitop | fu
|
||||
fnstsw %ax
|
||||
testb $0x01,%ah
|
||||
jz Lnewtop_fpop2
|
||||
|
||||
Lsortloop_fpop2:
|
||||
fstp %st(0) // clear the FP stack
|
||||
fstp %st(0)
|
||||
movl st_key(%edi),%eax
|
||||
jmp Lsortloop
|
||||
|
||||
|
||||
.globl C(R_EdgeCodeEnd)
|
||||
C(R_EdgeCodeEnd):
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface array address code patching routine
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_SurfacePatch)
|
||||
C(R_SurfacePatch):
|
||||
|
||||
movl C(surfaces),%eax
|
||||
addl $(st_size),%eax
|
||||
movl %eax,LPatch4-4
|
||||
|
||||
addl $(st_next),%eax
|
||||
movl %eax,LPatch0-4
|
||||
movl %eax,LPatch2-4
|
||||
movl %eax,LPatch3-4
|
||||
|
||||
ret
|
||||
|
||||
#endif // id386
|
||||
|
|
@ -1,476 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_light.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
|
||||
int r_dlightframecount;
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
R_AnimateLight
|
||||
==================
|
||||
*/
|
||||
void SWR_AnimateLight (void)
|
||||
{
|
||||
int i,j;
|
||||
int v1, v2;
|
||||
float f;
|
||||
|
||||
//
|
||||
// light animations
|
||||
// 'm' is normal light, 'a' is no light, 'z' is double bright
|
||||
f = (cl.time*r_lightstylespeed.value);
|
||||
if (f < 0)
|
||||
f = 0;
|
||||
i = (int)f;
|
||||
|
||||
if (r_lightstylesmooth.value)
|
||||
f -= i; //this can require updates at 1000 times a second.. Depends on your framerate of course
|
||||
else
|
||||
f = 0; //only update them 10 times a second
|
||||
for (j=0 ; j<MAX_LIGHTSTYLES ; j++)
|
||||
{
|
||||
if (!cl_lightstyle[j].length)
|
||||
{
|
||||
d_lightstylevalue[j] = 256;
|
||||
cl_lightstyle[j].colour = 7;
|
||||
continue;
|
||||
}
|
||||
v1 = i % cl_lightstyle[j].length;
|
||||
v1 = cl_lightstyle[j].map[v1] - 'a';
|
||||
|
||||
v2 = (i+1) % cl_lightstyle[j].length;
|
||||
v2 = cl_lightstyle[j].map[v2] - 'a';
|
||||
|
||||
d_lightstylevalue[j] = (v1*(1-f) + v2*(f))*22;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
DYNAMIC LIGHTS
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
=============
|
||||
R_MarkLights
|
||||
=============
|
||||
*/
|
||||
void SWR_MarkLights (dlight_t *light, int bit, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
|
||||
if (node->contents < 0)
|
||||
return;
|
||||
|
||||
splitplane = node->plane;
|
||||
dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
|
||||
|
||||
if (dist > light->radius)
|
||||
{
|
||||
SWR_MarkLights (light, bit, node->children[0]);
|
||||
return;
|
||||
}
|
||||
if (dist < -light->radius)
|
||||
{
|
||||
SWR_MarkLights (light, bit, node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the polygons
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->dlightframe != r_dlightframecount)
|
||||
{
|
||||
surf->dlightbits = 0;
|
||||
surf->dlightframe = r_dlightframecount;
|
||||
}
|
||||
surf->dlightbits |= bit;
|
||||
}
|
||||
|
||||
SWR_MarkLights (light, bit, node->children[0]);
|
||||
SWR_MarkLights (light, bit, node->children[1]);
|
||||
}
|
||||
|
||||
void SWR_Q2MarkLights (dlight_t *light, int bit, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
|
||||
if (node->contents != -1)
|
||||
return;
|
||||
|
||||
splitplane = node->plane;
|
||||
dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
|
||||
|
||||
if (dist > light->radius)
|
||||
{
|
||||
SWR_Q2MarkLights (light, bit, node->children[0]);
|
||||
return;
|
||||
}
|
||||
if (dist < -light->radius)
|
||||
{
|
||||
SWR_Q2MarkLights (light, bit, node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the polygons
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->dlightframe != r_dlightframecount)
|
||||
{
|
||||
surf->dlightbits = 0;
|
||||
surf->dlightframe = r_dlightframecount;
|
||||
}
|
||||
surf->dlightbits |= bit;
|
||||
}
|
||||
|
||||
SWR_Q2MarkLights (light, bit, node->children[0]);
|
||||
SWR_Q2MarkLights (light, bit, node->children[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_PushDlights
|
||||
=============
|
||||
*/
|
||||
void SWR_PushDlights (void)
|
||||
{
|
||||
int i;
|
||||
dlight_t *l;
|
||||
|
||||
r_dlightframecount = r_framecount + 1; // because the count hasn't
|
||||
// advanced yet for this frame
|
||||
|
||||
if (!r_dynamic.value)
|
||||
return;
|
||||
|
||||
l = cl_dlights;
|
||||
|
||||
if (cl.worldmodel->fromgame == fg_quake2)
|
||||
{
|
||||
for (i=0 ; i<dlights_software ; i++, l++)
|
||||
{
|
||||
if (!l->radius)
|
||||
continue;
|
||||
SWR_Q2MarkLights ( l, 1<<i, cl.worldmodel->nodes );
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0 ; i<dlights_software ; i++, l++)
|
||||
{
|
||||
if (!l->radius)
|
||||
continue;
|
||||
SWR_MarkLights ( l, 1<<i, cl.worldmodel->nodes );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
LIGHT SAMPLING
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
int SWRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
|
||||
{
|
||||
int r;
|
||||
float front, back, frac;
|
||||
int side;
|
||||
mplane_t *plane;
|
||||
vec3_t mid;
|
||||
msurface_t *surf;
|
||||
int s, t, ds, dt;
|
||||
int i;
|
||||
mtexinfo_t *tex;
|
||||
qbyte *lightmap;
|
||||
unsigned scale;
|
||||
int maps;
|
||||
|
||||
if (cl.worldmodel->fromgame == fg_quake2)
|
||||
{
|
||||
if (node->contents != -1)
|
||||
return -1; // solid
|
||||
}
|
||||
else if (node->contents < 0)
|
||||
return -1; // didn't hit anything
|
||||
|
||||
// calculate mid point
|
||||
|
||||
// FIXME: optimize for axial
|
||||
plane = node->plane;
|
||||
front = DotProduct (start, plane->normal) - plane->dist;
|
||||
back = DotProduct (end, plane->normal) - plane->dist;
|
||||
side = front < 0;
|
||||
|
||||
if ( (back < 0) == side)
|
||||
return SWRecursiveLightPoint (node->children[side], start, end);
|
||||
|
||||
frac = front / (front-back);
|
||||
mid[0] = start[0] + (end[0] - start[0])*frac;
|
||||
mid[1] = start[1] + (end[1] - start[1])*frac;
|
||||
mid[2] = start[2] + (end[2] - start[2])*frac;
|
||||
|
||||
// go down front side
|
||||
r = SWRecursiveLightPoint (node->children[side], start, mid);
|
||||
if (r >= 0)
|
||||
return r; // hit something
|
||||
|
||||
if ( (back < 0) == side )
|
||||
return -1; // didn't hit anuthing
|
||||
|
||||
// check for impact on this node
|
||||
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->flags & SURF_DRAWTILED)
|
||||
continue; // no lightmaps
|
||||
|
||||
tex = surf->texinfo;
|
||||
|
||||
s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
|
||||
t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];;
|
||||
|
||||
if (s < surf->texturemins[0] ||
|
||||
t < surf->texturemins[1])
|
||||
continue;
|
||||
|
||||
ds = s - surf->texturemins[0];
|
||||
dt = t - surf->texturemins[1];
|
||||
|
||||
if ( ds > surf->extents[0] || dt > surf->extents[1] )
|
||||
continue;
|
||||
|
||||
if (!surf->samples)
|
||||
return 0;
|
||||
|
||||
ds >>= 4;
|
||||
dt >>= 4;
|
||||
|
||||
lightmap = surf->samples;
|
||||
r = 0;
|
||||
if (lightmap)
|
||||
{
|
||||
|
||||
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds);
|
||||
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
r += *lightmap * scale;
|
||||
lightmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1);
|
||||
}
|
||||
|
||||
r >>= 8;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// go down back side
|
||||
return SWRecursiveLightPoint (node->children[!side], mid, end);
|
||||
}
|
||||
int SWRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
|
||||
{
|
||||
int r;
|
||||
float front, back, frac;
|
||||
int side;
|
||||
mplane_t *plane;
|
||||
vec3_t mid;
|
||||
msurface_t *surf;
|
||||
int s, t, ds, dt;
|
||||
int i;
|
||||
mtexinfo_t *tex;
|
||||
qbyte *lightmap;
|
||||
unsigned scale;
|
||||
int maps;
|
||||
|
||||
|
||||
if (cl.worldmodel->fromgame == fg_quake2)
|
||||
{
|
||||
if (node->contents != -1)
|
||||
return -1; // solid
|
||||
}
|
||||
else if (node->contents < 0)
|
||||
return -1; // didn't hit anything
|
||||
|
||||
// calculate mid point
|
||||
|
||||
// FIXME: optimize for axial
|
||||
plane = node->plane;
|
||||
front = DotProduct (start, plane->normal) - plane->dist;
|
||||
back = DotProduct (end, plane->normal) - plane->dist;
|
||||
side = front < 0;
|
||||
|
||||
if ( (back < 0) == side)
|
||||
return SWRecursiveLightPoint3C (node->children[side], start, end);
|
||||
|
||||
frac = front / (front-back);
|
||||
mid[0] = start[0] + (end[0] - start[0])*frac;
|
||||
mid[1] = start[1] + (end[1] - start[1])*frac;
|
||||
mid[2] = start[2] + (end[2] - start[2])*frac;
|
||||
|
||||
// go down front side
|
||||
r = SWRecursiveLightPoint (node->children[side], start, mid);
|
||||
if (r >= 0)
|
||||
return r; // hit something
|
||||
|
||||
if ( (back < 0) == side )
|
||||
return -1; // didn't hit anuthing
|
||||
|
||||
// check for impact on this node
|
||||
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->flags & SURF_DRAWTILED)
|
||||
continue; // no lightmaps
|
||||
|
||||
tex = surf->texinfo;
|
||||
|
||||
s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
|
||||
t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];;
|
||||
|
||||
if (s < surf->texturemins[0] ||
|
||||
t < surf->texturemins[1])
|
||||
continue;
|
||||
|
||||
ds = s - surf->texturemins[0];
|
||||
dt = t - surf->texturemins[1];
|
||||
|
||||
if ( ds > surf->extents[0] || dt > surf->extents[1] )
|
||||
continue;
|
||||
|
||||
if (!surf->samples)
|
||||
return 0;
|
||||
|
||||
ds >>= 4;
|
||||
dt >>= 4;
|
||||
|
||||
lightmap = surf->samples;
|
||||
r = 0;
|
||||
if (lightmap)
|
||||
{
|
||||
|
||||
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
|
||||
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
r += (lightmap[0]+lightmap[1]+lightmap[2])/3 * scale;
|
||||
lightmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1)*3;
|
||||
}
|
||||
|
||||
r >>= 8;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// go down back side
|
||||
return SWRecursiveLightPoint3C (node->children[!side], mid, end);
|
||||
}
|
||||
int SWR_LightPoint (vec3_t p)
|
||||
{
|
||||
vec3_t end;
|
||||
int r;
|
||||
extern qboolean r_usinglits;
|
||||
|
||||
if (r_refdef.flags & 1 || !cl.worldmodel || !cl.worldmodel->lightdata)
|
||||
return 255;
|
||||
|
||||
end[0] = p[0];
|
||||
end[1] = p[1];
|
||||
end[2] = p[2] - 2048;
|
||||
|
||||
if (r_usinglits)
|
||||
r = SWRecursiveLightPoint3C (cl.worldmodel->nodes, p, end);
|
||||
else
|
||||
r = SWRecursiveLightPoint (cl.worldmodel->nodes, p, end);
|
||||
|
||||
if (r == -1)
|
||||
r = 0;
|
||||
|
||||
if (r < r_refdef.ambientlight)
|
||||
r = r_refdef.ambientlight;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void SWQ1BSP_LightPointValues(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir)
|
||||
{
|
||||
vec3_t end;
|
||||
float r;
|
||||
|
||||
res_dir[0] = 0; //software doesn't load luxes
|
||||
res_dir[1] = 1;
|
||||
res_dir[2] = 1;
|
||||
|
||||
end[0] = point[0];
|
||||
end[1] = point[1];
|
||||
end[2] = point[2] - 2048;
|
||||
|
||||
r = SWRecursiveLightPoint3C(mod->nodes, point, end);
|
||||
if (r < 0)
|
||||
{
|
||||
res_diffuse[0] = 0;
|
||||
res_diffuse[1] = 0;
|
||||
res_diffuse[2] = 0;
|
||||
|
||||
res_ambient[0] = 0;
|
||||
res_ambient[1] = 0;
|
||||
res_ambient[2] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
res_diffuse[0] = r;
|
||||
res_diffuse[1] = r;
|
||||
res_diffuse[2] = r;
|
||||
|
||||
res_ambient[0] = r;
|
||||
res_ambient[1] = r;
|
||||
res_ambient[2] = r;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,325 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_local.h -- private refresh defs
|
||||
#ifndef R_LOCAL_H
|
||||
#define R_LOCAL_H
|
||||
|
||||
#ifdef SWQUAKE
|
||||
|
||||
#include "r_shared.h"
|
||||
|
||||
#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0)
|
||||
// normalizing factor so player model works out to about
|
||||
// 1 pixel per triangle
|
||||
|
||||
#define BMODEL_FULLY_CLIPPED 0x10 // value returned by R_BmodelCheckBBox ()
|
||||
// if bbox is trivially rejected
|
||||
|
||||
//===========================================================================
|
||||
// viewmodel lighting
|
||||
|
||||
typedef struct {
|
||||
int ambientlight;
|
||||
int shadelight;
|
||||
float *plightvec;
|
||||
} alight_t;
|
||||
|
||||
//===========================================================================
|
||||
// clipped bmodel edges
|
||||
|
||||
typedef struct bedge_s
|
||||
{
|
||||
mvertex_t *v[2];
|
||||
struct bedge_s *pnext;
|
||||
} bedge_t;
|
||||
|
||||
typedef struct {
|
||||
float fv[3]; // viewspace x, y
|
||||
} auxvert_t;
|
||||
|
||||
//===========================================================================
|
||||
|
||||
extern cvar_t r_draworder;
|
||||
extern cvar_t r_speeds;
|
||||
extern cvar_t r_timegraph;
|
||||
extern cvar_t r_graphheight;
|
||||
extern cvar_t r_clearcolor;
|
||||
extern cvar_t r_waterwarp;
|
||||
extern cvar_t r_fullbright;
|
||||
extern cvar_t r_drawentities;
|
||||
extern cvar_t r_aliasstats;
|
||||
extern cvar_t r_dspeeds;
|
||||
extern cvar_t r_ambient;
|
||||
extern cvar_t r_reportsurfout;
|
||||
extern cvar_t r_maxsurfs;
|
||||
extern cvar_t r_numsurfs;
|
||||
extern cvar_t r_reportedgeout;
|
||||
extern cvar_t r_maxedges;
|
||||
extern cvar_t r_numedges;
|
||||
|
||||
#define XCENTERING (1.0 / 2.0)
|
||||
#define YCENTERING (1.0 / 2.0)
|
||||
|
||||
#define CLIP_EPSILON 0.001
|
||||
|
||||
#define BACKFACE_EPSILON 0.01
|
||||
|
||||
//===========================================================================
|
||||
|
||||
#define DIST_NOT_SET 98765
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct clipplane_s
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
struct clipplane_s *next;
|
||||
qbyte leftedge;
|
||||
qbyte rightedge;
|
||||
qbyte reserved[2];
|
||||
} clipplane_t;
|
||||
|
||||
extern clipplane_t view_clipplanes[4];
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void R_RenderWorld (void);
|
||||
|
||||
//=============================================================================
|
||||
|
||||
extern mplane_t screenedge[4];
|
||||
|
||||
extern vec3_t r_origin;
|
||||
|
||||
extern vec3_t r_entorigin;
|
||||
|
||||
extern float screenAspect;
|
||||
extern float verticalFieldOfView;
|
||||
extern float xOrigin, yOrigin;
|
||||
|
||||
extern int r_visframecount;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
extern int vstartscan;
|
||||
|
||||
|
||||
void R_ClearPolyList (void);
|
||||
void R_DrawPolyList (void);
|
||||
|
||||
//
|
||||
// current entity info
|
||||
//
|
||||
extern qboolean insubmodel;
|
||||
extern vec3_t r_worldmodelorg;
|
||||
|
||||
|
||||
void R_DrawSprite (void);
|
||||
void R_RenderFace (msurface_t *fa, int clipflags);
|
||||
void R_RenderPoly (msurface_t *fa, int clipflags);
|
||||
void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf);
|
||||
void R_TransformPlane (mplane_t *p, float *normal, float *dist);
|
||||
void R_TransformFrustum (void);
|
||||
void R_SetSkyFrame (void);
|
||||
void R_DrawSurfaceBlock16From8 (void);
|
||||
void R_DrawSurfaceBlock8 (void);
|
||||
texture_t *SWR_TextureAnimation (texture_t *base);
|
||||
|
||||
#if id386
|
||||
|
||||
void R_DrawSurfaceBlock8_mip0 (void);
|
||||
void R_DrawSurfaceBlock8_mip1 (void);
|
||||
void R_DrawSurfaceBlock8_mip2 (void);
|
||||
void R_DrawSurfaceBlock8_mip3 (void);
|
||||
|
||||
#endif
|
||||
|
||||
void R_GenSkyTile (void *pdest);
|
||||
void R_GenSkyTile16 (void *pdest);
|
||||
void R_Surf8Patch (void);
|
||||
void R_Surf16Patch (void);
|
||||
void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags);
|
||||
void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel);
|
||||
|
||||
void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel);
|
||||
surf_t *R_GetSurf (void);
|
||||
void R_AliasDrawModel (alight_t *plighting);
|
||||
void R_BeginEdgeFrame (void);
|
||||
void R_ScanEdges (void);
|
||||
void D_DrawSurfaces (void);
|
||||
void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist);
|
||||
void R_StepActiveU (edge_t *pedge);
|
||||
void R_RemoveEdges (edge_t *pedge);
|
||||
|
||||
extern void R_Surf8Start (void);
|
||||
extern void R_Surf8End (void);
|
||||
extern void R_Surf16Start (void);
|
||||
extern void R_Surf16End (void);
|
||||
extern void R_EdgeCodeStart (void);
|
||||
extern void R_EdgeCodeEnd (void);
|
||||
|
||||
extern void R_RotateBmodel (void);
|
||||
|
||||
extern int c_faceclip;
|
||||
extern int r_polycount;
|
||||
extern int r_wholepolycount;
|
||||
|
||||
extern model_t *cl_worldmodel;
|
||||
|
||||
extern int *pfrustum_indexes[4];
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
#define NEAR_CLIP 0.01
|
||||
|
||||
extern int ubasestep, errorterm, erroradjustup, erroradjustdown;
|
||||
extern int vstartscan;
|
||||
|
||||
extern fixed16_t sadjust, tadjust;
|
||||
extern fixed16_t bbextents, bbextentt;
|
||||
|
||||
#define MAXBVERTINDEXES 1000 // new clipped vertices when clipping bmodels
|
||||
// to the world BSP
|
||||
extern mvertex_t *r_ptverts, *r_ptvertsmax;
|
||||
|
||||
extern vec3_t sbaseaxis[3], tbaseaxis[3];
|
||||
extern float entity_rotation[3][3];
|
||||
|
||||
extern int reinit_surfcache;
|
||||
|
||||
extern int r_currentkey;
|
||||
extern int r_currentbkey;
|
||||
|
||||
typedef struct btofpoly_s {
|
||||
int clipflags;
|
||||
msurface_t *psurf;
|
||||
} btofpoly_t;
|
||||
|
||||
#define MAX_BTOFPOLYS 5000 // FIXME: tune this
|
||||
|
||||
extern int numbtofpolys;
|
||||
extern btofpoly_t *pbtofpolys;
|
||||
|
||||
void R_InitTurb (void);
|
||||
void R_ZDrawSubmodelPolys (model_t *clmodel);
|
||||
|
||||
//=========================================================
|
||||
// Alias models
|
||||
//=========================================================
|
||||
|
||||
extern int numverts;
|
||||
extern int a_skinwidth;
|
||||
extern mtriangle_t *ptriangles;
|
||||
extern int numtriangles;
|
||||
extern aliashdr_t *paliashdr;
|
||||
extern mmdl_t *pmdl;
|
||||
extern float leftclip, topclip, rightclip, bottomclip;
|
||||
extern int r_acliptype;
|
||||
extern finalvert_t *pfinalverts;
|
||||
extern auxvert_t *pauxverts;
|
||||
|
||||
qboolean R_AliasCheckBBox (void);
|
||||
|
||||
//=========================================================
|
||||
// turbulence stuff
|
||||
|
||||
#define AMP 8*0x10000
|
||||
#define AMP2 3
|
||||
#define SPEED 20
|
||||
|
||||
void R_SurfacePatch (void);
|
||||
|
||||
extern int r_amodels_drawn;
|
||||
extern edge_t *auxedges;
|
||||
extern int r_numallocatededges;
|
||||
extern edge_t *r_edges, *edge_p, *edge_max;
|
||||
|
||||
extern edge_t *newedges[MAXHEIGHT];
|
||||
extern edge_t *removeedges[MAXHEIGHT];
|
||||
|
||||
extern int screenwidth;
|
||||
|
||||
extern qboolean r_usinglits;
|
||||
|
||||
// FIXME: make stack vars when debugging done
|
||||
extern edge_t edge_head;
|
||||
extern edge_t edge_tail;
|
||||
extern edge_t edge_aftertail;
|
||||
extern int r_bmodelactive;
|
||||
|
||||
extern float aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
|
||||
extern float r_aliastransition, r_resfudge;
|
||||
|
||||
extern int r_outofsurfaces;
|
||||
extern int r_outofedges;
|
||||
|
||||
extern mvertex_t *r_pcurrentvertbase;
|
||||
extern int r_maxvalidedgeoffset;
|
||||
|
||||
void R_AliasClipTriangle (mtriangle_t *ptri, void (*drawfnc) (void));
|
||||
|
||||
extern float r_time1;
|
||||
extern float dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
|
||||
extern float se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2;
|
||||
extern int r_frustum_indexes[4*6];
|
||||
extern int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
|
||||
extern qboolean r_surfsonstack;
|
||||
extern cshift_t cshift_water;
|
||||
extern qboolean r_dowarpold, r_viewchanged;
|
||||
|
||||
extern mleaf_t *r_viewleaf, *r_oldviewleaf;
|
||||
|
||||
extern vec3_t r_emins, r_emaxs;
|
||||
extern mnode_t *r_pefragtopnode;
|
||||
extern int r_clipflags;
|
||||
extern int r_dlightframecount;
|
||||
extern qboolean r_fov_greater_than_90;
|
||||
|
||||
void R_StoreEfrags (efrag_t **ppefrag);
|
||||
void SWR_TimeRefresh_f (void);
|
||||
void R_TimeGraph (void);
|
||||
void R_PrintAliasStats (void);
|
||||
void R_PrintTimes (void);
|
||||
void R_PrintDSpeeds (void);
|
||||
void SWR_AnimateLight (void);
|
||||
int SWR_LightPoint (vec3_t p);
|
||||
//void R_SetupFrame (void);
|
||||
void R_cshift_f (void);
|
||||
void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1);
|
||||
void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip);
|
||||
void R_Q1BSP_SplitEntityOnNode2 (mnode_t *node);
|
||||
void SWR_MarkLights (dlight_t *light, int bit, mnode_t *node);
|
||||
|
||||
void SWR_DrawAlphaSurfaces( void );
|
||||
void SWR_SetupFrame (void);
|
||||
void R_InitSkyBox (void);
|
||||
void R_InitSkyBox (void);
|
||||
void SWR_BuildLightmaps(void);
|
||||
void R_WipeDecals(void);
|
||||
void SWR_NetGraph (void);
|
||||
|
||||
qbyte *SWMod_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer);
|
||||
|
||||
void D_DrawSparkTrans (vec3_t src, vec3_t dest, float palpha, unsigned int pcolour, blendmode_t blendmode);
|
||||
|
||||
|
||||
void D_Shutdown (void);
|
||||
|
||||
#endif //def SWQUAKE
|
||||
#endif
|
1831
engine/sw/r_main.c
1831
engine/sw/r_main.c
File diff suppressed because it is too large
Load diff
|
@ -1,667 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_misc.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
extern int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
|
||||
|
||||
/*
|
||||
===============
|
||||
R_CheckVariables
|
||||
===============
|
||||
*/
|
||||
void R_CheckVariables (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Show
|
||||
|
||||
Debugging use
|
||||
============
|
||||
*/
|
||||
void Show (void)
|
||||
{
|
||||
vrect_t vr;
|
||||
|
||||
vr.x = vr.y = 0;
|
||||
vr.width = vid.width;
|
||||
vr.height = vid.height;
|
||||
vr.pnext = NULL;
|
||||
SWVID_Update (&vr);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
R_TimeRefresh_f
|
||||
|
||||
For program optimization
|
||||
====================
|
||||
*/
|
||||
void SWR_TimeRefresh_f (void)
|
||||
{
|
||||
int i;
|
||||
float start, stop, time;
|
||||
int startangle;
|
||||
vrect_t vr;
|
||||
|
||||
startangle = r_refdef.viewangles[1];
|
||||
|
||||
start = Sys_DoubleTime ();
|
||||
for (i=0 ; i<128 ; i++)
|
||||
{
|
||||
r_refdef.viewangles[1] = i/128.0*360.0;
|
||||
|
||||
VID_LockBuffer ();
|
||||
|
||||
R_RenderView ();
|
||||
|
||||
VID_UnlockBuffer ();
|
||||
|
||||
vr.x = r_refdef.vrect.x;
|
||||
vr.y = r_refdef.vrect.y;
|
||||
vr.width = r_refdef.vrect.width;
|
||||
vr.height = r_refdef.vrect.height;
|
||||
vr.pnext = NULL;
|
||||
SWVID_Update (&vr);
|
||||
}
|
||||
stop = Sys_DoubleTime ();
|
||||
time = stop-start;
|
||||
Con_Printf ("%f seconds (%f fps)\n", time, 128/time);
|
||||
|
||||
r_refdef.viewangles[1] = startangle;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_LineGraph
|
||||
|
||||
Only called by R_DisplayTime
|
||||
================
|
||||
*/
|
||||
void R_LineGraph (int x, int y, int h)
|
||||
{
|
||||
int i;
|
||||
qbyte *dest;
|
||||
unsigned short *dest16;
|
||||
unsigned int *dest32;
|
||||
int s;
|
||||
unsigned int color;
|
||||
|
||||
// FIXME: should be disabled on no-buffer adapters, or should be in the driver
|
||||
|
||||
// x += r_refdef.vrect.x;
|
||||
// y += r_refdef.vrect.y;
|
||||
s = r_graphheight.value;
|
||||
|
||||
if (h>s)
|
||||
h = s;
|
||||
|
||||
if (h == 10000)
|
||||
color = 0x6f; // yellow
|
||||
else if (h == 9999)
|
||||
color = 0x4f; // red
|
||||
else if (h == 9998)
|
||||
color = 0xd0; // blue
|
||||
else
|
||||
color = 0xff; // pink
|
||||
|
||||
switch (r_pixbytes)
|
||||
{
|
||||
case 2: // 16 bpp
|
||||
dest16 = (unsigned short*)vid.buffer + vid.rowbytes*y + x;
|
||||
|
||||
// use constant colors instead?
|
||||
color = d_8to16table[color];
|
||||
|
||||
for (i=0 ; i<h ; i++, dest16 -= vid.rowbytes*2)
|
||||
{
|
||||
dest16[0] = color;
|
||||
// *(dest-vid.rowbytes) = 0x30;
|
||||
}
|
||||
break;
|
||||
case 4: // 32 bpp
|
||||
dest32 = (unsigned int*)vid.buffer + vid.rowbytes*y + x;
|
||||
|
||||
// use constant colors instead?
|
||||
color = d_8to32table[color];
|
||||
|
||||
for (i=0 ; i<h ; i++, dest32 -= vid.rowbytes*2)
|
||||
{
|
||||
dest32[0] = color;
|
||||
// *(dest-vid.rowbytes) = 0x30;
|
||||
}
|
||||
break;
|
||||
default: // 8 bpp
|
||||
dest = vid.buffer + vid.rowbytes*y + x;
|
||||
|
||||
for (i=0 ; i<h ; i++, dest -= vid.rowbytes*2)
|
||||
{
|
||||
dest[0] = color;
|
||||
// *(dest-vid.rowbytes) = 0x30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_TimeGraph
|
||||
|
||||
Performance monitoring tool
|
||||
==============
|
||||
*/
|
||||
#define MAX_TIMINGS 100
|
||||
int graphval;
|
||||
void R_TimeGraph (void)
|
||||
{
|
||||
static int timex;
|
||||
int a;
|
||||
float r_time2;
|
||||
static qbyte r_timings[MAX_TIMINGS];
|
||||
int x;
|
||||
|
||||
r_time2 = Sys_DoubleTime ();
|
||||
|
||||
a = (r_time2-r_time1)/0.01;
|
||||
//a = fabs(mouse_y * 0.05);
|
||||
//a = (int)((r_refdef.vieworg[2] + 1024)/1)%(int)r_graphheight.value;
|
||||
//a = (int)((pmove.velocity[2] + 500)/10);
|
||||
//a = fabs(velocity[0])/20;
|
||||
//a = ((int)fabs(origin[0])/8)%20;
|
||||
//a = (cl.idealpitch + 30)/5;
|
||||
//a = (int)(cl.simangles[YAW] * 64/360) & 63;
|
||||
a = graphval;
|
||||
|
||||
r_timings[timex] = a;
|
||||
a = timex;
|
||||
|
||||
if (r_refdef.vrect.width <= MAX_TIMINGS)
|
||||
x = r_refdef.vrect.width-1;
|
||||
else
|
||||
x = r_refdef.vrect.width -
|
||||
(r_refdef.vrect.width - MAX_TIMINGS)/2;
|
||||
do
|
||||
{
|
||||
R_LineGraph (x, r_refdef.vrect.height-2, r_timings[a]);
|
||||
if (x==0)
|
||||
break; // screen too small to hold entire thing
|
||||
x--;
|
||||
a--;
|
||||
if (a == -1)
|
||||
a = MAX_TIMINGS-1;
|
||||
} while (a != timex);
|
||||
|
||||
timex = (timex+1)%MAX_TIMINGS;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_NetGraph
|
||||
==============
|
||||
*/
|
||||
void SWR_NetGraph (void)
|
||||
{
|
||||
int a, x, y, y2, w, i;
|
||||
int lost;
|
||||
char st[80];
|
||||
|
||||
if (vid.width - 16 <= NET_TIMINGS)
|
||||
w = vid.width - 16;
|
||||
else
|
||||
w = NET_TIMINGS;
|
||||
|
||||
x = -(int)((vid.width - 320)>>1);
|
||||
y = vid.height - sb_lines - 24 - (int)r_graphheight.value*2 - 2;
|
||||
|
||||
M_DrawTextBox (x, y, (w+7)/8, ((int)r_graphheight.value*2+7)/8 + 1);
|
||||
y2 = y + 8;
|
||||
y = vid.height - sb_lines - 8 - 2;
|
||||
|
||||
x = 8;
|
||||
lost = CL_CalcNet();
|
||||
for (a=NET_TIMINGS-w ; a<w ; a++)
|
||||
{
|
||||
i = (cls.netchan.outgoing_sequence-a) & NET_TIMINGSMASK;
|
||||
R_LineGraph (x+w-1-a, y, packet_latency[i]);
|
||||
}
|
||||
sprintf(st, "%3i%% packet loss", lost);
|
||||
Draw_String(8, y2, st);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_ZGraph
|
||||
==============
|
||||
*/
|
||||
void R_ZGraph (void)
|
||||
{
|
||||
int a, x, w, i;
|
||||
static int height[256];
|
||||
|
||||
if (r_refdef.vrect.width <= 256)
|
||||
w = r_refdef.vrect.width;
|
||||
else
|
||||
w = 256;
|
||||
|
||||
height[r_framecount&255] = ((int)r_origin[2]) & 31;
|
||||
|
||||
x = 0;
|
||||
for (a=0 ; a<w ; a++)
|
||||
{
|
||||
i = (r_framecount-a) & 255;
|
||||
R_LineGraph (x+w-1-a, r_refdef.vrect.height-2, height[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_PrintTimes
|
||||
=============
|
||||
*/
|
||||
void R_PrintTimes (void)
|
||||
{
|
||||
float r_time2;
|
||||
float ms;
|
||||
|
||||
r_time2 = Sys_DoubleTime ();
|
||||
|
||||
ms = 1000* (r_time2 - r_time1);
|
||||
|
||||
Con_Printf ("%5.1f ms %3i/%3i/%3i poly %3i surf\n",
|
||||
ms, c_faceclip, r_polycount, r_drawnpolycount, c_surf);
|
||||
c_surf = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_PrintDSpeeds
|
||||
=============
|
||||
*/
|
||||
void R_PrintDSpeeds (void)
|
||||
{
|
||||
float ms, dp_time, r_time2, rw_time, db_time, se_time, de_time, dv_time;
|
||||
|
||||
r_time2 = Sys_DoubleTime ();
|
||||
|
||||
dp_time = (dp_time2 - dp_time1) * 1000;
|
||||
rw_time = (rw_time2 - rw_time1) * 1000;
|
||||
db_time = (db_time2 - db_time1) * 1000;
|
||||
se_time = (se_time2 - se_time1) * 1000;
|
||||
de_time = (de_time2 - de_time1) * 1000;
|
||||
dv_time = (dv_time2 - dv_time1) * 1000;
|
||||
ms = (r_time2 - r_time1) * 1000;
|
||||
|
||||
Con_Printf ("%3i %4.1fp %3iw %4.1fb %3is %4.1fe %4.1fv\n",
|
||||
(int)ms, dp_time, (int)rw_time, db_time, (int)se_time, de_time,
|
||||
dv_time);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_PrintAliasStats
|
||||
=============
|
||||
*/
|
||||
void R_PrintAliasStats (void)
|
||||
{
|
||||
Con_Printf ("%3i polygon model drawn\n", r_amodels_drawn);
|
||||
}
|
||||
|
||||
|
||||
void WarpPalette (void)
|
||||
{
|
||||
int i,j;
|
||||
qbyte newpalette[768];
|
||||
int basecolor[3];
|
||||
|
||||
basecolor[0] = 130;
|
||||
basecolor[1] = 80;
|
||||
basecolor[2] = 50;
|
||||
|
||||
// pull the colors halfway to bright brown
|
||||
for (i=0 ; i<256 ; i++)
|
||||
{
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
newpalette[i*3+j] = (host_basepal[i*3+j] + basecolor[j])/2;
|
||||
}
|
||||
}
|
||||
|
||||
VID_ShiftPalette (newpalette);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
R_TransformFrustum
|
||||
===================
|
||||
*/
|
||||
void R_TransformFrustum (void)
|
||||
{
|
||||
int i;
|
||||
vec3_t v, v2;
|
||||
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
v[0] = screenedge[i].normal[2];
|
||||
v[1] = -screenedge[i].normal[0];
|
||||
v[2] = screenedge[i].normal[1];
|
||||
|
||||
v2[0] = v[1]*vright[0] + v[2]*vup[0] + v[0]*vpn[0];
|
||||
v2[1] = v[1]*vright[1] + v[2]*vup[1] + v[0]*vpn[1];
|
||||
v2[2] = v[1]*vright[2] + v[2]*vup[2] + v[0]*vpn[2];
|
||||
|
||||
VectorCopy (v2, view_clipplanes[i].normal);
|
||||
|
||||
view_clipplanes[i].dist = DotProduct (modelorg, v2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
================
|
||||
TransformVector
|
||||
================
|
||||
*/
|
||||
void TransformVector (vec3_t in, vec3_t out)
|
||||
{
|
||||
out[0] = DotProduct(in,vright);
|
||||
out[1] = DotProduct(in,vup);
|
||||
out[2] = DotProduct(in,vpn);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_TransformPlane
|
||||
================
|
||||
*/
|
||||
void R_TransformPlane (mplane_t *p, float *normal, float *dist)
|
||||
{
|
||||
float d;
|
||||
|
||||
d = DotProduct (r_origin, p->normal);
|
||||
*dist = p->dist - d;
|
||||
// TODO: when we have rotating entities, this will need to use the view matrix
|
||||
TransformVector (p->normal, normal);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_SetUpFrustumIndexes
|
||||
===============
|
||||
*/
|
||||
void R_SetUpFrustumIndexes (void)
|
||||
{
|
||||
int i, j, *pindex;
|
||||
|
||||
pindex = r_frustum_indexes;
|
||||
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
if (view_clipplanes[i].normal[j] < 0)
|
||||
{
|
||||
pindex[j] = j;
|
||||
pindex[j+3] = j+3;
|
||||
}
|
||||
else
|
||||
{
|
||||
pindex[j] = j+3;
|
||||
pindex[j+3] = j;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: do just once at start
|
||||
pfrustum_indexes[i] = pindex;
|
||||
pindex += 6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_SetupFrame
|
||||
===============
|
||||
*/
|
||||
void SWR_SetupFrame (void)
|
||||
{
|
||||
static mleaf_t fakeleaf;
|
||||
extern int r_dosirds;
|
||||
|
||||
extern int scr_chatmode;
|
||||
extern float r_wateralphaval;
|
||||
|
||||
int edgecount;
|
||||
vrect_t vrect;
|
||||
float w, h;
|
||||
|
||||
|
||||
// don't allow cheats in multiplayer
|
||||
r_wateralphaval = r_wateralpha.value;
|
||||
if (!cls.allow_watervis)
|
||||
r_wateralphaval = 1;
|
||||
|
||||
if (r_numsurfs.value)
|
||||
{
|
||||
if ((surface_p - surfaces) > r_maxsurfsseen)
|
||||
r_maxsurfsseen = surface_p - surfaces;
|
||||
|
||||
Con_Printf ("Used %d of %d surfs; %d max\n", surface_p - surfaces,
|
||||
surf_max - surfaces, r_maxsurfsseen);
|
||||
}
|
||||
|
||||
if (r_numedges.value)
|
||||
{
|
||||
edgecount = edge_p - r_edges;
|
||||
|
||||
if (edgecount > r_maxedgesseen)
|
||||
r_maxedgesseen = edgecount;
|
||||
|
||||
Con_Printf ("Used %d of %d edges; %d max\n", edgecount,
|
||||
r_numallocatededges, r_maxedgesseen);
|
||||
}
|
||||
|
||||
r_refdef.ambientlight = r_ambient.value;
|
||||
|
||||
if (r_refdef.ambientlight < 0)
|
||||
r_refdef.ambientlight = 0;
|
||||
|
||||
// if (!sv.active)
|
||||
r_draworder.value = 0; // don't let cheaters look behind walls
|
||||
|
||||
R_CheckVariables ();
|
||||
|
||||
SWR_AnimateLight ();
|
||||
|
||||
r_framecount++;
|
||||
|
||||
numbtofpolys = 0;
|
||||
|
||||
// debugging
|
||||
#if 0
|
||||
r_refdef.vieworg[0]= 80;
|
||||
r_refdef.vieworg[1]= 64;
|
||||
r_refdef.vieworg[2]= 40;
|
||||
r_refdef.viewangles[0]= 0;
|
||||
r_refdef.viewangles[1]= 46.763641357;
|
||||
r_refdef.viewangles[2]= 0;
|
||||
#endif
|
||||
|
||||
// build the transformation matrix for the given view angles
|
||||
VectorCopy (r_refdef.vieworg, modelorg);
|
||||
VectorCopy (r_refdef.vieworg, r_origin);
|
||||
|
||||
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
|
||||
|
||||
if (r_refdef.flags & 1)
|
||||
{
|
||||
r_oldviewleaf = r_viewleaf = &fakeleaf; //so we can use quake1 rendering routines for q2 bsps.
|
||||
r_viewleaf->contents = Q1CONTENTS_EMPTY;
|
||||
}
|
||||
#ifdef Q2BSPS
|
||||
else if (cl.worldmodel->fromgame == fg_quake2)
|
||||
{
|
||||
mleaf_t *leaf;
|
||||
|
||||
r_viewleaf = &fakeleaf; //so we can use quake1 rendering routines for q2 bsps.
|
||||
r_viewleaf->contents = Q1CONTENTS_EMPTY;
|
||||
|
||||
r_oldviewcluster = r_viewcluster;
|
||||
r_oldviewcluster2 = r_viewcluster2;
|
||||
leaf = SWMod_PointInLeaf (cl.worldmodel, r_origin);
|
||||
r_viewcluster = r_viewcluster2 = leaf->cluster;
|
||||
|
||||
// check above and below so crossing solid water doesn't draw wrong
|
||||
if (!leaf->contents)
|
||||
{ // look down a bit
|
||||
vec3_t temp;
|
||||
|
||||
VectorCopy (r_origin, temp);
|
||||
temp[2] -= 16;
|
||||
leaf = SWMod_PointInLeaf (cl.worldmodel, temp);
|
||||
if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
|
||||
(leaf->cluster != r_viewcluster2) )
|
||||
r_viewcluster2 = leaf->cluster;
|
||||
}
|
||||
else
|
||||
{ // look up a bit
|
||||
vec3_t temp;
|
||||
|
||||
VectorCopy (r_origin, temp);
|
||||
temp[2] += 16;
|
||||
leaf = SWMod_PointInLeaf (cl.worldmodel, temp);
|
||||
if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
|
||||
(leaf->cluster != r_viewcluster2) )
|
||||
r_viewcluster2 = leaf->cluster;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
// current viewleaf
|
||||
r_oldviewleaf = r_viewleaf;
|
||||
r_viewleaf = SWMod_PointInLeaf (cl.worldmodel, r_origin);
|
||||
}
|
||||
|
||||
r_dowarpold = r_dowarp;
|
||||
#ifdef SIDEVIEWS
|
||||
r_dowarp = r_waterwarp.value && (r_viewleaf->contents <= Q1CONTENTS_WATER) && !r_secondaryview;
|
||||
#else
|
||||
r_dowarp = r_waterwarp.value && (r_viewleaf->contents <= Q1CONTENTS_WATER);
|
||||
#endif
|
||||
if (vid.width > MAXWIDTH || r_pixbytes != 1 || scr_chatmode)
|
||||
r_dowarp = 0;
|
||||
if (r_dosirds)
|
||||
r_dowarp = 0;
|
||||
|
||||
if ((r_dowarp != r_dowarpold) || r_viewchanged)
|
||||
{
|
||||
if (r_dowarp)
|
||||
{
|
||||
if ((vid.width <= vid.maxwarpwidth) &&
|
||||
(vid.height <= vid.maxwarpheight))
|
||||
{
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height;
|
||||
|
||||
SWR_ViewChanged (&vrect, sb_lines, vid.aspect);
|
||||
}
|
||||
else
|
||||
{
|
||||
w = vid.width;
|
||||
h = vid.height;
|
||||
|
||||
if (w > vid.maxwarpwidth)
|
||||
{
|
||||
h *= (float)vid.maxwarpwidth / w;
|
||||
w = vid.maxwarpwidth;
|
||||
}
|
||||
|
||||
if (h > vid.maxwarpheight)
|
||||
{
|
||||
h = vid.maxwarpheight;
|
||||
w *= (float)vid.maxwarpheight / h;
|
||||
}
|
||||
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = (int)w;
|
||||
vrect.height = (int)h;
|
||||
|
||||
SWR_ViewChanged (&vrect,
|
||||
(int)((float)sb_lines * (h/(float)vid.height)),
|
||||
vid.aspect * (h / w) *
|
||||
((float)vid.width / (float)vid.height));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height;
|
||||
|
||||
SWR_ViewChanged (&vrect, sb_lines, vid.aspect);
|
||||
}
|
||||
|
||||
r_viewchanged = false;
|
||||
}
|
||||
|
||||
// start off with just the four screen edge clip planes
|
||||
R_TransformFrustum ();
|
||||
|
||||
// save base values
|
||||
VectorCopy (vpn, base_vpn);
|
||||
VectorCopy (vright, base_vright);
|
||||
VectorCopy (vup, base_vup);
|
||||
VectorCopy (modelorg, base_modelorg);
|
||||
|
||||
R_SetSkyFrame ();
|
||||
|
||||
R_SetUpFrustumIndexes ();
|
||||
|
||||
r_cache_thrash = false;
|
||||
|
||||
// clear frame counts
|
||||
c_faceclip = 0;
|
||||
d_spanpixcount = 0;
|
||||
r_polycount = 0;
|
||||
r_drawnpolycount = 0;
|
||||
r_wholepolycount = 0;
|
||||
r_amodels_drawn = 0;
|
||||
r_outofsurfaces = 0;
|
||||
r_outofedges = 0;
|
||||
|
||||
D_SetupFrame ();
|
||||
}
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#ifdef SWQUAKE
|
||||
// r_shared.h: general refresh-related stuff shared between the refresh and the
|
||||
// driver
|
||||
|
||||
// FIXME: clean up and move into d_iface.h
|
||||
|
||||
#ifndef _R_SHARED_H_
|
||||
#define _R_SHARED_H_
|
||||
|
||||
#define MAXVERTS 16 // max points in a surface polygon
|
||||
#define MAXWORKINGVERTS (MAXVERTS+4) // max points in an intermediate
|
||||
// polygon (while processing)
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
#define MAXHEIGHT 1024
|
||||
#define MAXWIDTH 1280
|
||||
|
||||
#define INFINITE_DISTANCE 0x10000 // distance that's always guaranteed to
|
||||
// be farther away than anything in
|
||||
// the scene
|
||||
|
||||
//===================================================================
|
||||
|
||||
extern void R_DrawLine (polyvert_t *polyvert0, polyvert_t *polyvert1);
|
||||
|
||||
extern int cachewidth;
|
||||
extern int cacheheight;
|
||||
extern pixel_t *cacheblock;
|
||||
extern int screenwidth;
|
||||
|
||||
extern float pixelAspect;
|
||||
|
||||
extern int r_drawnpolycount;
|
||||
|
||||
extern cvar_t r_clearcolor;
|
||||
#define SINTABLESIZE (MAXWIDTH+CYCLE)
|
||||
extern int sintable[SINTABLESIZE];
|
||||
extern int intsintable[SINTABLESIZE];
|
||||
|
||||
extern vec3_t vup, base_vup;
|
||||
extern vec3_t vpn, base_vpn;
|
||||
extern vec3_t vright, base_vright;
|
||||
extern entity_t *currententity;
|
||||
|
||||
#define NUMSTACKEDGES 2000
|
||||
#define MINEDGES NUMSTACKEDGES
|
||||
#define NUMSTACKSURFACES 1000
|
||||
#define MINSURFACES NUMSTACKSURFACES
|
||||
#define MAXSPANS 3000
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct espan_s
|
||||
{
|
||||
int u, v, count;
|
||||
struct espan_s *pnext;
|
||||
} espan_t;
|
||||
|
||||
// FIXME: compress, make a union if that will help
|
||||
// insubmodel is only 1, flags is fewer than 32, spanstate could be a byte
|
||||
typedef struct surf_s
|
||||
{
|
||||
struct surf_s *next; // active surface stack in r_edge.c
|
||||
struct surf_s *prev; // used in r_edge.c for active surf stack
|
||||
struct espan_s *spans; // pointer to linked list of spans to draw
|
||||
int key; // sorting key (BSP order)
|
||||
int last_u; // set during tracing
|
||||
int spanstate; // 0 = not in span
|
||||
// 1 = in span
|
||||
// -1 = in inverted span (end before
|
||||
// start)
|
||||
int flags; // currentface flags
|
||||
void *data; // associated data like msurface_t
|
||||
entity_t *entity;
|
||||
float nearzi; // nearest 1/z on surface, for mipmapping
|
||||
qboolean insubmodel;
|
||||
float d_ziorigin, d_zistepu, d_zistepv;
|
||||
|
||||
int pad[2]; // to 64 bytes
|
||||
} surf_t;
|
||||
|
||||
extern surf_t *surfaces, *surface_p, *surf_max;
|
||||
|
||||
// surfaces are generated in back to front order by the bsp, so if a surf
|
||||
// pointer is greater than another one, it should be drawn in front
|
||||
// surfaces[1] is the background, and is used as the active surface stack.
|
||||
// surfaces[0] is a dummy, because index 0 is used to indicate no surface
|
||||
// attached to an edge_t
|
||||
|
||||
//===================================================================
|
||||
|
||||
extern vec3_t sxformaxis[4]; // s axis transformed into viewspace
|
||||
extern vec3_t txformaxis[4]; // t axis transformed into viewspac
|
||||
|
||||
extern vec3_t modelorg, base_modelorg;
|
||||
|
||||
extern float xcenter, ycenter;
|
||||
extern float xscale, yscale;
|
||||
extern float xscaleinv, yscaleinv;
|
||||
extern float xscaleshrink, yscaleshrink;
|
||||
|
||||
extern int d_lightstylevalue[256]; // 8.8 frac of base light value
|
||||
|
||||
extern void TransformVector (vec3_t in, vec3_t out);
|
||||
extern void SetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
|
||||
fixed8_t endvertu, fixed8_t endvertv);
|
||||
|
||||
extern int r_skymade;
|
||||
extern void R_MakeSky (void);
|
||||
|
||||
extern int ubasestep, errorterm, erroradjustup, erroradjustdown;
|
||||
|
||||
// flags in finalvert_t.flags
|
||||
#define ALIAS_LEFT_CLIP 0x0001
|
||||
#define ALIAS_TOP_CLIP 0x0002
|
||||
#define ALIAS_RIGHT_CLIP 0x0004
|
||||
#define ALIAS_BOTTOM_CLIP 0x0008
|
||||
#define ALIAS_Z_CLIP 0x0010
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
#define ALIAS_ONSEAM 0x0020 // also defined in modelgen.h;
|
||||
// must be kept in sync
|
||||
#define ALIAS_XY_CLIP_MASK 0x000F
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct edge_s
|
||||
{
|
||||
fixed16_t u;
|
||||
fixed16_t u_step;
|
||||
struct edge_s *prev, *next;
|
||||
unsigned short surfs[2];
|
||||
struct edge_s *nextremove;
|
||||
float nearzi;
|
||||
medge_t *owner;
|
||||
} edge_t;
|
||||
|
||||
#endif // _R_SHARED_H_
|
||||
|
||||
#endif // SWQUAKE
|
|
@ -1,280 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_sky.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
#include "d_local.h"
|
||||
|
||||
|
||||
int iskyspeed = 8;
|
||||
int iskyspeed2 = 2;
|
||||
float skyspeed, skyspeed2;
|
||||
|
||||
float skytime;
|
||||
|
||||
qbyte *r_skysource;
|
||||
|
||||
int r_skymade;
|
||||
int r_skydirect; // not used?
|
||||
|
||||
|
||||
// TODO: clean up these routines
|
||||
|
||||
qbyte bottomsky[128*131];
|
||||
qbyte bottommask[128*131];
|
||||
qbyte newsky[128*256]; // newsky and topsky both pack in here, 128 bytes
|
||||
// of newsky on the left of each scan, 128 bytes
|
||||
// of topsky on the right, because the low-level
|
||||
// drawers need 256-byte scan widths
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_InitSky
|
||||
|
||||
A sky texture is 256*128, with the right side being a masked overlay
|
||||
==============
|
||||
*/
|
||||
void SWR_InitSky (texture_t *mt)
|
||||
{
|
||||
int i, j;
|
||||
qbyte *src;
|
||||
|
||||
src = (qbyte *)mt + mt->offsets[0];
|
||||
|
||||
for (i=0 ; i<128 ; i++)
|
||||
{
|
||||
for (j=0 ; j<128 ; j++)
|
||||
{
|
||||
newsky[(i*256) + j + 128] = src[i*256 + j + 128];
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0 ; i<128 ; i++)
|
||||
{
|
||||
for (j=0 ; j<131 ; j++)
|
||||
{
|
||||
if (src[i*256 + (j & 0x7F)])
|
||||
{
|
||||
bottomsky[(i*131) + j] = src[i*256 + (j & 0x7F)];
|
||||
bottommask[(i*131) + j] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bottomsky[(i*131) + j] = 0;
|
||||
bottommask[(i*131) + j] = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r_skysource = newsky;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_MakeSky
|
||||
=================
|
||||
*/
|
||||
void R_MakeSky (void)
|
||||
{
|
||||
int x, y;
|
||||
int ofs, baseofs;
|
||||
int xshift, yshift;
|
||||
unsigned *pnewsky;
|
||||
static int xlast = -1, ylast = -1;
|
||||
|
||||
xshift = skytime*skyspeed;
|
||||
yshift = skytime*skyspeed;
|
||||
|
||||
if ((xshift == xlast) && (yshift == ylast))
|
||||
return;
|
||||
|
||||
xlast = xshift;
|
||||
ylast = yshift;
|
||||
|
||||
pnewsky = (unsigned *)&newsky[0];
|
||||
|
||||
for (y=0 ; y<SKYSIZE ; y++)
|
||||
{
|
||||
baseofs = ((y+yshift) & SKYMASK) * 131;
|
||||
|
||||
// FIXME: clean this up
|
||||
#if UNALIGNED_OK
|
||||
|
||||
for (x=0 ; x<SKYSIZE ; x += 4)
|
||||
{
|
||||
ofs = baseofs + ((x+xshift) & SKYMASK);
|
||||
|
||||
// PORT: unaligned dword access to bottommask and bottomsky
|
||||
|
||||
*pnewsky = (*(pnewsky + (128 / sizeof (unsigned))) &
|
||||
*(unsigned *)&bottommask[ofs]) |
|
||||
*(unsigned *)&bottomsky[ofs];
|
||||
pnewsky++;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
for (x=0 ; x<SKYSIZE ; x++)
|
||||
{
|
||||
ofs = baseofs + ((x+xshift) & SKYMASK);
|
||||
|
||||
*(qbyte *)pnewsky = (*((qbyte *)pnewsky + 128) &
|
||||
*(qbyte *)&bottommask[ofs]) |
|
||||
*(qbyte *)&bottomsky[ofs];
|
||||
pnewsky = (unsigned *)((qbyte *)pnewsky + 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
pnewsky += 128 / sizeof (unsigned);
|
||||
}
|
||||
|
||||
r_skymade = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_GenSkyTile
|
||||
=================
|
||||
*/
|
||||
void R_GenSkyTile (void *pdest)
|
||||
{
|
||||
int x, y;
|
||||
int ofs, baseofs;
|
||||
int xshift, yshift;
|
||||
unsigned *pnewsky;
|
||||
unsigned *pd;
|
||||
|
||||
xshift = skytime*skyspeed;
|
||||
yshift = skytime*skyspeed;
|
||||
|
||||
pnewsky = (unsigned *)&newsky[0];
|
||||
pd = (unsigned *)pdest;
|
||||
|
||||
for (y=0 ; y<SKYSIZE ; y++)
|
||||
{
|
||||
baseofs = ((y+yshift) & SKYMASK) * 131;
|
||||
|
||||
// FIXME: clean this up
|
||||
#if UNALIGNED_OK
|
||||
|
||||
for (x=0 ; x<SKYSIZE ; x += 4)
|
||||
{
|
||||
ofs = baseofs + ((x+xshift) & SKYMASK);
|
||||
|
||||
// PORT: unaligned dword access to bottommask and bottomsky
|
||||
|
||||
*pd = (*(pnewsky + (128 / sizeof (unsigned))) &
|
||||
*(unsigned *)&bottommask[ofs]) |
|
||||
*(unsigned *)&bottomsky[ofs];
|
||||
pnewsky++;
|
||||
pd++;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
for (x=0 ; x<SKYSIZE ; x++)
|
||||
{
|
||||
ofs = baseofs + ((x+xshift) & SKYMASK);
|
||||
|
||||
*(qbyte *)pd = (*((qbyte *)pnewsky + 128) &
|
||||
*(qbyte *)&bottommask[ofs]) |
|
||||
*(qbyte *)&bottomsky[ofs];
|
||||
pnewsky = (unsigned *)((qbyte *)pnewsky + 1);
|
||||
pd = (unsigned *)((qbyte *)pd + 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
pnewsky += 128 / sizeof (unsigned);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_GenSkyTile16
|
||||
=================
|
||||
*/
|
||||
void R_GenSkyTile16 (void *pdest)
|
||||
{
|
||||
int x, y;
|
||||
int ofs, baseofs;
|
||||
int xshift, yshift;
|
||||
qbyte *pnewsky;
|
||||
unsigned short *pd;
|
||||
|
||||
xshift = skytime * skyspeed;
|
||||
yshift = skytime * skyspeed;
|
||||
|
||||
pnewsky = (qbyte *)&newsky[0];
|
||||
pd = (unsigned short *)pdest;
|
||||
|
||||
for (y=0 ; y<SKYSIZE ; y++)
|
||||
{
|
||||
baseofs = ((y+yshift) & SKYMASK) * 131;
|
||||
|
||||
// FIXME: clean this up
|
||||
// FIXME: do faster unaligned version?
|
||||
for (x=0 ; x<SKYSIZE ; x++)
|
||||
{
|
||||
ofs = baseofs + ((x+xshift) & SKYMASK);
|
||||
|
||||
*pd = d_8to16table[(*(pnewsky + 128) &
|
||||
*(qbyte *)&bottommask[ofs]) |
|
||||
*(qbyte *)&bottomsky[ofs]];
|
||||
pnewsky++;
|
||||
pd++;
|
||||
}
|
||||
|
||||
pnewsky += TILE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_SetSkyFrame
|
||||
==============
|
||||
*/
|
||||
void R_SetSkyFrame (void)
|
||||
{
|
||||
int g, s1, s2;
|
||||
float temp;
|
||||
|
||||
skyspeed = iskyspeed;
|
||||
skyspeed2 = iskyspeed2;
|
||||
|
||||
g = GreatestCommonDivisor (iskyspeed, iskyspeed2);
|
||||
s1 = iskyspeed / g;
|
||||
s2 = iskyspeed2 / g;
|
||||
temp = SKYSIZE * s1 * s2;
|
||||
|
||||
skytime = cl.time - ((int)(cl.time / temp) * temp);
|
||||
|
||||
|
||||
r_skymade = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,404 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_sprite.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
|
||||
static int clip_current;
|
||||
static vec5_t clip_verts[2][MAXWORKINGVERTS];
|
||||
static int sprite_width, sprite_height;
|
||||
|
||||
spritedesc_t r_spritedesc;
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RotateSprite
|
||||
================
|
||||
*/
|
||||
void R_RotateSprite (float beamlength)
|
||||
{
|
||||
vec3_t vec;
|
||||
|
||||
if (beamlength == 0.0)
|
||||
return;
|
||||
|
||||
VectorScale (r_spritedesc.vpn, -beamlength, vec);
|
||||
VectorAdd (r_entorigin, vec, r_entorigin);
|
||||
VectorSubtract (modelorg, vec, modelorg);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_ClipSpriteFace
|
||||
|
||||
Clips the winding at clip_verts[clip_current] and changes clip_current
|
||||
Throws out the back side
|
||||
==============
|
||||
*/
|
||||
int R_ClipSpriteFace (int nump, clipplane_t *pclipplane)
|
||||
{
|
||||
int i, outcount;
|
||||
float dists[MAXWORKINGVERTS+1];
|
||||
float frac, clipdist, *pclipnormal;
|
||||
float *in, *instep, *outstep, *vert2;
|
||||
|
||||
clipdist = pclipplane->dist;
|
||||
pclipnormal = pclipplane->normal;
|
||||
|
||||
// calc dists
|
||||
if (clip_current)
|
||||
{
|
||||
in = clip_verts[1][0];
|
||||
outstep = clip_verts[0][0];
|
||||
clip_current = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
in = clip_verts[0][0];
|
||||
outstep = clip_verts[1][0];
|
||||
clip_current = 1;
|
||||
}
|
||||
|
||||
instep = in;
|
||||
for (i=0 ; i<nump ; i++, instep += sizeof (vec5_t) / sizeof (float))
|
||||
{
|
||||
dists[i] = DotProduct (instep, pclipnormal) - clipdist;
|
||||
}
|
||||
|
||||
// handle wraparound case
|
||||
dists[nump] = dists[0];
|
||||
Q_memcpy (instep, in, sizeof (vec5_t));
|
||||
|
||||
|
||||
// clip the winding
|
||||
instep = in;
|
||||
outcount = 0;
|
||||
|
||||
for (i=0 ; i<nump ; i++, instep += sizeof (vec5_t) / sizeof (float))
|
||||
{
|
||||
if (dists[i] >= 0)
|
||||
{
|
||||
Q_memcpy (outstep, instep, sizeof (vec5_t));
|
||||
outstep += sizeof (vec5_t) / sizeof (float);
|
||||
outcount++;
|
||||
}
|
||||
|
||||
if (dists[i] == 0 || dists[i+1] == 0)
|
||||
continue;
|
||||
|
||||
if ( (dists[i] > 0) == (dists[i+1] > 0) )
|
||||
continue;
|
||||
|
||||
// split it into a new vertex
|
||||
frac = dists[i] / (dists[i] - dists[i+1]);
|
||||
|
||||
vert2 = instep + sizeof (vec5_t) / sizeof (float);
|
||||
|
||||
outstep[0] = instep[0] + frac*(vert2[0] - instep[0]);
|
||||
outstep[1] = instep[1] + frac*(vert2[1] - instep[1]);
|
||||
outstep[2] = instep[2] + frac*(vert2[2] - instep[2]);
|
||||
outstep[3] = instep[3] + frac*(vert2[3] - instep[3]);
|
||||
outstep[4] = instep[4] + frac*(vert2[4] - instep[4]);
|
||||
|
||||
outstep += sizeof (vec5_t) / sizeof (float);
|
||||
outcount++;
|
||||
}
|
||||
|
||||
return outcount;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_SetupAndDrawSprite
|
||||
================
|
||||
*/
|
||||
void R_SetupAndDrawSprite ()
|
||||
{
|
||||
int i, nump;
|
||||
float dot, scale, *pv;
|
||||
vec5_t *pverts;
|
||||
vec3_t left, up, right, down, transformed, local;
|
||||
emitpoint_t outverts[MAXWORKINGVERTS+1], *pout;
|
||||
|
||||
dot = DotProduct (r_spritedesc.vpn, modelorg);
|
||||
|
||||
// backface cull
|
||||
if (dot >= 0)
|
||||
return;
|
||||
|
||||
// build the sprite poster in worldspace
|
||||
VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->right, right);
|
||||
VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->up, up);
|
||||
VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->left, left);
|
||||
VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->down, down);
|
||||
|
||||
pverts = clip_verts[0];
|
||||
|
||||
pverts[0][0] = r_entorigin[0] + up[0] + left[0];
|
||||
pverts[0][1] = r_entorigin[1] + up[1] + left[1];
|
||||
pverts[0][2] = r_entorigin[2] + up[2] + left[2];
|
||||
pverts[0][3] = 0;
|
||||
pverts[0][4] = 0;
|
||||
|
||||
pverts[1][0] = r_entorigin[0] + up[0] + right[0];
|
||||
pverts[1][1] = r_entorigin[1] + up[1] + right[1];
|
||||
pverts[1][2] = r_entorigin[2] + up[2] + right[2];
|
||||
pverts[1][3] = sprite_width;
|
||||
pverts[1][4] = 0;
|
||||
|
||||
pverts[2][0] = r_entorigin[0] + down[0] + right[0];
|
||||
pverts[2][1] = r_entorigin[1] + down[1] + right[1];
|
||||
pverts[2][2] = r_entorigin[2] + down[2] + right[2];
|
||||
pverts[2][3] = sprite_width;
|
||||
pverts[2][4] = sprite_height;
|
||||
|
||||
pverts[3][0] = r_entorigin[0] + down[0] + left[0];
|
||||
pverts[3][1] = r_entorigin[1] + down[1] + left[1];
|
||||
pverts[3][2] = r_entorigin[2] + down[2] + left[2];
|
||||
pverts[3][3] = 0;
|
||||
pverts[3][4] = sprite_height;
|
||||
|
||||
// clip to the frustum in worldspace
|
||||
nump = 4;
|
||||
clip_current = 0;
|
||||
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
nump = R_ClipSpriteFace (nump, &view_clipplanes[i]);
|
||||
if (nump < 3)
|
||||
return;
|
||||
if (nump >= MAXWORKINGVERTS)
|
||||
Sys_Error("R_SetupAndDrawSprite: too many points");
|
||||
}
|
||||
|
||||
// transform vertices into viewspace and project
|
||||
pv = &clip_verts[clip_current][0][0];
|
||||
r_spritedesc.nearzi = -999999;
|
||||
|
||||
for (i=0 ; i<nump ; i++)
|
||||
{
|
||||
VectorSubtract (pv, r_origin, local);
|
||||
TransformVector (local, transformed);
|
||||
|
||||
if (transformed[2] < NEAR_CLIP)
|
||||
transformed[2] = NEAR_CLIP;
|
||||
|
||||
pout = &outverts[i];
|
||||
pout->zi = 1.0 / transformed[2];
|
||||
if (pout->zi > r_spritedesc.nearzi)
|
||||
r_spritedesc.nearzi = pout->zi;
|
||||
|
||||
pout->s = pv[3];
|
||||
pout->t = pv[4];
|
||||
|
||||
scale = xscale * pout->zi;
|
||||
pout->u = (xcenter + scale * transformed[0]);
|
||||
|
||||
scale = yscale * pout->zi;
|
||||
pout->v = (ycenter - scale * transformed[1]);
|
||||
|
||||
pv += sizeof (vec5_t) / sizeof (*pv);
|
||||
}
|
||||
|
||||
// draw it
|
||||
r_spritedesc.nump = nump;
|
||||
r_spritedesc.pverts = outverts;
|
||||
D_DrawSprite ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_GetSpriteframe
|
||||
================
|
||||
*/
|
||||
/*
|
||||
mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
|
||||
{
|
||||
msprite_t *psprite;
|
||||
mspritegroup_t *pspritegroup;
|
||||
mspriteframe_t *pspriteframe;
|
||||
int i, numframes, frame;
|
||||
float *pintervals, fullinterval, targettime, time;
|
||||
|
||||
psprite = currententity->model->cache.data;
|
||||
frame = currententity->frame;
|
||||
|
||||
if ((frame >= psprite->numframes) || (frame < 0))
|
||||
{
|
||||
Con_Printf ("R_DrawSprite: no such frame %d\n", frame);
|
||||
frame = 0;
|
||||
}
|
||||
|
||||
if (psprite->frames[frame].type == SPR_SINGLE)
|
||||
{
|
||||
pspriteframe = psprite->frames[frame].frameptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
|
||||
pintervals = pspritegroup->intervals;
|
||||
numframes = pspritegroup->numframes;
|
||||
fullinterval = pintervals[numframes-1];
|
||||
|
||||
time = currententity->frame1time;
|
||||
|
||||
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
|
||||
// are positive, so we don't have to worry about division by 0
|
||||
targettime = time - ((int)(time / fullinterval)) * fullinterval;
|
||||
|
||||
for (i=0 ; i<(numframes-1) ; i++)
|
||||
{
|
||||
if (pintervals[i] > targettime)
|
||||
break;
|
||||
}
|
||||
|
||||
pspriteframe = pspritegroup->frames[i];
|
||||
}
|
||||
|
||||
return pspriteframe;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawSprite
|
||||
================
|
||||
*/
|
||||
void R_DrawSprite (void)
|
||||
{
|
||||
int i;
|
||||
msprite_t *psprite;
|
||||
vec3_t tvec;
|
||||
float dot, angle, sr, cr;
|
||||
|
||||
psprite = currententity->model->cache.data;
|
||||
|
||||
r_spritedesc.pspriteframe = R_GetSpriteFrame (currententity);
|
||||
|
||||
sprite_width = r_spritedesc.pspriteframe->p.width;
|
||||
sprite_height = r_spritedesc.pspriteframe->p.height;
|
||||
|
||||
// TODO: make this caller-selectable
|
||||
if (psprite->type == SPR_FACING_UPRIGHT)
|
||||
{
|
||||
// generate the sprite's axes, with vup straight up in worldspace, and
|
||||
// r_spritedesc.vright perpendicular to modelorg.
|
||||
// This will not work if the view direction is very close to straight up or
|
||||
// down, because the cross product will be between two nearly parallel
|
||||
// vectors and starts to approach an undefined state, so we don't draw if
|
||||
// the two vectors are less than 1 degree apart
|
||||
tvec[0] = -modelorg[0];
|
||||
tvec[1] = -modelorg[1];
|
||||
tvec[2] = -modelorg[2];
|
||||
VectorNormalize (tvec);
|
||||
dot = tvec[2]; // same as DotProduct (tvec, r_spritedesc.vup) because
|
||||
// r_spritedesc.vup is 0, 0, 1
|
||||
if ((dot > 0.999848) || (dot < -0.999848)) // cos(1 degree) = 0.999848
|
||||
return;
|
||||
r_spritedesc.vup[0] = 0;
|
||||
r_spritedesc.vup[1] = 0;
|
||||
r_spritedesc.vup[2] = 1;
|
||||
r_spritedesc.vright[0] = tvec[1];
|
||||
// CrossProduct(r_spritedesc.vup, -modelorg,
|
||||
r_spritedesc.vright[1] = -tvec[0];
|
||||
// r_spritedesc.vright)
|
||||
r_spritedesc.vright[2] = 0;
|
||||
VectorNormalize (r_spritedesc.vright);
|
||||
r_spritedesc.vpn[0] = -r_spritedesc.vright[1];
|
||||
r_spritedesc.vpn[1] = r_spritedesc.vright[0];
|
||||
r_spritedesc.vpn[2] = 0;
|
||||
// CrossProduct (r_spritedesc.vright, r_spritedesc.vup,
|
||||
// r_spritedesc.vpn)
|
||||
}
|
||||
else if (psprite->type == SPR_VP_PARALLEL)
|
||||
{
|
||||
// generate the sprite's axes, completely parallel to the viewplane. There
|
||||
// are no problem situations, because the sprite is always in the same
|
||||
// position relative to the viewer
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
r_spritedesc.vup[i] = vup[i];
|
||||
r_spritedesc.vright[i] = vright[i];
|
||||
r_spritedesc.vpn[i] = vpn[i];
|
||||
}
|
||||
}
|
||||
else if (psprite->type == SPR_VP_PARALLEL_UPRIGHT)
|
||||
{
|
||||
// generate the sprite's axes, with vup straight up in worldspace, and
|
||||
// r_spritedesc.vright parallel to the viewplane.
|
||||
// This will not work if the view direction is very close to straight up or
|
||||
// down, because the cross product will be between two nearly parallel
|
||||
// vectors and starts to approach an undefined state, so we don't draw if
|
||||
// the two vectors are less than 1 degree apart
|
||||
dot = vpn[2]; // same as DotProduct (vpn, r_spritedesc.vup) because
|
||||
// r_spritedesc.vup is 0, 0, 1
|
||||
if ((dot > 0.999848) || (dot < -0.999848)) // cos(1 degree) = 0.999848
|
||||
return;
|
||||
r_spritedesc.vup[0] = 0;
|
||||
r_spritedesc.vup[1] = 0;
|
||||
r_spritedesc.vup[2] = 1;
|
||||
r_spritedesc.vright[0] = vpn[1];
|
||||
// CrossProduct (r_spritedesc.vup, vpn,
|
||||
r_spritedesc.vright[1] = -vpn[0]; // r_spritedesc.vright)
|
||||
r_spritedesc.vright[2] = 0;
|
||||
VectorNormalize (r_spritedesc.vright);
|
||||
r_spritedesc.vpn[0] = -r_spritedesc.vright[1];
|
||||
r_spritedesc.vpn[1] = r_spritedesc.vright[0];
|
||||
r_spritedesc.vpn[2] = 0;
|
||||
// CrossProduct (r_spritedesc.vright, r_spritedesc.vup,
|
||||
// r_spritedesc.vpn)
|
||||
}
|
||||
else if (psprite->type == SPR_ORIENTED)
|
||||
{
|
||||
// generate the sprite's axes, according to the sprite's world orientation
|
||||
AngleVectors (currententity->angles, r_spritedesc.vpn,
|
||||
r_spritedesc.vright, r_spritedesc.vup);
|
||||
}
|
||||
else if (psprite->type == SPR_VP_PARALLEL_ORIENTED)
|
||||
{
|
||||
// generate the sprite's axes, parallel to the viewplane, but rotated in
|
||||
// that plane around the center according to the sprite entity's roll
|
||||
// angle. So vpn stays the same, but vright and vup rotate
|
||||
angle = currententity->angles[ROLL] * (M_PI*2 / 360);
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
r_spritedesc.vpn[i] = vpn[i];
|
||||
r_spritedesc.vright[i] = vright[i] * cr + vup[i] * sr;
|
||||
r_spritedesc.vup[i] = vright[i] * -sr + vup[i] * cr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Error ("R_DrawSprite: Bad sprite type %d", psprite->type);
|
||||
}
|
||||
|
||||
R_RotateSprite (psprite->beamlength);
|
||||
|
||||
R_SetupAndDrawSprite ();
|
||||
}
|
||||
|
1881
engine/sw/r_surf.c
1881
engine/sw/r_surf.c
File diff suppressed because it is too large
Load diff
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_vars.c: global refresh variables
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
#if !id386
|
||||
|
||||
// all global and static refresh variables are collected in a contiguous block
|
||||
// to avoid cache conflicts.
|
||||
|
||||
//-------------------------------------------------------
|
||||
// global refresh variables
|
||||
//-------------------------------------------------------
|
||||
|
||||
// FIXME: make into one big structure, like cl or sv
|
||||
// FIXME: do separately for refresh engine and driver
|
||||
|
||||
int r_bmodelactive;
|
||||
|
||||
#endif // !id386
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// r_varsa.s
|
||||
//
|
||||
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
|
||||
//-------------------------------------------------------
|
||||
// ASM-only variables
|
||||
//-------------------------------------------------------
|
||||
.globl float_1, float_particle_z_clip, float_point5
|
||||
.globl float_minus_1, float_0
|
||||
float_0: .single 0.0
|
||||
float_1: .single 1.0
|
||||
float_minus_1: .single -1.0
|
||||
float_particle_z_clip: .single PARTICLE_Z_CLIP
|
||||
float_point5: .single 0.5
|
||||
|
||||
.globl fp_16, fp_64k, fp_1m, fp_64kx64k
|
||||
.globl fp_1m_minus_1
|
||||
.globl fp_8
|
||||
fp_1m: .single 1048576.0
|
||||
fp_1m_minus_1: .single 1048575.0
|
||||
fp_64k: .single 65536.0
|
||||
fp_8: .single 8.0
|
||||
fp_16: .single 16.0
|
||||
fp_64kx64k: .long 0x4f000000 // (float)0x8000*0x10000
|
||||
|
||||
|
||||
.globl FloatZero, Float2ToThe31nd, FloatMinus2ToThe31nd
|
||||
FloatZero: .long 0
|
||||
Float2ToThe31nd: .long 0x4f000000
|
||||
FloatMinus2ToThe31nd: .long 0xcf000000
|
||||
|
||||
.globl C(r_bmodelactive)
|
||||
C(r_bmodelactive): .long 0
|
||||
|
||||
#endif // id386
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// surf16.s
|
||||
// x86 assembly-language 16 bpp surface block drawing code.
|
||||
//
|
||||
|
||||
#define SWQUAKE
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#if id386
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.data
|
||||
|
||||
k: .long 0
|
||||
loopentry: .long 0
|
||||
|
||||
.align 4
|
||||
blockjumptable16:
|
||||
.long LEnter2_16
|
||||
.long LEnter4_16
|
||||
.long 0, LEnter8_16
|
||||
.long 0, 0, 0, LEnter16_16
|
||||
|
||||
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.globl C(R_Surf16Start)
|
||||
C(R_Surf16Start):
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock16)
|
||||
C(R_DrawSurfaceBlock16):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
movl C(blocksize),%eax
|
||||
movl C(prowdestbase),%edi
|
||||
movl C(pbasesource),%esi
|
||||
movl C(sourcesstep),%ebx
|
||||
movl blockjumptable16-4(,%eax,2),%ecx
|
||||
movl %eax,k
|
||||
movl %ecx,loopentry
|
||||
movl C(lightleft),%edx
|
||||
movl C(lightright),%ebp
|
||||
|
||||
Lblockloop16:
|
||||
|
||||
subl %edx,%ebp
|
||||
movb C(blockdivshift),%cl
|
||||
sarl %cl,%ebp
|
||||
jns Lp1_16
|
||||
testl C(blockdivmask),%ebp
|
||||
jz Lp1_16
|
||||
incl %ebp
|
||||
Lp1_16:
|
||||
|
||||
subl %eax,%eax
|
||||
subl %ecx,%ecx // high words must be 0 in loop for addressing
|
||||
|
||||
jmp *loopentry
|
||||
|
||||
.align 4
|
||||
|
||||
#include "block16.h"
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
movl C(lightleft),%edx
|
||||
movl C(lightright),%ebp
|
||||
movl C(sourcetstep),%eax
|
||||
movl C(lightrightstep),%ecx
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
addl %eax,%esi
|
||||
addl %ecx,%ebp
|
||||
|
||||
movl C(lightleftstep),%eax
|
||||
movl C(surfrowbytes),%ecx
|
||||
|
||||
addl %eax,%edx
|
||||
addl %ecx,%edi
|
||||
|
||||
movl %esi,C(pbasesource)
|
||||
movl %ebp,C(lightright)
|
||||
movl k,%eax
|
||||
movl %edx,C(lightleft)
|
||||
decl %eax
|
||||
movl %edi,C(prowdestbase)
|
||||
movl %eax,k
|
||||
jnz Lblockloop16
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
.globl C(R_Surf16End)
|
||||
C(R_Surf16End):
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Code patching routines
|
||||
//----------------------------------------------------------------------
|
||||
.data
|
||||
|
||||
.align 4
|
||||
LPatchTable16:
|
||||
.long LBPatch0-4
|
||||
.long LBPatch1-4
|
||||
.long LBPatch2-4
|
||||
.long LBPatch3-4
|
||||
.long LBPatch4-4
|
||||
.long LBPatch5-4
|
||||
.long LBPatch6-4
|
||||
.long LBPatch7-4
|
||||
.long LBPatch8-4
|
||||
.long LBPatch9-4
|
||||
.long LBPatch10-4
|
||||
.long LBPatch11-4
|
||||
.long LBPatch12-4
|
||||
.long LBPatch13-4
|
||||
.long LBPatch14-4
|
||||
.long LBPatch15-4
|
||||
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.globl C(R_Surf16Patch)
|
||||
C(R_Surf16Patch):
|
||||
pushl %ebx
|
||||
|
||||
movl C(colormap),%eax
|
||||
movl $LPatchTable16,%ebx
|
||||
movl $16,%ecx
|
||||
LPatchLoop16:
|
||||
movl (%ebx),%edx
|
||||
addl $4,%ebx
|
||||
movl %eax,(%edx)
|
||||
decl %ecx
|
||||
jnz LPatchLoop16
|
||||
|
||||
popl %ebx
|
||||
|
||||
ret
|
||||
|
||||
|
||||
#endif // id386
|
|
@ -1,783 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// surf8.s
|
||||
// x86 assembly-language 8 bpp surface block drawing code.
|
||||
//
|
||||
#define SWQUAKE
|
||||
#include "asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
|
||||
sb_v: .long 0
|
||||
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.globl C(R_Surf8Start)
|
||||
C(R_Surf8Start):
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 0
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip0)
|
||||
C(R_DrawSurfaceBlock8_mip0):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip0:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $4,%ecx
|
||||
orl $0xF0000000,%ebp
|
||||
|
||||
sarl $4,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
orl $0xF0000000,%ebx
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
Lblockloop8_mip0:
|
||||
movl %ebp,C(lightdelta)
|
||||
movb 14(%esi),%cl
|
||||
|
||||
sarl $4,%ebp
|
||||
movb %dh,%bh
|
||||
|
||||
movb 15(%esi),%bl
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch0:
|
||||
movb 13(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch1:
|
||||
movb 12(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch2:
|
||||
|
||||
movb 11(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch3:
|
||||
|
||||
movb 10(%esi),%cl
|
||||
movl %eax,12(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch4:
|
||||
movb 9(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch5:
|
||||
movb 8(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch6:
|
||||
|
||||
movb 7(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch7:
|
||||
|
||||
movb 6(%esi),%cl
|
||||
movl %eax,8(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch8:
|
||||
movb 5(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch9:
|
||||
movb 4(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch10:
|
||||
|
||||
movb 3(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch11:
|
||||
|
||||
movb 2(%esi),%cl
|
||||
movl %eax,4(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch12:
|
||||
movb 1(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch13:
|
||||
movb (%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch14:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch15:
|
||||
movl C(lightdelta),%ebp
|
||||
|
||||
movl %eax,(%edi)
|
||||
|
||||
addl C(sourcetstep),%esi
|
||||
addl C(surfrowbytes),%edi
|
||||
|
||||
addl C(lightrightstep),%edx
|
||||
addl C(lightdeltastep),%ebp
|
||||
|
||||
movl %edx,C(lightright)
|
||||
jc Lblockloop8_mip0
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip0
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip0:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip0
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 1
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip1)
|
||||
C(R_DrawSurfaceBlock8_mip1):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip1:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $3,%ecx
|
||||
orl $0x70000000,%ebp
|
||||
|
||||
sarl $3,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
orl $0xF0000000,%ebx
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
Lblockloop8_mip1:
|
||||
movl %ebp,C(lightdelta)
|
||||
movb 6(%esi),%cl
|
||||
|
||||
sarl $3,%ebp
|
||||
movb %dh,%bh
|
||||
|
||||
movb 7(%esi),%bl
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch22:
|
||||
movb 5(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch23:
|
||||
movb 4(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch24:
|
||||
|
||||
movb 3(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch25:
|
||||
|
||||
movb 2(%esi),%cl
|
||||
movl %eax,4(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch26:
|
||||
movb 1(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch27:
|
||||
movb (%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch28:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch29:
|
||||
movl C(lightdelta),%ebp
|
||||
|
||||
movl %eax,(%edi)
|
||||
movl C(sourcetstep),%eax
|
||||
|
||||
addl %eax,%esi
|
||||
movl C(surfrowbytes),%eax
|
||||
|
||||
addl %eax,%edi
|
||||
movl C(lightrightstep),%eax
|
||||
|
||||
addl %eax,%edx
|
||||
movl C(lightdeltastep),%eax
|
||||
|
||||
addl %eax,%ebp
|
||||
movl %edx,C(lightright)
|
||||
|
||||
jc Lblockloop8_mip1
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip1
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip1:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip1
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 2
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip2)
|
||||
C(R_DrawSurfaceBlock8_mip2):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip2:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $2,%ecx
|
||||
orl $0x30000000,%ebp
|
||||
|
||||
sarl $2,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
orl $0xF0000000,%ebx
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
Lblockloop8_mip2:
|
||||
movl %ebp,C(lightdelta)
|
||||
movb 2(%esi),%cl
|
||||
|
||||
sarl $2,%ebp
|
||||
movb %dh,%bh
|
||||
|
||||
movb 3(%esi),%bl
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch18:
|
||||
movb 1(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch19:
|
||||
movb (%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch20:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch21:
|
||||
movl C(lightdelta),%ebp
|
||||
|
||||
movl %eax,(%edi)
|
||||
movl C(sourcetstep),%eax
|
||||
|
||||
addl %eax,%esi
|
||||
movl C(surfrowbytes),%eax
|
||||
|
||||
addl %eax,%edi
|
||||
movl C(lightrightstep),%eax
|
||||
|
||||
addl %eax,%edx
|
||||
movl C(lightdeltastep),%eax
|
||||
|
||||
addl %eax,%ebp
|
||||
movl %edx,C(lightright)
|
||||
|
||||
jc Lblockloop8_mip2
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip2
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip2:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip2
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 3
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip3)
|
||||
C(R_DrawSurfaceBlock8_mip3):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip3:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
movl %ebp,C(lightdelta)
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $1,%ecx
|
||||
|
||||
sarl $1,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
sarl $1,%ebp
|
||||
orl $0xF0000000,%ebx
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
movb 1(%esi),%bl
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movb %dh,%bh
|
||||
movb (%esi),%cl
|
||||
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%al
|
||||
LBPatch16:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb %al,1(%edi)
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch17:
|
||||
|
||||
movb %al,(%edi)
|
||||
movl C(sourcetstep),%eax
|
||||
|
||||
addl %eax,%esi
|
||||
movl C(surfrowbytes),%eax
|
||||
|
||||
addl %eax,%edi
|
||||
movl C(lightdeltastep),%eax
|
||||
|
||||
movl C(lightdelta),%ebp
|
||||
movb (%esi),%cl
|
||||
|
||||
addl %eax,%ebp
|
||||
movl C(lightrightstep),%eax
|
||||
|
||||
sarl $1,%ebp
|
||||
addl %eax,%edx
|
||||
|
||||
movb %dh,%bh
|
||||
movb 1(%esi),%bl
|
||||
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%al
|
||||
LBPatch30:
|
||||
movl C(sourcetstep),%edx
|
||||
|
||||
movb %al,1(%edi)
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch31:
|
||||
|
||||
movb %al,(%edi)
|
||||
movl C(surfrowbytes),%ebp
|
||||
|
||||
addl %edx,%esi
|
||||
addl %ebp,%edi
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip3
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip3:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip3
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
.globl C(R_Surf8End)
|
||||
C(R_Surf8End):
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Code patching routines
|
||||
//----------------------------------------------------------------------
|
||||
.data
|
||||
|
||||
.align 4
|
||||
LPatchTable8:
|
||||
.long LBPatch0-4
|
||||
.long LBPatch1-4
|
||||
.long LBPatch2-4
|
||||
.long LBPatch3-4
|
||||
.long LBPatch4-4
|
||||
.long LBPatch5-4
|
||||
.long LBPatch6-4
|
||||
.long LBPatch7-4
|
||||
.long LBPatch8-4
|
||||
.long LBPatch9-4
|
||||
.long LBPatch10-4
|
||||
.long LBPatch11-4
|
||||
.long LBPatch12-4
|
||||
.long LBPatch13-4
|
||||
.long LBPatch14-4
|
||||
.long LBPatch15-4
|
||||
.long LBPatch16-4
|
||||
.long LBPatch17-4
|
||||
.long LBPatch18-4
|
||||
.long LBPatch19-4
|
||||
.long LBPatch20-4
|
||||
.long LBPatch21-4
|
||||
.long LBPatch22-4
|
||||
.long LBPatch23-4
|
||||
.long LBPatch24-4
|
||||
.long LBPatch25-4
|
||||
.long LBPatch26-4
|
||||
.long LBPatch27-4
|
||||
.long LBPatch28-4
|
||||
.long LBPatch29-4
|
||||
.long LBPatch30-4
|
||||
.long LBPatch31-4
|
||||
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.globl C(R_Surf8Patch)
|
||||
C(R_Surf8Patch):
|
||||
pushl %ebx
|
||||
|
||||
movl C(colormap),%eax
|
||||
movl $LPatchTable8,%ebx
|
||||
movl $32,%ecx
|
||||
LPatchLoop8:
|
||||
movl (%ebx),%edx
|
||||
addl $4,%ebx
|
||||
movl %eax,(%edx)
|
||||
decl %ecx
|
||||
jnz LPatchLoop8
|
||||
|
||||
popl %ebx
|
||||
|
||||
ret
|
||||
|
||||
#endif // id386
|
2694
engine/sw/sw_draw.c
2694
engine/sw/sw_draw.c
File diff suppressed because it is too large
Load diff
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// draw.h -- these are the only functions outside the refresh allowed
|
||||
// to touch the vid buffer
|
||||
|
||||
void SWDraw_Init (void);
|
||||
void SWDraw_Shutdown(void);
|
||||
void SWDraw_Character (int x, int y, unsigned int num);
|
||||
void SWDraw_TinyCharacter (int x, int y, unsigned int num);
|
||||
void SWDraw_ImageColours (float r, float g, float b, float a);
|
||||
void SWDraw_Image (float xp, float yp, float wp, float hp, float s1, float t1, float s2, float t2, mpic_t *pic);
|
||||
void SWDraw_ColouredCharacter (int x, int y, unsigned int num);
|
||||
void SWDraw_DebugChar (qbyte num);
|
||||
void SWDraw_SubPic(int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height);
|
||||
void SWDraw_Pic (int x, int y, mpic_t *pic);
|
||||
void SWDraw_TransPic (int x, int y, mpic_t *pic);
|
||||
void SWDraw_TransPicTranslate (int x, int y, int w, int h, qbyte *pic, qbyte *translation);
|
||||
void SWDraw_ConsoleBackground (int firstline, int lastline, qboolean forceopaque);
|
||||
void SWDraw_EditorBackground (int lines);
|
||||
void SWDraw_BeginDisc (void);
|
||||
void SWDraw_EndDisc (void);
|
||||
void SWDraw_TileClear (int x, int y, int w, int h);
|
||||
void SWDraw_Fill (int x, int y, int w, int h, unsigned int c);
|
||||
void SWDraw_FillRGB (int x, int y, int w, int h, float r, float g, float b);
|
||||
void SWDraw_FadeScreen (void);
|
||||
void SWDraw_String (int x, int y, const qbyte *str);
|
||||
void SWDraw_Alt_String (int x, int y, const qbyte *str);
|
||||
mpic_t *SWDraw_SafePicFromWad (char *name);
|
||||
mpic_t *SWDraw_PicFromWad (char *name);
|
||||
mpic_t *SWDraw_SafeCachePic (char *path);
|
||||
mpic_t *SWDraw_CachePic (char *path);
|
||||
void SWDraw_Crosshair(void);
|
||||
|
3921
engine/sw/sw_model.c
3921
engine/sw/sw_model.c
File diff suppressed because it is too large
Load diff
|
@ -1,275 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// screen.c -- master for refresh, status bar, console, chat, notify, etc
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
|
||||
|
||||
|
||||
extern qboolean scr_drawdialog;
|
||||
|
||||
extern cvar_t gl_triplebuffer;
|
||||
extern cvar_t scr_fov;
|
||||
|
||||
extern qboolean scr_initialized;
|
||||
extern float oldsbar;
|
||||
extern qboolean scr_drawloading;
|
||||
|
||||
extern int scr_chatmode;
|
||||
extern cvar_t scr_chatmodecvar;
|
||||
|
||||
/*
|
||||
==================
|
||||
SCR_UpdateScreen
|
||||
|
||||
This is called every frame, and can also be called explicitly to flush
|
||||
text to the screen.
|
||||
|
||||
WARNING: be very careful calling this from elsewhere, because the refresh
|
||||
needs almost the entire 256k of stack space!
|
||||
==================
|
||||
*/
|
||||
extern void D_SetTransLevel(float level, blendmode_t blend);
|
||||
extern qbyte Trans(qbyte p, qbyte p2);
|
||||
|
||||
void SWSCR_UpdateScreen (void)
|
||||
{
|
||||
qboolean nohud;
|
||||
qboolean noworld;
|
||||
int uimenu;
|
||||
vrect_t vrect;
|
||||
|
||||
if (scr_skipupdate || block_drawing)
|
||||
return;
|
||||
|
||||
if (scr_disabled_for_loading)
|
||||
{
|
||||
if (key_dest != key_console)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
{ // don't suck up any cpu if minimized
|
||||
extern qboolean Minimized;
|
||||
if (Minimized)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
scr_copytop = 0;
|
||||
scr_copyeverything = 0;
|
||||
|
||||
if (!scr_initialized || !con_initialized)
|
||||
return; // not initialized yet
|
||||
|
||||
#ifdef VM_UI
|
||||
uimenu = UI_MenuState();
|
||||
#else
|
||||
uimenu = 0;
|
||||
#endif
|
||||
|
||||
#ifdef TEXTEDITOR
|
||||
if (editormodal)
|
||||
{
|
||||
Editor_Draw();
|
||||
SWV_UpdatePalette (false, host_frametime);
|
||||
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height;
|
||||
vrect.pnext = 0;
|
||||
|
||||
SWVID_Update (&vrect);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (Media_ShowFilm())
|
||||
{
|
||||
SWV_UpdatePalette (false, host_frametime);
|
||||
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height;
|
||||
vrect.pnext = 0;
|
||||
|
||||
SWVID_Update (&vrect);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vid.recalc_refdef)
|
||||
{
|
||||
// something changed, so reorder the screen
|
||||
SCR_CalcRefdef ();
|
||||
}
|
||||
|
||||
//
|
||||
// do 3D refresh drawing, and then update the screen
|
||||
//
|
||||
D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly
|
||||
|
||||
SCR_SetUpToDrawConsole ();
|
||||
SCR_EraseCenterString ();
|
||||
|
||||
D_DisableBackBufferAccess (); // for adapters that can't stay mapped in
|
||||
// for linear writes all the time
|
||||
|
||||
nohud = false;
|
||||
noworld = false;
|
||||
#ifdef TEXTEDIT
|
||||
if (!editormodal) //don't render view.
|
||||
#endif
|
||||
{
|
||||
#ifdef CSQC_DAT
|
||||
if (cls.state == ca_active && CSQC_DrawView())
|
||||
nohud = true;
|
||||
else
|
||||
#endif
|
||||
|
||||
if (cl.worldmodel)
|
||||
{
|
||||
VID_LockBuffer ();
|
||||
V_RenderView ();
|
||||
VID_UnlockBuffer ();
|
||||
}
|
||||
else
|
||||
noworld = true;
|
||||
}
|
||||
|
||||
D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly
|
||||
|
||||
if (noworld)
|
||||
{
|
||||
if ((key_dest == key_console || key_dest == key_game) && SCR_GetLoadingStage() == LS_NONE)
|
||||
scr_con_current = vid.height;
|
||||
|
||||
nohud = true;
|
||||
Draw_ConsoleBackground(0, vid.height, true);
|
||||
}
|
||||
else if (!nohud)
|
||||
SCR_TileClear();
|
||||
|
||||
SCR_DrawTwoDimensional(uimenu, nohud);
|
||||
|
||||
D_DisableBackBufferAccess (); // for adapters that can't stay mapped in
|
||||
// for linear writes all the time
|
||||
|
||||
SWV_UpdatePalette (false, host_frametime);
|
||||
|
||||
//
|
||||
// update one of three areas
|
||||
//
|
||||
if (scr_copyeverything)
|
||||
{
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height;
|
||||
vrect.pnext = 0;
|
||||
|
||||
SWVID_Update (&vrect);
|
||||
}
|
||||
else if (scr_copytop)
|
||||
{
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height - sb_lines;
|
||||
vrect.pnext = 0;
|
||||
|
||||
SWVID_Update (&vrect);
|
||||
}
|
||||
else
|
||||
{
|
||||
vrect.x = scr_vrect.x;
|
||||
vrect.y = scr_vrect.y;
|
||||
vrect.width = scr_vrect.width;
|
||||
vrect.height = scr_vrect.height;
|
||||
vrect.pnext = 0;
|
||||
|
||||
SWVID_Update (&vrect);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SCR_UpdateWholeScreen
|
||||
==================
|
||||
*/
|
||||
void SCR_UpdateWholeScreen (void)
|
||||
{
|
||||
scr_fullupdate = 0;
|
||||
SCR_UpdateScreen ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
char *SWVID_GetRGBInfo(int prepadbytes, int *truewidth, int *trueheight)
|
||||
{ //returns a BZ_Malloced array
|
||||
qbyte *ret = BZ_Malloc(prepadbytes + vid.width*vid.height*3);
|
||||
|
||||
qbyte *dest, *src;
|
||||
int y, x;
|
||||
|
||||
extern unsigned char vid_curpal[256*3];
|
||||
|
||||
if (r_pixbytes == 4)
|
||||
{ //32 bit to 24
|
||||
dest = ret+prepadbytes + vid.width*3*(vid.height-1);
|
||||
|
||||
for (y=0 ; y<vid.height ; y++, dest -= vid.width*3)
|
||||
{
|
||||
src = vid.buffer + y*vid.rowbytes*4;
|
||||
for (x=0 ; x<vid.width*3 ; x+=3, src+=4)
|
||||
{
|
||||
dest[x] = src[2];
|
||||
dest[x+1] = src[1];
|
||||
dest[x+2] = src[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //8bit to 24 using palette lookups
|
||||
dest = ret+prepadbytes + vid.width*3*(vid.height-1);
|
||||
|
||||
for (y=0 ; y<vid.height ; y++, dest -= vid.width*3)
|
||||
{
|
||||
src = vid.buffer + y*vid.rowbytes;
|
||||
for (x=0 ; x<vid.width*3 ; x+=3, src++)
|
||||
{
|
||||
dest[x] = vid_curpal[*src*3];
|
||||
dest[x+1] = vid_curpal[*src*3+1];
|
||||
dest[x+2] = vid_curpal[*src*3+2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*truewidth = vid.width;
|
||||
*trueheight = vid.height;
|
||||
|
||||
return ret;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue