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:
TimeServ 2009-07-16 22:06:59 +00:00
parent fb2b58979b
commit a94a33212c
108 changed files with 2702 additions and 47022 deletions

View File

@ -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/

View File

@ -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

View File

@ -967,7 +967,6 @@ void CL_ClearState (void)
{
if (serverrunning)
SV_UnspawnServer();
D_FlushCaches ();
Mod_ClearAll ();
if (host_hunklevel) // FIXME: check this...

View File

@ -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;

View File

@ -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)
{

View File

@ -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

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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");
}

View File

@ -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;

View File

@ -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
}

View File

@ -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)
{

View File

@ -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?

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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 = *"";

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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
/*

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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)

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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();
}

View File

@ -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--);
}
}

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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);
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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];
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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 ();
}

View File

@ -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

View File

@ -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);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 ();
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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 ();
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 ();
}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -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