diff options
Diffstat (limited to 'QW')
308 files changed, 149609 insertions, 0 deletions
diff --git a/QW/Makefile.Linux b/QW/Makefile.Linux new file mode 100644 index 0000000..410480f --- /dev/null +++ b/QW/Makefile.Linux @@ -0,0 +1,930 @@ +# +# QuakeWorld Makefile for Linux 2.0 +# +# Apr '98 by Zoid <zoid@idsoftware.com> +# +# GNU Make required +# +# ELF only +# + +# RPM release number +RPM_RELEASE=1 + +VERSION=2.30$(GLIBC) + +ifneq (,$(findstring libc6,$(shell if [ -e /lib/libc.so.6* ];then echo libc6;fi))) +GLIBC=-glibc +else +GLIBC= +endif + +ifneq (,$(findstring alpha,$(shell uname -m))) +ARCH=axp +RPMARCH=alpha +else +ARCH=i386 +RPMARCH=i386 +endif + +MAINDIR=/grog/Projects/QW + +BUILD_DEBUG_DIR=debug$(ARCH)$(GLIBC) +BUILD_RELEASE_DIR=release$(ARCH)$(GLIBC) +CLIENT_DIR=$(MAINDIR)/client +SERVER_DIR=$(MAINDIR)/server + +MESA_DIR=/usr/local/src/Mesa-3.0 + +CC=gcc +BASE_CFLAGS=-Wall -Dstricmp=strcasecmp -I$(CLIENT_DIR) -I$(SERVER_DIR) +DEBUG_CFLAGS=$(BASE_CFLAGS) -g +ifeq ($(ARCH),axp) +RELEASE_CFLAGS=$(BASE_CFLAGS) -ffast-math -funroll-loops \ + -fomit-frame-pointer -fexpensive-optimizations +else +RELEASE_CFLAGS=$(BASE_CFLAGS) -m486 -O6 -ffast-math -funroll-loops \ + -fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \ + -malign-jumps=2 -malign-functions=2 +endif +GLCFLAGS=-DGLQUAKE -I/usr/local/src/Mesa-3.0/include -I/usr/include/glide + +LDFLAGS=-lm +SVGALDFLAGS=-lvga +XLDFLAGS=-L/usr/X11R6/lib -lX11 -lXext +GL_SVGA_LDFLAGS=-L/usr/X11/lib -L/usr/local/src/Mesa-3.0/lib -lm -lMesaGL -lglide2x -lX11 -lXext -lvga +GL_X11_LDFLAGS=-L/usr/X11/lib -L/usr/local/src/Mesa-3.0/lib -lm -lGL -lX11 -lXext + +DO_CC=$(CC) $(CFLAGS) -o $@ -c $< +DO_O_CC=$(CC) -O $(CFLAGS) -o $@ -c $< +DO_GL_CC=$(CC) $(CFLAGS) $(GLCFLAGS) -o $@ -c $< +DO_SERVER_CC=$(CC) -DSERVERONLY $(CFLAGS) -o $@ -c $< + +DO_AS=$(CC) $(CFLAGS) -DELF -x assembler-with-cpp -o $@ -c $< +DO_GL_AS=$(CC) $(CFLAGS) $(GLCFLAGS) -DELF -x assembler-with-cpp -o $@ -c $< + +############################################################################# +# SETUP AND BUILD +############################################################################# + +ifeq ($(ARCH),axp) +TARGETS=$(BUILDDIR)/qwsv +#$(BUILDDIR)/qwcl.x11 +else +TARGETS=$(BUILDDIR)/qwsv $(BUILDDIR)/qwcl $(BUILDDIR)/qwcl.x11 $(BUILDDIR)/glqwcl $(BUILDDIR)/glqwcl.glx +endif + +build_debug: + @-mkdir $(BUILD_DEBUG_DIR) \ + $(BUILD_DEBUG_DIR)/client \ + $(BUILD_DEBUG_DIR)/glclient \ + $(BUILD_DEBUG_DIR)/server + $(MAKE) targets BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +build_release: + @-mkdir $(BUILD_RELEASE_DIR) \ + $(BUILD_RELEASE_DIR)/client \ + $(BUILD_RELEASE_DIR)/glclient \ + $(BUILD_RELEASE_DIR)/server + $(MAKE) targets BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(RELEASE_CFLAGS)" + +all: build_debug build_release + +targets: $(TARGETS) + +############################################################################# +# SERVER +############################################################################# + +QWSV_OBJS = \ + $(BUILDDIR)/server/pr_cmds.o \ + $(BUILDDIR)/server/pr_edict.o \ + $(BUILDDIR)/server/pr_exec.o \ + $(BUILDDIR)/server/sv_init.o \ + $(BUILDDIR)/server/sv_main.o \ + $(BUILDDIR)/server/sv_nchan.o \ + $(BUILDDIR)/server/sv_ents.o \ + $(BUILDDIR)/server/sv_send.o \ + $(BUILDDIR)/server/sv_move.o \ + $(BUILDDIR)/server/sv_phys.o \ + $(BUILDDIR)/server/sv_user.o \ + $(BUILDDIR)/server/sv_ccmds.o \ + $(BUILDDIR)/server/world.o \ + $(BUILDDIR)/server/sys_unix.o \ + $(BUILDDIR)/server/model.o \ + $(BUILDDIR)/server/cmd.o \ + $(BUILDDIR)/server/common.o \ + $(BUILDDIR)/server/crc.o \ + $(BUILDDIR)/server/cvar.o \ + $(BUILDDIR)/server/mathlib.o \ + $(BUILDDIR)/server/md4.o \ + $(BUILDDIR)/server/zone.o \ + $(BUILDDIR)/server/pmove.o \ + $(BUILDDIR)/server/pmovetst.o \ + $(BUILDDIR)/server/net_chan.o \ + $(BUILDDIR)/server/net_udp.o + +$(BUILDDIR)/qwsv : $(QWSV_OBJS) + $(CC) $(CFLAGS) -o $@ $(QWSV_OBJS) $(LDFLAGS) + +$(BUILDDIR)/server/pr_cmds.o : $(SERVER_DIR)/pr_cmds.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/pr_edict.o : $(SERVER_DIR)/pr_edict.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/pr_exec.o : $(SERVER_DIR)/pr_exec.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_init.o : $(SERVER_DIR)/sv_init.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_main.o : $(SERVER_DIR)/sv_main.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_nchan.o : $(SERVER_DIR)/sv_nchan.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_ents.o : $(SERVER_DIR)/sv_ents.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_send.o : $(SERVER_DIR)/sv_send.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_move.o : $(SERVER_DIR)/sv_move.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_phys.o : $(SERVER_DIR)/sv_phys.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_user.o : $(SERVER_DIR)/sv_user.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_ccmds.o : $(SERVER_DIR)/sv_ccmds.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/world.o : $(SERVER_DIR)/world.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sys_unix.o : $(SERVER_DIR)/sys_unix.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/model.o : $(SERVER_DIR)/model.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/cmd.o : $(CLIENT_DIR)/cmd.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/common.o : $(CLIENT_DIR)/common.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/crc.o : $(CLIENT_DIR)/crc.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/cvar.o : $(CLIENT_DIR)/cvar.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/mathlib.o : $(CLIENT_DIR)/mathlib.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/md4.o : $(CLIENT_DIR)/md4.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/zone.o : $(CLIENT_DIR)/zone.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/pmove.o : $(CLIENT_DIR)/pmove.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/pmovetst.o : $(CLIENT_DIR)/pmovetst.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/net_chan.o : $(CLIENT_DIR)/net_chan.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/net_udp.o : $(CLIENT_DIR)/net_udp.c + $(DO_SERVER_CC) + +############################################################################# +# CLIENT +############################################################################# + +QWCL_OBJS = \ + $(BUILDDIR)/client/cl_demo.o \ + $(BUILDDIR)/client/cl_ents.o \ + $(BUILDDIR)/client/cl_input.o \ + $(BUILDDIR)/client/cl_main.o \ + $(BUILDDIR)/client/cl_parse.o \ + $(BUILDDIR)/client/cl_pred.o \ + $(BUILDDIR)/client/cl_tent.o \ + $(BUILDDIR)/client/cl_cam.o \ + $(BUILDDIR)/client/cmd.o \ + $(BUILDDIR)/client/common.o \ + $(BUILDDIR)/client/console.o \ + $(BUILDDIR)/client/crc.o \ + $(BUILDDIR)/client/cvar.o \ + $(BUILDDIR)/client/d_edge.o \ + $(BUILDDIR)/client/d_fill.o \ + $(BUILDDIR)/client/d_init.o \ + $(BUILDDIR)/client/d_modech.o \ + $(BUILDDIR)/client/d_part.o \ + $(BUILDDIR)/client/d_polyse.o \ + $(BUILDDIR)/client/d_scan.o \ + $(BUILDDIR)/client/d_sky.o \ + $(BUILDDIR)/client/d_sprite.o \ + $(BUILDDIR)/client/d_surf.o \ + $(BUILDDIR)/client/d_vars.o \ + $(BUILDDIR)/client/d_zpoint.o \ + $(BUILDDIR)/client/draw.o \ + $(BUILDDIR)/client/keys.o \ + $(BUILDDIR)/client/mathlib.o \ + $(BUILDDIR)/client/md4.o \ + $(BUILDDIR)/client/menu.o \ + $(BUILDDIR)/client/model.o \ + $(BUILDDIR)/client/net_chan.o \ + $(BUILDDIR)/client/net_udp.o \ + $(BUILDDIR)/client/nonintel.o \ + $(BUILDDIR)/client/pmove.o \ + $(BUILDDIR)/client/pmovetst.o \ + $(BUILDDIR)/client/r_aclip.o \ + $(BUILDDIR)/client/r_alias.o \ + $(BUILDDIR)/client/r_bsp.o \ + $(BUILDDIR)/client/r_draw.o \ + $(BUILDDIR)/client/r_edge.o \ + $(BUILDDIR)/client/r_efrag.o \ + $(BUILDDIR)/client/r_light.o \ + $(BUILDDIR)/client/r_main.o \ + $(BUILDDIR)/client/r_misc.o \ + $(BUILDDIR)/client/r_part.o \ + $(BUILDDIR)/client/r_sky.o \ + $(BUILDDIR)/client/r_sprite.o \ + $(BUILDDIR)/client/r_surf.o \ + $(BUILDDIR)/client/r_vars.o \ + $(BUILDDIR)/client/sbar.o \ + $(BUILDDIR)/client/screen.o \ + $(BUILDDIR)/client/skin.o \ + $(BUILDDIR)/client/snd_dma.o \ + $(BUILDDIR)/client/snd_mem.o \ + $(BUILDDIR)/client/snd_mix.o \ + $(BUILDDIR)/client/view.o \ + $(BUILDDIR)/client/wad.o \ + $(BUILDDIR)/client/zone.o \ + $(BUILDDIR)/client/cd_linux.o \ + $(BUILDDIR)/client/sys_linux.o \ + $(BUILDDIR)/client/snd_linux.o \ + +ifeq ($(ARCH),i386) + QWCL_AS_OBJS = \ + $(BUILDDIR)/client/d_copy.o \ + $(BUILDDIR)/client/d_draw.o \ + $(BUILDDIR)/client/d_draw16.o \ + $(BUILDDIR)/client/d_parta.o \ + $(BUILDDIR)/client/d_polysa.o \ + $(BUILDDIR)/client/d_scana.o \ + $(BUILDDIR)/client/d_spr8.o \ + $(BUILDDIR)/client/d_varsa.o \ + $(BUILDDIR)/client/math.o \ + $(BUILDDIR)/client/r_aclipa.o \ + $(BUILDDIR)/client/r_aliasa.o \ + $(BUILDDIR)/client/r_drawa.o \ + $(BUILDDIR)/client/r_edgea.o \ + $(BUILDDIR)/client/r_varsa.o \ + $(BUILDDIR)/client/snd_mixa.o \ + $(BUILDDIR)/client/surf16.o \ + $(BUILDDIR)/client/surf8.o \ + $(BUILDDIR)/client/sys_dosa.o +else + QWCL_AS_OBJS= +endif + +QWCL_SVGA_OBJS = $(BUILDDIR)/client/vid_svgalib.o +QWCL_X11_OBJS = $(BUILDDIR)/client/vid_x.o + +$(BUILDDIR)/qwcl : $(QWCL_OBJS) $(QWCL_AS_OBJS) $(QWCL_SVGA_OBJS) + $(CC) $(CFLAGS) -o $@ $(QWCL_OBJS) $(QWCL_AS_OBJS) $(QWCL_SVGA_OBJS) \ + $(LDFLAGS) $(SVGALDFLAGS) + +$(BUILDDIR)/qwcl.x11 : $(QWCL_OBJS) $(QWCL_AS_OBJS) $(QWCL_X11_OBJS) + $(CC) $(CFLAGS) -o $@ $(QWCL_OBJS) $(QWCL_AS_OBJS) $(QWCL_X11_OBJS) \ + $(LDFLAGS) $(XLDFLAGS) + +$(BUILDDIR)/client/cl_demo.o : $(CLIENT_DIR)/cl_demo.c + $(DO_CC) + +$(BUILDDIR)/client/cl_ents.o : $(CLIENT_DIR)/cl_ents.c + $(DO_CC) + +$(BUILDDIR)/client/cl_input.o : $(CLIENT_DIR)/cl_input.c + $(DO_CC) + +$(BUILDDIR)/client/cl_main.o : $(CLIENT_DIR)/cl_main.c + $(DO_CC) + +$(BUILDDIR)/client/cl_parse.o : $(CLIENT_DIR)/cl_parse.c + $(DO_CC) + +$(BUILDDIR)/client/cl_pred.o : $(CLIENT_DIR)/cl_pred.c + $(DO_CC) + +$(BUILDDIR)/client/cl_tent.o : $(CLIENT_DIR)/cl_tent.c + $(DO_CC) + +$(BUILDDIR)/client/cl_cam.o : $(CLIENT_DIR)/cl_cam.c + $(DO_CC) + +$(BUILDDIR)/client/cmd.o : $(CLIENT_DIR)/cmd.c + $(DO_CC) + +$(BUILDDIR)/client/common.o : $(CLIENT_DIR)/common.c + $(DO_CC) + +$(BUILDDIR)/client/console.o : $(CLIENT_DIR)/console.c + $(DO_CC) + +$(BUILDDIR)/client/crc.o : $(CLIENT_DIR)/crc.c + $(DO_CC) + +$(BUILDDIR)/client/cvar.o : $(CLIENT_DIR)/cvar.c + $(DO_CC) + +$(BUILDDIR)/client/d_edge.o : $(CLIENT_DIR)/d_edge.c + $(DO_CC) + +$(BUILDDIR)/client/d_fill.o : $(CLIENT_DIR)/d_fill.c + $(DO_CC) + +$(BUILDDIR)/client/d_init.o : $(CLIENT_DIR)/d_init.c + $(DO_CC) + +$(BUILDDIR)/client/d_modech.o : $(CLIENT_DIR)/d_modech.c + $(DO_CC) + +$(BUILDDIR)/client/d_part.o : $(CLIENT_DIR)/d_part.c + $(DO_CC) + +$(BUILDDIR)/client/d_polyse.o : $(CLIENT_DIR)/d_polyse.c + $(DO_CC) + +$(BUILDDIR)/client/d_scan.o : $(CLIENT_DIR)/d_scan.c + $(DO_CC) + +$(BUILDDIR)/client/d_sky.o : $(CLIENT_DIR)/d_sky.c + $(DO_CC) + +$(BUILDDIR)/client/d_sprite.o : $(CLIENT_DIR)/d_sprite.c + $(DO_CC) + +$(BUILDDIR)/client/d_surf.o : $(CLIENT_DIR)/d_surf.c + $(DO_CC) + +$(BUILDDIR)/client/d_vars.o : $(CLIENT_DIR)/d_vars.c + $(DO_CC) + +$(BUILDDIR)/client/d_zpoint.o : $(CLIENT_DIR)/d_zpoint.c + $(DO_CC) + +$(BUILDDIR)/client/draw.o : $(CLIENT_DIR)/draw.c + $(DO_CC) + +$(BUILDDIR)/client/keys.o : $(CLIENT_DIR)/keys.c + $(DO_CC) + +$(BUILDDIR)/client/mathlib.o : $(CLIENT_DIR)/mathlib.c + $(DO_CC) + +$(BUILDDIR)/client/md4.o : $(CLIENT_DIR)/md4.c + $(DO_CC) + +$(BUILDDIR)/client/menu.o : $(CLIENT_DIR)/menu.c + $(DO_CC) + +$(BUILDDIR)/client/model.o : $(CLIENT_DIR)/model.c + $(DO_CC) + +$(BUILDDIR)/client/net_chan.o : $(CLIENT_DIR)/net_chan.c + $(DO_CC) + +$(BUILDDIR)/client/net_udp.o : $(CLIENT_DIR)/net_udp.c + $(DO_CC) + +$(BUILDDIR)/client/nonintel.o : $(CLIENT_DIR)/nonintel.c + $(DO_CC) + +$(BUILDDIR)/client/pmove.o : $(CLIENT_DIR)/pmove.c + $(DO_CC) + +$(BUILDDIR)/client/pmovetst.o : $(CLIENT_DIR)/pmovetst.c + $(DO_CC) + +$(BUILDDIR)/client/r_aclip.o : $(CLIENT_DIR)/r_aclip.c + $(DO_CC) + +$(BUILDDIR)/client/r_alias.o : $(CLIENT_DIR)/r_alias.c + $(DO_CC) + +$(BUILDDIR)/client/r_bsp.o : $(CLIENT_DIR)/r_bsp.c + $(DO_CC) + +$(BUILDDIR)/client/r_draw.o : $(CLIENT_DIR)/r_draw.c + $(DO_CC) + +$(BUILDDIR)/client/r_edge.o : $(CLIENT_DIR)/r_edge.c + $(DO_CC) + +$(BUILDDIR)/client/r_efrag.o : $(CLIENT_DIR)/r_efrag.c + $(DO_CC) + +$(BUILDDIR)/client/r_light.o : $(CLIENT_DIR)/r_light.c + $(DO_CC) + +$(BUILDDIR)/client/r_main.o : $(CLIENT_DIR)/r_main.c + $(DO_CC) + +$(BUILDDIR)/client/r_misc.o : $(CLIENT_DIR)/r_misc.c + $(DO_CC) + +$(BUILDDIR)/client/r_part.o : $(CLIENT_DIR)/r_part.c + $(DO_CC) + +$(BUILDDIR)/client/r_sky.o : $(CLIENT_DIR)/r_sky.c + $(DO_CC) + +$(BUILDDIR)/client/r_sprite.o : $(CLIENT_DIR)/r_sprite.c + $(DO_CC) + +$(BUILDDIR)/client/r_surf.o : $(CLIENT_DIR)/r_surf.c + $(DO_CC) + +$(BUILDDIR)/client/r_vars.o : $(CLIENT_DIR)/r_vars.c + $(DO_CC) + +$(BUILDDIR)/client/sbar.o : $(CLIENT_DIR)/sbar.c + $(DO_CC) + +$(BUILDDIR)/client/screen.o : $(CLIENT_DIR)/screen.c + $(DO_CC) + +$(BUILDDIR)/client/skin.o : $(CLIENT_DIR)/skin.c + $(DO_CC) + +$(BUILDDIR)/client/snd_dma.o : $(CLIENT_DIR)/snd_dma.c + $(DO_CC) + +$(BUILDDIR)/client/snd_mem.o : $(CLIENT_DIR)/snd_mem.c + $(DO_CC) + +$(BUILDDIR)/client/snd_mix.o : $(CLIENT_DIR)/snd_mix.c + $(DO_CC) + +$(BUILDDIR)/client/view.o : $(CLIENT_DIR)/view.c + $(DO_CC) + +$(BUILDDIR)/client/wad.o : $(CLIENT_DIR)/wad.c + $(DO_CC) + +$(BUILDDIR)/client/zone.o : $(CLIENT_DIR)/zone.c + $(DO_CC) + +$(BUILDDIR)/client/cd_linux.o : $(CLIENT_DIR)/cd_linux.c + $(DO_CC) + +$(BUILDDIR)/client/sys_linux.o : $(CLIENT_DIR)/sys_linux.c + $(DO_CC) + +$(BUILDDIR)/client/snd_linux.o : $(CLIENT_DIR)/snd_linux.c + $(DO_CC) + +$(BUILDDIR)/client/d_copy.o : $(CLIENT_DIR)/d_copy.s + $(DO_AS) + +$(BUILDDIR)/client/d_draw.o : $(CLIENT_DIR)/d_draw.s + $(DO_AS) + +$(BUILDDIR)/client/d_draw16.o : $(CLIENT_DIR)/d_draw16.s + $(DO_AS) + +$(BUILDDIR)/client/d_parta.o : $(CLIENT_DIR)/d_parta.s + $(DO_AS) + +$(BUILDDIR)/client/d_polysa.o : $(CLIENT_DIR)/d_polysa.s + $(DO_AS) + +$(BUILDDIR)/client/d_scana.o : $(CLIENT_DIR)/d_scana.s + $(DO_AS) + +$(BUILDDIR)/client/d_spr8.o : $(CLIENT_DIR)/d_spr8.s + $(DO_AS) + +$(BUILDDIR)/client/d_varsa.o : $(CLIENT_DIR)/d_varsa.s + $(DO_AS) + +$(BUILDDIR)/client/math.o : $(CLIENT_DIR)/math.s + $(DO_AS) + +$(BUILDDIR)/client/r_aclipa.o : $(CLIENT_DIR)/r_aclipa.s + $(DO_AS) + +$(BUILDDIR)/client/r_aliasa.o : $(CLIENT_DIR)/r_aliasa.s + $(DO_AS) + +$(BUILDDIR)/client/r_drawa.o : $(CLIENT_DIR)/r_drawa.s + $(DO_AS) + +$(BUILDDIR)/client/r_edgea.o : $(CLIENT_DIR)/r_edgea.s + $(DO_AS) + +$(BUILDDIR)/client/r_varsa.o : $(CLIENT_DIR)/r_varsa.s + $(DO_AS) + +$(BUILDDIR)/client/snd_mixa.o : $(CLIENT_DIR)/snd_mixa.s + $(DO_AS) + +$(BUILDDIR)/client/surf16.o : $(CLIENT_DIR)/surf16.s + $(DO_AS) + +$(BUILDDIR)/client/surf8.o : $(CLIENT_DIR)/surf8.s + $(DO_AS) + +$(BUILDDIR)/client/sys_dosa.o : $(CLIENT_DIR)/sys_dosa.s + $(DO_AS) + +$(BUILDDIR)/client/vid_svgalib.o : $(CLIENT_DIR)/vid_svgalib.c + $(DO_O_CC) + +$(BUILDDIR)/client/vid_x.o : $(CLIENT_DIR)/vid_x.c + $(DO_CC) + +############################################################################# +# GL CLIENT +############################################################################# + +GLQWCL_OBJS = \ + $(BUILDDIR)/glclient/cl_demo.o \ + $(BUILDDIR)/glclient/cl_ents.o \ + $(BUILDDIR)/glclient/cl_input.o \ + $(BUILDDIR)/glclient/cl_main.o \ + $(BUILDDIR)/glclient/cl_parse.o \ + $(BUILDDIR)/glclient/cl_pred.o \ + $(BUILDDIR)/glclient/cl_tent.o \ + $(BUILDDIR)/glclient/cl_cam.o \ + $(BUILDDIR)/glclient/cmd.o \ + $(BUILDDIR)/glclient/common.o \ + $(BUILDDIR)/glclient/console.o \ + $(BUILDDIR)/glclient/crc.o \ + $(BUILDDIR)/glclient/cvar.o \ + $(BUILDDIR)/glclient/keys.o \ + $(BUILDDIR)/glclient/mathlib.o \ + $(BUILDDIR)/glclient/md4.o \ + $(BUILDDIR)/glclient/menu.o \ + $(BUILDDIR)/glclient/net_chan.o \ + $(BUILDDIR)/glclient/net_udp.o \ + $(BUILDDIR)/glclient/nonintel.o \ + $(BUILDDIR)/glclient/pmove.o \ + $(BUILDDIR)/glclient/pmovetst.o \ + $(BUILDDIR)/glclient/r_part.o \ + $(BUILDDIR)/glclient/sbar.o \ + $(BUILDDIR)/glclient/skin.o \ + $(BUILDDIR)/glclient/snd_dma.o \ + $(BUILDDIR)/glclient/snd_mem.o \ + $(BUILDDIR)/glclient/snd_mix.o \ + $(BUILDDIR)/glclient/view.o \ + $(BUILDDIR)/glclient/wad.o \ + $(BUILDDIR)/glclient/zone.o \ + $(BUILDDIR)/glclient/cd_linux.o \ + $(BUILDDIR)/glclient/sys_linux.o \ + $(BUILDDIR)/glclient/snd_linux.o \ + \ + $(BUILDDIR)/glclient/gl_draw.o \ + $(BUILDDIR)/glclient/gl_mesh.o \ + $(BUILDDIR)/glclient/gl_model.o \ + $(BUILDDIR)/glclient/gl_ngraph.o \ + $(BUILDDIR)/glclient/gl_refrag.o \ + $(BUILDDIR)/glclient/gl_rlight.o \ + $(BUILDDIR)/glclient/gl_rmain.o \ + $(BUILDDIR)/glclient/gl_rmisc.o \ + $(BUILDDIR)/glclient/gl_rsurf.o \ + $(BUILDDIR)/glclient/gl_screen.o \ + $(BUILDDIR)/glclient/gl_warp.o \ + \ + $(BUILDDIR)/glclient/math.o \ + $(BUILDDIR)/glclient/snd_mixa.o \ + $(BUILDDIR)/glclient/sys_dosa.o + +GLQWCL_SVGA_OBJS = $(BUILDDIR)/glclient/gl_vidlinux.o +GLQWCL_X11_OBJS = $(BUILDDIR)/glclient/gl_vidlinuxglx.o + +$(BUILDDIR)/glqwcl : $(GLQWCL_OBJS) $(GLQWCL_SVGA_OBJS) + $(CC) $(CFLAGS) -o $@ $(GLQWCL_OBJS) $(GLQWCL_SVGA_OBJS) $(LDFLAGS) $(GL_SVGA_LDFLAGS) + +$(BUILDDIR)/glqwcl.glx : $(GLQWCL_OBJS) $(GLQWCL_X11_OBJS) + $(CC) $(CFLAGS) -o $@ $(GLQWCL_OBJS) $(GLQWCL_X11_OBJS) $(LDFLAGS) $(GL_X11_LDFLAGS) + +$(BUILDDIR)/glclient/cl_demo.o : $(CLIENT_DIR)/cl_demo.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/cl_ents.o : $(CLIENT_DIR)/cl_ents.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/cl_input.o : $(CLIENT_DIR)/cl_input.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/cl_main.o : $(CLIENT_DIR)/cl_main.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/cl_parse.o : $(CLIENT_DIR)/cl_parse.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/cl_pred.o : $(CLIENT_DIR)/cl_pred.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/cl_tent.o : $(CLIENT_DIR)/cl_tent.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/cl_cam.o : $(CLIENT_DIR)/cl_cam.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/cmd.o : $(CLIENT_DIR)/cmd.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/common.o : $(CLIENT_DIR)/common.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/console.o : $(CLIENT_DIR)/console.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/crc.o : $(CLIENT_DIR)/crc.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/cvar.o : $(CLIENT_DIR)/cvar.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/keys.o : $(CLIENT_DIR)/keys.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/mathlib.o : $(CLIENT_DIR)/mathlib.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/md4.o : $(CLIENT_DIR)/md4.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/menu.o : $(CLIENT_DIR)/menu.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/net_chan.o : $(CLIENT_DIR)/net_chan.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/net_udp.o : $(CLIENT_DIR)/net_udp.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/nonintel.o : $(CLIENT_DIR)/nonintel.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/pmove.o : $(CLIENT_DIR)/pmove.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/pmovetst.o : $(CLIENT_DIR)/pmovetst.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/r_part.o : $(CLIENT_DIR)/r_part.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/sbar.o : $(CLIENT_DIR)/sbar.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/screen.o : $(CLIENT_DIR)/screen.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/skin.o : $(CLIENT_DIR)/skin.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/snd_dma.o : $(CLIENT_DIR)/snd_dma.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/snd_mem.o : $(CLIENT_DIR)/snd_mem.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/snd_mix.o : $(CLIENT_DIR)/snd_mix.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/view.o : $(CLIENT_DIR)/view.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/wad.o : $(CLIENT_DIR)/wad.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/zone.o : $(CLIENT_DIR)/zone.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/cd_linux.o : $(CLIENT_DIR)/cd_linux.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/sys_linux.o : $(CLIENT_DIR)/sys_linux.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/snd_linux.o : $(CLIENT_DIR)/snd_linux.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_draw.o : $(CLIENT_DIR)/gl_draw.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_mesh.o : $(CLIENT_DIR)/gl_mesh.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_model.o : $(CLIENT_DIR)/gl_model.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_ngraph.o : $(CLIENT_DIR)/gl_ngraph.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_refrag.o : $(CLIENT_DIR)/gl_refrag.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_rlight.o : $(CLIENT_DIR)/gl_rlight.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_rmain.o : $(CLIENT_DIR)/gl_rmain.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_rmisc.o : $(CLIENT_DIR)/gl_rmisc.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_rsurf.o : $(CLIENT_DIR)/gl_rsurf.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_screen.o : $(CLIENT_DIR)/gl_screen.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_vidlinux.o : $(CLIENT_DIR)/gl_vidlinux.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_vidlinuxglx.o : $(CLIENT_DIR)/gl_vidlinuxglx.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/gl_warp.o : $(CLIENT_DIR)/gl_warp.c + $(DO_GL_CC) + +$(BUILDDIR)/glclient/math.o : $(CLIENT_DIR)/math.s + $(DO_GL_AS) + +$(BUILDDIR)/glclient/snd_mixa.o : $(CLIENT_DIR)/snd_mixa.s + $(DO_GL_AS) + +$(BUILDDIR)/glclient/sys_dosa.o : $(CLIENT_DIR)/sys_dosa.s + $(DO_GL_AS) + +############################################################################# +# RPM +############################################################################# + +# Make RPMs. You need to be root to make this work +RPMROOT=/usr/src/redhat +RPM = rpm +RPMFLAGS = -bb +INSTALLDIR = /usr/local/games/quake + +ifeq ($(ARCH),axp) +rpm: rpm-qwsv +tar: tar-qwsv +else +rpm: rpm-qwcl rpm-qwsv +tar: tar-qwcl tar-qwsv +endif + +QWCL_RPMDIR=/var/tmp/qwcl-$(VERSION) +TDFXGL_DIR=/home/zoid/3dfxgl + +QWPROGS = \ + $(MAINDIR)/progs/buttons.qc \ + $(MAINDIR)/progs/client.qc \ + $(MAINDIR)/progs/combat.qc \ + $(MAINDIR)/progs/defs.qc \ + $(MAINDIR)/progs/doors.qc \ + $(MAINDIR)/progs/items.qc \ + $(MAINDIR)/progs/misc.qc \ + $(MAINDIR)/progs/models.qc \ + $(MAINDIR)/progs/plats.qc \ + $(MAINDIR)/progs/player.qc \ + $(MAINDIR)/progs/progdefs.h \ + $(MAINDIR)/progs/progs.src \ + $(MAINDIR)/progs/qwprogs.dat \ + $(MAINDIR)/progs/server.qc \ + $(MAINDIR)/progs/spectate.qc \ + $(MAINDIR)/progs/sprites.qc \ + $(MAINDIR)/progs/subs.qc \ + $(MAINDIR)/progs/triggers.qc \ + $(MAINDIR)/progs/weapons.qc \ + $(MAINDIR)/progs/world.qc + +rpm-qwcl: qwcl.spec \ + $(BUILD_RELEASE_DIR)/qwcl \ + $(BUILD_RELEASE_DIR)/glqwcl \ + $(BUILD_RELEASE_DIR)/glqwcl.glx \ + $(BUILD_RELEASE_DIR)/qwcl.x11 + touch $(RPMROOT)/SOURCES/qwcl-$(VERSION).tar.gz + if [ ! -d archives ];then mkdir archives;fi + $(MAKE) copyfiles-qwcl DESTDIR=$(QWCL_RPMDIR)/$(INSTALLDIR) + cp qwcl.spec $(RPMROOT)/SPECS/qwcl.spec + cp $(MAINDIR)/quake.gif $(RPMROOT)/SOURCES/quake.gif + cd $(RPMROOT)/SPECS; $(RPM) $(RPMFLAGS) qwcl.spec + cp $(RPMROOT)/RPMS/$(RPMARCH)/qwcl-$(VERSION)-$(RPM_RELEASE).$(RPMARCH).rpm archives/. + rm -rf $(QWCL_RPMDIR) + +tar-qwcl: $(BUILD_RELEASE_DIR)/qwcl \ + $(BUILD_RELEASE_DIR)/glqwcl \ + $(BUILD_RELEASE_DIR)/glqwcl.glx \ + $(BUILD_RELEASE_DIR)/qwcl.x11 + if [ ! -d archives ];then mkdir archives;fi + $(MAKE) copyfiles-qwcl DESTDIR=$(QWCL_RPMDIR)/$(INSTALLDIR) + cd $(QWCL_RPMDIR)/$(INSTALLDIR); tar czvf qwcl-$(VERSION)-$(RPMARCH)-unknown-linux2.0.tar.gz * + mv $(QWCL_RPMDIR)/$(INSTALLDIR)/*.tar.gz archives/. + rm -rf $(QWCL_RPMDIR) + +copyfiles-qwcl: + -mkdirhier $(DESTDIR) + -mkdirhier $(DESTDIR)/qw + -mkdirhier $(DESTDIR)/qw/skins + cp $(BUILD_RELEASE_DIR)/qwcl $(DESTDIR)/. + strip $(DESTDIR)/qwcl + chmod 4755 $(DESTDIR)/qwcl + cp $(BUILD_RELEASE_DIR)/qwcl.x11 $(DESTDIR)/. + strip $(DESTDIR)/qwcl.x11 + chmod 755 $(DESTDIR)/qwcl.x11 + cp $(BUILD_RELEASE_DIR)/glqwcl $(DESTDIR)/. + strip $(DESTDIR)/glqwcl + chmod 4755 $(DESTDIR)/glqwcl + cp $(BUILD_RELEASE_DIR)/glqwcl.glx $(DESTDIR)/. + strip $(DESTDIR)/glqwcl.glx + chmod 4755 $(DESTDIR)/glqwcl.glx + cp $(TDFXGL_DIR)/release$(ARCH)/lib3dfxgl.so $(DESTDIR)/. + chmod 755 $(DESTDIR)/lib3dfxgl.so + cp $(MAINDIR)/glqwcl.3dfxgl $(DESTDIR)/. + chmod 755 $(DESTDIR)/glqwcl.3dfxgl + cp $(MAINDIR)/docs/README.qwcl $(DESTDIR)/. + chmod 644 $(DESTDIR)/README.qwcl + cp $(MAINDIR)/fixskins.sh $(DESTDIR)/qw/skins/. + chmod 755 $(DESTDIR)/qw/skins/fixskins.sh + cp $(MESA_DIR)/lib/libMesaGL.so.2.6 $(DESTDIR) + chmod 755 $(DESTDIR)/libMesaGL.so.2.6 + cd $(DESTDIR); ln -sf libMesaGL.so.2.6 libMesaGL.so.2 + cd $(DESTDIR); ln -sf libMesaGL.so.2 libMesaGL.so + cd $(DESTDIR); ln -sf libMesaGL.so libGL.so + +qwcl.spec : $(MAINDIR)/qwcl.spec.sh $(BUILD_RELEASE_DIR)/qwcl + sh $< $(VERSION) $(RPM_RELEASE) $(INSTALLDIR) > $@ + +QWSV_RPMDIR=/var/tmp/qwsv-$(VERSION) +rpm-qwsv: qwsv.spec $(BUILD_RELEASE_DIR)/qwsv $(QWPROGS) + touch $(RPMROOT)/SOURCES/qwsv-$(VERSION).tar.gz + if [ ! -d archives ];then mkdir archives;fi + $(MAKE) copyfiles-qwsv DESTDIR=$(QWSV_RPMDIR)/$(INSTALLDIR) + cp qwsv.spec $(RPMROOT)/SPECS/qwsv.spec + cp $(MAINDIR)/quake.gif $(RPMROOT)/SOURCES/quake.gif + cd $(RPMROOT)/SPECS; $(RPM) $(RPMFLAGS) qwsv.spec + cp $(RPMROOT)/RPMS/$(RPMARCH)/qwsv-$(VERSION)-$(RPM_RELEASE).$(RPMARCH).rpm archives/. + rm -rf $(QWSV_RPMDIR) + +tar-qwsv: $(BUILD_RELEASE_DIR)/qwsv $(QWPROGS) + if [ ! -d archives ];then mkdir archives;fi + $(MAKE) copyfiles-qwsv DESTDIR=$(QWSV_RPMDIR)/$(INSTALLDIR) + cd $(QWSV_RPMDIR)/$(INSTALLDIR); tar czvf qwsv-$(VERSION)-$(RPMARCH)-unknown-linux2.0.tar.gz * + mv $(QWSV_RPMDIR)/$(INSTALLDIR)/*.tar.gz archives/. + rm -rf $(QWSV_RPMDIR) + +copyfiles-qwsv: + -mkdirhier $(DESTDIR) + -mkdirhier $(DESTDIR)/qw + -mkdirhier $(DESTDIR)/qw/skins + cp $(BUILD_RELEASE_DIR)/qwsv $(DESTDIR)/. + strip $(DESTDIR)/qwsv + chmod 755 $(DESTDIR)/qwsv + cp $(MAINDIR)/docs/README.qwsv $(DESTDIR)/. + chmod 644 $(DESTDIR)/README.qwsv + cp $(QWPROGS) $(DESTDIR)/qw/. + cd $(DESTDIR)/qw; chmod 644 * + chmod 755 $(DESTDIR)/qw/skins + cp $(MAINDIR)/fixskins.sh $(DESTDIR)/qw/skins/. + chmod 755 $(DESTDIR)/qw/skins/fixskins.sh + +qwsv.spec : $(MAINDIR)/qwsv.spec.sh $(BUILD_RELEASE_DIR)/qwsv + sh $< $(VERSION) $(RPM_RELEASE) $(INSTALLDIR) > $@ + +############################################################################# +# MISC +############################################################################# + +clean: clean-debug clean-release + +clean-debug: + $(MAKE) clean2 BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +clean-release: + $(MAKE) clean2 BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +clean2: + -rm -f $(QWSV_OBJS) \ + $(QWCL_OBJS) \ + $(QWCL_AS_OBJS) \ + $(QWCL_SVGA_OBJS) \ + $(QWCL_X11_OBJS) \ + $(GLQWCL_OBJS) \ + diff --git a/QW/Makefile.Solaris b/QW/Makefile.Solaris new file mode 100644 index 0000000..a323662 --- /dev/null +++ b/QW/Makefile.Solaris @@ -0,0 +1,185 @@ +# +# QuakeWorld Makefile for Linux 2.0 +# +# Apr '98 by Zoid <zoid@idsoftware.com> +# +# GNU Make required +# + +ifneq (,$(findstring i86pc,$(shell uname -m))) +ARCH=i386 +else +ARCH=sparc +endif + +MAINDIR=/grog/Projects/QW + +BUILD_DEBUG_DIR=debug$(ARCH) +BUILD_RELEASE_DIR=release$(ARCH) +CLIENT_DIR=$(MAINDIR)/client +SERVER_DIR=$(MAINDIR)/server + +CC=gcc +BASE_CFLAGS=-Wall -Dstricmp=strcasecmp -I$(CLIENT_DIR) -I$(SERVER_DIR) +RELEASE_CFLAGS=$(BASE_CFLAGS) -O2 -ffast-math + # -funroll-loops -fomit-frame-pointer -fexpensive-optimizations +DEBUG_CFLAGS=$(BASE_CFLAGS) -g + +LDFLAGS=-lm -lsocket -lnsl + +DO_CC=$(CC) $(CFLAGS) -o $@ -c $< +DO_SERVER_CC=$(CC) -DSERVERONLY $(CFLAGS) -o $@ -c $< + +############################################################################# +# SETUP AND BUILD +############################################################################# + +TARGETS=$(BUILDDIR)/qwsv + +build_debug: + @-mkdir $(BUILD_DEBUG_DIR) \ + $(BUILD_DEBUG_DIR)/server + $(MAKE) targets BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +build_release: + @-mkdir $(BUILD_RELEASE_DIR) \ + $(BUILD_RELEASE_DIR)/server + $(MAKE) targets BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(RELEASE_CFLAGS)" + +all: build_debug build_release + +targets: $(TARGETS) + +############################################################################# +# SERVER +############################################################################# + +QWSV_OBJS = \ + $(BUILDDIR)/server/pr_cmds.o \ + $(BUILDDIR)/server/pr_edict.o \ + $(BUILDDIR)/server/pr_exec.o \ + $(BUILDDIR)/server/sv_init.o \ + $(BUILDDIR)/server/sv_main.o \ + $(BUILDDIR)/server/sv_nchan.o \ + $(BUILDDIR)/server/sv_ents.o \ + $(BUILDDIR)/server/sv_send.o \ + $(BUILDDIR)/server/sv_move.o \ + $(BUILDDIR)/server/sv_phys.o \ + $(BUILDDIR)/server/sv_user.o \ + $(BUILDDIR)/server/sv_ccmds.o \ + $(BUILDDIR)/server/world.o \ + $(BUILDDIR)/server/sys_unix.o \ + $(BUILDDIR)/server/model.o \ + $(BUILDDIR)/server/cmd.o \ + $(BUILDDIR)/server/common.o \ + $(BUILDDIR)/server/crc.o \ + $(BUILDDIR)/server/cvar.o \ + $(BUILDDIR)/server/mathlib.o \ + $(BUILDDIR)/server/md4.o \ + $(BUILDDIR)/server/zone.o \ + $(BUILDDIR)/server/pmove.o \ + $(BUILDDIR)/server/pmovetst.o \ + $(BUILDDIR)/server/net_chan.o \ + $(BUILDDIR)/server/net_udp.o + +$(BUILDDIR)/qwsv : $(QWSV_OBJS) + $(CC) $(CFLAGS) -o $@ $(QWSV_OBJS) $(LDFLAGS) + +$(BUILDDIR)/server/pr_cmds.o : $(SERVER_DIR)/pr_cmds.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/pr_edict.o : $(SERVER_DIR)/pr_edict.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/pr_exec.o : $(SERVER_DIR)/pr_exec.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_init.o : $(SERVER_DIR)/sv_init.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_main.o : $(SERVER_DIR)/sv_main.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_nchan.o : $(SERVER_DIR)/sv_nchan.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_ents.o : $(SERVER_DIR)/sv_ents.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_send.o : $(SERVER_DIR)/sv_send.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_move.o : $(SERVER_DIR)/sv_move.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_phys.o : $(SERVER_DIR)/sv_phys.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_user.o : $(SERVER_DIR)/sv_user.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sv_ccmds.o : $(SERVER_DIR)/sv_ccmds.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/world.o : $(SERVER_DIR)/world.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/sys_unix.o : $(SERVER_DIR)/sys_unix.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/model.o : $(SERVER_DIR)/model.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/cmd.o : $(CLIENT_DIR)/cmd.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/common.o : $(CLIENT_DIR)/common.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/crc.o : $(CLIENT_DIR)/crc.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/cvar.o : $(CLIENT_DIR)/cvar.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/mathlib.o : $(CLIENT_DIR)/mathlib.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/md4.o : $(CLIENT_DIR)/md4.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/zone.o : $(CLIENT_DIR)/zone.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/pmove.o : $(CLIENT_DIR)/pmove.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/pmovetst.o : $(CLIENT_DIR)/pmovetst.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/net_chan.o : $(CLIENT_DIR)/net_chan.c + $(DO_SERVER_CC) + +$(BUILDDIR)/server/net_udp.o : $(CLIENT_DIR)/net_udp.c + $(DO_SERVER_CC) + +############################################################################# +# MISC +############################################################################# + +clean: clean-debug clean-release + +clean-debug: + $(MAKE) clean2 BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +clean-release: + $(MAKE) clean2 BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +clean2: + -rm -f $(QWSV_OBJS) \ + $(QWCL_OBJS) \ + $(QWCL_AS_OBJS) \ + $(QWCL_SVGA_OBJS) \ + $(QWCL_X11_OBJS) \ + $(GLQWCL_OBJS) \ + diff --git a/QW/clean.bat b/QW/clean.bat new file mode 100644 index 0000000..b0c522e --- /dev/null +++ b/QW/clean.bat @@ -0,0 +1,40 @@ +rm -rf client\debug +rm -rf client\release +rm -rf client\gldebug +rm -rf client\glrelease + +rm -f client\qwcl.ncb +rm -f client\qwcl.opt +rm -f client\qwcl.plg +rm -f client\qwcl.stt + +rm -rf server\debug +rm -rf server\release + +rm -f server\qwsv.ncb +rm -f server\qwsv.opt +rm -f server\qwsv.plg +rm -f server\qwsv.stt + +rm -rf gas2masm\debug +rm -rf gas2masm\release + +rm -f gas2masm\gas2masm.ncb +rm -f gas2masm\gas2masm.opt +rm -f gas2masm\gas2masm.plg +rm -f gas2masm\gas2masm.stt + +rm -rf qwfwd\debug +rm -rf qwfwd\release + +rm -f qwfwd\qwfwd.ncb +rm -f qwfwd\qwfwd.opt +rm -f qwfwd\qwfwd.plg +rm -f qwfwd\qwfwd.stt + +rm -f qw.ncb +rm -f qw.opt +rm -f qw.plg +rm -f qw.stt + + diff --git a/QW/client/adivtab.h b/QW/client/adivtab.h new file mode 100644 index 0000000..5d556e4 --- /dev/null +++ b/QW/client/adivtab.h @@ -0,0 +1,1074 @@ +/* +Copyright (C) 1999, 2000 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. +*/ + +// table of quotients and remainders for [-15...16] / [-15...16] + +// numerator = -15 +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{1, -7}, +{2, -1}, +{2, -3}, +{3, 0}, +{3, -3}, +{5, 0}, +{7, -1}, +{15, 0}, +{0, 0}, +{-15, 0}, +{-8, 1}, +{-5, 0}, +{-4, 1}, +{-3, 0}, +{-3, 3}, +{-3, 6}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-2, 11}, +{-2, 13}, +{-1, 0}, +{-1, 1}, +// numerator = -14 +{0, -14}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{2, 0}, +{2, -2}, +{2, -4}, +{3, -2}, +{4, -2}, +{7, 0}, +{14, 0}, +{0, 0}, +{-14, 0}, +{-7, 0}, +{-5, 1}, +{-4, 2}, +{-3, 1}, +{-3, 4}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-2, 10}, +{-2, 12}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +// numerator = -13 +{0, -13}, +{0, -13}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{2, -1}, +{2, -3}, +{3, -1}, +{4, -1}, +{6, -1}, +{13, 0}, +{0, 0}, +{-13, 0}, +{-7, 1}, +{-5, 2}, +{-4, 3}, +{-3, 2}, +{-3, 5}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-2, 11}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +// numerator = -12 +{0, -12}, +{0, -12}, +{0, -12}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{2, 0}, +{2, -2}, +{3, 0}, +{4, 0}, +{6, 0}, +{12, 0}, +{0, 0}, +{-12, 0}, +{-6, 0}, +{-4, 0}, +{-3, 0}, +{-3, 3}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-2, 10}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +// numerator = -11 +{0, -11}, +{0, -11}, +{0, -11}, +{0, -11}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{2, -1}, +{2, -3}, +{3, -2}, +{5, -1}, +{11, 0}, +{0, 0}, +{-11, 0}, +{-6, 1}, +{-4, 1}, +{-3, 1}, +{-3, 4}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +// numerator = -10 +{0, -10}, +{0, -10}, +{0, -10}, +{0, -10}, +{0, -10}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{2, 0}, +{2, -2}, +{3, -1}, +{5, 0}, +{10, 0}, +{0, 0}, +{-10, 0}, +{-5, 0}, +{-4, 2}, +{-3, 2}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +// numerator = -9 +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{2, -1}, +{3, 0}, +{4, -1}, +{9, 0}, +{0, 0}, +{-9, 0}, +{-5, 1}, +{-3, 0}, +{-3, 3}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +// numerator = -8 +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{2, 0}, +{2, -2}, +{4, 0}, +{8, 0}, +{0, 0}, +{-8, 0}, +{-4, 0}, +{-3, 1}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +// numerator = -7 +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{2, -1}, +{3, -1}, +{7, 0}, +{0, 0}, +{-7, 0}, +{-4, 1}, +{-3, 2}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +// numerator = -6 +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{1, 0}, +{1, -1}, +{1, -2}, +{2, 0}, +{3, 0}, +{6, 0}, +{0, 0}, +{-6, 0}, +{-3, 0}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +// numerator = -5 +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{1, 0}, +{1, -1}, +{1, -2}, +{2, -1}, +{5, 0}, +{0, 0}, +{-5, 0}, +{-3, 1}, +{-2, 1}, +{-2, 3}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +// numerator = -4 +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{1, 0}, +{1, -1}, +{2, 0}, +{4, 0}, +{0, 0}, +{-4, 0}, +{-2, 0}, +{-2, 2}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +// numerator = -3 +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{1, 0}, +{1, -1}, +{3, 0}, +{0, 0}, +{-3, 0}, +{-2, 1}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +{-1, 13}, +// numerator = -2 +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{1, 0}, +{2, 0}, +{0, 0}, +{-2, 0}, +{-1, 0}, +{-1, 1}, +{-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}, +// numerator = -1 +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{1, 0}, +{0, 0}, +{-1, 0}, +{-1, 1}, +{-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}, +{-1, 15}, +// numerator = 0 +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +// numerator = 1 +{-1, -14}, +{-1, -13}, +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{0, 0}, +{1, 0}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +// numerator = 2 +{-1, -13}, +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, 0}, +{0, 0}, +{2, 0}, +{1, 0}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +// numerator = 3 +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -1}, +{-3, 0}, +{0, 0}, +{3, 0}, +{1, 1}, +{1, 0}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +// numerator = 4 +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -2}, +{-2, 0}, +{-4, 0}, +{0, 0}, +{4, 0}, +{2, 0}, +{1, 1}, +{1, 0}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +// numerator = 5 +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -3}, +{-2, -1}, +{-3, -1}, +{-5, 0}, +{0, 0}, +{5, 0}, +{2, 1}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +// numerator = 6 +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, 0}, +{-6, 0}, +{0, 0}, +{6, 0}, +{3, 0}, +{2, 0}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +// numerator = 7 +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -2}, +{-4, -1}, +{-7, 0}, +{0, 0}, +{7, 0}, +{3, 1}, +{2, 1}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +// numerator = 8 +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -1}, +{-4, 0}, +{-8, 0}, +{0, 0}, +{8, 0}, +{4, 0}, +{2, 2}, +{2, 0}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +// numerator = 9 +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -3}, +{-3, 0}, +{-5, -1}, +{-9, 0}, +{0, 0}, +{9, 0}, +{4, 1}, +{3, 0}, +{2, 1}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +// numerator = 10 +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -2}, +{-4, -2}, +{-5, 0}, +{-10, 0}, +{0, 0}, +{10, 0}, +{5, 0}, +{3, 1}, +{2, 2}, +{2, 0}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +// numerator = 11 +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -4}, +{-3, -1}, +{-4, -1}, +{-6, -1}, +{-11, 0}, +{0, 0}, +{11, 0}, +{5, 1}, +{3, 2}, +{2, 3}, +{2, 1}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 11}, +{0, 11}, +{0, 11}, +{0, 11}, +{0, 11}, +// numerator = 12 +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -3}, +{-3, 0}, +{-4, 0}, +{-6, 0}, +{-12, 0}, +{0, 0}, +{12, 0}, +{6, 0}, +{4, 0}, +{3, 0}, +{2, 2}, +{2, 0}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 12}, +{0, 12}, +{0, 12}, +{0, 12}, +// numerator = 13 +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -11}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -5}, +{-3, -2}, +{-4, -3}, +{-5, -2}, +{-7, -1}, +{-13, 0}, +{0, 0}, +{13, 0}, +{6, 1}, +{4, 1}, +{3, 1}, +{2, 3}, +{2, 1}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 13}, +{0, 13}, +{0, 13}, +// numerator = 14 +{-1, -1}, +{-1, 0}, +{-2, -12}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -4}, +{-3, -1}, +{-4, -2}, +{-5, -1}, +{-7, 0}, +{-14, 0}, +{0, 0}, +{14, 0}, +{7, 0}, +{4, 2}, +{3, 2}, +{2, 4}, +{2, 2}, +{2, 0}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 14}, +{0, 14}, +// numerator = 15 +{-1, 0}, +{-2, -13}, +{-2, -11}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -6}, +{-3, -3}, +{-3, 0}, +{-4, -1}, +{-5, 0}, +{-8, -1}, +{-15, 0}, +{0, 0}, +{15, 0}, +{7, 1}, +{5, 0}, +{3, 3}, +{3, 0}, +{2, 3}, +{2, 1}, +{1, 7}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 15}, +// numerator = 16 +{-2, -14}, +{-2, -12}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -5}, +{-3, -2}, +{-4, -4}, +{-4, 0}, +{-6, -2}, +{-8, 0}, +{-16, 0}, +{0, 0}, +{16, 0}, +{8, 0}, +{5, 1}, +{4, 0}, +{3, 1}, +{2, 4}, +{2, 2}, +{2, 0}, +{1, 7}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, diff --git a/QW/client/anorm_dots.h b/QW/client/anorm_dots.h new file mode 100644 index 0000000..2845fa2 --- /dev/null +++ b/QW/client/anorm_dots.h @@ -0,0 +1,37 @@ +/* +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. + +*/ +{ +{1.23,1.30,1.47,1.35,1.56,1.71,1.37,1.38,1.59,1.60,1.79,1.97,1.88,1.92,1.79,1.02,0.93,1.07,0.82,0.87,0.88,0.94,0.96,1.14,1.11,0.82,0.83,0.89,0.89,0.86,0.94,0.91,1.00,1.21,0.98,1.48,1.30,1.57,0.96,1.07,1.14,1.60,1.61,1.40,1.37,1.72,1.78,1.79,1.93,1.99,1.90,1.68,1.71,1.86,1.60,1.68,1.78,1.86,1.93,1.99,1.97,1.44,1.22,1.49,0.93,0.99,0.99,1.23,1.22,1.44,1.49,0.89,0.89,0.97,0.91,0.98,1.19,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.19,0.98,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.87,0.93,0.94,1.02,1.30,1.07,1.35,1.38,1.11,1.56,1.92,1.79,1.79,1.59,1.60,1.72,1.90,1.79,0.80,0.85,0.79,0.93,0.80,0.85,0.77,0.74,0.72,0.77,0.74,0.72,0.70,0.70,0.71,0.76,0.73,0.79,0.79,0.73,0.76,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.26,1.26,1.48,1.23,1.50,1.71,1.14,1.19,1.38,1.46,1.64,1.94,1.87,1.84,1.71,1.02,0.92,1.00,0.79,0.85,0.84,0.91,0.90,0.98,0.99,0.77,0.77,0.83,0.82,0.79,0.86,0.84,0.92,0.99,0.91,1.24,1.03,1.33,0.88,0.94,0.97,1.41,1.39,1.18,1.11,1.51,1.61,1.59,1.80,1.91,1.76,1.54,1.65,1.76,1.70,1.70,1.85,1.85,1.97,1.99,1.93,1.28,1.09,1.39,0.92,0.97,0.99,1.18,1.26,1.52,1.48,0.83,0.85,0.90,0.88,0.93,1.00,0.77,0.73,0.78,0.72,0.71,0.74,0.75,0.79,0.86,0.81,0.75,0.81,0.79,0.96,0.88,0.94,0.86,0.93,0.92,0.85,1.08,1.33,1.05,1.55,1.31,1.01,1.05,1.27,1.31,1.60,1.47,1.70,1.54,1.76,1.76,1.57,0.93,0.90,0.99,0.88,0.88,0.95,0.97,1.11,1.39,1.20,0.92,0.97,1.01,1.10,1.39,1.22,1.51,1.58,1.32,1.64,1.97,1.85,1.91,1.77,1.74,1.88,1.99,1.91,0.79,0.86,0.80,0.94,0.84,0.88,0.74,0.74,0.71,0.82,0.77,0.76,0.70,0.73,0.72,0.73,0.70,0.74,0.85,0.77,0.82,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.34,1.27,1.53,1.17,1.46,1.71,0.98,1.05,1.20,1.34,1.48,1.86,1.82,1.71,1.62,1.09,0.94,0.99,0.79,0.85,0.82,0.90,0.87,0.93,0.96,0.76,0.74,0.79,0.76,0.74,0.79,0.78,0.85,0.92,0.85,1.00,0.93,1.06,0.81,0.86,0.89,1.16,1.12,0.97,0.95,1.28,1.38,1.35,1.60,1.77,1.57,1.33,1.50,1.58,1.69,1.63,1.82,1.74,1.91,1.92,1.80,1.04,0.97,1.21,0.90,0.93,0.97,1.05,1.21,1.48,1.37,0.77,0.80,0.84,0.85,0.88,0.92,0.73,0.71,0.74,0.74,0.71,0.75,0.73,0.79,0.84,0.78,0.79,0.86,0.81,1.05,0.94,0.99,0.90,0.95,0.92,0.86,1.24,1.44,1.14,1.59,1.34,1.02,1.27,1.50,1.49,1.80,1.69,1.86,1.72,1.87,1.80,1.69,1.00,0.98,1.23,0.95,0.96,1.09,1.16,1.37,1.63,1.46,0.99,1.10,1.25,1.24,1.51,1.41,1.67,1.77,1.55,1.72,1.95,1.89,1.98,1.91,1.86,1.97,1.99,1.94,0.81,0.89,0.85,0.98,0.90,0.94,0.75,0.78,0.73,0.89,0.83,0.82,0.72,0.77,0.76,0.72,0.70,0.71,0.91,0.83,0.89,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.46,1.34,1.60,1.16,1.46,1.71,0.94,0.99,1.05,1.26,1.33,1.74,1.76,1.57,1.54,1.23,0.98,1.05,0.83,0.89,0.84,0.92,0.87,0.91,0.96,0.78,0.74,0.79,0.72,0.72,0.75,0.76,0.80,0.88,0.83,0.94,0.87,0.95,0.76,0.80,0.82,0.97,0.96,0.89,0.88,1.08,1.11,1.10,1.37,1.59,1.37,1.07,1.27,1.34,1.57,1.45,1.69,1.55,1.77,1.79,1.60,0.93,0.90,0.99,0.86,0.87,0.93,0.96,1.07,1.35,1.18,0.73,0.76,0.77,0.81,0.82,0.85,0.70,0.71,0.72,0.78,0.73,0.77,0.73,0.79,0.82,0.76,0.83,0.90,0.84,1.18,0.98,1.03,0.92,0.95,0.90,0.86,1.32,1.45,1.15,1.53,1.27,0.99,1.42,1.65,1.58,1.93,1.83,1.94,1.81,1.88,1.74,1.70,1.19,1.17,1.44,1.11,1.15,1.36,1.41,1.61,1.81,1.67,1.22,1.34,1.50,1.42,1.65,1.61,1.82,1.91,1.75,1.80,1.89,1.89,1.98,1.99,1.94,1.98,1.92,1.87,0.86,0.95,0.92,1.14,0.98,1.03,0.79,0.84,0.77,0.97,0.90,0.89,0.76,0.82,0.82,0.74,0.72,0.71,0.98,0.89,0.97,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.60,1.44,1.68,1.22,1.49,1.71,0.93,0.99,0.99,1.23,1.22,1.60,1.68,1.44,1.49,1.40,1.14,1.19,0.89,0.96,0.89,0.97,0.89,0.91,0.98,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.91,0.83,0.89,0.72,0.76,0.76,0.89,0.89,0.82,0.82,0.98,0.96,0.97,1.14,1.40,1.19,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.70,0.72,0.73,0.77,0.76,0.79,0.70,0.72,0.71,0.82,0.77,0.80,0.74,0.79,0.80,0.74,0.87,0.93,0.85,1.23,1.02,1.02,0.93,0.93,0.87,0.85,1.30,1.35,1.07,1.38,1.11,0.94,1.47,1.71,1.56,1.97,1.88,1.92,1.79,1.79,1.59,1.60,1.30,1.35,1.56,1.37,1.38,1.59,1.60,1.79,1.92,1.79,1.48,1.57,1.72,1.61,1.78,1.79,1.93,1.99,1.90,1.86,1.78,1.86,1.93,1.99,1.97,1.90,1.79,1.72,0.94,1.07,1.00,1.37,1.21,1.30,0.86,0.91,0.83,1.14,0.98,0.96,0.82,0.88,0.89,0.79,0.76,0.73,1.07,0.94,1.11,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.74,1.57,1.76,1.33,1.54,1.71,0.94,1.05,0.99,1.26,1.16,1.46,1.60,1.34,1.46,1.59,1.37,1.37,0.97,1.11,0.96,1.10,0.95,0.94,1.08,0.89,0.82,0.88,0.72,0.76,0.75,0.80,0.80,0.88,0.87,0.91,0.83,0.87,0.72,0.76,0.74,0.83,0.84,0.78,0.79,0.96,0.89,0.92,0.98,1.23,1.05,0.86,0.92,0.95,1.11,0.98,1.22,1.03,1.34,1.42,1.14,0.79,0.77,0.84,0.78,0.76,0.82,0.82,0.89,0.97,0.90,0.70,0.71,0.71,0.73,0.72,0.74,0.73,0.76,0.72,0.86,0.81,0.82,0.76,0.79,0.77,0.73,0.90,0.95,0.86,1.18,1.03,0.98,0.92,0.90,0.83,0.84,1.19,1.17,0.98,1.15,0.97,0.89,1.42,1.65,1.44,1.93,1.83,1.81,1.67,1.61,1.36,1.41,1.32,1.45,1.58,1.57,1.53,1.74,1.70,1.88,1.94,1.81,1.69,1.77,1.87,1.79,1.89,1.92,1.98,1.99,1.98,1.89,1.65,1.80,1.82,1.91,1.94,1.75,1.61,1.50,1.07,1.34,1.27,1.60,1.45,1.55,0.93,0.99,0.90,1.35,1.18,1.07,0.87,0.93,0.96,0.85,0.82,0.77,1.15,0.99,1.27,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.86,1.71,1.82,1.48,1.62,1.71,0.98,1.20,1.05,1.34,1.17,1.34,1.53,1.27,1.46,1.77,1.60,1.57,1.16,1.38,1.12,1.35,1.06,1.00,1.28,0.97,0.89,0.95,0.76,0.81,0.79,0.86,0.85,0.92,0.93,0.93,0.85,0.87,0.74,0.78,0.74,0.79,0.82,0.76,0.79,0.96,0.85,0.90,0.94,1.09,0.99,0.81,0.85,0.89,0.95,0.90,0.99,0.94,1.10,1.24,0.98,0.75,0.73,0.78,0.74,0.72,0.77,0.76,0.82,0.89,0.83,0.73,0.71,0.71,0.71,0.70,0.72,0.77,0.80,0.74,0.90,0.85,0.84,0.78,0.79,0.75,0.73,0.92,0.95,0.86,1.05,0.99,0.94,0.90,0.86,0.79,0.81,1.00,0.98,0.91,0.96,0.89,0.83,1.27,1.50,1.23,1.80,1.69,1.63,1.46,1.37,1.09,1.16,1.24,1.44,1.49,1.69,1.59,1.80,1.69,1.87,1.86,1.72,1.82,1.91,1.94,1.92,1.95,1.99,1.98,1.91,1.97,1.89,1.51,1.72,1.67,1.77,1.86,1.55,1.41,1.25,1.33,1.58,1.50,1.80,1.63,1.74,1.04,1.21,0.97,1.48,1.37,1.21,0.93,0.97,1.05,0.92,0.88,0.84,1.14,1.02,1.34,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.94,1.84,1.87,1.64,1.71,1.71,1.14,1.38,1.19,1.46,1.23,1.26,1.48,1.26,1.50,1.91,1.80,1.76,1.41,1.61,1.39,1.59,1.33,1.24,1.51,1.18,0.97,1.11,0.82,0.88,0.86,0.94,0.92,0.99,1.03,0.98,0.91,0.90,0.79,0.84,0.77,0.79,0.84,0.77,0.83,0.99,0.85,0.91,0.92,1.02,1.00,0.79,0.80,0.86,0.88,0.84,0.92,0.88,0.97,1.10,0.94,0.74,0.71,0.74,0.72,0.70,0.73,0.72,0.76,0.82,0.77,0.77,0.73,0.74,0.71,0.70,0.73,0.83,0.85,0.78,0.92,0.88,0.86,0.81,0.79,0.74,0.75,0.92,0.93,0.85,0.96,0.94,0.88,0.86,0.81,0.75,0.79,0.93,0.90,0.85,0.88,0.82,0.77,1.05,1.27,0.99,1.60,1.47,1.39,1.20,1.11,0.95,0.97,1.08,1.33,1.31,1.70,1.55,1.76,1.57,1.76,1.70,1.54,1.85,1.97,1.91,1.99,1.97,1.99,1.91,1.77,1.88,1.85,1.39,1.64,1.51,1.58,1.74,1.32,1.22,1.01,1.54,1.76,1.65,1.93,1.70,1.85,1.28,1.39,1.09,1.52,1.48,1.26,0.97,0.99,1.18,1.00,0.93,0.90,1.05,1.01,1.31,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.97,1.92,1.88,1.79,1.79,1.71,1.37,1.59,1.38,1.60,1.35,1.23,1.47,1.30,1.56,1.99,1.93,1.90,1.60,1.78,1.61,1.79,1.57,1.48,1.72,1.40,1.14,1.37,0.89,0.96,0.94,1.07,1.00,1.21,1.30,1.14,0.98,0.96,0.86,0.91,0.83,0.82,0.88,0.82,0.89,1.11,0.87,0.94,0.93,1.02,1.07,0.80,0.79,0.85,0.82,0.80,0.87,0.85,0.93,1.02,0.93,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.82,0.76,0.79,0.72,0.73,0.76,0.89,0.89,0.82,0.93,0.91,0.86,0.83,0.79,0.73,0.76,0.91,0.89,0.83,0.89,0.89,0.82,0.82,0.76,0.72,0.76,0.86,0.83,0.79,0.82,0.76,0.73,0.94,1.00,0.91,1.37,1.21,1.14,0.98,0.96,0.88,0.89,0.96,1.14,1.07,1.60,1.40,1.61,1.37,1.57,1.48,1.30,1.78,1.93,1.79,1.99,1.92,1.90,1.79,1.59,1.72,1.79,1.30,1.56,1.35,1.38,1.60,1.11,1.07,0.94,1.68,1.86,1.71,1.97,1.68,1.86,1.44,1.49,1.22,1.44,1.49,1.22,0.99,0.99,1.23,1.19,0.98,0.97,0.97,0.98,1.19,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.94,1.97,1.87,1.91,1.85,1.71,1.60,1.77,1.58,1.74,1.51,1.26,1.48,1.39,1.64,1.99,1.97,1.99,1.70,1.85,1.76,1.91,1.76,1.70,1.88,1.55,1.33,1.57,0.96,1.08,1.05,1.31,1.27,1.47,1.54,1.39,1.20,1.11,0.93,0.99,0.90,0.88,0.95,0.88,0.97,1.32,0.92,1.01,0.97,1.10,1.22,0.84,0.80,0.88,0.79,0.79,0.85,0.86,0.92,1.02,0.94,0.82,0.76,0.77,0.72,0.73,0.70,0.72,0.71,0.74,0.74,0.88,0.81,0.85,0.75,0.77,0.82,0.94,0.93,0.86,0.92,0.92,0.86,0.85,0.79,0.74,0.79,0.88,0.85,0.81,0.82,0.83,0.77,0.78,0.73,0.71,0.75,0.79,0.77,0.74,0.77,0.73,0.70,0.86,0.92,0.84,1.14,0.99,0.98,0.91,0.90,0.84,0.83,0.88,0.97,0.94,1.41,1.18,1.39,1.11,1.33,1.24,1.03,1.61,1.80,1.59,1.91,1.84,1.76,1.64,1.38,1.51,1.71,1.26,1.50,1.23,1.19,1.46,0.99,1.00,0.91,1.70,1.85,1.65,1.93,1.54,1.76,1.52,1.48,1.26,1.28,1.39,1.09,0.99,0.97,1.18,1.31,1.01,1.05,0.90,0.93,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.86,1.95,1.82,1.98,1.89,1.71,1.80,1.91,1.77,1.86,1.67,1.34,1.53,1.51,1.72,1.92,1.91,1.99,1.69,1.82,1.80,1.94,1.87,1.86,1.97,1.59,1.44,1.69,1.05,1.24,1.27,1.49,1.50,1.69,1.72,1.63,1.46,1.37,1.00,1.23,0.98,0.95,1.09,0.96,1.16,1.55,0.99,1.25,1.10,1.24,1.41,0.90,0.85,0.94,0.79,0.81,0.85,0.89,0.94,1.09,0.98,0.89,0.82,0.83,0.74,0.77,0.72,0.76,0.73,0.75,0.78,0.94,0.86,0.91,0.79,0.83,0.89,0.99,0.95,0.90,0.90,0.92,0.84,0.86,0.79,0.75,0.81,0.85,0.80,0.78,0.76,0.77,0.73,0.74,0.71,0.71,0.73,0.74,0.74,0.71,0.76,0.72,0.70,0.79,0.85,0.78,0.98,0.92,0.93,0.85,0.87,0.82,0.79,0.81,0.89,0.86,1.16,0.97,1.12,0.95,1.06,1.00,0.93,1.38,1.60,1.35,1.77,1.71,1.57,1.48,1.20,1.28,1.62,1.27,1.46,1.17,1.05,1.34,0.96,0.99,0.90,1.63,1.74,1.50,1.80,1.33,1.58,1.48,1.37,1.21,1.04,1.21,0.97,0.97,0.93,1.05,1.34,1.02,1.14,0.84,0.88,0.92,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.74,1.89,1.76,1.98,1.89,1.71,1.93,1.99,1.91,1.94,1.82,1.46,1.60,1.65,1.80,1.79,1.77,1.92,1.57,1.69,1.74,1.87,1.88,1.94,1.98,1.53,1.45,1.70,1.18,1.32,1.42,1.58,1.65,1.83,1.81,1.81,1.67,1.61,1.19,1.44,1.17,1.11,1.36,1.15,1.41,1.75,1.22,1.50,1.34,1.42,1.61,0.98,0.92,1.03,0.83,0.86,0.89,0.95,0.98,1.23,1.14,0.97,0.89,0.90,0.78,0.82,0.76,0.82,0.77,0.79,0.84,0.98,0.90,0.98,0.83,0.89,0.97,1.03,0.95,0.92,0.86,0.90,0.82,0.86,0.79,0.77,0.84,0.81,0.76,0.76,0.72,0.73,0.70,0.72,0.71,0.73,0.73,0.72,0.74,0.71,0.78,0.74,0.72,0.75,0.80,0.76,0.94,0.88,0.91,0.83,0.87,0.84,0.79,0.76,0.82,0.80,0.97,0.89,0.96,0.88,0.95,0.94,0.87,1.11,1.37,1.10,1.59,1.57,1.37,1.33,1.05,1.08,1.54,1.34,1.46,1.16,0.99,1.26,0.96,1.05,0.92,1.45,1.55,1.27,1.60,1.07,1.34,1.35,1.18,1.07,0.93,0.99,0.90,0.93,0.87,0.96,1.27,0.99,1.15,0.77,0.82,0.85,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.60,1.78,1.68,1.93,1.86,1.71,1.97,1.99,1.99,1.97,1.93,1.60,1.68,1.78,1.86,1.61,1.57,1.79,1.37,1.48,1.59,1.72,1.79,1.92,1.90,1.38,1.35,1.60,1.23,1.30,1.47,1.56,1.71,1.88,1.79,1.92,1.79,1.79,1.30,1.56,1.35,1.37,1.59,1.38,1.60,1.90,1.48,1.72,1.57,1.61,1.79,1.21,1.00,1.30,0.89,0.94,0.96,1.07,1.14,1.40,1.37,1.14,0.96,0.98,0.82,0.88,0.82,0.89,0.83,0.86,0.91,1.02,0.93,1.07,0.87,0.94,1.11,1.02,0.93,0.93,0.82,0.87,0.80,0.85,0.79,0.80,0.85,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.72,0.76,0.73,0.82,0.79,0.76,0.73,0.79,0.76,0.93,0.86,0.91,0.83,0.89,0.89,0.82,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.44,1.19,1.22,0.99,0.98,1.49,1.44,1.49,1.22,0.99,1.23,0.98,1.19,0.97,1.21,1.30,1.00,1.37,0.94,1.07,1.14,0.98,0.96,0.86,0.91,0.83,0.88,0.82,0.89,1.11,0.94,1.07,0.73,0.76,0.79,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.46,1.65,1.60,1.82,1.80,1.71,1.93,1.91,1.99,1.94,1.98,1.74,1.76,1.89,1.89,1.42,1.34,1.61,1.11,1.22,1.36,1.50,1.61,1.81,1.75,1.15,1.17,1.41,1.18,1.19,1.42,1.44,1.65,1.83,1.67,1.94,1.81,1.88,1.32,1.58,1.45,1.57,1.74,1.53,1.70,1.98,1.69,1.87,1.77,1.79,1.92,1.45,1.27,1.55,0.97,1.07,1.11,1.34,1.37,1.59,1.60,1.35,1.07,1.18,0.86,0.93,0.87,0.96,0.90,0.93,0.99,1.03,0.95,1.15,0.90,0.99,1.27,0.98,0.90,0.92,0.78,0.83,0.77,0.84,0.79,0.82,0.86,0.73,0.71,0.73,0.72,0.70,0.73,0.72,0.76,0.81,0.76,0.76,0.82,0.77,0.89,0.85,0.82,0.75,0.80,0.80,0.94,0.88,0.94,0.87,0.95,0.96,0.88,0.72,0.74,0.76,0.83,0.78,0.84,0.79,0.87,0.91,0.83,0.89,0.98,0.92,1.23,1.34,1.05,1.16,0.99,0.96,1.46,1.57,1.54,1.33,1.05,1.26,1.08,1.37,1.10,0.98,1.03,0.92,1.14,0.86,0.95,0.97,0.90,0.89,0.79,0.84,0.77,0.82,0.76,0.82,0.97,0.89,0.98,0.71,0.72,0.74,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.34,1.51,1.53,1.67,1.72,1.71,1.80,1.77,1.91,1.86,1.98,1.86,1.82,1.95,1.89,1.24,1.10,1.41,0.95,0.99,1.09,1.25,1.37,1.63,1.55,0.96,0.98,1.16,1.05,1.00,1.27,1.23,1.50,1.69,1.46,1.86,1.72,1.87,1.24,1.49,1.44,1.69,1.80,1.59,1.69,1.97,1.82,1.94,1.91,1.92,1.99,1.63,1.50,1.74,1.16,1.33,1.38,1.58,1.60,1.77,1.80,1.48,1.21,1.37,0.90,0.97,0.93,1.05,0.97,1.04,1.21,0.99,0.95,1.14,0.92,1.02,1.34,0.94,0.86,0.90,0.74,0.79,0.75,0.81,0.79,0.84,0.86,0.71,0.71,0.73,0.76,0.73,0.77,0.74,0.80,0.85,0.78,0.81,0.89,0.84,0.97,0.92,0.88,0.79,0.85,0.86,0.98,0.92,1.00,0.93,1.06,1.12,0.95,0.74,0.74,0.78,0.79,0.76,0.82,0.79,0.87,0.93,0.85,0.85,0.94,0.90,1.09,1.27,0.99,1.17,1.05,0.96,1.46,1.71,1.62,1.48,1.20,1.34,1.28,1.57,1.35,0.90,0.94,0.85,0.98,0.81,0.89,0.89,0.83,0.82,0.75,0.78,0.73,0.77,0.72,0.76,0.89,0.83,0.91,0.71,0.70,0.72,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, +{1.26,1.39,1.48,1.51,1.64,1.71,1.60,1.58,1.77,1.74,1.91,1.94,1.87,1.97,1.85,1.10,0.97,1.22,0.88,0.92,0.95,1.01,1.11,1.39,1.32,0.88,0.90,0.97,0.96,0.93,1.05,0.99,1.27,1.47,1.20,1.70,1.54,1.76,1.08,1.31,1.33,1.70,1.76,1.55,1.57,1.88,1.85,1.91,1.97,1.99,1.99,1.70,1.65,1.85,1.41,1.54,1.61,1.76,1.80,1.91,1.93,1.52,1.26,1.48,0.92,0.99,0.97,1.18,1.09,1.28,1.39,0.94,0.93,1.05,0.92,1.01,1.31,0.88,0.81,0.86,0.72,0.75,0.74,0.79,0.79,0.86,0.85,0.71,0.73,0.75,0.82,0.77,0.83,0.78,0.85,0.88,0.81,0.88,0.97,0.90,1.18,1.00,0.93,0.86,0.92,0.94,1.14,0.99,1.24,1.03,1.33,1.39,1.11,0.79,0.77,0.84,0.79,0.77,0.84,0.83,0.90,0.98,0.91,0.85,0.92,0.91,1.02,1.26,1.00,1.23,1.19,0.99,1.50,1.84,1.71,1.64,1.38,1.46,1.51,1.76,1.59,0.84,0.88,0.80,0.94,0.79,0.86,0.82,0.77,0.76,0.74,0.74,0.71,0.73,0.70,0.72,0.82,0.77,0.85,0.74,0.70,0.73,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00} +} diff --git a/QW/client/anorms.h b/QW/client/anorms.h new file mode 100644 index 0000000..11a9007 --- /dev/null +++ b/QW/client/anorms.h @@ -0,0 +1,181 @@ +/* +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. + +*/ +{-0.525731, 0.000000, 0.850651}, +{-0.442863, 0.238856, 0.864188}, +{-0.295242, 0.000000, 0.955423}, +{-0.309017, 0.500000, 0.809017}, +{-0.162460, 0.262866, 0.951056}, +{0.000000, 0.000000, 1.000000}, +{0.000000, 0.850651, 0.525731}, +{-0.147621, 0.716567, 0.681718}, +{0.147621, 0.716567, 0.681718}, +{0.000000, 0.525731, 0.850651}, +{0.309017, 0.500000, 0.809017}, +{0.525731, 0.000000, 0.850651}, +{0.295242, 0.000000, 0.955423}, +{0.442863, 0.238856, 0.864188}, +{0.162460, 0.262866, 0.951056}, +{-0.681718, 0.147621, 0.716567}, +{-0.809017, 0.309017, 0.500000}, +{-0.587785, 0.425325, 0.688191}, +{-0.850651, 0.525731, 0.000000}, +{-0.864188, 0.442863, 0.238856}, +{-0.716567, 0.681718, 0.147621}, +{-0.688191, 0.587785, 0.425325}, +{-0.500000, 0.809017, 0.309017}, +{-0.238856, 0.864188, 0.442863}, +{-0.425325, 0.688191, 0.587785}, +{-0.716567, 0.681718, -0.147621}, +{-0.500000, 0.809017, -0.309017}, +{-0.525731, 0.850651, 0.000000}, +{0.000000, 0.850651, -0.525731}, +{-0.238856, 0.864188, -0.442863}, +{0.000000, 0.955423, -0.295242}, +{-0.262866, 0.951056, -0.162460}, +{0.000000, 1.000000, 0.000000}, +{0.000000, 0.955423, 0.295242}, +{-0.262866, 0.951056, 0.162460}, +{0.238856, 0.864188, 0.442863}, +{0.262866, 0.951056, 0.162460}, +{0.500000, 0.809017, 0.309017}, +{0.238856, 0.864188, -0.442863}, +{0.262866, 0.951056, -0.162460}, +{0.500000, 0.809017, -0.309017}, +{0.850651, 0.525731, 0.000000}, +{0.716567, 0.681718, 0.147621}, +{0.716567, 0.681718, -0.147621}, +{0.525731, 0.850651, 0.000000}, +{0.425325, 0.688191, 0.587785}, +{0.864188, 0.442863, 0.238856}, +{0.688191, 0.587785, 0.425325}, +{0.809017, 0.309017, 0.500000}, +{0.681718, 0.147621, 0.716567}, +{0.587785, 0.425325, 0.688191}, +{0.955423, 0.295242, 0.000000}, +{1.000000, 0.000000, 0.000000}, +{0.951056, 0.162460, 0.262866}, +{0.850651, -0.525731, 0.000000}, +{0.955423, -0.295242, 0.000000}, +{0.864188, -0.442863, 0.238856}, +{0.951056, -0.162460, 0.262866}, +{0.809017, -0.309017, 0.500000}, +{0.681718, -0.147621, 0.716567}, +{0.850651, 0.000000, 0.525731}, +{0.864188, 0.442863, -0.238856}, +{0.809017, 0.309017, -0.500000}, +{0.951056, 0.162460, -0.262866}, +{0.525731, 0.000000, -0.850651}, +{0.681718, 0.147621, -0.716567}, +{0.681718, -0.147621, -0.716567}, +{0.850651, 0.000000, -0.525731}, +{0.809017, -0.309017, -0.500000}, +{0.864188, -0.442863, -0.238856}, +{0.951056, -0.162460, -0.262866}, +{0.147621, 0.716567, -0.681718}, +{0.309017, 0.500000, -0.809017}, +{0.425325, 0.688191, -0.587785}, +{0.442863, 0.238856, -0.864188}, +{0.587785, 0.425325, -0.688191}, +{0.688191, 0.587785, -0.425325}, +{-0.147621, 0.716567, -0.681718}, +{-0.309017, 0.500000, -0.809017}, +{0.000000, 0.525731, -0.850651}, +{-0.525731, 0.000000, -0.850651}, +{-0.442863, 0.238856, -0.864188}, +{-0.295242, 0.000000, -0.955423}, +{-0.162460, 0.262866, -0.951056}, +{0.000000, 0.000000, -1.000000}, +{0.295242, 0.000000, -0.955423}, +{0.162460, 0.262866, -0.951056}, +{-0.442863, -0.238856, -0.864188}, +{-0.309017, -0.500000, -0.809017}, +{-0.162460, -0.262866, -0.951056}, +{0.000000, -0.850651, -0.525731}, +{-0.147621, -0.716567, -0.681718}, +{0.147621, -0.716567, -0.681718}, +{0.000000, -0.525731, -0.850651}, +{0.309017, -0.500000, -0.809017}, +{0.442863, -0.238856, -0.864188}, +{0.162460, -0.262866, -0.951056}, +{0.238856, -0.864188, -0.442863}, +{0.500000, -0.809017, -0.309017}, +{0.425325, -0.688191, -0.587785}, +{0.716567, -0.681718, -0.147621}, +{0.688191, -0.587785, -0.425325}, +{0.587785, -0.425325, -0.688191}, +{0.000000, -0.955423, -0.295242}, +{0.000000, -1.000000, 0.000000}, +{0.262866, -0.951056, -0.162460}, +{0.000000, -0.850651, 0.525731}, +{0.000000, -0.955423, 0.295242}, +{0.238856, -0.864188, 0.442863}, +{0.262866, -0.951056, 0.162460}, +{0.500000, -0.809017, 0.309017}, +{0.716567, -0.681718, 0.147621}, +{0.525731, -0.850651, 0.000000}, +{-0.238856, -0.864188, -0.442863}, +{-0.500000, -0.809017, -0.309017}, +{-0.262866, -0.951056, -0.162460}, +{-0.850651, -0.525731, 0.000000}, +{-0.716567, -0.681718, -0.147621}, +{-0.716567, -0.681718, 0.147621}, +{-0.525731, -0.850651, 0.000000}, +{-0.500000, -0.809017, 0.309017}, +{-0.238856, -0.864188, 0.442863}, +{-0.262866, -0.951056, 0.162460}, +{-0.864188, -0.442863, 0.238856}, +{-0.809017, -0.309017, 0.500000}, +{-0.688191, -0.587785, 0.425325}, +{-0.681718, -0.147621, 0.716567}, +{-0.442863, -0.238856, 0.864188}, +{-0.587785, -0.425325, 0.688191}, +{-0.309017, -0.500000, 0.809017}, +{-0.147621, -0.716567, 0.681718}, +{-0.425325, -0.688191, 0.587785}, +{-0.162460, -0.262866, 0.951056}, +{0.442863, -0.238856, 0.864188}, +{0.162460, -0.262866, 0.951056}, +{0.309017, -0.500000, 0.809017}, +{0.147621, -0.716567, 0.681718}, +{0.000000, -0.525731, 0.850651}, +{0.425325, -0.688191, 0.587785}, +{0.587785, -0.425325, 0.688191}, +{0.688191, -0.587785, 0.425325}, +{-0.955423, 0.295242, 0.000000}, +{-0.951056, 0.162460, 0.262866}, +{-1.000000, 0.000000, 0.000000}, +{-0.850651, 0.000000, 0.525731}, +{-0.955423, -0.295242, 0.000000}, +{-0.951056, -0.162460, 0.262866}, +{-0.864188, 0.442863, -0.238856}, +{-0.951056, 0.162460, -0.262866}, +{-0.809017, 0.309017, -0.500000}, +{-0.864188, -0.442863, -0.238856}, +{-0.951056, -0.162460, -0.262866}, +{-0.809017, -0.309017, -0.500000}, +{-0.681718, 0.147621, -0.716567}, +{-0.681718, -0.147621, -0.716567}, +{-0.850651, 0.000000, -0.525731}, +{-0.688191, 0.587785, -0.425325}, +{-0.587785, 0.425325, -0.688191}, +{-0.425325, 0.688191, -0.587785}, +{-0.425325, -0.688191, -0.587785}, +{-0.587785, -0.425325, -0.688191}, +{-0.688191, -0.587785, -0.425325}, diff --git a/QW/client/asm_draw.h b/QW/client/asm_draw.h new file mode 100644 index 0000000..5534ab6 --- /dev/null +++ b/QW/client/asm_draw.h @@ -0,0 +1,151 @@ +/* +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 +#define me_size 8 + +// 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 +#define rd_ambientlight 136 +#define rd_size 140 + +// mtriangle_t structure +// !!! if this is changed, it must be changed in model.h too !!! +#define mtri_facesfront 0 +#define mtri_vertindex 4 +#define mtri_size 16 // !!! if this changes, array indexing in !!! + // !!! d_polysa.s must be changed to match !!! +#define mtri_shift 4 + diff --git a/QW/client/asm_i386.h b/QW/client/asm_i386.h new file mode 100644 index 0000000..03dc2aa --- /dev/null +++ b/QW/client/asm_i386.h @@ -0,0 +1,97 @@ +/* +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. + +*/ + +#ifndef __ASM_I386__ +#define __ASM_I386__ + +#ifdef ELF +#define C(label) label +#else +#define C(label) _##label +#endif + +// +// !!! note that this file must match the corresponding C structures at all +// times !!! +// + +// plane_t structure +// !!! if this is changed, it must be changed in model.h too !!! +// !!! if the size of this is changed, the array lookup in SV_HullPointContents +// must be changed too !!! +#define pl_normal 0 +#define pl_dist 12 +#define pl_type 16 +#define pl_signbits 17 +#define pl_pad 18 +#define pl_size 20 + +// hull_t structure +// !!! if this is changed, it must be changed in model.h too !!! +#define hu_clipnodes 0 +#define hu_planes 4 +#define hu_firstclipnode 8 +#define hu_lastclipnode 12 +#define hu_clip_mins 16 +#define hu_clip_maxs 28 +#define hu_size 40 + +// dnode_t structure +// !!! if this is changed, it must be changed in bspfile.h too !!! +#define nd_planenum 0 +#define nd_children 4 +#define nd_mins 8 +#define nd_maxs 20 +#define nd_firstface 32 +#define nd_numfaces 36 +#define nd_size 40 + +// sfxcache_t structure +// !!! if this is changed, it much be changed in sound.h too !!! +#define sfxc_length 0 +#define sfxc_loopstart 4 +#define sfxc_speed 8 +#define sfxc_width 12 +#define sfxc_stereo 16 +#define sfxc_data 20 + +// channel_t structure +// !!! if this is changed, it much be changed in sound.h too !!! +#define ch_sfx 0 +#define ch_leftvol 4 +#define ch_rightvol 8 +#define ch_end 12 +#define ch_pos 16 +#define ch_looping 20 +#define ch_entnum 24 +#define ch_entchannel 28 +#define ch_origin 32 +#define ch_dist_mult 44 +#define ch_master_vol 48 +#define ch_size 52 + +// portable_samplepair_t structure +// !!! if this is changed, it much be changed in sound.h too !!! +#define psp_left 0 +#define psp_right 4 +#define psp_size 8 + +#endif + diff --git a/QW/client/block16.h b/QW/client/block16.h new file mode 100644 index 0000000..98a1cf7 --- /dev/null +++ b/QW/client/block16.h @@ -0,0 +1,123 @@ +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 diff --git a/QW/client/block8.h b/QW/client/block8.h new file mode 100644 index 0000000..d501379 --- /dev/null +++ b/QW/client/block8.h @@ -0,0 +1,124 @@ +LEnter16_8: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch0: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch1: + movb %cl,1(%edi) + addl $0x2,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch2: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch3: + movb %cl,1(%edi) + addl $0x2,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch4: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch5: + movb %cl,1(%edi) + addl $0x2,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch6: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch7: + movb %cl,1(%edi) + addl $0x2,%edi + +LEnter8_8: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch8: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch9: + movb %cl,1(%edi) + addl $0x2,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch10: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch11: + movb %cl,1(%edi) + addl $0x2,%edi + +LEnter4_8: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch12: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch13: + movb %cl,1(%edi) + addl $0x2,%edi + +LEnter2_8: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch14: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch15: + movb %cl,1(%edi) + addl $0x2,%edi + diff --git a/QW/client/bothdefs.h b/QW/client/bothdefs.h new file mode 100644 index 0000000..50dc7ea --- /dev/null +++ b/QW/client/bothdefs.h @@ -0,0 +1,157 @@ +/* +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. + +*/ + +// defs common to client and server + +#define GLQUAKE_VERSION 1.00 +#define VERSION 2.40 +#define LINUX_VERSION 0.98 + + +#if (defined(_M_IX86) || defined(__i386__)) && !defined(id386) +#define id386 1 +#else +#define id386 0 +#endif + +#ifdef SERVERONLY // no asm in dedicated server +#undef id386 +#endif + +#if id386 +#define UNALIGNED_OK 1 // set to 0 if unaligned accesses are not supported +#else +#define UNALIGNED_OK 0 +#endif + +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +#define CACHE_SIZE 32 // used to align key data structures + +#define UNUSED(x) (x = x) // for pesky compiler / lint warnings + +#define MINIMUM_MEMORY 0x550000 + +// up / down +#define PITCH 0 + +// left / right +#define YAW 1 + +// fall over +#define ROLL 2 + + +#define MAX_SCOREBOARD 16 // max numbers of players + +#define SOUND_CHANNELS 8 + + +#define MAX_QPATH 64 // max length of a quake game pathname +#define MAX_OSPATH 128 // max length of a filesystem pathname + +#define ON_EPSILON 0.1 // point on plane side epsilon + +#define MAX_MSGLEN 1450 // max length of a reliable message +#define MAX_DATAGRAM 1450 // max length of unreliable message + +// +// per-level limits +// +#define MAX_EDICTS 768 // FIXME: ouch! ouch! ouch! +#define MAX_LIGHTSTYLES 64 +#define MAX_MODELS 256 // these are sent over the net as bytes +#define MAX_SOUNDS 256 // so they cannot be blindly increased + +#define SAVEGAME_COMMENT_LENGTH 39 + +#define MAX_STYLESTRING 64 + +// +// stats are integers communicated to the client by the server +// +#define MAX_CL_STATS 32 +#define STAT_HEALTH 0 +//define STAT_FRAGS 1 +#define STAT_WEAPON 2 +#define STAT_AMMO 3 +#define STAT_ARMOR 4 +//define STAT_WEAPONFRAME 5 +#define STAT_SHELLS 6 +#define STAT_NAILS 7 +#define STAT_ROCKETS 8 +#define STAT_CELLS 9 +#define STAT_ACTIVEWEAPON 10 +#define STAT_TOTALSECRETS 11 +#define STAT_TOTALMONSTERS 12 +#define STAT_SECRETS 13 // bumped on client side by svc_foundsecret +#define STAT_MONSTERS 14 // bumped by svc_killedmonster +#define STAT_ITEMS 15 +//define STAT_VIEWHEIGHT 16 + + +// +// item flags +// +#define IT_SHOTGUN 1 +#define IT_SUPER_SHOTGUN 2 +#define IT_NAILGUN 4 +#define IT_SUPER_NAILGUN 8 + +#define IT_GRENADE_LAUNCHER 16 +#define IT_ROCKET_LAUNCHER 32 +#define IT_LIGHTNING 64 +#define IT_SUPER_LIGHTNING 128 + +#define IT_SHELLS 256 +#define IT_NAILS 512 +#define IT_ROCKETS 1024 +#define IT_CELLS 2048 + +#define IT_AXE 4096 + +#define IT_ARMOR1 8192 +#define IT_ARMOR2 16384 +#define IT_ARMOR3 32768 + +#define IT_SUPERHEALTH 65536 + +#define IT_KEY1 131072 +#define IT_KEY2 262144 + +#define IT_INVISIBILITY 524288 + +#define IT_INVULNERABILITY 1048576 +#define IT_SUIT 2097152 +#define IT_QUAD 4194304 + +#define IT_SIGIL1 (1<<28) + +#define IT_SIGIL2 (1<<29) +#define IT_SIGIL3 (1<<30) +#define IT_SIGIL4 (1<<31) + +// +// print flags +// +#define PRINT_LOW 0 // pickup messages +#define PRINT_MEDIUM 1 // death messages +#define PRINT_HIGH 2 // critical messages +#define PRINT_CHAT 3 // chat messages + diff --git a/QW/client/bspfile.h b/QW/client/bspfile.h new file mode 100644 index 0000000..8513b1c --- /dev/null +++ b/QW/client/bspfile.h @@ -0,0 +1,271 @@ +/* +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. + +*/ + + +// upper design bounds + +#define MAX_MAP_HULLS 4 + +#define MAX_MAP_MODELS 256 +#define MAX_MAP_BRUSHES 4096 +#define MAX_MAP_ENTITIES 1024 +#define MAX_MAP_ENTSTRING 65536 + +#define MAX_MAP_PLANES 8192 +#define MAX_MAP_NODES 32767 // because negative shorts are contents +#define MAX_MAP_CLIPNODES 32767 // +#define MAX_MAP_LEAFS 32767 // +#define MAX_MAP_VERTS 65535 +#define MAX_MAP_FACES 65535 +#define MAX_MAP_MARKSURFACES 65535 +#define MAX_MAP_TEXINFO 4096 +#define MAX_MAP_EDGES 256000 +#define MAX_MAP_SURFEDGES 512000 +#define MAX_MAP_MIPTEX 0x200000 +#define MAX_MAP_LIGHTING 0x100000 +#define MAX_MAP_VISIBILITY 0x100000 + +// key / value pair sizes + +#define MAX_KEY 32 +#define MAX_VALUE 1024 + + +//============================================================================= + + +#define BSPVERSION 29 + +typedef struct +{ + int fileofs, filelen; +} lump_t; + +#define LUMP_ENTITIES 0 +#define LUMP_PLANES 1 +#define LUMP_TEXTURES 2 +#define LUMP_VERTEXES 3 +#define LUMP_VISIBILITY 4 +#define LUMP_NODES 5 +#define LUMP_TEXINFO 6 +#define LUMP_FACES 7 +#define LUMP_LIGHTING 8 +#define LUMP_CLIPNODES 9 +#define LUMP_LEAFS 10 +#define LUMP_MARKSURFACES 11 +#define LUMP_EDGES 12 +#define LUMP_SURFEDGES 13 +#define LUMP_MODELS 14 + +#define HEADER_LUMPS 15 + +typedef struct +{ + float mins[3], maxs[3]; + float origin[3]; + int headnode[MAX_MAP_HULLS]; + int visleafs; // not including the solid leaf 0 + int firstface, numfaces; +} dmodel_t; + +typedef struct +{ + int version; + lump_t lumps[HEADER_LUMPS]; +} dheader_t; + +typedef struct +{ + int nummiptex; + int dataofs[4]; // [nummiptex] +} dmiptexlump_t; + +#define MIPLEVELS 4 +typedef struct miptex_s +{ + char name[16]; + unsigned width, height; + unsigned offsets[MIPLEVELS]; // four mip maps stored +} miptex_t; + + +typedef struct +{ + float point[3]; +} dvertex_t; + + +// 0-2 are axial planes +#define PLANE_X 0 +#define PLANE_Y 1 +#define PLANE_Z 2 + +// 3-5 are non-axial planes snapped to the nearest +#define PLANE_ANYX 3 +#define PLANE_ANYY 4 +#define PLANE_ANYZ 5 + +typedef struct +{ + float normal[3]; + float dist; + int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate +} dplane_t; + + + +#define CONTENTS_EMPTY -1 +#define CONTENTS_SOLID -2 +#define CONTENTS_WATER -3 +#define CONTENTS_SLIME -4 +#define CONTENTS_LAVA -5 +#define CONTENTS_SKY -6 + +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct +{ + int planenum; + short children[2]; // negative numbers are -(leafs+1), not nodes + short mins[3]; // for sphere culling + short maxs[3]; + unsigned short firstface; + unsigned short numfaces; // counting both sides +} dnode_t; + +typedef struct +{ + int planenum; + short children[2]; // negative numbers are contents +} dclipnode_t; + + +typedef struct texinfo_s +{ + float vecs[2][4]; // [s/t][xyz offset] + int miptex; + int flags; +} texinfo_t; +#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision + +// note that edge 0 is never used, because negative edge nums are used for +// counterclockwise use of the edge in a face +typedef struct +{ + unsigned short v[2]; // vertex numbers +} dedge_t; + +#define MAXLIGHTMAPS 4 +typedef struct +{ + short planenum; + short side; + + int firstedge; // we must support > 64k edges + short numedges; + short texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + int lightofs; // start of [numstyles*surfsize] samples +} dface_t; + + + +#define AMBIENT_WATER 0 +#define AMBIENT_SKY 1 +#define AMBIENT_SLIME 2 +#define AMBIENT_LAVA 3 + +#define NUM_AMBIENTS 4 // automatic ambient sounds + +// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas +// all other leafs need visibility info +typedef struct +{ + int contents; + int visofs; // -1 = no visibility info + + short mins[3]; // for frustum culling + short maxs[3]; + + unsigned short firstmarksurface; + unsigned short nummarksurfaces; + + byte ambient_level[NUM_AMBIENTS]; +} dleaf_t; + +//============================================================================ + +#ifndef QUAKE_GAME + +// the utilities get to be lazy and just use large static arrays + +extern int nummodels; +extern dmodel_t dmodels[MAX_MAP_MODELS]; + +extern int visdatasize; +extern byte dvisdata[MAX_MAP_VISIBILITY]; + +extern int lightdatasize; +extern byte dlightdata[MAX_MAP_LIGHTING]; + +extern int texdatasize; +extern byte dtexdata[MAX_MAP_MIPTEX]; // (dmiptexlump_t) + +extern int entdatasize; +extern char dentdata[MAX_MAP_ENTSTRING]; + +extern int numleafs; +extern dleaf_t dleafs[MAX_MAP_LEAFS]; + +extern int numplanes; +extern dplane_t dplanes[MAX_MAP_PLANES]; + +extern int numvertexes; +extern dvertex_t dvertexes[MAX_MAP_VERTS]; + +extern int numnodes; +extern dnode_t dnodes[MAX_MAP_NODES]; + +extern int numtexinfo; +extern texinfo_t texinfo[MAX_MAP_TEXINFO]; + +extern int numfaces; +extern dface_t dfaces[MAX_MAP_FACES]; + +extern int numclipnodes; +extern dclipnode_t dclipnodes[MAX_MAP_CLIPNODES]; + +extern int numedges; +extern dedge_t dedges[MAX_MAP_EDGES]; + +extern int nummarksurfaces; +extern unsigned short dmarksurfaces[MAX_MAP_MARKSURFACES]; + +extern int numsurfedges; +extern int dsurfedges[MAX_MAP_SURFEDGES]; + + + +void LoadBSPFile (char *filename); +void WriteBSPFile (char *filename); +void PrintBSPFileSizes (void); + +#endif diff --git a/QW/client/buildnum.c b/QW/client/buildnum.c new file mode 100644 index 0000000..eac7d49 --- /dev/null +++ b/QW/client/buildnum.c @@ -0,0 +1,76 @@ +/* +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 included (GNU.txt) 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. + +*/ +#include <stdlib.h> +#include <string.h> + +#include <quakedef.h> + +// char *date = "Oct 24 1996"; +// char *time = "13:22:52"; +char *date = __DATE__ ; +char *time = __TIME__ ; + +char *mon[12] = +{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +char mond[12] = +{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +// returns days since Oct 24 1996 +int build_number( void ) +{ + int m = 0; + int d = 0; + int y = 0; + int hr, min; + static int b = 0; + + if (b != 0) + return b; + + for (m = 0; m < 11; m++) + { + if (_strnicmp( &date[0], mon[m], 3 ) == 0) + break; + d += mond[m]; + } + + d += atoi( &date[4] ) - 1; + + y = atoi( &date[7] ) - 1900; + + b = d + (int)((y - 1) * 365.25); + + if (((y % 4) == 0) && m > 1) + { + b += 1; + } + + b -= 34995; // Oct 24 1996 + + hr = (time[0] - '0') * 10 + (time[1] - '0'); + min = (time[3] - '0') * 10 + (time[4] - '0'); +// sec = (time[6] - '0') * 10 + (time[7] - '0'); + + b *= 60*24; + b += hr * 60 + min; + + return b; +} + diff --git a/QW/client/cd_audio.c b/QW/client/cd_audio.c new file mode 100644 index 0000000..4e977b3 --- /dev/null +++ b/QW/client/cd_audio.c @@ -0,0 +1,847 @@ +#include <dpmi.h> +#include "quakedef.h" +#include "dosisms.h" + +extern cvar_t bgmvolume; + +#define ADDRESS_MODE_HSG 0 +#define ADDRESS_MODE_RED_BOOK 1 + +#define STATUS_ERROR_BIT 0x8000 +#define STATUS_BUSY_BIT 0x0200 +#define STATUS_DONE_BIT 0x0100 +#define STATUS_ERROR_MASK 0x00ff + +#define ERROR_WRITE_PROTECT 0 +#define ERROR_UNKNOWN_UNIT 1 +#define ERROR_DRIVE_NOT_READY 2 +#define ERROR_UNKNOWN_COMMAND 3 +#define ERROR_CRC_ERROR 4 +#define ERROR_BAD_REQUEST_LEN 5 +#define ERROR_SEEK_ERROR 6 +#define ERROR_UNKNOWN_MEDIA 7 +#define ERROR_SECTOR_NOT_FOUND 8 +#define ERROR_OUT_OF_PAPER 9 +#define ERROR_WRITE_FAULT 10 +#define ERROR_READ_FAULT 11 +#define ERROR_GENERAL_FAILURE 12 +#define ERROR_RESERVED_13 13 +#define ERROR_RESERVED_14 14 +#define ERROR_BAD_DISK_CHANGE 15 + +#define COMMAND_READ 3 +#define COMMAND_WRITE 12 +#define COMMAND_PLAY_AUDIO 132 +#define COMMAND_STOP_AUDIO 133 +#define COMMAND_RESUME_AUDIO 136 + +#define READ_REQUEST_AUDIO_CHANNEL_INFO 4 +#define READ_REQUEST_DEVICE_STATUS 6 +#define READ_REQUEST_MEDIA_CHANGE 9 +#define READ_REQUEST_AUDIO_DISK_INFO 10 +#define READ_REQUEST_AUDIO_TRACK_INFO 11 +#define READ_REQUEST_AUDIO_STATUS 15 + +#define WRITE_REQUEST_EJECT 0 +#define WRITE_REQUEST_RESET 2 +#define WRITE_REQUEST_AUDIO_CHANNEL_INFO 3 + +#define STATUS_DOOR_OPEN 0x00000001 +#define STATUS_DOOR_UNLOCKED 0x00000002 +#define STATUS_RAW_SUPPORT 0x00000004 +#define STATUS_READ_WRITE 0x00000008 +#define STATUS_AUDIO_SUPPORT 0x00000010 +#define STATUS_INTERLEAVE_SUPPORT 0x00000020 +#define STATUS_BIT_6_RESERVED 0x00000040 +#define STATUS_PREFETCH_SUPPORT 0x00000080 +#define STATUS_AUDIO_MANIPLUATION_SUPPORT 0x00000100 +#define STATUS_RED_BOOK_ADDRESS_SUPPORT 0x00000200 + +#define MEDIA_NOT_CHANGED 1 +#define MEDIA_STATUS_UNKNOWN 0 +#define MEDIA_CHANGED -1 + +#define AUDIO_CONTROL_MASK 0xd0 +#define AUDIO_CONTROL_DATA_TRACK 0x40 +#define AUDIO_CONTROL_AUDIO_2_TRACK 0x00 +#define AUDIO_CONTROL_AUDIO_2P_TRACK 0x10 +#define AUDIO_CONTROL_AUDIO_4_TRACK 0x80 +#define AUDIO_CONTROL_AUDIO_4P_TRACK 0x90 + +#define AUDIO_STATUS_PAUSED 0x0001 + +#pragma pack(1) + +struct playAudioRequest +{ + char addressingMode; + int startLocation; + int sectors; +}; + +struct readRequest +{ + char mediaDescriptor; + short bufferOffset; + short bufferSegment; + short length; + short startSector; + int volumeID; +}; + +struct writeRequest +{ + char mediaDescriptor; + short bufferOffset; + short bufferSegment; + short length; + short startSector; + int volumeID; +}; + +struct cd_request +{ + char headerLength; + char unit; + char command; + short status; + char reserved[8]; + union + { + struct playAudioRequest playAudio; + struct readRequest read; + struct writeRequest write; + } x; +}; + + +struct audioChannelInfo_s +{ + char code; + char channel0input; + char channel0volume; + char channel1input; + char channel1volume; + char channel2input; + char channel2volume; + char channel3input; + char channel3volume; +}; + +struct deviceStatus_s +{ + char code; + int status; +}; + +struct mediaChange_s +{ + char code; + char status; +}; + +struct audioDiskInfo_s +{ + char code; + char lowTrack; + char highTrack; + int leadOutStart; +}; + +struct audioTrackInfo_s +{ + char code; + char track; + int start; + char control; +}; + +struct audioStatus_s +{ + char code; + short status; + int PRstartLocation; + int PRendLocation; +}; + +struct reset_s +{ + char code; +}; + +union readInfo_u +{ + struct audioChannelInfo_s audioChannelInfo; + struct deviceStatus_s deviceStatus; + struct mediaChange_s mediaChange; + struct audioDiskInfo_s audioDiskInfo; + struct audioTrackInfo_s audioTrackInfo; + struct audioStatus_s audioStatus; + struct reset_s reset; +}; + +#pragma pack() + +#define MAXIMUM_TRACKS 32 + +typedef struct +{ + int start; + int length; + qboolean isData; +} track_info; + +typedef struct +{ + qboolean valid; + int leadOutAddress; + track_info track[MAXIMUM_TRACKS]; + byte lowTrack; + byte highTrack; +} cd_info; + +static struct cd_request *cdRequest; +static union readInfo_u *readInfo; +static cd_info cd; + +static qboolean playing = false; +static qboolean wasPlaying = false; +static qboolean mediaCheck = false; +static qboolean initialized = false; +static qboolean enabled = true; +static qboolean playLooping = false; +static short cdRequestSegment; +static short cdRequestOffset; +static short readInfoSegment; +static short readInfoOffset; +static byte remap[256]; +static byte cdrom; +static byte playTrack; +static byte cdvolume; + + +static int RedBookToSector(int rb) +{ + byte minute; + byte second; + byte frame; + + minute = (rb >> 16) & 0xff; + second = (rb >> 8) & 0xff; + frame = rb & 0xff; + return minute * 60 * 75 + second * 75 + frame; +} + + +static void CDAudio_Reset(void) +{ + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_WRITE; + cdRequest->status = 0; + + cdRequest->x.write.mediaDescriptor = 0; + cdRequest->x.write.bufferOffset = readInfoOffset; + cdRequest->x.write.bufferSegment = readInfoSegment; + cdRequest->x.write.length = sizeof(struct reset_s); + cdRequest->x.write.startSector = 0; + cdRequest->x.write.volumeID = 0; + + readInfo->reset.code = WRITE_REQUEST_RESET; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); +} + + +static void CDAudio_Eject(void) +{ + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_WRITE; + cdRequest->status = 0; + + cdRequest->x.write.mediaDescriptor = 0; + cdRequest->x.write.bufferOffset = readInfoOffset; + cdRequest->x.write.bufferSegment = readInfoSegment; + cdRequest->x.write.length = sizeof(struct reset_s); + cdRequest->x.write.startSector = 0; + cdRequest->x.write.volumeID = 0; + + readInfo->reset.code = WRITE_REQUEST_EJECT; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); +} + + +static int CDAudio_GetAudioTrackInfo(byte track, int *start) +{ + byte control; + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_READ; + cdRequest->status = 0; + + cdRequest->x.read.mediaDescriptor = 0; + cdRequest->x.read.bufferOffset = readInfoOffset; + cdRequest->x.read.bufferSegment = readInfoSegment; + cdRequest->x.read.length = sizeof(struct audioTrackInfo_s); + cdRequest->x.read.startSector = 0; + cdRequest->x.read.volumeID = 0; + + readInfo->audioTrackInfo.code = READ_REQUEST_AUDIO_TRACK_INFO; + readInfo->audioTrackInfo.track = track; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + if (cdRequest->status & STATUS_ERROR_BIT) + { + Con_DPrintf("CDAudio_GetAudioTrackInfo %04x\n", cdRequest->status & 0xffff); + return -1; + } + + *start = readInfo->audioTrackInfo.start; + control = readInfo->audioTrackInfo.control & AUDIO_CONTROL_MASK; + return (control & AUDIO_CONTROL_DATA_TRACK); +} + + +static int CDAudio_GetAudioDiskInfo(void) +{ + int n; + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_READ; + cdRequest->status = 0; + + cdRequest->x.read.mediaDescriptor = 0; + cdRequest->x.read.bufferOffset = readInfoOffset; + cdRequest->x.read.bufferSegment = readInfoSegment; + cdRequest->x.read.length = sizeof(struct audioDiskInfo_s); + cdRequest->x.read.startSector = 0; + cdRequest->x.read.volumeID = 0; + + readInfo->audioDiskInfo.code = READ_REQUEST_AUDIO_DISK_INFO; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + if (cdRequest->status & STATUS_ERROR_BIT) + { + Con_DPrintf("CDAudio_GetAudioDiskInfo %04x\n", cdRequest->status & 0xffff); + return -1; + } + + cd.valid = true; + cd.lowTrack = readInfo->audioDiskInfo.lowTrack; + cd.highTrack = readInfo->audioDiskInfo.highTrack; + cd.leadOutAddress = readInfo->audioDiskInfo.leadOutStart; + + for (n = cd.lowTrack; n <= cd.highTrack; n++) + { + cd.track[n].isData = CDAudio_GetAudioTrackInfo (n, &cd.track[n].start); + if (n > cd.lowTrack) + { + cd.track[n-1].length = RedBookToSector(cd.track[n].start) - RedBookToSector(cd.track[n-1].start); + if (n == cd.highTrack) + cd.track[n].length = RedBookToSector(cd.leadOutAddress) - RedBookToSector(cd.track[n].start); + } + } + + return 0; +} + + +static int CDAudio_GetAudioStatus(void) +{ + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_READ; + cdRequest->status = 0; + + cdRequest->x.read.mediaDescriptor = 0; + cdRequest->x.read.bufferOffset = readInfoOffset; + cdRequest->x.read.bufferSegment = readInfoSegment; + cdRequest->x.read.length = sizeof(struct audioStatus_s); + cdRequest->x.read.startSector = 0; + cdRequest->x.read.volumeID = 0; + + readInfo->audioDiskInfo.code = READ_REQUEST_AUDIO_STATUS; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + if (cdRequest->status & STATUS_ERROR_BIT) + return -1; + return 0; +} + + +static int CDAudio_MediaChange(void) +{ + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_READ; + cdRequest->status = 0; + + cdRequest->x.read.mediaDescriptor = 0; + cdRequest->x.read.bufferOffset = readInfoOffset; + cdRequest->x.read.bufferSegment = readInfoSegment; + cdRequest->x.read.length = sizeof(struct mediaChange_s); + cdRequest->x.read.startSector = 0; + cdRequest->x.read.volumeID = 0; + + readInfo->mediaChange.code = READ_REQUEST_MEDIA_CHANGE; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + return readInfo->mediaChange.status; +} + + +byte CDAudio_GetVolume (void) +{ + return cdvolume; +} + + +// we set the volume to 0 first and then to the desired volume +// some cd-rom drivers seem to need it done this way +void CDAudio_SetVolume (byte volume) +{ + if (!initialized || !enabled) + return; + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_WRITE; + cdRequest->status = 0; + + cdRequest->x.read.mediaDescriptor = 0; + cdRequest->x.read.bufferOffset = readInfoOffset; + cdRequest->x.read.bufferSegment = readInfoSegment; + cdRequest->x.read.length = sizeof(struct audioChannelInfo_s); + cdRequest->x.read.startSector = 0; + cdRequest->x.read.volumeID = 0; + + readInfo->audioChannelInfo.code = WRITE_REQUEST_AUDIO_CHANNEL_INFO; + readInfo->audioChannelInfo.channel0input = 0; + readInfo->audioChannelInfo.channel0volume = 0; + readInfo->audioChannelInfo.channel1input = 1; + readInfo->audioChannelInfo.channel1volume = 0; + readInfo->audioChannelInfo.channel2input = 2; + readInfo->audioChannelInfo.channel2volume = 0; + readInfo->audioChannelInfo.channel3input = 3; + readInfo->audioChannelInfo.channel3volume = 0; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + readInfo->audioChannelInfo.channel0volume = volume; + readInfo->audioChannelInfo.channel1volume = volume; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + cdvolume = volume; +} + + +void CDAudio_Play(byte track, qboolean looping) +{ + if (!initialized || !enabled) + return; + + if (!cd.valid) + return; + + track = remap[track]; + + if (playing) + { + if (playTrack == track) + return; + CDAudio_Stop(); + } + + playLooping = looping; + + if (track < cd.lowTrack || track > cd.highTrack) + { + Con_DPrintf("CDAudio_Play: Bad track number %u.\n", track); + return; + } + + playTrack = track; + + if (cd.track[track].isData) + { + Con_DPrintf("CDAudio_Play: Can not play data.\n"); + return; + } + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_PLAY_AUDIO; + cdRequest->status = 0; + + cdRequest->x.playAudio.addressingMode = ADDRESS_MODE_RED_BOOK; + cdRequest->x.playAudio.startLocation = cd.track[track].start; + cdRequest->x.playAudio.sectors = cd.track[track].length; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + if (cdRequest->status & STATUS_ERROR_BIT) + { + Con_DPrintf("CDAudio_Play: track %u failed\n", track); + cd.valid = false; + playing = false; + return; + } + + playing = true; +} + + +void CDAudio_Stop(void) +{ + if (!initialized || !enabled) + return; + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_STOP_AUDIO; + cdRequest->status = 0; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + wasPlaying = playing; + playing = false; +} + + +void CDAudio_Resume(void) +{ + if (!initialized || !enabled) + return; + + if (!cd.valid) + return; + + if (!wasPlaying) + return; + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_RESUME_AUDIO; + cdRequest->status = 0; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + playing = true; +} + + +static void CD_f (void) +{ + char *command; + int ret; + int n; + int startAddress; + + if (Cmd_Argc() < 2) + return; + + command = Cmd_Argv (1); + + if (Q_strcasecmp(command, "on") == 0) + { + enabled = true; + return; + } + + if (Q_strcasecmp(command, "off") == 0) + { + if (playing) + CDAudio_Stop(); + enabled = false; + return; + } + + if (Q_strcasecmp(command, "reset") == 0) + { + enabled = true; + if (playing) + CDAudio_Stop(); + for (n = 0; n < 256; n++) + remap[n] = n; + CDAudio_Reset(); + CDAudio_GetAudioDiskInfo(); + return; + } + + if (Q_strcasecmp(command, "remap") == 0) + { + ret = Cmd_Argc() - 2; + if (ret <= 0) + { + for (n = 1; n < 256; n++) + if (remap[n] != n) + Con_Printf(" %u -> %u\n", n, remap[n]); + return; + } + for (n = 1; n <= ret; n++) + remap[n] = Q_atoi(Cmd_Argv (n+1)); + return; + } + + if (!cd.valid) + { + Con_Printf("No CD in player.\n"); + return; + } + + if (Q_strcasecmp(command, "play") == 0) + { + CDAudio_Play(Q_atoi(Cmd_Argv (2)), false); + return; + } + + if (Q_strcasecmp(command, "loop") == 0) + { + CDAudio_Play(Q_atoi(Cmd_Argv (2)), true); + return; + } + + if (Q_strcasecmp(command, "stop") == 0) + { + CDAudio_Stop(); + return; + } + + if (Q_strcasecmp(command, "resume") == 0) + { + CDAudio_Resume(); + return; + } + + if (Q_strcasecmp(command, "eject") == 0) + { + if (playing) + CDAudio_Stop(); + CDAudio_Eject(); + cd.valid = false; + return; + } + + if (Q_strcasecmp(command, "info") == 0) + { + Con_Printf("%u tracks\n", cd.highTrack - cd.lowTrack + 1); + for (n = cd.lowTrack; n <= cd.highTrack; n++) + { + ret = CDAudio_GetAudioTrackInfo (n, &startAddress); + Con_Printf("Track %2u: %s at %2u:%02u\n", n, ret ? "data " : "music", (startAddress >> 16) & 0xff, (startAddress >> 8) & 0xff); + } + if (playing) + Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack); + Con_Printf("Volume is %u\n", cdvolume); + CDAudio_MediaChange(); + Con_Printf("Status %04x\n", cdRequest->status & 0xffff); + return; + } +} + + +void CDAudio_Update(void) +{ + int ret; + int newVolume; + static double lastUpdate; + + if (!initialized || !enabled) + return; + + if ((realtime - lastUpdate) < 0.25) + return; + lastUpdate = realtime; + + if (mediaCheck) + { + static double lastCheck; + + if ((realtime - lastCheck) < 5.0) + return; + lastCheck = realtime; + + ret = CDAudio_MediaChange(); + if (ret == MEDIA_CHANGED) + { + Con_DPrintf("CDAudio: media changed\n"); + playing = false; + wasPlaying = false; + cd.valid = false; + CDAudio_GetAudioDiskInfo(); + return; + } + } + + newVolume = (int)(bgmvolume.value * 255.0); + if (newVolume < 0) + { + Cvar_SetValue ("bgmvolume", 0.0); + newVolume = 0; + } + else if (newVolume > 255) + { + Cvar_SetValue ("bgmvolume", 1.0); + newVolume = 255; + } + if (cdvolume != newVolume) + CDAudio_SetVolume (newVolume); + + if (playing) + { + CDAudio_GetAudioStatus(); + if ((cdRequest->status & STATUS_BUSY_BIT) == 0) + { + playing = false; + if (playLooping) + CDAudio_Play(playTrack, true); + } + } +} + + +qboolean CDAudio_Playing(void) +{ + return playing; +} + + +int CDAudio_Init(void) +{ + char *memory; + int n; + + if (cls.state == ca_dedicated) + return -1; + + if (COM_CheckParm("-nocdaudio")) + return -1; + + if (COM_CheckParm("-cdmediacheck")) + mediaCheck = true; + + regs.x.ax = 0x1500; + regs.x.bx = 0; + dos_int86 (0x2f); + if (regs.x.bx == 0) + { + Con_NotifyBox ( + "MSCDEX not loaded, music is\n" + "disabled. Use \"-nocdaudio\" if you\n" + "wish to avoid this message in the\n" + "future. See README.TXT for help.\n" + ); + return -1; + } + if (regs.x.bx > 1) + Con_DPrintf("CDAudio_Init: First CD-ROM drive will be used\n"); + cdrom = regs.x.cx; + + regs.x.ax = 0x150c; + regs.x.bx = 0; + dos_int86 (0x2f); + if (regs.x.bx == 0) + { + Con_NotifyBox ( + "MSCDEX version 2.00 or later\n" + "required for music. See README.TXT\n" + "for help.\n" + ); + Con_DPrintf("CDAudio_Init: MSCDEX version 2.00 or later required.\n"); + return -1; + } + + memory = dos_getmemory(sizeof(struct cd_request +) + sizeof(union readInfo_u)); + if (memory == NULL) + { + Con_DPrintf("CDAudio_Init: Unable to allocate low memory.\n"); + return -1; + } + + cdRequest = (struct cd_request *)memory; + cdRequestSegment = ptr2real(cdRequest) >> 4; + cdRequestOffset = ptr2real(cdRequest) & 0xf; + + readInfo = (union readInfo_u *)(memory + sizeof(struct cd_request)); + readInfoSegment = ptr2real(readInfo) >> 4; + readInfoOffset = ptr2real(readInfo) & 0xf; + + for (n = 0; n < 256; n++) + remap[n] = n; + initialized = true; + + CDAudio_SetVolume (255); + if (CDAudio_GetAudioDiskInfo()) + { + Con_Printf("CDAudio_Init: No CD in player.\n"); + enabled = false; + } + + Cmd_AddCommand ("cd", CD_f); + + Con_Printf("CD Audio Initialized\n"); + + return 0; +} + + +void CDAudio_Shutdown(void) +{ + if (!initialized) + return; + CDAudio_Stop(); +} diff --git a/QW/client/cd_linux.c b/QW/client/cd_linux.c new file mode 100644 index 0000000..2bf8409 --- /dev/null +++ b/QW/client/cd_linux.c @@ -0,0 +1,418 @@ +/* +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 included (GNU.txt) 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. + +*/ +// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All +// rights reserved. + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sys/file.h> +#include <sys/types.h> +#include <fcntl.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#include <linux/cdrom.h> + +#include "quakedef.h" + +static qboolean cdValid = false; +static qboolean playing = false; +static qboolean wasPlaying = false; +static qboolean initialized = false; +static qboolean enabled = true; +static qboolean playLooping = false; +static float cdvolume; +static byte remap[100]; +static byte playTrack; +static byte maxTrack; + +static int cdfile = -1; +static char cd_dev[64] = "/dev/cdrom"; + +static void CDAudio_Eject(void) +{ + if (cdfile == -1 || !enabled) + return; // no cd init'd + + if ( ioctl(cdfile, CDROMEJECT) == -1 ) + Con_DPrintf("ioctl cdromeject failed\n"); +} + + +static void CDAudio_CloseDoor(void) +{ + if (cdfile == -1 || !enabled) + return; // no cd init'd + + if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 ) + Con_DPrintf("ioctl cdromclosetray failed\n"); +} + +static int CDAudio_GetAudioDiskInfo(void) +{ + struct cdrom_tochdr tochdr; + + cdValid = false; + + if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 ) + { + Con_DPrintf("ioctl cdromreadtochdr failed\n"); + return -1; + } + + if (tochdr.cdth_trk0 < 1) + { + Con_DPrintf("CDAudio: no music tracks\n"); + return -1; + } + + cdValid = true; + maxTrack = tochdr.cdth_trk1; + + return 0; +} + + +void CDAudio_Play(byte track, qboolean looping) +{ + struct cdrom_tocentry entry; + struct cdrom_ti ti; + + if (cdfile == -1 || !enabled) + return; + + if (!cdValid) + { + CDAudio_GetAudioDiskInfo(); + if (!cdValid) + return; + } + + track = remap[track]; + + if (track < 1 || track > maxTrack) + { + Con_DPrintf("CDAudio: Bad track number %u.\n", track); + return; + } + + // don't try to play a non-audio track + entry.cdte_track = track; + entry.cdte_format = CDROM_MSF; + if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 ) + { + Con_DPrintf("ioctl cdromreadtocentry failed\n"); + return; + } + if (entry.cdte_ctrl == CDROM_DATA_TRACK) + { + Con_Printf("CDAudio: track %i is not audio\n", track); + return; + } + + if (playing) + { + if (playTrack == track) + return; + CDAudio_Stop(); + } + + ti.cdti_trk0 = track; + ti.cdti_trk1 = track; + ti.cdti_ind0 = 1; + ti.cdti_ind1 = 99; + + if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 ) + { + Con_DPrintf("ioctl cdromplaytrkind failed\n"); + return; + } + + if ( ioctl(cdfile, CDROMRESUME) == -1 ) + Con_DPrintf("ioctl cdromresume failed\n"); + + playLooping = looping; + playTrack = track; + playing = true; + + if (cdvolume == 0.0) + CDAudio_Pause (); +} + + +void CDAudio_Stop(void) +{ + if (cdfile == -1 || !enabled) + return; + + if (!playing) + return; + + if ( ioctl(cdfile, CDROMSTOP) == -1 ) + Con_DPrintf("ioctl cdromstop failed (%d)\n", errno); + + wasPlaying = false; + playing = false; +} + +void CDAudio_Pause(void) +{ + if (cdfile == -1 || !enabled) + return; + + if (!playing) + return; + + if ( ioctl(cdfile, CDROMPAUSE) == -1 ) + Con_DPrintf("ioctl cdrompause failed\n"); + + wasPlaying = playing; + playing = false; +} + + +void CDAudio_Resume(void) +{ + if (cdfile == -1 || !enabled) + return; + + if (!cdValid) + return; + + if (!wasPlaying) + return; + + if ( ioctl(cdfile, CDROMRESUME) == -1 ) + Con_DPrintf("ioctl cdromresume failed\n"); + playing = true; +} + +static void CD_f (void) +{ + char *command; + int ret; + int n; + + if (Cmd_Argc() < 2) + return; + + command = Cmd_Argv (1); + + if (Q_strcasecmp(command, "on") == 0) + { + enabled = true; + return; + } + + if (Q_strcasecmp(command, "off") == 0) + { + if (playing) + CDAudio_Stop(); + enabled = false; + return; + } + + if (Q_strcasecmp(command, "reset") == 0) + { + enabled = true; + if (playing) + CDAudio_Stop(); + for (n = 0; n < 100; n++) + remap[n] = n; + CDAudio_GetAudioDiskInfo(); + return; + } + + if (Q_strcasecmp(command, "remap") == 0) + { + ret = Cmd_Argc() - 2; + if (ret <= 0) + { + for (n = 1; n < 100; n++) + if (remap[n] != n) + Con_Printf(" %u -> %u\n", n, remap[n]); + return; + } + for (n = 1; n <= ret; n++) + remap[n] = Q_atoi(Cmd_Argv (n+1)); + return; + } + + if (Q_strcasecmp(command, "close") == 0) + { + CDAudio_CloseDoor(); + return; + } + + if (!cdValid) + { + CDAudio_GetAudioDiskInfo(); + if (!cdValid) + { + Con_Printf("No CD in player.\n"); + return; + } + } + + if (Q_strcasecmp(command, "play") == 0) + { + CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), false); + return; + } + + if (Q_strcasecmp(command, "loop") == 0) + { + CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), true); + return; + } + + if (Q_strcasecmp(command, "stop") == 0) + { + CDAudio_Stop(); + return; + } + + if (Q_strcasecmp(command, "pause") == 0) + { + CDAudio_Pause(); + return; + } + + if (Q_strcasecmp(command, "resume") == 0) + { + CDAudio_Resume(); + return; + } + + if (Q_strcasecmp(command, "eject") == 0) + { + if (playing) + CDAudio_Stop(); + CDAudio_Eject(); + cdValid = false; + return; + } + + if (Q_strcasecmp(command, "info") == 0) + { + Con_Printf("%u tracks\n", maxTrack); + if (playing) + Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack); + else if (wasPlaying) + Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack); + Con_Printf("Volume is %f\n", cdvolume); + return; + } +} + +void CDAudio_Update(void) +{ + struct cdrom_subchnl subchnl; + static time_t lastchk; + + if (!enabled) + return; + + if (bgmvolume.value != cdvolume) + { + if (cdvolume) + { + Cvar_SetValue ("bgmvolume", 0.0); + cdvolume = bgmvolume.value; + CDAudio_Pause (); + } + else + { + Cvar_SetValue ("bgmvolume", 1.0); + cdvolume = bgmvolume.value; + CDAudio_Resume (); + } + } + + if (playing && lastchk < time(NULL)) { + lastchk = time(NULL) + 2; //two seconds between chks + subchnl.cdsc_format = CDROM_MSF; + if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) { + Con_DPrintf("ioctl cdromsubchnl failed\n"); + playing = false; + return; + } + if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY && + subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) { + playing = false; + if (playLooping) + CDAudio_Play(playTrack, true); + } + } +} + +int CDAudio_Init(void) +{ + int i; + +#if 0 + if (cls.state == ca_dedicated) + return -1; +#endif + + if (COM_CheckParm("-nocdaudio")) + return -1; + + if ((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1) { + strncpy(cd_dev, com_argv[i + 1], sizeof(cd_dev)); + cd_dev[sizeof(cd_dev) - 1] = 0; + } + + if ((cdfile = open(cd_dev, O_RDONLY)) == -1) { + Con_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev, errno); + cdfile = -1; + return -1; + } + + for (i = 0; i < 100; i++) + remap[i] = i; + initialized = true; + enabled = true; + + if (CDAudio_GetAudioDiskInfo()) + { + Con_Printf("CDAudio_Init: No CD in player.\n"); + cdValid = false; + } + + Cmd_AddCommand ("cd", CD_f); + + Con_Printf("CD Audio Initialized\n"); + + return 0; +} + + +void CDAudio_Shutdown(void) +{ + if (!initialized) + return; + CDAudio_Stop(); + close(cdfile); + cdfile = -1; +} diff --git a/QW/client/cd_null.c b/QW/client/cd_null.c new file mode 100644 index 0000000..ce8027f --- /dev/null +++ b/QW/client/cd_null.c @@ -0,0 +1,31 @@ +#include "quakedef.h" + +void CDAudio_Play(byte track, qboolean looping) +{ +} + + +void CDAudio_Stop(void) +{ +} + + +void CDAudio_Resume(void) +{ +} + + +void CDAudio_Update(void) +{ +} + + +int CDAudio_Init(void) +{ + return 0; +} + + +void CDAudio_Shutdown(void) +{ +}
\ No newline at end of file diff --git a/QW/client/cd_win.c b/QW/client/cd_win.c new file mode 100644 index 0000000..6956f5a --- /dev/null +++ b/QW/client/cd_win.c @@ -0,0 +1,479 @@ +/* +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 included (GNU.txt) 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. + +*/ +// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All +// rights reserved. + +#include <windows.h> +#include "quakedef.h" + +extern HWND mainwindow; +extern cvar_t bgmvolume; + +static qboolean cdValid = false; +static qboolean playing = false; +static qboolean wasPlaying = false; +static qboolean initialized = false; +static qboolean enabled = false; +static qboolean playLooping = false; +static float cdvolume; +static byte remap[100]; +static byte cdrom; +static byte playTrack; +static byte maxTrack; + +UINT wDeviceID; + + +static void CDAudio_Eject(void) +{ + DWORD dwReturn; + + if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, (DWORD)NULL)) + Con_DPrintf("MCI_SET_DOOR_OPEN failed (%i)\n", dwReturn); +} + + +static void CDAudio_CloseDoor(void) +{ + DWORD dwReturn; + + if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, (DWORD)NULL)) + Con_DPrintf("MCI_SET_DOOR_CLOSED failed (%i)\n", dwReturn); +} + + +static int CDAudio_GetAudioDiskInfo(void) +{ + DWORD dwReturn; + MCI_STATUS_PARMS mciStatusParms; + + + cdValid = false; + + mciStatusParms.dwItem = MCI_STATUS_READY; + dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms); + if (dwReturn) + { + Con_DPrintf("CDAudio: drive ready test - get status failed\n"); + return -1; + } + if (!mciStatusParms.dwReturn) + { + Con_DPrintf("CDAudio: drive not ready\n"); + return -1; + } + + mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; + dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms); + if (dwReturn) + { + Con_DPrintf("CDAudio: get tracks - status failed\n"); + return -1; + } + if (mciStatusParms.dwReturn < 1) + { + Con_DPrintf("CDAudio: no music tracks\n"); + return -1; + } + + cdValid = true; + maxTrack = mciStatusParms.dwReturn; + + return 0; +} + + +void CDAudio_Play(byte track, qboolean looping) +{ + DWORD dwReturn; + MCI_PLAY_PARMS mciPlayParms; + MCI_STATUS_PARMS mciStatusParms; + + if (!enabled) + return; + + if (!cdValid) + { + CDAudio_GetAudioDiskInfo(); + if (!cdValid) + return; + } + + track = remap[track]; + + if (track < 1 || track > maxTrack) + { + Con_DPrintf("CDAudio: Bad track number %u.\n", track); + return; + } + + // don't try to play a non-audio track + mciStatusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK; + mciStatusParms.dwTrack = track; + dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms); + if (dwReturn) + { + Con_DPrintf("MCI_STATUS failed (%i)\n", dwReturn); + return; + } + if (mciStatusParms.dwReturn != MCI_CDA_TRACK_AUDIO) + { + Con_Printf("CDAudio: track %i is not audio\n", track); + return; + } + + // get the length of the track to be played + mciStatusParms.dwItem = MCI_STATUS_LENGTH; + mciStatusParms.dwTrack = track; + dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms); + if (dwReturn) + { + Con_DPrintf("MCI_STATUS failed (%i)\n", dwReturn); + return; + } + + if (playing) + { + if (playTrack == track) + return; + CDAudio_Stop(); + } + + mciPlayParms.dwFrom = MCI_MAKE_TMSF(track, 0, 0, 0); + mciPlayParms.dwTo = (mciStatusParms.dwReturn << 8) | track; + mciPlayParms.dwCallback = (DWORD)mainwindow; + dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD)(LPVOID) &mciPlayParms); + if (dwReturn) + { + Con_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn); + return; + } + + playLooping = looping; + playTrack = track; + playing = true; + + if (cdvolume == 0.0) + CDAudio_Pause (); +} + + +void CDAudio_Stop(void) +{ + DWORD dwReturn; + + if (!enabled) + return; + + if (!playing) + return; + + if (dwReturn = mciSendCommand(wDeviceID, MCI_STOP, 0, (DWORD)NULL)) + Con_DPrintf("MCI_STOP failed (%i)", dwReturn); + + wasPlaying = false; + playing = false; +} + + +void CDAudio_Pause(void) +{ + DWORD dwReturn; + MCI_GENERIC_PARMS mciGenericParms; + + if (!enabled) + return; + + if (!playing) + return; + + mciGenericParms.dwCallback = (DWORD)mainwindow; + if (dwReturn = mciSendCommand(wDeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &mciGenericParms)) + Con_DPrintf("MCI_PAUSE failed (%i)", dwReturn); + + wasPlaying = playing; + playing = false; +} + + +void CDAudio_Resume(void) +{ + DWORD dwReturn; + MCI_PLAY_PARMS mciPlayParms; + + if (!enabled) + return; + + if (!cdValid) + return; + + if (!wasPlaying) + return; + + mciPlayParms.dwFrom = MCI_MAKE_TMSF(playTrack, 0, 0, 0); + mciPlayParms.dwTo = MCI_MAKE_TMSF(playTrack + 1, 0, 0, 0); + mciPlayParms.dwCallback = (DWORD)mainwindow; + dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms); + if (dwReturn) + { + Con_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn); + return; + } + playing = true; +} + + +static void CD_f (void) +{ + char *command; + int ret; + int n; + int startAddress; + + if (Cmd_Argc() < 2) + return; + + command = Cmd_Argv (1); + + if (Q_strcasecmp(command, "on") == 0) + { + enabled = true; + return; + } + + if (Q_strcasecmp(command, "off") == 0) + { + if (playing) + CDAudio_Stop(); + enabled = false; + return; + } + + if (Q_strcasecmp(command, "reset") == 0) + { + enabled = true; + if (playing) + CDAudio_Stop(); + for (n = 0; n < 100; n++) + remap[n] = n; + CDAudio_GetAudioDiskInfo(); + return; + } + + if (Q_strcasecmp(command, "remap") == 0) + { + ret = Cmd_Argc() - 2; + if (ret <= 0) + { + for (n = 1; n < 100; n++) + if (remap[n] != n) + Con_Printf(" %u -> %u\n", n, remap[n]); + return; + } + for (n = 1; n <= ret; n++) + remap[n] = Q_atoi(Cmd_Argv (n+1)); + return; + } + + if (Q_strcasecmp(command, "close") == 0) + { + CDAudio_CloseDoor(); + return; + } + + if (!cdValid) + { + CDAudio_GetAudioDiskInfo(); + if (!cdValid) + { + Con_Printf("No CD in player.\n"); + return; + } + } + + if (Q_strcasecmp(command, "play") == 0) + { + CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), false); + return; + } + + if (Q_strcasecmp(command, "loop") == 0) + { + CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), true); + return; + } + + if (Q_strcasecmp(command, "stop") == 0) + { + CDAudio_Stop(); + return; + } + + if (Q_strcasecmp(command, "pause") == 0) + { + CDAudio_Pause(); + return; + } + + if (Q_strcasecmp(command, "resume") == 0) + { + CDAudio_Resume(); + return; + } + + if (Q_strcasecmp(command, "eject") == 0) + { + if (playing) + CDAudio_Stop(); + CDAudio_Eject(); + cdValid = false; + return; + } + + if (Q_strcasecmp(command, "info") == 0) + { + Con_Printf("%u tracks\n", maxTrack); + if (playing) + Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack); + else if (wasPlaying) + Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack); + Con_Printf("Volume is %f\n", cdvolume); + return; + } +} + + +LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (lParam != wDeviceID) + return 1; + + switch (wParam) + { + case MCI_NOTIFY_SUCCESSFUL: + if (playing) + { + playing = false; + if (playLooping) + CDAudio_Play(playTrack, true); + } + break; + + case MCI_NOTIFY_ABORTED: + case MCI_NOTIFY_SUPERSEDED: + break; + + case MCI_NOTIFY_FAILURE: + Con_DPrintf("MCI_NOTIFY_FAILURE\n"); + CDAudio_Stop (); + cdValid = false; + break; + + default: + Con_DPrintf("Unexpected MM_MCINOTIFY type (%i)\n", wParam); + return 1; + } + + return 0; +} + + +void CDAudio_Update(void) +{ + if (!enabled) + return; + + if (bgmvolume.value != cdvolume) + { + if (cdvolume) + { + Cvar_SetValue ("bgmvolume", 0.0); + cdvolume = bgmvolume.value; + CDAudio_Pause (); + } + else + { + Cvar_SetValue ("bgmvolume", 1.0); + cdvolume = bgmvolume.value; + CDAudio_Resume (); + } + } +} + + +int CDAudio_Init(void) +{ + DWORD dwReturn; + MCI_OPEN_PARMS mciOpenParms; + MCI_SET_PARMS mciSetParms; + int n; + +#if 0 // QW + if (cls.state == ca_dedicated) + return -1; +#endif + if (COM_CheckParm("-nocdaudio")) + return -1; + + mciOpenParms.lpstrDeviceType = "cdaudio"; + if (dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE, (DWORD) (LPVOID) &mciOpenParms)) + { + Con_Printf("CDAudio_Init: MCI_OPEN failed (%i)\n", dwReturn); + return -1; + } + wDeviceID = mciOpenParms.wDeviceID; + + // Set the time format to track/minute/second/frame (TMSF). + mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF; + if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &mciSetParms)) + { + Con_Printf("MCI_SET_TIME_FORMAT failed (%i)\n", dwReturn); + mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD)NULL); + return -1; + } + + for (n = 0; n < 100; n++) + remap[n] = n; + initialized = true; + enabled = true; + + if (CDAudio_GetAudioDiskInfo()) + { + Con_Printf("CDAudio_Init: No CD in player.\n"); + cdValid = false; + enabled = false; + } + + Cmd_AddCommand ("cd", CD_f); + +// Con_Printf("CD Audio Initialized\n"); + + return 0; +} + + +void CDAudio_Shutdown(void) +{ + if (!initialized) + return; + CDAudio_Stop(); + if (mciSendCommand(wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)NULL)) + Con_DPrintf("CDAudio_Shutdown: MCI_CLOSE failed\n"); +} diff --git a/QW/client/cdaudio.h b/QW/client/cdaudio.h new file mode 100644 index 0000000..80e975b --- /dev/null +++ b/QW/client/cdaudio.h @@ -0,0 +1,27 @@ +/* +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. + +*/ + +int CDAudio_Init(void); +void CDAudio_Play(byte track, qboolean looping); +void CDAudio_Stop(void); +void CDAudio_Pause(void); +void CDAudio_Resume(void); +void CDAudio_Shutdown(void); +void CDAudio_Update(void); diff --git a/QW/client/cl_cam.c b/QW/client/cl_cam.c new file mode 100644 index 0000000..41704f9 --- /dev/null +++ b/QW/client/cl_cam.c @@ -0,0 +1,574 @@ +/* +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 included (GNU.txt) 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. + +*/ +/* ZOID + * + * Player camera tracking in Spectator mode + * + * This takes over player controls for spectator automatic camera. + * Player moves as a spectator, but the camera tracks and enemy player + */ + +#include "quakedef.h" +#include "winquake.h" + +#define PM_SPECTATORMAXSPEED 500 +#define PM_STOPSPEED 100 +#define PM_MAXSPEED 320 +#define BUTTON_JUMP 2 +#define BUTTON_ATTACK 1 +#define MAX_ANGLE_TURN 10 + +static vec3_t desired_position; // where the camera wants to be +static qboolean locked = false; +static int oldbuttons; + +// track high fragger +cvar_t cl_hightrack = {"cl_hightrack", "0" }; + +cvar_t cl_chasecam = {"cl_chasecam", "0"}; + +//cvar_t cl_camera_maxpitch = {"cl_camera_maxpitch", "10" }; +//cvar_t cl_camera_maxyaw = {"cl_camera_maxyaw", "30" }; + +qboolean cam_forceview; +vec3_t cam_viewangles; +double cam_lastviewtime; + +int spec_track = 0; // player# of who we are tracking +int autocam = CAM_NONE; + +static void vectoangles(vec3_t vec, vec3_t ang) +{ + float forward; + float yaw, pitch; + + if (vec[1] == 0 && vec[0] == 0) + { + yaw = 0; + if (vec[2] > 0) + pitch = 90; + else + pitch = 270; + } + else + { + yaw = (int) (atan2(vec[1], vec[0]) * 180 / M_PI); + if (yaw < 0) + yaw += 360; + + forward = sqrt (vec[0]*vec[0] + vec[1]*vec[1]); + pitch = (int) (atan2(vec[2], forward) * 180 / M_PI); + if (pitch < 0) + pitch += 360; + } + + ang[0] = pitch; + ang[1] = yaw; + ang[2] = 0; +} + +static float vlen(vec3_t v) +{ + return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); +} + +// returns true if weapon model should be drawn in camera mode +qboolean Cam_DrawViewModel(void) +{ + if (!cl.spectator) + return true; + + if (autocam && locked && cl_chasecam.value) + return true; + return false; +} + +// returns true if we should draw this player, we don't if we are chase camming +qboolean Cam_DrawPlayer(int playernum) +{ + if (cl.spectator && autocam && locked && cl_chasecam.value && + spec_track == playernum) + return false; + return true; +} + +void Cam_Unlock(void) +{ + if (autocam) { + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + MSG_WriteString (&cls.netchan.message, "ptrack"); + autocam = CAM_NONE; + locked = false; + Sbar_Changed(); + } +} + +void Cam_Lock(int playernum) +{ + char st[40]; + + sprintf(st, "ptrack %i", playernum); + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + MSG_WriteString (&cls.netchan.message, st); + spec_track = playernum; + cam_forceview = true; + locked = false; + Sbar_Changed(); +} + +pmtrace_t Cam_DoTrace(vec3_t vec1, vec3_t vec2) +{ +#if 0 + memset(&pmove, 0, sizeof(pmove)); + + pmove.numphysent = 1; + VectorCopy (vec3_origin, pmove.physents[0].origin); + pmove.physents[0].model = cl.worldmodel; +#endif + + VectorCopy (vec1, pmove.origin); + return PM_PlayerMove(pmove.origin, vec2); +} + +// Returns distance or 9999 if invalid for some reason +static float Cam_TryFlyby(player_state_t *self, player_state_t *player, vec3_t vec, qboolean checkvis) +{ + vec3_t v; + pmtrace_t trace; + float len; + + vectoangles(vec, v); +// v[0] = -v[0]; + VectorCopy (v, pmove.angles); + VectorNormalize(vec); + VectorMA(player->origin, 800, vec, v); + // v is endpos + // fake a player move + trace = Cam_DoTrace(player->origin, v); + if (/*trace.inopen ||*/ trace.inwater) + return 9999; + VectorCopy(trace.endpos, vec); + VectorSubtract(trace.endpos, player->origin, v); + len = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + if (len < 32 || len > 800) + return 9999; + if (checkvis) { + VectorSubtract(trace.endpos, self->origin, v); + len = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + + trace = Cam_DoTrace(self->origin, vec); + if (trace.fraction != 1 || trace.inwater) + return 9999; + } + return len; +} + +// Is player visible? +static qboolean Cam_IsVisible(player_state_t *player, vec3_t vec) +{ + pmtrace_t trace; + vec3_t v; + float d; + + trace = Cam_DoTrace(player->origin, vec); + if (trace.fraction != 1 || /*trace.inopen ||*/ trace.inwater) + return false; + // check distance, don't let the player get too far away or too close + VectorSubtract(player->origin, vec, v); + d = vlen(v); + if (d < 16) + return false; + return true; +} + +static qboolean InitFlyby(player_state_t *self, player_state_t *player, int checkvis) +{ + float f, max; + vec3_t vec, vec2; + vec3_t forward, right, up; + + VectorCopy(player->viewangles, vec); + vec[0] = 0; + AngleVectors (vec, forward, right, up); +// for (i = 0; i < 3; i++) +// forward[i] *= 3; + + max = 1000; + VectorAdd(forward, up, vec2); + VectorAdd(vec2, right, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + VectorAdd(forward, up, vec2); + VectorSubtract(vec2, right, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + VectorAdd(forward, right, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + VectorSubtract(forward, right, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + VectorAdd(forward, up, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + VectorSubtract(forward, up, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + VectorAdd(up, right, vec2); + VectorSubtract(vec2, forward, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + VectorSubtract(up, right, vec2); + VectorSubtract(vec2, forward, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + // invert + VectorSubtract(vec3_origin, forward, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + VectorCopy(forward, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + // invert + VectorSubtract(vec3_origin, right, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + VectorCopy(right, vec2); + if ((f = Cam_TryFlyby(self, player, vec2, checkvis)) < max) { + max = f; + VectorCopy(vec2, vec); + } + + // ack, can't find him + if (max >= 1000) { +// Cam_Unlock(); + return false; + } + locked = true; + VectorCopy(vec, desired_position); + return true; +} + +static void Cam_CheckHighTarget(void) +{ + int i, j, max; + player_info_t *s; + + j = -1; + for (i = 0, max = -9999; i < MAX_CLIENTS; i++) { + s = &cl.players[i]; + if (s->name[0] && !s->spectator && s->frags > max) { + max = s->frags; + j = i; + } + } + if (j >= 0) { + if (!locked || cl.players[j].frags > cl.players[spec_track].frags) + Cam_Lock(j); + } else + Cam_Unlock(); +} + +// ZOID +// +// Take over the user controls and track a player. +// We find a nice position to watch the player and move there +void Cam_Track(usercmd_t *cmd) +{ + player_state_t *player, *self; + frame_t *frame; + vec3_t vec; + float len; + + if (!cl.spectator) + return; + + if (cl_hightrack.value && !locked) + Cam_CheckHighTarget(); + + if (!autocam || cls.state != ca_active) + return; + + if (locked && (!cl.players[spec_track].name[0] || cl.players[spec_track].spectator)) { + locked = false; + if (cl_hightrack.value) + Cam_CheckHighTarget(); + else + Cam_Unlock(); + return; + } + + frame = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK]; + player = frame->playerstate + spec_track; + self = frame->playerstate + cl.playernum; + + if (!locked || !Cam_IsVisible(player, desired_position)) { + if (!locked || realtime - cam_lastviewtime > 0.1) { + if (!InitFlyby(self, player, true)) + InitFlyby(self, player, false); + cam_lastviewtime = realtime; + } + } else + cam_lastviewtime = realtime; + + // couldn't track for some reason + if (!locked || !autocam) + return; + + if (cl_chasecam.value) { + cmd->forwardmove = cmd->sidemove = cmd->upmove = 0; + + VectorCopy(player->viewangles, cl.viewangles); + VectorCopy(player->origin, desired_position); + if (memcmp(&desired_position, &self->origin, sizeof(desired_position)) != 0) { + MSG_WriteByte (&cls.netchan.message, clc_tmove); + MSG_WriteCoord (&cls.netchan.message, desired_position[0]); + MSG_WriteCoord (&cls.netchan.message, desired_position[1]); + MSG_WriteCoord (&cls.netchan.message, desired_position[2]); + // move there locally immediately + VectorCopy(desired_position, self->origin); + } + self->weaponframe = player->weaponframe; + + } else { + // Ok, move to our desired position and set our angles to view + // the player + VectorSubtract(desired_position, self->origin, vec); + len = vlen(vec); + cmd->forwardmove = cmd->sidemove = cmd->upmove = 0; + if (len > 16) { // close enough? + MSG_WriteByte (&cls.netchan.message, clc_tmove); + MSG_WriteCoord (&cls.netchan.message, desired_position[0]); + MSG_WriteCoord (&cls.netchan.message, desired_position[1]); + MSG_WriteCoord (&cls.netchan.message, desired_position[2]); + } + + // move there locally immediately + VectorCopy(desired_position, self->origin); + + VectorSubtract(player->origin, desired_position, vec); + vectoangles(vec, cl.viewangles); + cl.viewangles[0] = -cl.viewangles[0]; + } +} + +#if 0 +static float adjustang(float current, float ideal, float speed) +{ + float move; + + current = anglemod(current); + ideal = anglemod(ideal); + + if (current == ideal) + return current; + + move = ideal - current; + if (ideal > current) + { + if (move >= 180) + move = move - 360; + } + else + { + if (move <= -180) + move = move + 360; + } + if (move > 0) + { + if (move > speed) + move = speed; + } + else + { + if (move < -speed) + move = -speed; + } + +//Con_Printf("c/i: %4.2f/%4.2f move: %4.2f\n", current, ideal, move); + return anglemod (current + move); +} +#endif + +#if 0 +void Cam_SetView(void) +{ + return; + player_state_t *player, *self; + frame_t *frame; + vec3_t vec, vec2; + + if (cls.state != ca_active || !cl.spectator || + !autocam || !locked) + return; + + frame = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK]; + player = frame->playerstate + spec_track; + self = frame->playerstate + cl.playernum; + + VectorSubtract(player->origin, cl.simorg, vec); + if (cam_forceview) { + cam_forceview = false; + vectoangles(vec, cam_viewangles); + cam_viewangles[0] = -cam_viewangles[0]; + } else { + vectoangles(vec, vec2); + vec2[PITCH] = -vec2[PITCH]; + + cam_viewangles[PITCH] = adjustang(cam_viewangles[PITCH], vec2[PITCH], cl_camera_maxpitch.value); + cam_viewangles[YAW] = adjustang(cam_viewangles[YAW], vec2[YAW], cl_camera_maxyaw.value); + } + VectorCopy(cam_viewangles, cl.viewangles); + VectorCopy(cl.viewangles, cl.simangles); +} +#endif + +void Cam_FinishMove(usercmd_t *cmd) +{ + int i; + player_info_t *s; + int end; + + if (cls.state != ca_active) + return; + + if (!cl.spectator) // only in spectator mode + return; + +#if 0 + if (autocam && locked) { + frame = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK]; + player = frame->playerstate + spec_track; + self = frame->playerstate + cl.playernum; + + VectorSubtract(player->origin, self->origin, vec); + if (cam_forceview) { + cam_forceview = false; + vectoangles(vec, cam_viewangles); + cam_viewangles[0] = -cam_viewangles[0]; + } else { + vectoangles(vec, vec2); + vec2[PITCH] = -vec2[PITCH]; + + cam_viewangles[PITCH] = adjustang(cam_viewangles[PITCH], vec2[PITCH], cl_camera_maxpitch.value); + cam_viewangles[YAW] = adjustang(cam_viewangles[YAW], vec2[YAW], cl_camera_maxyaw.value); + } + VectorCopy(cam_viewangles, cl.viewangles); + } +#endif + + if (cmd->buttons & BUTTON_ATTACK) { + if (!(oldbuttons & BUTTON_ATTACK)) { + + oldbuttons |= BUTTON_ATTACK; + autocam++; + + if (autocam > CAM_TRACK) { + Cam_Unlock(); + VectorCopy(cl.viewangles, cmd->angles); + return; + } + } else + return; + } else { + oldbuttons &= ~BUTTON_ATTACK; + if (!autocam) + return; + } + + if (autocam && cl_hightrack.value) { + Cam_CheckHighTarget(); + return; + } + + if (locked) { + if ((cmd->buttons & BUTTON_JUMP) && (oldbuttons & BUTTON_JUMP)) + return; // don't pogo stick + + if (!(cmd->buttons & BUTTON_JUMP)) { + oldbuttons &= ~BUTTON_JUMP; + return; + } + oldbuttons |= BUTTON_JUMP; // don't jump again until released + } + +// Con_Printf("Selecting track target...\n"); + + if (locked && autocam) + end = (spec_track + 1) % MAX_CLIENTS; + else + end = spec_track; + i = end; + do { + s = &cl.players[i]; + if (s->name[0] && !s->spectator) { + Cam_Lock(i); + return; + } + i = (i + 1) % MAX_CLIENTS; + } while (i != end); + // stay on same guy? + i = spec_track; + s = &cl.players[i]; + if (s->name[0] && !s->spectator) { + Cam_Lock(i); + return; + } + Con_Printf("No target found ...\n"); + autocam = locked = false; +} + +void Cam_Reset(void) +{ + autocam = CAM_NONE; + spec_track = 0; +} + +void CL_InitCam(void) +{ + Cvar_RegisterVariable (&cl_hightrack); + Cvar_RegisterVariable (&cl_chasecam); +// Cvar_RegisterVariable (&cl_camera_maxpitch); +// Cvar_RegisterVariable (&cl_camera_maxyaw); +} + + diff --git a/QW/client/cl_demo.c b/QW/client/cl_demo.c new file mode 100644 index 0000000..683e8ab --- /dev/null +++ b/QW/client/cl_demo.c @@ -0,0 +1,805 @@ +/* +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 included (GNU.txt) 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. + +*/ + +#include "quakedef.h" + +void CL_FinishTimeDemo (void); + +/* +============================================================================== + +DEMO CODE + +When a demo is playing back, all NET_SendMessages are skipped, and +NET_GetMessages are read from the demo file. + +Whenever cl.time gets past the last received message, another message is +read from the demo file. +============================================================================== +*/ + +/* +============== +CL_StopPlayback + +Called when a demo file runs out, or the user starts a game +============== +*/ +void CL_StopPlayback (void) +{ + if (!cls.demoplayback) + return; + + fclose (cls.demofile); + cls.demofile = NULL; + cls.state = ca_disconnected; + cls.demoplayback = 0; + + if (cls.timedemo) + CL_FinishTimeDemo (); +} + +#define dem_cmd 0 +#define dem_read 1 +#define dem_set 2 + +/* +==================== +CL_WriteDemoCmd + +Writes the current user cmd +==================== +*/ +void CL_WriteDemoCmd (usercmd_t *pcmd) +{ + int i; + float fl; + byte c; + usercmd_t cmd; + +//Con_Printf("write: %ld bytes, %4.4f\n", msg->cursize, realtime); + + fl = LittleFloat((float)realtime); + fwrite (&fl, sizeof(fl), 1, cls.demofile); + + c = dem_cmd; + fwrite (&c, sizeof(c), 1, cls.demofile); + + // correct for byte order, bytes don't matter + cmd = *pcmd; + + for (i = 0; i < 3; i++) + cmd.angles[i] = LittleFloat(cmd.angles[i]); + cmd.forwardmove = LittleShort(cmd.forwardmove); + cmd.sidemove = LittleShort(cmd.sidemove); + cmd.upmove = LittleShort(cmd.upmove); + + fwrite(&cmd, sizeof(cmd), 1, cls.demofile); + + for (i=0 ; i<3 ; i++) + { + fl = LittleFloat (cl.viewangles[i]); + fwrite (&fl, 4, 1, cls.demofile); + } + + fflush (cls.demofile); +} + +/* +==================== +CL_WriteDemoMessage + +Dumps the current net message, prefixed by the length and view angles +==================== +*/ +void CL_WriteDemoMessage (sizebuf_t *msg) +{ + int len; + float fl; + byte c; + +//Con_Printf("write: %ld bytes, %4.4f\n", msg->cursize, realtime); + + if (!cls.demorecording) + return; + + fl = LittleFloat((float)realtime); + fwrite (&fl, sizeof(fl), 1, cls.demofile); + + c = dem_read; + fwrite (&c, sizeof(c), 1, cls.demofile); + + len = LittleLong (msg->cursize); + fwrite (&len, 4, 1, cls.demofile); + fwrite (msg->data, msg->cursize, 1, cls.demofile); + + fflush (cls.demofile); +} + +/* +==================== +CL_GetDemoMessage + + FIXME... +==================== +*/ +qboolean CL_GetDemoMessage (void) +{ + int r, i, j; + float f; + float demotime; + byte c; + usercmd_t *pcmd; + + // read the time from the packet + fread(&demotime, sizeof(demotime), 1, cls.demofile); + demotime = LittleFloat(demotime); + +// decide if it is time to grab the next message + if (cls.timedemo) { + if (cls.td_lastframe < 0) + cls.td_lastframe = demotime; + else if (demotime > cls.td_lastframe) { + cls.td_lastframe = demotime; + // rewind back to time + fseek(cls.demofile, ftell(cls.demofile) - sizeof(demotime), + SEEK_SET); + return 0; // allready read this frame's message + } + if (!cls.td_starttime && cls.state == ca_active) { + cls.td_starttime = Sys_DoubleTime(); + cls.td_startframe = host_framecount; + } + realtime = demotime; // warp + } else if (!cl.paused && cls.state >= ca_onserver) { // allways grab until fully connected + if (realtime + 1.0 < demotime) { + // too far back + realtime = demotime - 1.0; + // rewind back to time + fseek(cls.demofile, ftell(cls.demofile) - sizeof(demotime), + SEEK_SET); + return 0; + } else if (realtime < demotime) { + // rewind back to time + fseek(cls.demofile, ftell(cls.demofile) - sizeof(demotime), + SEEK_SET); + return 0; // don't need another message yet + } + } else + realtime = demotime; // we're warping + + if (cls.state < ca_demostart) + Host_Error ("CL_GetDemoMessage: cls.state != ca_active"); + + // get the msg type + fread (&c, sizeof(c), 1, cls.demofile); + + switch (c) { + case dem_cmd : + // user sent input + i = cls.netchan.outgoing_sequence & UPDATE_MASK; + pcmd = &cl.frames[i].cmd; + r = fread (pcmd, sizeof(*pcmd), 1, cls.demofile); + if (r != 1) + { + CL_StopPlayback (); + return 0; + } + // byte order stuff + for (j = 0; j < 3; j++) + pcmd->angles[j] = LittleFloat(pcmd->angles[j]); + pcmd->forwardmove = LittleShort(pcmd->forwardmove); + pcmd->sidemove = LittleShort(pcmd->sidemove); + pcmd->upmove = LittleShort(pcmd->upmove); + cl.frames[i].senttime = demotime; + cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet + cls.netchan.outgoing_sequence++; + for (i=0 ; i<3 ; i++) + { + r = fread (&f, 4, 1, cls.demofile); + cl.viewangles[i] = LittleFloat (f); + } + break; + + case dem_read: + // get the next message + fread (&net_message.cursize, 4, 1, cls.demofile); + net_message.cursize = LittleLong (net_message.cursize); + //Con_Printf("read: %ld bytes\n", net_message.cursize); + if (net_message.cursize > MAX_MSGLEN) + Sys_Error ("Demo message > MAX_MSGLEN"); + r = fread (net_message.data, net_message.cursize, 1, cls.demofile); + if (r != 1) + { + CL_StopPlayback (); + return 0; + } + break; + + case dem_set : + fread (&i, 4, 1, cls.demofile); + cls.netchan.outgoing_sequence = LittleLong(i); + fread (&i, 4, 1, cls.demofile); + cls.netchan.incoming_sequence = LittleLong(i); + break; + + default : + Con_Printf("Corrupted demo.\n"); + CL_StopPlayback (); + return 0; + } + + return 1; +} + +/* +==================== +CL_GetMessage + +Handles recording and playback of demos, on top of NET_ code +==================== +*/ +qboolean CL_GetMessage (void) +{ + if (cls.demoplayback) + return CL_GetDemoMessage (); + + if (!NET_GetPacket ()) + return false; + + CL_WriteDemoMessage (&net_message); + + return true; +} + + +/* +==================== +CL_Stop_f + +stop recording a demo +==================== +*/ +void CL_Stop_f (void) +{ + if (!cls.demorecording) + { + Con_Printf ("Not recording a demo.\n"); + return; + } + +// write a disconnect message to the demo file + SZ_Clear (&net_message); + MSG_WriteLong (&net_message, -1); // -1 sequence means out of band + MSG_WriteByte (&net_message, svc_disconnect); + MSG_WriteString (&net_message, "EndOfDemo"); + CL_WriteDemoMessage (&net_message); + +// finish up + fclose (cls.demofile); + cls.demofile = NULL; + cls.demorecording = false; + Con_Printf ("Completed demo\n"); +} + + +/* +==================== +CL_WriteDemoMessage + +Dumps the current net message, prefixed by the length and view angles +==================== +*/ +void CL_WriteRecordDemoMessage (sizebuf_t *msg, int seq) +{ + int len; + int i; + float fl; + byte c; + +//Con_Printf("write: %ld bytes, %4.4f\n", msg->cursize, realtime); + + if (!cls.demorecording) + return; + + fl = LittleFloat((float)realtime); + fwrite (&fl, sizeof(fl), 1, cls.demofile); + + c = dem_read; + fwrite (&c, sizeof(c), 1, cls.demofile); + + len = LittleLong (msg->cursize + 8); + fwrite (&len, 4, 1, cls.demofile); + + i = LittleLong(seq); + fwrite (&i, 4, 1, cls.demofile); + fwrite (&i, 4, 1, cls.demofile); + + fwrite (msg->data, msg->cursize, 1, cls.demofile); + + fflush (cls.demofile); +} + + +void CL_WriteSetDemoMessage (void) +{ + int len; + float fl; + byte c; + +//Con_Printf("write: %ld bytes, %4.4f\n", msg->cursize, realtime); + + if (!cls.demorecording) + return; + + fl = LittleFloat((float)realtime); + fwrite (&fl, sizeof(fl), 1, cls.demofile); + + c = dem_set; + fwrite (&c, sizeof(c), 1, cls.demofile); + + len = LittleLong(cls.netchan.outgoing_sequence); + fwrite (&len, 4, 1, cls.demofile); + len = LittleLong(cls.netchan.incoming_sequence); + fwrite (&len, 4, 1, cls.demofile); + + fflush (cls.demofile); +} + + + + +/* +==================== +CL_Record_f + +record <demoname> <server> +==================== +*/ +void CL_Record_f (void) +{ + int c; + char name[MAX_OSPATH]; + sizebuf_t buf; + char buf_data[MAX_MSGLEN]; + int n, i, j; + char *s; + entity_t *ent; + entity_state_t *es, blankes; + player_info_t *player; + extern char gamedirfile[]; + int seq = 1; + + c = Cmd_Argc(); + if (c != 2) + { + Con_Printf ("record <demoname>\n"); + return; + } + + if (cls.state != ca_active) { + Con_Printf ("You must be connected to record.\n"); + return; + } + + if (cls.demorecording) + CL_Stop_f(); + + sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); + +// +// open the demo file +// + COM_DefaultExtension (name, ".qwd"); + + cls.demofile = fopen (name, "wb"); + if (!cls.demofile) + { + Con_Printf ("ERROR: couldn't open.\n"); + return; + } + + Con_Printf ("recording to %s.\n", name); + cls.demorecording = true; + +/*-------------------------------------------------*/ + +// serverdata + // send the info about the new client to all connected clients + memset(&buf, 0, sizeof(buf)); + buf.data = buf_data; + buf.maxsize = sizeof(buf_data); + +// send the serverdata + MSG_WriteByte (&buf, svc_serverdata); + MSG_WriteLong (&buf, PROTOCOL_VERSION); + MSG_WriteLong (&buf, cl.servercount); + MSG_WriteString (&buf, gamedirfile); + + if (cl.spectator) + MSG_WriteByte (&buf, cl.playernum | 128); + else + MSG_WriteByte (&buf, cl.playernum); + + // send full levelname + MSG_WriteString (&buf, cl.levelname); + + // send the movevars + MSG_WriteFloat(&buf, movevars.gravity); + MSG_WriteFloat(&buf, movevars.stopspeed); + MSG_WriteFloat(&buf, movevars.maxspeed); + MSG_WriteFloat(&buf, movevars.spectatormaxspeed); + MSG_WriteFloat(&buf, movevars.accelerate); + MSG_WriteFloat(&buf, movevars.airaccelerate); + MSG_WriteFloat(&buf, movevars.wateraccelerate); + MSG_WriteFloat(&buf, movevars.friction); + MSG_WriteFloat(&buf, movevars.waterfriction); + MSG_WriteFloat(&buf, movevars.entgravity); + + // send music + MSG_WriteByte (&buf, svc_cdtrack); + MSG_WriteByte (&buf, 0); // none in demos + + // send server info string + MSG_WriteByte (&buf, svc_stufftext); + MSG_WriteString (&buf, va("fullserverinfo \"%s\"\n", cl.serverinfo) ); + + // flush packet + CL_WriteRecordDemoMessage (&buf, seq++); + SZ_Clear (&buf); + +// soundlist + MSG_WriteByte (&buf, svc_soundlist); + MSG_WriteByte (&buf, 0); + + n = 0; + s = cl.sound_name[n+1]; + while (*s) { + MSG_WriteString (&buf, s); + if (buf.cursize > MAX_MSGLEN/2) { + MSG_WriteByte (&buf, 0); + MSG_WriteByte (&buf, n); + CL_WriteRecordDemoMessage (&buf, seq++); + SZ_Clear (&buf); + MSG_WriteByte (&buf, svc_soundlist); + MSG_WriteByte (&buf, n + 1); + } + n++; + s = cl.sound_name[n+1]; + } + if (buf.cursize) { + MSG_WriteByte (&buf, 0); + MSG_WriteByte (&buf, 0); + CL_WriteRecordDemoMessage (&buf, seq++); + SZ_Clear (&buf); + } + +// modellist + MSG_WriteByte (&buf, svc_modellist); + MSG_WriteByte (&buf, 0); + + n = 0; + s = cl.model_name[n+1]; + while (*s) { + MSG_WriteString (&buf, s); + if (buf.cursize > MAX_MSGLEN/2) { + MSG_WriteByte (&buf, 0); + MSG_WriteByte (&buf, n); + CL_WriteRecordDemoMessage (&buf, seq++); + SZ_Clear (&buf); + MSG_WriteByte (&buf, svc_modellist); + MSG_WriteByte (&buf, n + 1); + } + n++; + s = cl.model_name[n+1]; + } + if (buf.cursize) { + MSG_WriteByte (&buf, 0); + MSG_WriteByte (&buf, 0); + CL_WriteRecordDemoMessage (&buf, seq++); + SZ_Clear (&buf); + } + +// spawnstatic + + for (i = 0; i < cl.num_statics; i++) { + ent = cl_static_entities + i; + + MSG_WriteByte (&buf, svc_spawnstatic); + + for (j = 1; j < MAX_MODELS; j++) + if (ent->model == cl.model_precache[j]) + break; + if (j == MAX_MODELS) + MSG_WriteByte (&buf, 0); + else + MSG_WriteByte (&buf, j); + + MSG_WriteByte (&buf, ent->frame); + MSG_WriteByte (&buf, 0); + MSG_WriteByte (&buf, ent->skinnum); + for (j=0 ; j<3 ; j++) + { + MSG_WriteCoord (&buf, ent->origin[j]); + MSG_WriteAngle (&buf, ent->angles[j]); + } + + if (buf.cursize > MAX_MSGLEN/2) { + CL_WriteRecordDemoMessage (&buf, seq++); + SZ_Clear (&buf); + } + } + +// spawnstaticsound + // static sounds are skipped in demos, life is hard + +// baselines + + memset(&blankes, 0, sizeof(blankes)); + for (i = 0; i < MAX_EDICTS; i++) { + es = cl_baselines + i; + + if (memcmp(es, &blankes, sizeof(blankes))) { + MSG_WriteByte (&buf,svc_spawnbaseline); + MSG_WriteShort (&buf, i); + + MSG_WriteByte (&buf, es->modelindex); + MSG_WriteByte (&buf, es->frame); + MSG_WriteByte (&buf, es->colormap); + MSG_WriteByte (&buf, es->skinnum); + for (j=0 ; j<3 ; j++) + { + MSG_WriteCoord(&buf, es->origin[j]); + MSG_WriteAngle(&buf, es->angles[j]); + } + + if (buf.cursize > MAX_MSGLEN/2) { + CL_WriteRecordDemoMessage (&buf, seq++); + SZ_Clear (&buf); + } + } + } + + MSG_WriteByte (&buf, svc_stufftext); + MSG_WriteString (&buf, va("cmd spawn %i 0\n", cl.servercount) ); + + if (buf.cursize) { + CL_WriteRecordDemoMessage (&buf, seq++); + SZ_Clear (&buf); + } + +// send current status of all other players + + for (i = 0; i < MAX_CLIENTS; i++) { + player = cl.players + i; + + MSG_WriteByte (&buf, svc_updatefrags); + MSG_WriteByte (&buf, i); + MSG_WriteShort (&buf, player->frags); + + MSG_WriteByte (&buf, svc_updateping); + MSG_WriteByte (&buf, i); + MSG_WriteShort (&buf, player->ping); + + MSG_WriteByte (&buf, svc_updatepl); + MSG_WriteByte (&buf, i); + MSG_WriteByte (&buf, player->pl); + + MSG_WriteByte (&buf, svc_updateentertime); + MSG_WriteByte (&buf, i); + MSG_WriteFloat (&buf, player->entertime); + + MSG_WriteByte (&buf, svc_updateuserinfo); + MSG_WriteByte (&buf, i); + MSG_WriteLong (&buf, player->userid); + MSG_WriteString (&buf, player->userinfo); + + if (buf.cursize > MAX_MSGLEN/2) { + CL_WriteRecordDemoMessage (&buf, seq++); + SZ_Clear (&buf); + } + } + +// send all current light styles + for (i=0 ; i<MAX_LIGHTSTYLES ; i++) + { + MSG_WriteByte (&buf, svc_lightstyle); + MSG_WriteByte (&buf, (char)i); + MSG_WriteString (&buf, cl_lightstyle[i].map); + } + + for (i = 0; i < MAX_CL_STATS; i++) { + MSG_WriteByte (&buf, svc_updatestatlong); + MSG_WriteByte (&buf, i); + MSG_WriteLong (&buf, cl.stats[i]); + if (buf.cursize > MAX_MSGLEN/2) { + CL_WriteRecordDemoMessage (&buf, seq++); + SZ_Clear (&buf); + } + } + +#if 0 + MSG_WriteByte (&buf, svc_updatestatlong); + MSG_WriteByte (&buf, STAT_TOTALMONSTERS); + MSG_WriteLong (&buf, cl.stats[STAT_TOTALMONSTERS]); + + MSG_WriteByte (&buf, svc_updatestatlong); + MSG_WriteByte (&buf, STAT_SECRETS); + MSG_WriteLong (&buf, cl.stats[STAT_SECRETS]); + + MSG_WriteByte (&buf, svc_updatestatlong); + MSG_WriteByte (&buf, STAT_MONSTERS); + MSG_WriteLong (&buf, cl.stats[STAT_MONSTERS]); +#endif + + // get the client to check and download skins + // when that is completed, a begin command will be issued + MSG_WriteByte (&buf, svc_stufftext); + MSG_WriteString (&buf, va("skins\n") ); + + CL_WriteRecordDemoMessage (&buf, seq++); + + CL_WriteSetDemoMessage(); + + // done +} + +/* +==================== +CL_ReRecord_f + +record <demoname> +==================== +*/ +void CL_ReRecord_f (void) +{ + int c; + char name[MAX_OSPATH]; + + c = Cmd_Argc(); + if (c != 2) + { + Con_Printf ("rerecord <demoname>\n"); + return; + } + + if (!*cls.servername) { + Con_Printf("No server to reconnect to...\n"); + return; + } + + if (cls.demorecording) + CL_Stop_f(); + + sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); + +// +// open the demo file +// + COM_DefaultExtension (name, ".qwd"); + + cls.demofile = fopen (name, "wb"); + if (!cls.demofile) + { + Con_Printf ("ERROR: couldn't open.\n"); + return; + } + + Con_Printf ("recording to %s.\n", name); + cls.demorecording = true; + + CL_Disconnect(); + CL_BeginServerConnect(); +} + + +/* +==================== +CL_PlayDemo_f + +play [demoname] +==================== +*/ +void CL_PlayDemo_f (void) +{ + char name[256]; + + if (Cmd_Argc() != 2) + { + Con_Printf ("play <demoname> : plays a demo\n"); + return; + } + +// +// disconnect from server +// + CL_Disconnect (); + +// +// open the demo file +// + strcpy (name, Cmd_Argv(1)); + COM_DefaultExtension (name, ".qwd"); + + Con_Printf ("Playing demo from %s.\n", name); + COM_FOpenFile (name, &cls.demofile); + if (!cls.demofile) + { + Con_Printf ("ERROR: couldn't open.\n"); + cls.demonum = -1; // stop demo loop + return; + } + + cls.demoplayback = true; + cls.state = ca_demostart; + Netchan_Setup (&cls.netchan, net_from, 0); + realtime = 0; +} + +/* +==================== +CL_FinishTimeDemo + +==================== +*/ +void CL_FinishTimeDemo (void) +{ + int frames; + float time; + + cls.timedemo = false; + +// the first frame didn't count + frames = (host_framecount - cls.td_startframe) - 1; + time = Sys_DoubleTime() - cls.td_starttime; + if (!time) + time = 1; + Con_Printf ("%i frames %5.1f seconds %5.1f fps\n", frames, time, frames/time); +} + +/* +==================== +CL_TimeDemo_f + +timedemo [demoname] +==================== +*/ +void CL_TimeDemo_f (void) +{ + if (Cmd_Argc() != 2) + { + Con_Printf ("timedemo <demoname> : gets demo speeds\n"); + return; + } + + CL_PlayDemo_f (); + + if (cls.state != ca_demostart) + return; + +// cls.td_starttime will be grabbed at the second frame of the demo, so +// all the loading time doesn't get counted + + cls.timedemo = true; + cls.td_starttime = 0; + cls.td_startframe = host_framecount; + cls.td_lastframe = -1; // get a new message this frame +} + diff --git a/QW/client/cl_ents.c b/QW/client/cl_ents.c new file mode 100644 index 0000000..80d28c4 --- /dev/null +++ b/QW/client/cl_ents.c @@ -0,0 +1,1083 @@ +/* +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. + +*/ +// cl_ents.c -- entity parsing and management + +#include "quakedef.h" + +extern cvar_t cl_predict_players; +extern cvar_t cl_predict_players2; +extern cvar_t cl_solid_players; + +static struct predicted_player { + int flags; + qboolean active; + vec3_t origin; // predicted origin +} predicted_players[MAX_CLIENTS]; + +//============================================================ + +/* +=============== +CL_AllocDlight + +=============== +*/ +dlight_t *CL_AllocDlight (int key) +{ + int i; + dlight_t *dl; + +// first look for an exact key match + if (key) + { + dl = cl_dlights; + for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) + { + if (dl->key == key) + { + memset (dl, 0, sizeof(*dl)); + dl->key = key; + return dl; + } + } + } + +// then look for anything else + dl = cl_dlights; + for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) + { + if (dl->die < cl.time) + { + memset (dl, 0, sizeof(*dl)); + dl->key = key; + return dl; + } + } + + dl = &cl_dlights[0]; + memset (dl, 0, sizeof(*dl)); + dl->key = key; + return dl; +} + +/* +=============== +CL_NewDlight +=============== +*/ +void CL_NewDlight (int key, float x, float y, float z, float radius, float time, + int type) +{ + dlight_t *dl; + + dl = CL_AllocDlight (key); + dl->origin[0] = x; + dl->origin[1] = y; + dl->origin[2] = z; + dl->radius = radius; + dl->die = cl.time + time; + if (type == 0) { + dl->color[0] = 0.2; + dl->color[1] = 0.1; + dl->color[2] = 0.05; + dl->color[3] = 0.7; + } else if (type == 1) { + dl->color[0] = 0.05; + dl->color[1] = 0.05; + dl->color[2] = 0.3; + dl->color[3] = 0.7; + } else if (type == 2) { + dl->color[0] = 0.5; + dl->color[1] = 0.05; + dl->color[2] = 0.05; + dl->color[3] = 0.7; + } else if (type == 3) { + dl->color[0]=0.5; + dl->color[1] = 0.05; + dl->color[2] = 0.4; + dl->color[3] = 0.7; + } +} + + +/* +=============== +CL_DecayLights + +=============== +*/ +void CL_DecayLights (void) +{ + int i; + dlight_t *dl; + + dl = cl_dlights; + for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) + { + if (dl->die < cl.time || !dl->radius) + continue; + + dl->radius -= host_frametime*dl->decay; + if (dl->radius < 0) + dl->radius = 0; + } +} + + +/* +========================================================================= + +PACKET ENTITY PARSING / LINKING + +========================================================================= +*/ + +/* +================== +CL_ParseDelta + +Can go from either a baseline or a previous packet_entity +================== +*/ +int bitcounts[32]; /// just for protocol profiling +void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits) +{ + int i; + + // set everything to the state we are delta'ing from + *to = *from; + + to->number = bits & 511; + bits &= ~511; + + if (bits & U_MOREBITS) + { // read in the low order bits + i = MSG_ReadByte (); + bits |= i; + } + + // count the bits for net profiling + for (i=0 ; i<16 ; i++) + if (bits&(1<<i)) + bitcounts[i]++; + + to->flags = bits; + + if (bits & U_MODEL) + to->modelindex = MSG_ReadByte (); + + if (bits & U_FRAME) + to->frame = MSG_ReadByte (); + + if (bits & U_COLORMAP) + to->colormap = MSG_ReadByte(); + + if (bits & U_SKIN) + to->skinnum = MSG_ReadByte(); + + if (bits & U_EFFECTS) + to->effects = MSG_ReadByte(); + + if (bits & U_ORIGIN1) + to->origin[0] = MSG_ReadCoord (); + + if (bits & U_ANGLE1) + to->angles[0] = MSG_ReadAngle(); + + if (bits & U_ORIGIN2) + to->origin[1] = MSG_ReadCoord (); + + if (bits & U_ANGLE2) + to->angles[1] = MSG_ReadAngle(); + + if (bits & U_ORIGIN3) + to->origin[2] = MSG_ReadCoord (); + + if (bits & U_ANGLE3) + to->angles[2] = MSG_ReadAngle(); + + if (bits & U_SOLID) + { + // FIXME + } +} + + +/* +================= +FlushEntityPacket +================= +*/ +void FlushEntityPacket (void) +{ + int word; + entity_state_t olde, newe; + + Con_DPrintf ("FlushEntityPacket\n"); + + memset (&olde, 0, sizeof(olde)); + + cl.validsequence = 0; // can't render a frame + cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].invalid = true; + + // read it all, but ignore it + while (1) + { + word = (unsigned short)MSG_ReadShort (); + if (msg_badread) + { // something didn't parse right... + Host_EndGame ("msg_badread in packetentities"); + return; + } + + if (!word) + break; // done + + CL_ParseDelta (&olde, &newe, word); + } +} + +/* +================== +CL_ParsePacketEntities + +An svc_packetentities has just been parsed, deal with the +rest of the data stream. +================== +*/ +void CL_ParsePacketEntities (qboolean delta) +{ + int oldpacket, newpacket; + packet_entities_t *oldp, *newp, dummy; + int oldindex, newindex; + int word, newnum, oldnum; + qboolean full; + byte from; + + newpacket = cls.netchan.incoming_sequence&UPDATE_MASK; + newp = &cl.frames[newpacket].packet_entities; + cl.frames[newpacket].invalid = false; + + if (delta) + { + from = MSG_ReadByte (); + + oldpacket = cl.frames[newpacket].delta_sequence; + + if ( (from&UPDATE_MASK) != (oldpacket&UPDATE_MASK) ) + Con_DPrintf ("WARNING: from mismatch\n"); + } + else + oldpacket = -1; + + full = false; + if (oldpacket != -1) + { + if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP-1) + { // we can't use this, it is too old + FlushEntityPacket (); + return; + } + cl.validsequence = cls.netchan.incoming_sequence; + oldp = &cl.frames[oldpacket&UPDATE_MASK].packet_entities; + } + else + { // this is a full update that we can start delta compressing from now + oldp = &dummy; + dummy.num_entities = 0; + cl.validsequence = cls.netchan.incoming_sequence; + full = true; + } + + oldindex = 0; + newindex = 0; + newp->num_entities = 0; + + while (1) + { + word = (unsigned short)MSG_ReadShort (); + if (msg_badread) + { // something didn't parse right... + Host_EndGame ("msg_badread in packetentities"); + return; + } + + if (!word) + { + while (oldindex < oldp->num_entities) + { // copy all the rest of the entities from the old packet +//Con_Printf ("copy %i\n", oldp->entities[oldindex].number); + if (newindex >= MAX_PACKET_ENTITIES) + Host_EndGame ("CL_ParsePacketEntities: newindex == MAX_PACKET_ENTITIES"); + newp->entities[newindex] = oldp->entities[oldindex]; + newindex++; + oldindex++; + } + break; + } + newnum = word&511; + oldnum = oldindex >= oldp->num_entities ? 9999 : oldp->entities[oldindex].number; + + while (newnum > oldnum) + { + if (full) + { + Con_Printf ("WARNING: oldcopy on full update"); + FlushEntityPacket (); + return; + } + +//Con_Printf ("copy %i\n", oldnum); + // copy one of the old entities over to the new packet unchanged + if (newindex >= MAX_PACKET_ENTITIES) + Host_EndGame ("CL_ParsePacketEntities: newindex == MAX_PACKET_ENTITIES"); + newp->entities[newindex] = oldp->entities[oldindex]; + newindex++; + oldindex++; + oldnum = oldindex >= oldp->num_entities ? 9999 : oldp->entities[oldindex].number; + } + + if (newnum < oldnum) + { // new from baseline +//Con_Printf ("baseline %i\n", newnum); + if (word & U_REMOVE) + { + if (full) + { + cl.validsequence = 0; + Con_Printf ("WARNING: U_REMOVE on full update\n"); + FlushEntityPacket (); + return; + } + continue; + } + if (newindex >= MAX_PACKET_ENTITIES) + Host_EndGame ("CL_ParsePacketEntities: newindex == MAX_PACKET_ENTITIES"); + CL_ParseDelta (&cl_baselines[newnum], &newp->entities[newindex], word); + newindex++; + continue; + } + + if (newnum == oldnum) + { // delta from previous + if (full) + { + cl.validsequence = 0; + Con_Printf ("WARNING: delta on full update"); + } + if (word & U_REMOVE) + { + oldindex++; + continue; + } +//Con_Printf ("delta %i\n",newnum); + CL_ParseDelta (&oldp->entities[oldindex], &newp->entities[newindex], word); + newindex++; + oldindex++; + } + + } + + newp->num_entities = newindex; +} + + +/* +=============== +CL_LinkPacketEntities + +=============== +*/ +void CL_LinkPacketEntities (void) +{ + entity_t *ent; + packet_entities_t *pack; + entity_state_t *s1, *s2; + float f; + model_t *model; + vec3_t old_origin; + float autorotate; + int i; + int pnum; + dlight_t *dl; + + pack = &cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities; + + autorotate = anglemod(100*cl.time); + + f = 0; // FIXME: no interpolation right now + + for (pnum=0 ; pnum<pack->num_entities ; pnum++) + { + s1 = &pack->entities[pnum]; + s2 = s1; // FIXME: no interpolation right now + + // spawn light flashes, even ones coming from invisible objects + if ((s1->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED)) + CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 3); + else if (s1->effects & EF_BLUE) + CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 1); + else if (s1->effects & EF_RED) + CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 2); + else if (s1->effects & EF_BRIGHTLIGHT) + CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2] + 16, 400 + (rand()&31), 0.1, 0); + else if (s1->effects & EF_DIMLIGHT) + CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 0); + + // if set to invisible, skip + if (!s1->modelindex) + continue; + + // create a new entity + if (cl_numvisedicts == MAX_VISEDICTS) + break; // object list is full + + ent = &cl_visedicts[cl_numvisedicts]; + cl_numvisedicts++; + + ent->keynum = s1->number; + ent->model = model = cl.model_precache[s1->modelindex]; + + // set colormap + if (s1->colormap && (s1->colormap < MAX_CLIENTS) + && !strcmp(ent->model->name,"progs/player.mdl") ) + { + ent->colormap = cl.players[s1->colormap-1].translations; + ent->scoreboard = &cl.players[s1->colormap-1]; + } + else + { + ent->colormap = vid.colormap; + ent->scoreboard = NULL; + } + + // set skin + ent->skinnum = s1->skinnum; + + // set frame + ent->frame = s1->frame; + + // rotate binary objects locally + if (model->flags & EF_ROTATE) + { + ent->angles[0] = 0; + ent->angles[1] = autorotate; + ent->angles[2] = 0; + } + else + { + float a1, a2; + + for (i=0 ; i<3 ; i++) + { + a1 = s1->angles[i]; + a2 = s2->angles[i]; + if (a1 - a2 > 180) + a1 -= 360; + if (a1 - a2 < -180) + a1 += 360; + ent->angles[i] = a2 + f * (a1 - a2); + } + } + + // calculate origin + for (i=0 ; i<3 ; i++) + ent->origin[i] = s2->origin[i] + + f * (s1->origin[i] - s2->origin[i]); + + // add automatic particle trails + if (!model->flags) + continue; + + // scan the old entity display list for a matching + for (i=0 ; i<cl_oldnumvisedicts ; i++) + { + if (cl_oldvisedicts[i].keynum == ent->keynum) + { + VectorCopy (cl_oldvisedicts[i].origin, old_origin); + break; + } + } + if (i == cl_oldnumvisedicts) + continue; // not in last message + + for (i=0 ; i<3 ; i++) + if ( abs(old_origin[i] - ent->origin[i]) > 128) + { // no trail if too far + VectorCopy (ent->origin, old_origin); + break; + } + if (model->flags & EF_ROCKET) + { + R_RocketTrail (old_origin, ent->origin, 0); + dl = CL_AllocDlight (s1->number); + VectorCopy (ent->origin, dl->origin); + dl->radius = 200; + dl->die = cl.time + 0.1; + } + else if (model->flags & EF_GRENADE) + R_RocketTrail (old_origin, ent->origin, 1); + else if (model->flags & EF_GIB) + R_RocketTrail (old_origin, ent->origin, 2); + else if (model->flags & EF_ZOMGIB) + R_RocketTrail (old_origin, ent->origin, 4); + else if (model->flags & EF_TRACER) + R_RocketTrail (old_origin, ent->origin, 3); + else if (model->flags & EF_TRACER2) + R_RocketTrail (old_origin, ent->origin, 5); + else if (model->flags & EF_TRACER3) + R_RocketTrail (old_origin, ent->origin, 6); + } +} + + +/* +========================================================================= + +PROJECTILE PARSING / LINKING + +========================================================================= +*/ + +typedef struct +{ + int modelindex; + vec3_t origin; + vec3_t angles; +} projectile_t; + +#define MAX_PROJECTILES 32 +projectile_t cl_projectiles[MAX_PROJECTILES]; +int cl_num_projectiles; + +extern int cl_spikeindex; + +void CL_ClearProjectiles (void) +{ + cl_num_projectiles = 0; +} + +/* +===================== +CL_ParseProjectiles + +Nails are passed as efficient temporary entities +===================== +*/ +void CL_ParseProjectiles (void) +{ + int i, c, j; + byte bits[6]; + projectile_t *pr; + + c = MSG_ReadByte (); + for (i=0 ; i<c ; i++) + { + for (j=0 ; j<6 ; j++) + bits[j] = MSG_ReadByte (); + + if (cl_num_projectiles == MAX_PROJECTILES) + continue; + + pr = &cl_projectiles[cl_num_projectiles]; + cl_num_projectiles++; + + pr->modelindex = cl_spikeindex; + pr->origin[0] = ( ( bits[0] + ((bits[1]&15)<<8) ) <<1) - 4096; + pr->origin[1] = ( ( (bits[1]>>4) + (bits[2]<<4) ) <<1) - 4096; + pr->origin[2] = ( ( bits[3] + ((bits[4]&15)<<8) ) <<1) - 4096; + pr->angles[0] = 360*(bits[4]>>4)/16; + pr->angles[1] = 360*bits[5]/256; + } +} + +/* +============= +CL_LinkProjectiles + +============= +*/ +void CL_LinkProjectiles (void) +{ + int i; + projectile_t *pr; + entity_t *ent; + + for (i=0, pr=cl_projectiles ; i<cl_num_projectiles ; i++, pr++) + { + // grab an entity to fill in + if (cl_numvisedicts == MAX_VISEDICTS) + break; // object list is full + ent = &cl_visedicts[cl_numvisedicts]; + cl_numvisedicts++; + ent->keynum = 0; + + if (pr->modelindex < 1) + continue; + ent->model = cl.model_precache[pr->modelindex]; + ent->skinnum = 0; + ent->frame = 0; + ent->colormap = vid.colormap; + ent->scoreboard = NULL; + VectorCopy (pr->origin, ent->origin); + VectorCopy (pr->angles, ent->angles); + } +} + +//======================================== + +extern int cl_spikeindex, cl_playerindex, cl_flagindex; + +entity_t *CL_NewTempEntity (void); + +/* +=================== +CL_ParsePlayerinfo +=================== +*/ +extern int parsecountmod; +extern double parsecounttime; +void CL_ParsePlayerinfo (void) +{ + int msec; + int flags; + player_info_t *info; + player_state_t *state; + int num; + int i; + + num = MSG_ReadByte (); + if (num > MAX_CLIENTS) + Sys_Error ("CL_ParsePlayerinfo: bad num"); + + info = &cl.players[num]; + + state = &cl.frames[parsecountmod].playerstate[num]; + + flags = state->flags = MSG_ReadShort (); + + state->messagenum = cl.parsecount; + state->origin[0] = MSG_ReadCoord (); + state->origin[1] = MSG_ReadCoord (); + state->origin[2] = MSG_ReadCoord (); + + state->frame = MSG_ReadByte (); + + // the other player's last move was likely some time + // before the packet was sent out, so accurately track + // the exact time it was valid at + if (flags & PF_MSEC) + { + msec = MSG_ReadByte (); + state->state_time = parsecounttime - msec*0.001; + } + else + state->state_time = parsecounttime; + + if (flags & PF_COMMAND) + MSG_ReadDeltaUsercmd (&nullcmd, &state->command); + + for (i=0 ; i<3 ; i++) + { + if (flags & (PF_VELOCITY1<<i) ) + state->velocity[i] = MSG_ReadShort(); + else + state->velocity[i] = 0; + } + if (flags & PF_MODEL) + state->modelindex = MSG_ReadByte (); + else + state->modelindex = cl_playerindex; + + if (flags & PF_SKINNUM) + state->skinnum = MSG_ReadByte (); + else + state->skinnum = 0; + + if (flags & PF_EFFECTS) + state->effects = MSG_ReadByte (); + else + state->effects = 0; + + if (flags & PF_WEAPONFRAME) + state->weaponframe = MSG_ReadByte (); + else + state->weaponframe = 0; + + VectorCopy (state->command.angles, state->viewangles); +} + + +/* +================ +CL_AddFlagModels + +Called when the CTF flags are set +================ +*/ +void CL_AddFlagModels (entity_t *ent, int team) +{ + int i; + float f; + vec3_t v_forward, v_right, v_up; + entity_t *newent; + + if (cl_flagindex == -1) + return; + + f = 14; + if (ent->frame >= 29 && ent->frame <= 40) { + if (ent->frame >= 29 && ent->frame <= 34) { //axpain + if (ent->frame == 29) f = f + 2; + else if (ent->frame == 30) f = f + 8; + else if (ent->frame == 31) f = f + 12; + else if (ent->frame == 32) f = f + 11; + else if (ent->frame == 33) f = f + 10; + else if (ent->frame == 34) f = f + 4; + } else if (ent->frame >= 35 && ent->frame <= 40) { // pain + if (ent->frame == 35) f = f + 2; + else if (ent->frame == 36) f = f + 10; + else if (ent->frame == 37) f = f + 10; + else if (ent->frame == 38) f = f + 8; + else if (ent->frame == 39) f = f + 4; + else if (ent->frame == 40) f = f + 2; + } + } else if (ent->frame >= 103 && ent->frame <= 118) { + if (ent->frame >= 103 && ent->frame <= 104) f = f + 6; //nailattack + else if (ent->frame >= 105 && ent->frame <= 106) f = f + 6; //light + else if (ent->frame >= 107 && ent->frame <= 112) f = f + 7; //rocketattack + else if (ent->frame >= 112 && ent->frame <= 118) f = f + 7; //shotattack + } + + newent = CL_NewTempEntity (); + newent->model = cl.model_precache[cl_flagindex]; + newent->skinnum = team; + + AngleVectors (ent->angles, v_forward, v_right, v_up); + v_forward[2] = -v_forward[2]; // reverse z component + for (i=0 ; i<3 ; i++) + newent->origin[i] = ent->origin[i] - f*v_forward[i] + 22*v_right[i]; + newent->origin[2] -= 16; + + VectorCopy (ent->angles, newent->angles) + newent->angles[2] -= 45; +} + +/* +============= +CL_LinkPlayers + +Create visible entities in the correct position +for all current players +============= +*/ +void CL_LinkPlayers (void) +{ + int j; + player_info_t *info; + player_state_t *state; + player_state_t exact; + double playertime; + entity_t *ent; + int msec; + frame_t *frame; + int oldphysent; + + playertime = realtime - cls.latency + 0.02; + if (playertime > realtime) + playertime = realtime; + + frame = &cl.frames[cl.parsecount&UPDATE_MASK]; + + for (j=0, info=cl.players, state=frame->playerstate ; j < MAX_CLIENTS + ; j++, info++, state++) + { + if (state->messagenum != cl.parsecount) + continue; // not present this frame + + // spawn light flashes, even ones coming from invisible objects +#ifdef GLQUAKE + if (!gl_flashblend.value || j != cl.playernum) { +#endif + if ((state->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED)) + CL_NewDlight (j, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 3); + else if (state->effects & EF_BLUE) + CL_NewDlight (j, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 1); + else if (state->effects & EF_RED) + CL_NewDlight (j, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 2); + else if (state->effects & EF_BRIGHTLIGHT) + CL_NewDlight (j, state->origin[0], state->origin[1], state->origin[2] + 16, 400 + (rand()&31), 0.1, 0); + else if (state->effects & EF_DIMLIGHT) + CL_NewDlight (j, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 0); +#ifdef GLQUAKE + } +#endif + + // the player object never gets added + if (j == cl.playernum) + continue; + + if (!state->modelindex) + continue; + + if (!Cam_DrawPlayer(j)) + continue; + + // grab an entity to fill in + if (cl_numvisedicts == MAX_VISEDICTS) + break; // object list is full + ent = &cl_visedicts[cl_numvisedicts]; + cl_numvisedicts++; + ent->keynum = 0; + + ent->model = cl.model_precache[state->modelindex]; + ent->skinnum = state->skinnum; + ent->frame = state->frame; + ent->colormap = info->translations; + if (state->modelindex == cl_playerindex) + ent->scoreboard = info; // use custom skin + else + ent->scoreboard = NULL; + + // + // angles + // + ent->angles[PITCH] = -state->viewangles[PITCH]/3; + ent->angles[YAW] = state->viewangles[YAW]; + ent->angles[ROLL] = 0; + ent->angles[ROLL] = V_CalcRoll (ent->angles, state->velocity)*4; + + // only predict half the move to minimize overruns + msec = 500*(playertime - state->state_time); + if (msec <= 0 || (!cl_predict_players.value && !cl_predict_players2.value)) + { + VectorCopy (state->origin, ent->origin); +//Con_DPrintf ("nopredict\n"); + } + else + { + // predict players movement + if (msec > 255) + msec = 255; + state->command.msec = msec; +//Con_DPrintf ("predict: %i\n", msec); + + oldphysent = pmove.numphysent; + CL_SetSolidPlayers (j); + CL_PredictUsercmd (state, &exact, &state->command, false); + pmove.numphysent = oldphysent; + VectorCopy (exact.origin, ent->origin); + } + + if (state->effects & EF_FLAG1) + CL_AddFlagModels (ent, 0); + else if (state->effects & EF_FLAG2) + CL_AddFlagModels (ent, 1); + + } +} + +//====================================================================== + +/* +=============== +CL_SetSolid + +Builds all the pmove physents for the current frame +=============== +*/ +void CL_SetSolidEntities (void) +{ + int i; + frame_t *frame; + packet_entities_t *pak; + entity_state_t *state; + + pmove.physents[0].model = cl.worldmodel; + VectorCopy (vec3_origin, pmove.physents[0].origin); + pmove.physents[0].info = 0; + pmove.numphysent = 1; + + frame = &cl.frames[parsecountmod]; + pak = &frame->packet_entities; + + for (i=0 ; i<pak->num_entities ; i++) + { + state = &pak->entities[i]; + + if (!state->modelindex) + continue; + if (!cl.model_precache[state->modelindex]) + continue; + if ( cl.model_precache[state->modelindex]->hulls[1].firstclipnode + || cl.model_precache[state->modelindex]->clipbox ) + { + pmove.physents[pmove.numphysent].model = cl.model_precache[state->modelindex]; + VectorCopy (state->origin, pmove.physents[pmove.numphysent].origin); + pmove.numphysent++; + } + } + +} + +/* +=== +Calculate the new position of players, without other player clipping + +We do this to set up real player prediction. +Players are predicted twice, first without clipping other players, +then with clipping against them. +This sets up the first phase. +=== +*/ +void CL_SetUpPlayerPrediction(qboolean dopred) +{ + int j; + player_state_t *state; + player_state_t exact; + double playertime; + int msec; + frame_t *frame; + struct predicted_player *pplayer; + + playertime = realtime - cls.latency + 0.02; + if (playertime > realtime) + playertime = realtime; + + frame = &cl.frames[cl.parsecount&UPDATE_MASK]; + + for (j=0, pplayer = predicted_players, state=frame->playerstate; + j < MAX_CLIENTS; + j++, pplayer++, state++) { + + pplayer->active = false; + + if (state->messagenum != cl.parsecount) + continue; // not present this frame + + if (!state->modelindex) + continue; + + pplayer->active = true; + pplayer->flags = state->flags; + + // note that the local player is special, since he moves locally + // we use his last predicted postition + if (j == cl.playernum) { + VectorCopy(cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].playerstate[cl.playernum].origin, + pplayer->origin); + } else { + // only predict half the move to minimize overruns + msec = 500*(playertime - state->state_time); + if (msec <= 0 || + (!cl_predict_players.value && !cl_predict_players2.value) || + !dopred) + { + VectorCopy (state->origin, pplayer->origin); + //Con_DPrintf ("nopredict\n"); + } + else + { + // predict players movement + if (msec > 255) + msec = 255; + state->command.msec = msec; + //Con_DPrintf ("predict: %i\n", msec); + + CL_PredictUsercmd (state, &exact, &state->command, false); + VectorCopy (exact.origin, pplayer->origin); + } + } + } +} + +/* +=============== +CL_SetSolid + +Builds all the pmove physents for the current frame +Note that CL_SetUpPlayerPrediction() must be called first! +pmove must be setup with world and solid entity hulls before calling +(via CL_PredictMove) +=============== +*/ +void CL_SetSolidPlayers (int playernum) +{ + int j; + extern vec3_t player_mins; + extern vec3_t player_maxs; + struct predicted_player *pplayer; + physent_t *pent; + + if (!cl_solid_players.value) + return; + + pent = pmove.physents + pmove.numphysent; + + for (j=0, pplayer = predicted_players; j < MAX_CLIENTS; j++, pplayer++) { + + if (!pplayer->active) + continue; // not present this frame + + // the player object never gets added + if (j == playernum) + continue; + + if (pplayer->flags & PF_DEAD) + continue; // dead players aren't solid + + pent->model = 0; + VectorCopy(pplayer->origin, pent->origin); + VectorCopy(player_mins, pent->mins); + VectorCopy(player_maxs, pent->maxs); + pmove.numphysent++; + pent++; + } +} + + +/* +=============== +CL_EmitEntities + +Builds the visedicts array for cl.time + +Made up of: clients, packet_entities, nails, and tents +=============== +*/ +void CL_EmitEntities (void) +{ + if (cls.state != ca_active) + return; + if (!cl.validsequence) + return; + + cl_oldnumvisedicts = cl_numvisedicts; + cl_oldvisedicts = cl_visedicts_list[(cls.netchan.incoming_sequence-1)&1]; + cl_visedicts = cl_visedicts_list[cls.netchan.incoming_sequence&1]; + + cl_numvisedicts = 0; + + CL_LinkPlayers (); + CL_LinkPacketEntities (); + CL_LinkProjectiles (); + CL_UpdateTEnts (); +} + diff --git a/QW/client/cl_input.c b/QW/client/cl_input.c new file mode 100644 index 0000000..bfff293 --- /dev/null +++ b/QW/client/cl_input.c @@ -0,0 +1,533 @@ +/* +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. + +*/ +// cl.input.c -- builds an intended movement command to send to the server + +#include "quakedef.h" + +cvar_t cl_nodelta = {"cl_nodelta","0"}; + +/* +=============================================================================== + +KEY BUTTONS + +Continuous button event tracking is complicated by the fact that two different +input sources (say, mouse button 1 and the control key) can both press the +same button, but the button should only be released when both of the +pressing key have been released. + +When a key event issues a button command (+forward, +attack, etc), it appends +its key number as a parameter to the command so it can be matched up with +the release. + +state bit 0 is the current state of the key +state bit 1 is edge triggered on the up to down transition +state bit 2 is edge triggered on the down to up transition + +=============================================================================== +*/ + + +kbutton_t in_mlook, in_klook; +kbutton_t in_left, in_right, in_forward, in_back; +kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright; +kbutton_t in_strafe, in_speed, in_use, in_jump, in_attack; +kbutton_t in_up, in_down; + +int in_impulse; + + +void KeyDown (kbutton_t *b) +{ + int k; + char *c; + + c = Cmd_Argv(1); + if (c[0]) + k = atoi(c); + else + k = -1; // typed manually at the console for continuous down + + if (k == b->down[0] || k == b->down[1]) + return; // repeating key + + if (!b->down[0]) + b->down[0] = k; + else if (!b->down[1]) + b->down[1] = k; + else + { + Con_Printf ("Three keys down for a button!\n"); + return; + } + + if (b->state & 1) + return; // still down + b->state |= 1 + 2; // down + impulse down +} + +void KeyUp (kbutton_t *b) +{ + int k; + char *c; + + c = Cmd_Argv(1); + if (c[0]) + k = atoi(c); + else + { // typed manually at the console, assume for unsticking, so clear all + b->down[0] = b->down[1] = 0; + b->state = 4; // impulse up + return; + } + + if (b->down[0] == k) + b->down[0] = 0; + else if (b->down[1] == k) + b->down[1] = 0; + else + return; // key up without coresponding down (menu pass through) + if (b->down[0] || b->down[1]) + return; // some other key is still holding it down + + if (!(b->state & 1)) + return; // still up (this should not happen) + b->state &= ~1; // now up + b->state |= 4; // impulse up +} + +void IN_KLookDown (void) {KeyDown(&in_klook);} +void IN_KLookUp (void) {KeyUp(&in_klook);} +void IN_MLookDown (void) {KeyDown(&in_mlook);} +void IN_MLookUp (void) { +KeyUp(&in_mlook); +if ( !(in_mlook.state&1) && lookspring.value) + V_StartPitchDrift(); +} +void IN_UpDown(void) {KeyDown(&in_up);} +void IN_UpUp(void) {KeyUp(&in_up);} +void IN_DownDown(void) {KeyDown(&in_down);} +void IN_DownUp(void) {KeyUp(&in_down);} +void IN_LeftDown(void) {KeyDown(&in_left);} +void IN_LeftUp(void) {KeyUp(&in_left);} +void IN_RightDown(void) {KeyDown(&in_right);} +void IN_RightUp(void) {KeyUp(&in_right);} +void IN_ForwardDown(void) {KeyDown(&in_forward);} +void IN_ForwardUp(void) {KeyUp(&in_forward);} +void IN_BackDown(void) {KeyDown(&in_back);} +void IN_BackUp(void) {KeyUp(&in_back);} +void IN_LookupDown(void) {KeyDown(&in_lookup);} +void IN_LookupUp(void) {KeyUp(&in_lookup);} +void IN_LookdownDown(void) {KeyDown(&in_lookdown);} +void IN_LookdownUp(void) {KeyUp(&in_lookdown);} +void IN_MoveleftDown(void) {KeyDown(&in_moveleft);} +void IN_MoveleftUp(void) {KeyUp(&in_moveleft);} +void IN_MoverightDown(void) {KeyDown(&in_moveright);} +void IN_MoverightUp(void) {KeyUp(&in_moveright);} + +void IN_SpeedDown(void) {KeyDown(&in_speed);} +void IN_SpeedUp(void) {KeyUp(&in_speed);} +void IN_StrafeDown(void) {KeyDown(&in_strafe);} +void IN_StrafeUp(void) {KeyUp(&in_strafe);} + +void IN_AttackDown(void) {KeyDown(&in_attack);} +void IN_AttackUp(void) {KeyUp(&in_attack);} + +void IN_UseDown (void) {KeyDown(&in_use);} +void IN_UseUp (void) {KeyUp(&in_use);} +void IN_JumpDown (void) {KeyDown(&in_jump);} +void IN_JumpUp (void) {KeyUp(&in_jump);} + +void IN_Impulse (void) {in_impulse=Q_atoi(Cmd_Argv(1));} + +/* +=============== +CL_KeyState + +Returns 0.25 if a key was pressed and released during the frame, +0.5 if it was pressed and held +0 if held then released, and +1.0 if held for the entire time +=============== +*/ +float CL_KeyState (kbutton_t *key) +{ + float val; + qboolean impulsedown, impulseup, down; + + impulsedown = key->state & 2; + impulseup = key->state & 4; + down = key->state & 1; + val = 0; + + if (impulsedown && !impulseup) + if (down) + val = 0.5; // pressed and held this frame + else + val = 0; // I_Error (); + if (impulseup && !impulsedown) + if (down) + val = 0; // I_Error (); + else + val = 0; // released this frame + if (!impulsedown && !impulseup) + if (down) + val = 1.0; // held the entire frame + else + val = 0; // up the entire frame + if (impulsedown && impulseup) + if (down) + val = 0.75; // released and re-pressed this frame + else + val = 0.25; // pressed and released this frame + + key->state &= 1; // clear impulses + + return val; +} + + + + +//========================================================================== + +cvar_t cl_upspeed = {"cl_upspeed","200"}; +cvar_t cl_forwardspeed = {"cl_forwardspeed","200", true}; +cvar_t cl_backspeed = {"cl_backspeed","200", true}; +cvar_t cl_sidespeed = {"cl_sidespeed","350"}; + +cvar_t cl_movespeedkey = {"cl_movespeedkey","2.0"}; + +cvar_t cl_yawspeed = {"cl_yawspeed","140"}; +cvar_t cl_pitchspeed = {"cl_pitchspeed","150"}; + +cvar_t cl_anglespeedkey = {"cl_anglespeedkey","1.5"}; + + +/* +================ +CL_AdjustAngles + +Moves the local angle positions +================ +*/ +void CL_AdjustAngles (void) +{ + float speed; + float up, down; + + if (in_speed.state & 1) + speed = host_frametime * cl_anglespeedkey.value; + else + speed = host_frametime; + + if (!(in_strafe.state & 1)) + { + cl.viewangles[YAW] -= speed*cl_yawspeed.value*CL_KeyState (&in_right); + cl.viewangles[YAW] += speed*cl_yawspeed.value*CL_KeyState (&in_left); + cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]); + } + if (in_klook.state & 1) + { + V_StopPitchDrift (); + cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * CL_KeyState (&in_forward); + cl.viewangles[PITCH] += speed*cl_pitchspeed.value * CL_KeyState (&in_back); + } + + up = CL_KeyState (&in_lookup); + down = CL_KeyState(&in_lookdown); + + cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * up; + cl.viewangles[PITCH] += speed*cl_pitchspeed.value * down; + + if (up || down) + V_StopPitchDrift (); + + if (cl.viewangles[PITCH] > 80) + cl.viewangles[PITCH] = 80; + if (cl.viewangles[PITCH] < -70) + cl.viewangles[PITCH] = -70; + + if (cl.viewangles[ROLL] > 50) + cl.viewangles[ROLL] = 50; + if (cl.viewangles[ROLL] < -50) + cl.viewangles[ROLL] = -50; + +} + +/* +================ +CL_BaseMove + +Send the intended movement message to the server +================ +*/ +void CL_BaseMove (usercmd_t *cmd) +{ + CL_AdjustAngles (); + + memset (cmd, 0, sizeof(*cmd)); + + VectorCopy (cl.viewangles, cmd->angles); + if (in_strafe.state & 1) + { + cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_right); + cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_left); + } + + cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_moveright); + cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_moveleft); + + cmd->upmove += cl_upspeed.value * CL_KeyState (&in_up); + cmd->upmove -= cl_upspeed.value * CL_KeyState (&in_down); + + if (! (in_klook.state & 1) ) + { + cmd->forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward); + cmd->forwardmove -= cl_backspeed.value * CL_KeyState (&in_back); + } + +// +// adjust for speed key +// + if (in_speed.state & 1) + { + cmd->forwardmove *= cl_movespeedkey.value; + cmd->sidemove *= cl_movespeedkey.value; + cmd->upmove *= cl_movespeedkey.value; + } +} + +int MakeChar (int i) +{ + i &= ~3; + if (i < -127*4) + i = -127*4; + if (i > 127*4) + i = 127*4; + return i; +} + +/* +============== +CL_FinishMove +============== +*/ +void CL_FinishMove (usercmd_t *cmd) +{ + int i; + int ms; + +// +// allways dump the first two message, because it may contain leftover inputs +// from the last level +// + if (++cl.movemessages <= 2) + return; +// +// figure button bits +// + if ( in_attack.state & 3 ) + cmd->buttons |= 1; + in_attack.state &= ~2; + + if (in_jump.state & 3) + cmd->buttons |= 2; + in_jump.state &= ~2; + + // send milliseconds of time to apply the move + ms = host_frametime * 1000; + if (ms > 250) + ms = 100; // time was unreasonable + cmd->msec = ms; + + VectorCopy (cl.viewangles, cmd->angles); + + cmd->impulse = in_impulse; + in_impulse = 0; + + +// +// chop down so no extra bits are kept that the server wouldn't get +// + cmd->forwardmove = MakeChar (cmd->forwardmove); + cmd->sidemove = MakeChar (cmd->sidemove); + cmd->upmove = MakeChar (cmd->upmove); + + for (i=0 ; i<3 ; i++) + cmd->angles[i] = ((int)(cmd->angles[i]*65536.0/360)&65535) * (360.0/65536.0); +} + +/* +================= +CL_SendCmd +================= +*/ +void CL_SendCmd (void) +{ + sizebuf_t buf; + byte data[128]; + int i; + usercmd_t *cmd, *oldcmd; + int checksumIndex; + int lost; + int seq_hash; + + if (cls.demoplayback) + return; // sendcmds come from the demo + + // save this command off for prediction + i = cls.netchan.outgoing_sequence & UPDATE_MASK; + cmd = &cl.frames[i].cmd; + cl.frames[i].senttime = realtime; + cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet + +// seq_hash = (cls.netchan.outgoing_sequence & 0xffff) ; // ^ QW_CHECK_HASH; + seq_hash = cls.netchan.outgoing_sequence; + + // get basic movement from keyboard + CL_BaseMove (cmd); + + // allow mice or other external controllers to add to the move + IN_Move (cmd); + + // if we are spectator, try autocam + if (cl.spectator) + Cam_Track(cmd); + + CL_FinishMove(cmd); + + Cam_FinishMove(cmd); + +// send this and the previous cmds in the message, so +// if the last packet was dropped, it can be recovered + buf.maxsize = 128; + buf.cursize = 0; + buf.data = data; + + MSG_WriteByte (&buf, clc_move); + + // save the position for a checksum byte + checksumIndex = buf.cursize; + MSG_WriteByte (&buf, 0); + + // write our lossage percentage + lost = CL_CalcNet(); + MSG_WriteByte (&buf, (byte)lost); + + i = (cls.netchan.outgoing_sequence-2) & UPDATE_MASK; + cmd = &cl.frames[i].cmd; + MSG_WriteDeltaUsercmd (&buf, &nullcmd, cmd); + oldcmd = cmd; + + i = (cls.netchan.outgoing_sequence-1) & UPDATE_MASK; + cmd = &cl.frames[i].cmd; + MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd); + oldcmd = cmd; + + i = (cls.netchan.outgoing_sequence) & UPDATE_MASK; + cmd = &cl.frames[i].cmd; + MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd); + + // calculate a checksum over the move commands + buf.data[checksumIndex] = COM_BlockSequenceCRCByte( + buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1, + seq_hash); + + // request delta compression of entities + if (cls.netchan.outgoing_sequence - cl.validsequence >= UPDATE_BACKUP-1) + cl.validsequence = 0; + + if (cl.validsequence && !cl_nodelta.value && cls.state == ca_active && + !cls.demorecording) + { + cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = cl.validsequence; + MSG_WriteByte (&buf, clc_delta); + MSG_WriteByte (&buf, cl.validsequence&255); + } + else + cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = -1; + + if (cls.demorecording) + CL_WriteDemoCmd(cmd); + +// +// deliver the message +// + Netchan_Transmit (&cls.netchan, buf.cursize, buf.data); +} + + + +/* +============ +CL_InitInput +============ +*/ +void CL_InitInput (void) +{ + Cmd_AddCommand ("+moveup",IN_UpDown); + Cmd_AddCommand ("-moveup",IN_UpUp); + Cmd_AddCommand ("+movedown",IN_DownDown); + Cmd_AddCommand ("-movedown",IN_DownUp); + Cmd_AddCommand ("+left",IN_LeftDown); + Cmd_AddCommand ("-left",IN_LeftUp); + Cmd_AddCommand ("+right",IN_RightDown); + Cmd_AddCommand ("-right",IN_RightUp); + Cmd_AddCommand ("+forward",IN_ForwardDown); + Cmd_AddCommand ("-forward",IN_ForwardUp); + Cmd_AddCommand ("+back",IN_BackDown); + Cmd_AddCommand ("-back",IN_BackUp); + Cmd_AddCommand ("+lookup", IN_LookupDown); + Cmd_AddCommand ("-lookup", IN_LookupUp); + Cmd_AddCommand ("+lookdown", IN_LookdownDown); + Cmd_AddCommand ("-lookdown", IN_LookdownUp); + Cmd_AddCommand ("+strafe", IN_StrafeDown); + Cmd_AddCommand ("-strafe", IN_StrafeUp); + Cmd_AddCommand ("+moveleft", IN_MoveleftDown); + Cmd_AddCommand ("-moveleft", IN_MoveleftUp); + Cmd_AddCommand ("+moveright", IN_MoverightDown); + Cmd_AddCommand ("-moveright", IN_MoverightUp); + Cmd_AddCommand ("+speed", IN_SpeedDown); + Cmd_AddCommand ("-speed", IN_SpeedUp); + Cmd_AddCommand ("+attack", IN_AttackDown); + Cmd_AddCommand ("-attack", IN_AttackUp); + Cmd_AddCommand ("+use", IN_UseDown); + Cmd_AddCommand ("-use", IN_UseUp); + Cmd_AddCommand ("+jump", IN_JumpDown); + Cmd_AddCommand ("-jump", IN_JumpUp); + Cmd_AddCommand ("impulse", IN_Impulse); + Cmd_AddCommand ("+klook", IN_KLookDown); + Cmd_AddCommand ("-klook", IN_KLookUp); + Cmd_AddCommand ("+mlook", IN_MLookDown); + Cmd_AddCommand ("-mlook", IN_MLookUp); + + Cvar_RegisterVariable (&cl_nodelta); +} + +/* +============ +CL_ClearStates +============ +*/ +void CL_ClearStates (void) +{ +} + diff --git a/QW/client/cl_main.c b/QW/client/cl_main.c new file mode 100644 index 0000000..dfe7653 --- /dev/null +++ b/QW/client/cl_main.c @@ -0,0 +1,1535 @@ +/* +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. + +*/ +// cl_main.c -- client main loop + +#include "quakedef.h" +#include "winquake.h" +#ifdef _WIN32 +#include "winsock.h" +#else +#include <netinet/in.h> +#endif + + +// we need to declare some mouse variables here, because the menu system +// references them even when on a unix system. + +qboolean noclip_anglehack; // remnant from old quake + + +cvar_t rcon_password = {"rcon_password", "", false}; + +cvar_t rcon_address = {"rcon_address", ""}; + +cvar_t cl_timeout = {"cl_timeout", "60"}; + +cvar_t cl_shownet = {"cl_shownet","0"}; // can be 0, 1, or 2 + +cvar_t cl_sbar = {"cl_sbar", "0", true}; +cvar_t cl_hudswap = {"cl_hudswap", "0", true}; +cvar_t cl_maxfps = {"cl_maxfps", "0", true}; + +cvar_t lookspring = {"lookspring","0", true}; +cvar_t lookstrafe = {"lookstrafe","0", true}; +cvar_t sensitivity = {"sensitivity","3", true}; + +cvar_t m_pitch = {"m_pitch","0.022", true}; +cvar_t m_yaw = {"m_yaw","0.022"}; +cvar_t m_forward = {"m_forward","1"}; +cvar_t m_side = {"m_side","0.8"}; + +cvar_t entlatency = {"entlatency", "20"}; +cvar_t cl_predict_players = {"cl_predict_players", "1"}; +cvar_t cl_predict_players2 = {"cl_predict_players2", "1"}; +cvar_t cl_solid_players = {"cl_solid_players", "1"}; + +cvar_t localid = {"localid", ""}; + +static qboolean allowremotecmd = true; + +// +// info mirrors +// +cvar_t password = {"password", "", false, true}; +cvar_t spectator = {"spectator", "", false, true}; +cvar_t name = {"name","unnamed", true, true}; +cvar_t team = {"team","", true, true}; +cvar_t skin = {"skin","", true, true}; +cvar_t topcolor = {"topcolor","0", true, true}; +cvar_t bottomcolor = {"bottomcolor","0", true, true}; +cvar_t rate = {"rate","2500", true, true}; +cvar_t noaim = {"noaim","0", true, true}; +cvar_t msg = {"msg","1", true, true}; + +extern cvar_t cl_hightrack; + + +client_static_t cls; +client_state_t cl; + +entity_state_t cl_baselines[MAX_EDICTS]; +efrag_t cl_efrags[MAX_EFRAGS]; +entity_t cl_static_entities[MAX_STATIC_ENTITIES]; +lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; +dlight_t cl_dlights[MAX_DLIGHTS]; + +// refresh list +// this is double buffered so the last frame +// can be scanned for oldorigins of trailing objects +int cl_numvisedicts, cl_oldnumvisedicts; +entity_t *cl_visedicts, *cl_oldvisedicts; +entity_t cl_visedicts_list[2][MAX_VISEDICTS]; + +double connect_time = -1; // for connection retransmits + +quakeparms_t host_parms; + +qboolean host_initialized; // true if into command execution +qboolean nomaster; + +double host_frametime; +double realtime; // without any filtering or bounding +double oldrealtime; // last frame run +int host_framecount; + +int host_hunklevel; + +byte *host_basepal; +byte *host_colormap; + +netadr_t master_adr; // address of the master server + +cvar_t host_speeds = {"host_speeds","0"}; // set for running times +cvar_t show_fps = {"show_fps","0"}; // set for running times +cvar_t developer = {"developer","0"}; + +int fps_count; + +jmp_buf host_abort; + +void Master_Connect_f (void); + +float server_version = 0; // version of server we connected to + +char emodel_name[] = + { 'e' ^ 0xff, 'm' ^ 0xff, 'o' ^ 0xff, 'd' ^ 0xff, 'e' ^ 0xff, 'l' ^ 0xff, 0 }; +char pmodel_name[] = + { 'p' ^ 0xff, 'm' ^ 0xff, 'o' ^ 0xff, 'd' ^ 0xff, 'e' ^ 0xff, 'l' ^ 0xff, 0 }; +char prespawn_name[] = + { 'p'^0xff, 'r'^0xff, 'e'^0xff, 's'^0xff, 'p'^0xff, 'a'^0xff, 'w'^0xff, 'n'^0xff, + ' '^0xff, '%'^0xff, 'i'^0xff, ' '^0xff, '0'^0xff, ' '^0xff, '%'^0xff, 'i'^0xff, 0 }; +char modellist_name[] = + { 'm'^0xff, 'o'^0xff, 'd'^0xff, 'e'^0xff, 'l'^0xff, 'l'^0xff, 'i'^0xff, 's'^0xff, 't'^0xff, + ' '^0xff, '%'^0xff, 'i'^0xff, ' '^0xff, '%'^0xff, 'i'^0xff, 0 }; +char soundlist_name[] = + { 's'^0xff, 'o'^0xff, 'u'^0xff, 'n'^0xff, 'd'^0xff, 'l'^0xff, 'i'^0xff, 's'^0xff, 't'^0xff, + ' '^0xff, '%'^0xff, 'i'^0xff, ' '^0xff, '%'^0xff, 'i'^0xff, 0 }; + +/* +================== +CL_Quit_f +================== +*/ +void CL_Quit_f (void) +{ + if (1 /* key_dest != key_console */ /* && cls.state != ca_dedicated */) + { + M_Menu_Quit_f (); + return; + } + CL_Disconnect (); + Sys_Quit (); +} + +/* +======================= +CL_Version_f +====================== +*/ +void CL_Version_f (void) +{ + Con_Printf ("Version %4.2f\n", VERSION); + Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); +} + + +/* +======================= +CL_SendConnectPacket + +called by CL_Connect_f and CL_CheckResend +====================== +*/ +void CL_SendConnectPacket (void) +{ + netadr_t adr; + char data[2048]; + double t1, t2; +// JACK: Fixed bug where DNS lookups would cause two connects real fast +// Now, adds lookup time to the connect time. +// Should I add it to realtime instead?!?! + + if (cls.state != ca_disconnected) + return; + + t1 = Sys_DoubleTime (); + + if (!NET_StringToAdr (cls.servername, &adr)) + { + Con_Printf ("Bad server address\n"); + connect_time = -1; + return; + } + + if (!NET_IsClientLegal(&adr)) + { + Con_Printf ("Illegal server address\n"); + connect_time = -1; + return; + } + + if (adr.port == 0) + adr.port = BigShort (27500); + t2 = Sys_DoubleTime (); + + connect_time = realtime+t2-t1; // for retransmit requests + + cls.qport = Cvar_VariableValue("qport"); + + Info_SetValueForStarKey (cls.userinfo, "*ip", NET_AdrToString(adr), MAX_INFO_STRING); + +// Con_Printf ("Connecting to %s...\n", cls.servername); + sprintf (data, "%c%c%c%cconnect %i %i %i \"%s\"\n", + 255, 255, 255, 255, PROTOCOL_VERSION, cls.qport, cls.challenge, cls.userinfo); + NET_SendPacket (strlen(data), data, adr); +} + +/* +================= +CL_CheckForResend + +Resend a connect message if the last one has timed out + +================= +*/ +void CL_CheckForResend (void) +{ + netadr_t adr; + char data[2048]; + double t1, t2; + + if (connect_time == -1) + return; + if (cls.state != ca_disconnected) + return; + if (connect_time && realtime - connect_time < 5.0) + return; + + t1 = Sys_DoubleTime (); + if (!NET_StringToAdr (cls.servername, &adr)) + { + Con_Printf ("Bad server address\n"); + connect_time = -1; + return; + } + if (!NET_IsClientLegal(&adr)) + { + Con_Printf ("Illegal server address\n"); + connect_time = -1; + return; + } + + if (adr.port == 0) + adr.port = BigShort (27500); + t2 = Sys_DoubleTime (); + + connect_time = realtime+t2-t1; // for retransmit requests + + Con_Printf ("Connecting to %s...\n", cls.servername); + sprintf (data, "%c%c%c%cgetchallenge\n", 255, 255, 255, 255); + NET_SendPacket (strlen(data), data, adr); +} + +void CL_BeginServerConnect(void) +{ + connect_time = 0; + CL_CheckForResend(); +} + +/* +================ +CL_Connect_f + +================ +*/ +void CL_Connect_f (void) +{ + char *server; + + if (Cmd_Argc() != 2) + { + Con_Printf ("usage: connect <server>\n"); + return; + } + + server = Cmd_Argv (1); + + CL_Disconnect (); + + strncpy (cls.servername, server, sizeof(cls.servername)-1); + CL_BeginServerConnect(); +} + + +/* +===================== +CL_Rcon_f + + Send the rest of the command line over as + an unconnected command. +===================== +*/ +void CL_Rcon_f (void) +{ + char message[1024]; + int i; + netadr_t to; + + if (!rcon_password.string) + { + Con_Printf ("You must set 'rcon_password' before\n" + "issuing an rcon command.\n"); + return; + } + + message[0] = 255; + message[1] = 255; + message[2] = 255; + message[3] = 255; + message[4] = 0; + + strcat (message, "rcon "); + + strcat (message, rcon_password.string); + strcat (message, " "); + + for (i=1 ; i<Cmd_Argc() ; i++) + { + strcat (message, Cmd_Argv(i)); + strcat (message, " "); + } + + if (cls.state >= ca_connected) + to = cls.netchan.remote_address; + else + { + if (!strlen(rcon_address.string)) + { + Con_Printf ("You must either be connected,\n" + "or set the 'rcon_address' cvar\n" + "to issue rcon commands\n"); + + return; + } + NET_StringToAdr (rcon_address.string, &to); + } + + NET_SendPacket (strlen(message)+1, message + , to); +} + + +/* +===================== +CL_ClearState + +===================== +*/ +void CL_ClearState (void) +{ + int i; + + S_StopAllSounds (true); + + Con_DPrintf ("Clearing memory\n"); + D_FlushCaches (); + Mod_ClearAll (); + if (host_hunklevel) // FIXME: check this... + Hunk_FreeToLowMark (host_hunklevel); + + CL_ClearTEnts (); + +// wipe the entire cl structure + memset (&cl, 0, sizeof(cl)); + + SZ_Clear (&cls.netchan.message); + +// clear other arrays + memset (cl_efrags, 0, sizeof(cl_efrags)); + memset (cl_dlights, 0, sizeof(cl_dlights)); + memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); + +// +// allocate the efrags and chain together into a free list +// + cl.free_efrags = cl_efrags; + for (i=0 ; i<MAX_EFRAGS-1 ; i++) + cl.free_efrags[i].entnext = &cl.free_efrags[i+1]; + cl.free_efrags[i].entnext = NULL; +} + +/* +===================== +CL_Disconnect + +Sends a disconnect message to the server +This is also called on Host_Error, so it shouldn't cause any errors +===================== +*/ +void CL_Disconnect (void) +{ + byte final[10]; + + connect_time = -1; + +#ifdef _WIN32 + SetWindowText (mainwindow, "QuakeWorld: disconnected"); +#endif + +// stop sounds (especially looping!) + S_StopAllSounds (true); + +// if running a local server, shut it down + if (cls.demoplayback) + CL_StopPlayback (); + else if (cls.state != ca_disconnected) + { + if (cls.demorecording) + CL_Stop_f (); + + final[0] = clc_stringcmd; + strcpy (final+1, "drop"); + Netchan_Transmit (&cls.netchan, 6, final); + Netchan_Transmit (&cls.netchan, 6, final); + Netchan_Transmit (&cls.netchan, 6, final); + + cls.state = ca_disconnected; + + cls.demoplayback = cls.demorecording = cls.timedemo = false; + } + Cam_Reset(); + + if (cls.download) { + fclose(cls.download); + cls.download = NULL; + } + + CL_StopUpload(); + +} + +void CL_Disconnect_f (void) +{ + CL_Disconnect (); +} + +/* +==================== +CL_User_f + +user <name or userid> + +Dump userdata / masterdata for a user +==================== +*/ +void CL_User_f (void) +{ + int uid; + int i; + + if (Cmd_Argc() != 2) + { + Con_Printf ("Usage: user <username / userid>\n"); + return; + } + + uid = atoi(Cmd_Argv(1)); + + for (i=0 ; i<MAX_CLIENTS ; i++) + { + if (!cl.players[i].name[0]) + continue; + if (cl.players[i].userid == uid + || !strcmp(cl.players[i].name, Cmd_Argv(1)) ) + { + Info_Print (cl.players[i].userinfo); + return; + } + } + Con_Printf ("User not in server.\n"); +} + +/* +==================== +CL_Users_f + +Dump userids for all current players +==================== +*/ +void CL_Users_f (void) +{ + int i; + int c; + + c = 0; + Con_Printf ("userid frags name\n"); + Con_Printf ("------ ----- ----\n"); + for (i=0 ; i<MAX_CLIENTS ; i++) + { + if (cl.players[i].name[0]) + { + Con_Printf ("%6i %4i %s\n", cl.players[i].userid, cl.players[i].frags, cl.players[i].name); + c++; + } + } + + Con_Printf ("%i total users\n", c); +} + +void CL_Color_f (void) +{ + // just for quake compatability... + int top, bottom; + char num[16]; + + if (Cmd_Argc() == 1) + { + Con_Printf ("\"color\" is \"%s %s\"\n", + Info_ValueForKey (cls.userinfo, "topcolor"), + Info_ValueForKey (cls.userinfo, "bottomcolor") ); + Con_Printf ("color <0-13> [0-13]\n"); + return; + } + + if (Cmd_Argc() == 2) + top = bottom = atoi(Cmd_Argv(1)); + else + { + top = atoi(Cmd_Argv(1)); + bottom = atoi(Cmd_Argv(2)); + } + + top &= 15; + if (top > 13) + top = 13; + bottom &= 15; + if (bottom > 13) + bottom = 13; + + sprintf (num, "%i", top); + Cvar_Set ("topcolor", num); + sprintf (num, "%i", bottom); + Cvar_Set ("bottomcolor", num); +} + +/* +================== +CL_FullServerinfo_f + +Sent by server when serverinfo changes +================== +*/ +void CL_FullServerinfo_f (void) +{ + char *p; + float v; + + if (Cmd_Argc() != 2) + { + Con_Printf ("usage: fullserverinfo <complete info string>\n"); + return; + } + + strcpy (cl.serverinfo, Cmd_Argv(1)); + + if ((p = Info_ValueForKey(cl.serverinfo, "*vesion")) && *p) { + v = Q_atof(p); + if (v) { + if (!server_version) + Con_Printf("Version %1.2f Server\n", v); + server_version = v; + } + } +} + +/* +================== +CL_FullInfo_f + +Allow clients to change userinfo +================== +Casey was here :) +*/ +void CL_FullInfo_f (void) +{ + char key[512]; + char value[512]; + char *o; + char *s; + + if (Cmd_Argc() != 2) + { + Con_Printf ("fullinfo <complete info string>\n"); + return; + } + + s = Cmd_Argv(1); + if (*s == '\\') + s++; + while (*s) + { + o = key; + while (*s && *s != '\\') + *o++ = *s++; + *o = 0; + + if (!*s) + { + Con_Printf ("MISSING VALUE\n"); + return; + } + + o = value; + s++; + while (*s && *s != '\\') + *o++ = *s++; + *o = 0; + + if (*s) + s++; + + if (!stricmp(key, pmodel_name) || !stricmp(key, emodel_name)) + continue; + + Info_SetValueForKey (cls.userinfo, key, value, MAX_INFO_STRING); + } +} + +/* +================== +CL_SetInfo_f + +Allow clients to change userinfo +================== +*/ +void CL_SetInfo_f (void) +{ + if (Cmd_Argc() == 1) + { + Info_Print (cls.userinfo); + return; + } + if (Cmd_Argc() != 3) + { + Con_Printf ("usage: setinfo [ <key> <value> ]\n"); + return; + } + if (!stricmp(Cmd_Argv(1), pmodel_name) || !strcmp(Cmd_Argv(1), emodel_name)) + return; + + Info_SetValueForKey (cls.userinfo, Cmd_Argv(1), Cmd_Argv(2), MAX_INFO_STRING); + if (cls.state >= ca_connected) + Cmd_ForwardToServer (); +} + +/* +==================== +CL_Packet_f + +packet <destination> <contents> + +Contents allows \n escape character +==================== +*/ +void CL_Packet_f (void) +{ + char send[2048]; + int i, l; + char *in, *out; + netadr_t adr; + + if (Cmd_Argc() != 3) + { + Con_Printf ("packet <destination> <contents>\n"); + return; + } + + if (!NET_StringToAdr (Cmd_Argv(1), &adr)) + { + Con_Printf ("Bad address\n"); + return; + } + + in = Cmd_Argv(2); + out = send+4; + send[0] = send[1] = send[2] = send[3] = 0xff; + + l = strlen (in); + for (i=0 ; i<l ; i++) + { + if (in[i] == '\\' && in[i+1] == 'n') + { + *out++ = '\n'; + i++; + } + else + *out++ = in[i]; + } + *out = 0; + + NET_SendPacket (out-send, send, adr); +} + + +/* +===================== +CL_NextDemo + +Called to play the next demo in the demo loop +===================== +*/ +void CL_NextDemo (void) +{ + char str[1024]; + + if (cls.demonum == -1) + return; // don't play demos + + if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS) + { + cls.demonum = 0; + if (!cls.demos[cls.demonum][0]) + { +// Con_Printf ("No demos listed with startdemos\n"); + cls.demonum = -1; + return; + } + } + + sprintf (str,"playdemo %s\n", cls.demos[cls.demonum]); + Cbuf_InsertText (str); + cls.demonum++; +} + + +/* +================= +CL_Changing_f + +Just sent as a hint to the client that they should +drop to full console +================= +*/ +void CL_Changing_f (void) +{ + if (cls.download) // don't change when downloading + return; + + S_StopAllSounds (true); + cl.intermission = 0; + cls.state = ca_connected; // not active anymore, but not disconnected + Con_Printf ("\nChanging map...\n"); +} + + +/* +================= +CL_Reconnect_f + +The server is changing levels +================= +*/ +void CL_Reconnect_f (void) +{ + if (cls.download) // don't change when downloading + return; + + S_StopAllSounds (true); + + if (cls.state == ca_connected) { + Con_Printf ("reconnecting...\n"); + MSG_WriteChar (&cls.netchan.message, clc_stringcmd); + MSG_WriteString (&cls.netchan.message, "new"); + return; + } + + if (!*cls.servername) { + Con_Printf("No server to reconnect to...\n"); + return; + } + + CL_Disconnect(); + CL_BeginServerConnect(); +} + +/* +================= +CL_ConnectionlessPacket + +Responses to broadcasts, etc +================= +*/ +void CL_ConnectionlessPacket (void) +{ + char *s; + int c; + + MSG_BeginReading (); + MSG_ReadLong (); // skip the -1 + + c = MSG_ReadByte (); + if (!cls.demoplayback) + Con_Printf ("%s: ", NET_AdrToString (net_from)); +// Con_DPrintf ("%s", net_message.data + 5); + if (c == S2C_CONNECTION) + { + Con_Printf ("connection\n"); + if (cls.state >= ca_connected) + { + if (!cls.demoplayback) + Con_Printf ("Dup connect received. Ignored.\n"); + return; + } + Netchan_Setup (&cls.netchan, net_from, cls.qport); + MSG_WriteChar (&cls.netchan.message, clc_stringcmd); + MSG_WriteString (&cls.netchan.message, "new"); + cls.state = ca_connected; + Con_Printf ("Connected.\n"); + allowremotecmd = false; // localid required now for remote cmds + return; + } + // remote command from gui front end + if (c == A2C_CLIENT_COMMAND) + { + char cmdtext[2048]; + + Con_Printf ("client command\n"); + + if ((*(unsigned *)net_from.ip != *(unsigned *)net_local_adr.ip + && *(unsigned *)net_from.ip != htonl(INADDR_LOOPBACK)) ) + { + Con_Printf ("Command packet from remote host. Ignored.\n"); + return; + } +#ifdef _WIN32 + ShowWindow (mainwindow, SW_RESTORE); + SetForegroundWindow (mainwindow); +#endif + s = MSG_ReadString (); + + strncpy(cmdtext, s, sizeof(cmdtext) - 1); + cmdtext[sizeof(cmdtext) - 1] = 0; + + s = MSG_ReadString (); + + while (*s && isspace(*s)) + s++; + while (*s && isspace(s[strlen(s) - 1])) + s[strlen(s) - 1] = 0; + + if (!allowremotecmd && (!*localid.string || strcmp(localid.string, s))) { + if (!*localid.string) { + Con_Printf("===========================\n"); + Con_Printf("Command packet received from local host, but no " + "localid has been set. You may need to upgrade your server " + "browser.\n"); + Con_Printf("===========================\n"); + return; + } + Con_Printf("===========================\n"); + Con_Printf("Invalid localid on command packet received from local host. " + "\n|%s| != |%s|\n" + "You may need to reload your server browser and QuakeWorld.\n", + s, localid.string); + Con_Printf("===========================\n"); + Cvar_Set("localid", ""); + return; + } + + Cbuf_AddText (cmdtext); + allowremotecmd = false; + return; + } + // print command from somewhere + if (c == A2C_PRINT) + { + Con_Printf ("print\n"); + + s = MSG_ReadString (); + Con_Print (s); + return; + } + + // ping from somewhere + if (c == A2A_PING) + { + char data[6]; + + Con_Printf ("ping\n"); + + data[0] = 0xff; + data[1] = 0xff; + data[2] = 0xff; + data[3] = 0xff; + data[4] = A2A_ACK; + data[5] = 0; + + NET_SendPacket (6, &data, net_from); + return; + } + + if (c == S2C_CHALLENGE) { + Con_Printf ("challenge\n"); + + s = MSG_ReadString (); + cls.challenge = atoi(s); + CL_SendConnectPacket (); + return; + } + +#if 0 + if (c == svc_disconnect) { + Con_Printf ("disconnect\n"); + + Host_EndGame ("Server disconnected"); + return; + } +#endif + + Con_Printf ("unknown: %c\n", c); +} + + +/* +================= +CL_ReadPackets +================= +*/ +void CL_ReadPackets (void) +{ +// while (NET_GetPacket ()) + while (CL_GetMessage()) + { + // + // remote command packet + // + if (*(int *)net_message.data == -1) + { + CL_ConnectionlessPacket (); + continue; + } + + if (net_message.cursize < 8) + { + Con_Printf ("%s: Runt packet\n",NET_AdrToString(net_from)); + continue; + } + + // + // packet from server + // + if (!cls.demoplayback && + !NET_CompareAdr (net_from, cls.netchan.remote_address)) + { + Con_DPrintf ("%s:sequenced packet without connection\n" + ,NET_AdrToString(net_from)); + continue; + } + if (!Netchan_Process(&cls.netchan)) + continue; // wasn't accepted for some reason + CL_ParseServerMessage (); + +// if (cls.demoplayback && cls.state >= ca_active && !CL_DemoBehind()) +// return; + } + + // + // check timeout + // + if (cls.state >= ca_connected + && realtime - cls.netchan.last_received > cl_timeout.value) + { + Con_Printf ("\nServer connection timed out.\n"); + CL_Disconnect (); + return; + } + +} + +//============================================================================= + +/* +===================== +CL_Download_f +===================== +*/ +void CL_Download_f (void) +{ + char *p, *q; + + if (cls.state == ca_disconnected) + { + Con_Printf ("Must be connected.\n"); + return; + } + + if (Cmd_Argc() != 2) + { + Con_Printf ("Usage: download <datafile>\n"); + return; + } + + sprintf (cls.downloadname, "%s/%s", com_gamedir, Cmd_Argv(1)); + + p = cls.downloadname; + for (;;) { + if ((q = strchr(p, '/')) != NULL) { + *q = 0; + Sys_mkdir(cls.downloadname); + *q = '/'; + p = q + 1; + } else + break; + } + + strcpy(cls.downloadtempname, cls.downloadname); + cls.download = fopen (cls.downloadname, "wb"); + cls.downloadtype = dl_single; + + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + SZ_Print (&cls.netchan.message, va("download %s\n",Cmd_Argv(1))); +} + +#ifdef _WINDOWS +#include <windows.h> +/* +================= +CL_Minimize_f +================= +*/ +void CL_Windows_f (void) { +// if (modestate == MS_WINDOWED) +// ShowWindow(mainwindow, SW_MINIMIZE); +// else + SendMessage(mainwindow, WM_SYSKEYUP, VK_TAB, 1 | (0x0F << 16) | (1<<29)); +} +#endif + +/* +================= +CL_Init +================= +*/ +void CL_Init (void) +{ + extern cvar_t baseskin; + extern cvar_t noskins; + char st[80]; + + cls.state = ca_disconnected; + + Info_SetValueForKey (cls.userinfo, "name", "unnamed", MAX_INFO_STRING); + Info_SetValueForKey (cls.userinfo, "topcolor", "0", MAX_INFO_STRING); + Info_SetValueForKey (cls.userinfo, "bottomcolor", "0", MAX_INFO_STRING); + Info_SetValueForKey (cls.userinfo, "rate", "2500", MAX_INFO_STRING); + Info_SetValueForKey (cls.userinfo, "msg", "1", MAX_INFO_STRING); + sprintf (st, "%4.2f-%04d", VERSION, build_number()); + Info_SetValueForStarKey (cls.userinfo, "*ver", st, MAX_INFO_STRING); + + CL_InitInput (); + CL_InitTEnts (); + CL_InitPrediction (); + CL_InitCam (); + Pmove_Init (); + +// +// register our commands +// + Cvar_RegisterVariable (&show_fps); + Cvar_RegisterVariable (&host_speeds); + Cvar_RegisterVariable (&developer); + + Cvar_RegisterVariable (&cl_warncmd); + Cvar_RegisterVariable (&cl_upspeed); + Cvar_RegisterVariable (&cl_forwardspeed); + Cvar_RegisterVariable (&cl_backspeed); + Cvar_RegisterVariable (&cl_sidespeed); + Cvar_RegisterVariable (&cl_movespeedkey); + Cvar_RegisterVariable (&cl_yawspeed); + Cvar_RegisterVariable (&cl_pitchspeed); + Cvar_RegisterVariable (&cl_anglespeedkey); + Cvar_RegisterVariable (&cl_shownet); + Cvar_RegisterVariable (&cl_sbar); + Cvar_RegisterVariable (&cl_hudswap); + Cvar_RegisterVariable (&cl_maxfps); + Cvar_RegisterVariable (&cl_timeout); + Cvar_RegisterVariable (&lookspring); + Cvar_RegisterVariable (&lookstrafe); + Cvar_RegisterVariable (&sensitivity); + + Cvar_RegisterVariable (&m_pitch); + Cvar_RegisterVariable (&m_yaw); + Cvar_RegisterVariable (&m_forward); + Cvar_RegisterVariable (&m_side); + + Cvar_RegisterVariable (&rcon_password); + Cvar_RegisterVariable (&rcon_address); + + Cvar_RegisterVariable (&entlatency); + Cvar_RegisterVariable (&cl_predict_players2); + Cvar_RegisterVariable (&cl_predict_players); + Cvar_RegisterVariable (&cl_solid_players); + + Cvar_RegisterVariable (&localid); + + Cvar_RegisterVariable (&baseskin); + Cvar_RegisterVariable (&noskins); + + // + // info mirrors + // + Cvar_RegisterVariable (&name); + Cvar_RegisterVariable (&password); + Cvar_RegisterVariable (&spectator); + Cvar_RegisterVariable (&skin); + Cvar_RegisterVariable (&team); + Cvar_RegisterVariable (&topcolor); + Cvar_RegisterVariable (&bottomcolor); + Cvar_RegisterVariable (&rate); + Cvar_RegisterVariable (&msg); + Cvar_RegisterVariable (&noaim); + + + Cmd_AddCommand ("version", CL_Version_f); + + Cmd_AddCommand ("changing", CL_Changing_f); + Cmd_AddCommand ("disconnect", CL_Disconnect_f); + Cmd_AddCommand ("record", CL_Record_f); + Cmd_AddCommand ("rerecord", CL_ReRecord_f); + Cmd_AddCommand ("stop", CL_Stop_f); + Cmd_AddCommand ("playdemo", CL_PlayDemo_f); + Cmd_AddCommand ("timedemo", CL_TimeDemo_f); + + Cmd_AddCommand ("skins", Skin_Skins_f); + Cmd_AddCommand ("allskins", Skin_AllSkins_f); + + Cmd_AddCommand ("quit", CL_Quit_f); + + Cmd_AddCommand ("connect", CL_Connect_f); + Cmd_AddCommand ("reconnect", CL_Reconnect_f); + + Cmd_AddCommand ("rcon", CL_Rcon_f); + Cmd_AddCommand ("packet", CL_Packet_f); + Cmd_AddCommand ("user", CL_User_f); + Cmd_AddCommand ("users", CL_Users_f); + + Cmd_AddCommand ("setinfo", CL_SetInfo_f); + Cmd_AddCommand ("fullinfo", CL_FullInfo_f); + Cmd_AddCommand ("fullserverinfo", CL_FullServerinfo_f); + + Cmd_AddCommand ("color", CL_Color_f); + Cmd_AddCommand ("download", CL_Download_f); + + Cmd_AddCommand ("nextul", CL_NextUpload); + Cmd_AddCommand ("stopul", CL_StopUpload); + +// +// forward to server commands +// + Cmd_AddCommand ("kill", NULL); + Cmd_AddCommand ("pause", NULL); + Cmd_AddCommand ("say", NULL); + Cmd_AddCommand ("say_team", NULL); + Cmd_AddCommand ("serverinfo", NULL); + +// +// Windows commands +// +#ifdef _WINDOWS + Cmd_AddCommand ("windows", CL_Windows_f); +#endif +} + + +/* +================ +Host_EndGame + +Call this to drop to a console without exiting the qwcl +================ +*/ +void Host_EndGame (char *message, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,message); + vsprintf (string,message,argptr); + va_end (argptr); + Con_Printf ("\n===========================\n"); + Con_Printf ("Host_EndGame: %s\n",string); + Con_Printf ("===========================\n\n"); + + CL_Disconnect (); + + longjmp (host_abort, 1); +} + +/* +================ +Host_Error + +This shuts down the client and exits qwcl +================ +*/ +void Host_Error (char *error, ...) +{ + va_list argptr; + char string[1024]; + static qboolean inerror = false; + + if (inerror) + Sys_Error ("Host_Error: recursively entered"); + inerror = true; + + va_start (argptr,error); + vsprintf (string,error,argptr); + va_end (argptr); + Con_Printf ("Host_Error: %s\n",string); + + CL_Disconnect (); + cls.demonum = -1; + + inerror = false; + +// FIXME + Sys_Error ("Host_Error: %s\n",string); +} + + +/* +=============== +Host_WriteConfiguration + +Writes key bindings and archived cvars to config.cfg +=============== +*/ +void Host_WriteConfiguration (void) +{ + FILE *f; + + if (host_initialized) + { + f = fopen (va("%s/config.cfg",com_gamedir), "w"); + if (!f) + { + Con_Printf ("Couldn't write config.cfg.\n"); + return; + } + + Key_WriteBindings (f); + Cvar_WriteVariables (f); + + fclose (f); + } +} + + +//============================================================================ + +#if 0 +/* +================== +Host_SimulationTime + +This determines if enough time has passed to run a simulation frame +================== +*/ +qboolean Host_SimulationTime(float time) +{ + float fps; + + if (oldrealtime > realtime) + oldrealtime = 0; + + if (cl_maxfps.value) + fps = max(30.0, min(cl_maxfps.value, 72.0)); + else + fps = max(30.0, min(rate.value/80.0, 72.0)); + + if (!cls.timedemo && (realtime + time) - oldrealtime < 1.0/fps) + return false; // framerate is too high + return true; +} +#endif + + +/* +================== +Host_Frame + +Runs all active servers +================== +*/ +int nopacketcount; +void Host_Frame (float time) +{ + static double time1 = 0; + static double time2 = 0; + static double time3 = 0; + int pass1, pass2, pass3; + float fps; + if (setjmp (host_abort) ) + return; // something bad happened, or the server disconnected + + // decide the simulation time + realtime += time; + if (oldrealtime > realtime) + oldrealtime = 0; + + if (cl_maxfps.value) + fps = max(30.0, min(cl_maxfps.value, 72.0)); + else + fps = max(30.0, min(rate.value/80.0, 72.0)); + + if (!cls.timedemo && realtime - oldrealtime < 1.0/fps) + return; // framerate is too high + + host_frametime = realtime - oldrealtime; + oldrealtime = realtime; + if (host_frametime > 0.2) + host_frametime = 0.2; + + // get new key events + Sys_SendKeyEvents (); + + // allow mice or other external controllers to add commands + IN_Commands (); + + // process console commands + Cbuf_Execute (); + + // fetch results from server + CL_ReadPackets (); + + // send intentions now + // resend a connection request if necessary + if (cls.state == ca_disconnected) { + CL_CheckForResend (); + } else + CL_SendCmd (); + + // Set up prediction for other players + CL_SetUpPlayerPrediction(false); + + // do client side motion prediction + CL_PredictMove (); + + // Set up prediction for other players + CL_SetUpPlayerPrediction(true); + + // build a refresh entity list + CL_EmitEntities (); + + // update video + if (host_speeds.value) + time1 = Sys_DoubleTime (); + + SCR_UpdateScreen (); + + if (host_speeds.value) + time2 = Sys_DoubleTime (); + + // update audio + if (cls.state == ca_active) + { + S_Update (r_origin, vpn, vright, vup); + CL_DecayLights (); + } + else + S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin); + + CDAudio_Update(); + + if (host_speeds.value) + { + pass1 = (time1 - time3)*1000; + time3 = Sys_DoubleTime (); + pass2 = (time2 - time1)*1000; + pass3 = (time3 - time2)*1000; + Con_Printf ("%3i tot %3i server %3i gfx %3i snd\n", + pass1+pass2+pass3, pass1, pass2, pass3); + } + + host_framecount++; + fps_count++; +} + +static void simple_crypt(char *buf, int len) +{ + while (len--) + *buf++ ^= 0xff; +} + +void Host_FixupModelNames(void) +{ + simple_crypt(emodel_name, sizeof(emodel_name) - 1); + simple_crypt(pmodel_name, sizeof(pmodel_name) - 1); + simple_crypt(prespawn_name, sizeof(prespawn_name) - 1); + simple_crypt(modellist_name, sizeof(modellist_name) - 1); + simple_crypt(soundlist_name, sizeof(soundlist_name) - 1); +} + +//============================================================================ + +/* +==================== +Host_Init +==================== +*/ +void Host_Init (quakeparms_t *parms) +{ + COM_InitArgv (parms->argc, parms->argv); + COM_AddParm ("-game"); + COM_AddParm ("qw"); + + Sys_mkdir("qw"); + + if (COM_CheckParm ("-minmemory")) + parms->memsize = MINIMUM_MEMORY; + + host_parms = *parms; + + if (parms->memsize < MINIMUM_MEMORY) + Sys_Error ("Only %4.1f megs of memory reported, can't execute game", parms->memsize / (float)0x100000); + + Memory_Init (parms->membase, parms->memsize); + Cbuf_Init (); + Cmd_Init (); + V_Init (); + + COM_Init (); + + Host_FixupModelNames(); + + NET_Init (PORT_CLIENT); + Netchan_Init (); + + W_LoadWadFile ("gfx.wad"); + Key_Init (); + Con_Init (); + M_Init (); + Mod_Init (); + +// Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); + Con_Printf ("%4.1f megs RAM used.\n",parms->memsize/ (1024*1024.0)); + + R_InitTextures (); + + host_basepal = (byte *)COM_LoadHunkFile ("gfx/palette.lmp"); + if (!host_basepal) + Sys_Error ("Couldn't load gfx/palette.lmp"); + host_colormap = (byte *)COM_LoadHunkFile ("gfx/colormap.lmp"); + if (!host_colormap) + Sys_Error ("Couldn't load gfx/colormap.lmp"); +#ifdef __linux__ + IN_Init (); + CDAudio_Init (); + VID_Init (host_basepal); + Draw_Init (); + SCR_Init (); + R_Init (); + +// S_Init (); // S_Init is now done as part of VID. Sigh. + + cls.state = ca_disconnected; + Sbar_Init (); + CL_Init (); +#else + VID_Init (host_basepal); + Draw_Init (); + SCR_Init (); + R_Init (); +// S_Init (); // S_Init is now done as part of VID. Sigh. +#ifdef GLQUAKE + S_Init(); +#endif + + cls.state = ca_disconnected; + CDAudio_Init (); + Sbar_Init (); + CL_Init (); + IN_Init (); +#endif + + Cbuf_InsertText ("exec quake.rc\n"); + Cbuf_AddText ("echo Type connect <internet address> or use GameSpy to connect to a game.\n"); + Cbuf_AddText ("cl_warncmd 1\n"); + + Hunk_AllocName (0, "-HOST_HUNKLEVEL-"); + host_hunklevel = Hunk_LowMark (); + + host_initialized = true; + + Con_Printf ("\nClient Version %4.2f (Build %04d)\n\n", VERSION, build_number()); + + Con_Printf ("€������ QuakeWorld Initialized ������‚\n"); +} + + +/* +=============== +Host_Shutdown + +FIXME: this is a callback from Sys_Quit and Sys_Error. It would be better +to run quit through here before the final handoff to the sys code. +=============== +*/ +void Host_Shutdown(void) +{ + static qboolean isdown = false; + + if (isdown) + { + printf ("recursive shutdown\n"); + return; + } + isdown = true; + + Host_WriteConfiguration (); + + CDAudio_Shutdown (); + NET_Shutdown (); + S_Shutdown(); + IN_Shutdown (); + if (host_basepal) + VID_Shutdown(); +} + diff --git a/QW/client/cl_parse.c b/QW/client/cl_parse.c new file mode 100644 index 0000000..267e523 --- /dev/null +++ b/QW/client/cl_parse.c @@ -0,0 +1,1383 @@ +/* +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. + +*/ +// cl_parse.c -- parse a message received from the server + +#include "quakedef.h" + +char *svc_strings[] = +{ + "svc_bad", + "svc_nop", + "svc_disconnect", + "svc_updatestat", + "svc_version", // [long] server version + "svc_setview", // [short] entity number + "svc_sound", // <see code> + "svc_time", // [float] server time + "svc_print", // [string] null terminated string + "svc_stufftext", // [string] stuffed into client's console buffer + // the string should be \n terminated + "svc_setangle", // [vec3] set the view angle to this absolute value + + "svc_serverdata", // [long] version ... + "svc_lightstyle", // [byte] [string] + "svc_updatename", // [byte] [string] + "svc_updatefrags", // [byte] [short] + "svc_clientdata", // <shortbits + data> + "svc_stopsound", // <see code> + "svc_updatecolors", // [byte] [byte] + "svc_particle", // [vec3] <variable> + "svc_damage", // [byte] impact [byte] blood [vec3] from + + "svc_spawnstatic", + "OBSOLETE svc_spawnbinary", + "svc_spawnbaseline", + + "svc_temp_entity", // <variable> + "svc_setpause", + "svc_signonnum", + "svc_centerprint", + "svc_killedmonster", + "svc_foundsecret", + "svc_spawnstaticsound", + "svc_intermission", + "svc_finale", + + "svc_cdtrack", + "svc_sellscreen", + + "svc_smallkick", + "svc_bigkick", + + "svc_updateping", + "svc_updateentertime", + + "svc_updatestatlong", + "svc_muzzleflash", + "svc_updateuserinfo", + "svc_download", + "svc_playerinfo", + "svc_nails", + "svc_choke", + "svc_modellist", + "svc_soundlist", + "svc_packetentities", + "svc_deltapacketentities", + "svc_maxspeed", + "svc_entgravity", + + "svc_setinfo", + "svc_serverinfo", + "svc_updatepl", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL", + "NEW PROTOCOL" +}; + +int oldparsecountmod; +int parsecountmod; +double parsecounttime; + +int cl_spikeindex, cl_playerindex, cl_flagindex; + +//============================================================================= + +int packet_latency[NET_TIMINGS]; + +int CL_CalcNet (void) +{ + int a, i; + frame_t *frame; + int lost; + char st[80]; + + for (i=cls.netchan.outgoing_sequence-UPDATE_BACKUP+1 + ; i <= cls.netchan.outgoing_sequence + ; i++) + { + frame = &cl.frames[i&UPDATE_MASK]; + if (frame->receivedtime == -1) + packet_latency[i&NET_TIMINGSMASK] = 9999; // dropped + else if (frame->receivedtime == -2) + packet_latency[i&NET_TIMINGSMASK] = 10000; // choked + else if (frame->invalid) + packet_latency[i&NET_TIMINGSMASK] = 9998; // invalid delta + else + packet_latency[i&NET_TIMINGSMASK] = (frame->receivedtime - frame->senttime)*20; + } + + lost = 0; + for (a=0 ; a<NET_TIMINGS ; a++) + { + i = (cls.netchan.outgoing_sequence-a) & NET_TIMINGSMASK; + if (packet_latency[i] == 9999) + lost++; + } + return lost * 100 / NET_TIMINGS; +} + +//============================================================================= + +/* +=============== +CL_CheckOrDownloadFile + +Returns true if the file exists, otherwise it attempts +to start a download from the server. +=============== +*/ +qboolean CL_CheckOrDownloadFile (char *filename) +{ + FILE *f; + + if (strstr (filename, "..")) + { + Con_Printf ("Refusing to download a path with ..\n"); + return true; + } + + COM_FOpenFile (filename, &f); + if (f) + { // it exists, no need to download + fclose (f); + return true; + } + + //ZOID - can't download when recording + if (cls.demorecording) { + Con_Printf("Unable to download %s in record mode.\n", cls.downloadname); + return true; + } + //ZOID - can't download when playback + if (cls.demoplayback) + return true; + + strcpy (cls.downloadname, filename); + Con_Printf ("Downloading %s...\n", cls.downloadname); + + // download to a temp name, and only rename + // to the real name when done, so if interrupted + // a runt file wont be left + COM_StripExtension (cls.downloadname, cls.downloadtempname); + strcat (cls.downloadtempname, ".tmp"); + + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname)); + + cls.downloadnumber++; + + return false; +} + +/* +================= +Model_NextDownload +================= +*/ +void Model_NextDownload (void) +{ + char *s; + int i; + extern char gamedirfile[]; + + if (cls.downloadnumber == 0) + { + Con_Printf ("Checking models...\n"); + cls.downloadnumber = 1; + } + + cls.downloadtype = dl_model; + for ( + ; cl.model_name[cls.downloadnumber][0] + ; cls.downloadnumber++) + { + s = cl.model_name[cls.downloadnumber]; + if (s[0] == '*') + continue; // inline brush model + if (!CL_CheckOrDownloadFile(s)) + return; // started a download + } + + for (i=1 ; i<MAX_MODELS ; i++) + { + if (!cl.model_name[i][0]) + break; + + cl.model_precache[i] = Mod_ForName (cl.model_name[i], false); + + if (!cl.model_precache[i]) + { + Con_Printf ("\nThe required model file '%s' could not be found or downloaded.\n\n" + , cl.model_name[i]); + Con_Printf ("You may need to download or purchase a %s client " + "pack in order to play on this server.\n\n", gamedirfile); + CL_Disconnect (); + return; + } + } + + // all done + cl.worldmodel = cl.model_precache[1]; + R_NewMap (); + Hunk_Check (); // make sure nothing is hurt + + // done with modellist, request first of static signon messages + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); +// MSG_WriteString (&cls.netchan.message, va("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2)); + MSG_WriteString (&cls.netchan.message, va(prespawn_name, cl.servercount, cl.worldmodel->checksum2)); +} + +/* +================= +Sound_NextDownload +================= +*/ +void Sound_NextDownload (void) +{ + char *s; + int i; + + if (cls.downloadnumber == 0) + { + Con_Printf ("Checking sounds...\n"); + cls.downloadnumber = 1; + } + + cls.downloadtype = dl_sound; + for ( + ; cl.sound_name[cls.downloadnumber][0] + ; cls.downloadnumber++) + { + s = cl.sound_name[cls.downloadnumber]; + if (!CL_CheckOrDownloadFile(va("sound/%s",s))) + return; // started a download + } + + for (i=1 ; i<MAX_SOUNDS ; i++) + { + if (!cl.sound_name[i][0]) + break; + cl.sound_precache[i] = S_PrecacheSound (cl.sound_name[i]); + } + + // done with sounds, request models now + memset (cl.model_precache, 0, sizeof(cl.model_precache)); + cl_playerindex = -1; + cl_spikeindex = -1; + cl_flagindex = -1; + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); +// MSG_WriteString (&cls.netchan.message, va("modellist %i 0", cl.servercount)); + MSG_WriteString (&cls.netchan.message, va(modellist_name, cl.servercount, 0)); +} + + +/* +====================== +CL_RequestNextDownload +====================== +*/ +void CL_RequestNextDownload (void) +{ + switch (cls.downloadtype) + { + case dl_single: + break; + case dl_skin: + Skin_NextDownload (); + break; + case dl_model: + Model_NextDownload (); + break; + case dl_sound: + Sound_NextDownload (); + break; + case dl_none: + default: + Con_DPrintf("Unknown download type.\n"); + } +} + +/* +===================== +CL_ParseDownload + +A download message has been received from the server +===================== +*/ +void CL_ParseDownload (void) +{ + int size, percent; + byte name[1024]; + int r; + + + // read the data + size = MSG_ReadShort (); + percent = MSG_ReadByte (); + + if (cls.demoplayback) { + if (size > 0) + msg_readcount += size; + return; // not in demo playback + } + + if (size == -1) + { + Con_Printf ("File not found.\n"); + if (cls.download) + { + Con_Printf ("cls.download shouldn't have been set\n"); + fclose (cls.download); + cls.download = NULL; + } + CL_RequestNextDownload (); + return; + } + + // open the file if not opened yet + if (!cls.download) + { + if (strncmp(cls.downloadtempname,"skins/",6)) + sprintf (name, "%s/%s", com_gamedir, cls.downloadtempname); + else + sprintf (name, "qw/%s", cls.downloadtempname); + + COM_CreatePath (name); + + cls.download = fopen (name, "wb"); + if (!cls.download) + { + msg_readcount += size; + Con_Printf ("Failed to open %s\n", cls.downloadtempname); + CL_RequestNextDownload (); + return; + } + } + + fwrite (net_message.data + msg_readcount, 1, size, cls.download); + msg_readcount += size; + + if (percent != 100) + { +// change display routines by zoid + // request next block +#if 0 + Con_Printf ("."); + if (10*(percent/10) != cls.downloadpercent) + { + cls.downloadpercent = 10*(percent/10); + Con_Printf ("%i%%", cls.downloadpercent); + } +#endif + cls.downloadpercent = percent; + + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + SZ_Print (&cls.netchan.message, "nextdl"); + } + else + { + char oldn[MAX_OSPATH]; + char newn[MAX_OSPATH]; + +#if 0 + Con_Printf ("100%%\n"); +#endif + + fclose (cls.download); + + // rename the temp file to it's final name + if (strcmp(cls.downloadtempname, cls.downloadname)) { + if (strncmp(cls.downloadtempname,"skins/",6)) { + sprintf (oldn, "%s/%s", com_gamedir, cls.downloadtempname); + sprintf (newn, "%s/%s", com_gamedir, cls.downloadname); + } else { + sprintf (oldn, "qw/%s", cls.downloadtempname); + sprintf (newn, "qw/%s", cls.downloadname); + } + r = rename (oldn, newn); + if (r) + Con_Printf ("failed to rename.\n"); + } + + cls.download = NULL; + cls.downloadpercent = 0; + + // get another file if needed + + CL_RequestNextDownload (); + } +} + +static byte *upload_data; +static int upload_pos; +static int upload_size; + +void CL_NextUpload(void) +{ + byte buffer[1024]; + int r; + int percent; + int size; + + if (!upload_data) + return; + + r = upload_size - upload_pos; + if (r > 768) + r = 768; + memcpy(buffer, upload_data + upload_pos, r); + MSG_WriteByte (&cls.netchan.message, clc_upload); + MSG_WriteShort (&cls.netchan.message, r); + + upload_pos += r; + size = upload_size; + if (!size) + size = 1; + percent = upload_pos*100/size; + MSG_WriteByte (&cls.netchan.message, percent); + SZ_Write (&cls.netchan.message, buffer, r); + +Con_DPrintf ("UPLOAD: %6d: %d written\n", upload_pos - r, r); + + if (upload_pos != upload_size) + return; + + Con_Printf ("Upload completed\n"); + + free(upload_data); + upload_data = 0; + upload_pos = upload_size = 0; +} + +void CL_StartUpload (byte *data, int size) +{ + if (cls.state < ca_onserver) + return; // gotta be connected + + // override + if (upload_data) + free(upload_data); + +Con_DPrintf("Upload starting of %d...\n", size); + + upload_data = malloc(size); + memcpy(upload_data, data, size); + upload_size = size; + upload_pos = 0; + + CL_NextUpload(); +} + +qboolean CL_IsUploading(void) +{ + if (upload_data) + return true; + return false; +} + +void CL_StopUpload(void) +{ + if (upload_data) + free(upload_data); + upload_data = NULL; +} + +/* +===================================================================== + + SERVER CONNECTING MESSAGES + +===================================================================== +*/ + +/* +================== +CL_ParseServerData +================== +*/ +void CL_ParseServerData (void) +{ + char *str; + FILE *f; + char fn[MAX_OSPATH]; + qboolean cflag = false; + extern char gamedirfile[MAX_OSPATH]; + int protover; + + Con_DPrintf ("Serverdata packet received.\n"); +// +// wipe the client_state_t struct +// + CL_ClearState (); + +// parse protocol version number +// allow 2.2 and 2.29 demos to play + protover = MSG_ReadLong (); + if (protover != PROTOCOL_VERSION && + !(cls.demoplayback && (protover == 26 || protover == 27 || protover == 28))) + Host_EndGame ("Server returned version %i, not %i\nYou probably need to upgrade.\nCheck http://www.quakeworld.net/", protover, PROTOCOL_VERSION); + + cl.servercount = MSG_ReadLong (); + + // game directory + str = MSG_ReadString (); + + if (stricmp(gamedirfile, str)) { + // save current config + Host_WriteConfiguration (); + cflag = true; + } + + COM_Gamedir(str); + + //ZOID--run the autoexec.cfg in the gamedir + //if it exists + if (cflag) { + sprintf(fn, "%s/%s", com_gamedir, "config.cfg"); + if ((f = fopen(fn, "r")) != NULL) { + fclose(f); + Cbuf_AddText ("cl_warncmd 0\n"); + Cbuf_AddText("exec config.cfg\n"); + Cbuf_AddText("exec frontend.cfg\n"); + Cbuf_AddText ("cl_warncmd 1\n"); + } + } + + // parse player slot, high bit means spectator + cl.playernum = MSG_ReadByte (); + if (cl.playernum & 128) + { + cl.spectator = true; + cl.playernum &= ~128; + } + + // get the full level name + str = MSG_ReadString (); + strncpy (cl.levelname, str, sizeof(cl.levelname)-1); + + // get the movevars + movevars.gravity = MSG_ReadFloat(); + movevars.stopspeed = MSG_ReadFloat(); + movevars.maxspeed = MSG_ReadFloat(); + movevars.spectatormaxspeed = MSG_ReadFloat(); + movevars.accelerate = MSG_ReadFloat(); + movevars.airaccelerate = MSG_ReadFloat(); + movevars.wateraccelerate = MSG_ReadFloat(); + movevars.friction = MSG_ReadFloat(); + movevars.waterfriction = MSG_ReadFloat(); + movevars.entgravity = MSG_ReadFloat(); + + // seperate the printfs so the server message can have a color + Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); + Con_Printf ("%c%s\n", 2, str); + + // ask for the sound list next + memset(cl.sound_name, 0, sizeof(cl.sound_name)); + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); +// MSG_WriteString (&cls.netchan.message, va("soundlist %i 0", cl.servercount)); + MSG_WriteString (&cls.netchan.message, va(soundlist_name, cl.servercount, 0)); + + // now waiting for downloads, etc + cls.state = ca_onserver; +} + +/* +================== +CL_ParseSoundlist +================== +*/ +void CL_ParseSoundlist (void) +{ + int numsounds; + char *str; + int n; + +// precache sounds +// memset (cl.sound_precache, 0, sizeof(cl.sound_precache)); + + numsounds = MSG_ReadByte(); + + for (;;) { + str = MSG_ReadString (); + if (!str[0]) + break; + numsounds++; + if (numsounds == MAX_SOUNDS) + Host_EndGame ("Server sent too many sound_precache"); + strcpy (cl.sound_name[numsounds], str); + } + + n = MSG_ReadByte(); + + if (n) { + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); +// MSG_WriteString (&cls.netchan.message, va("soundlist %i %i", cl.servercount, n)); + MSG_WriteString (&cls.netchan.message, va(soundlist_name, cl.servercount, n)); + return; + } + + cls.downloadnumber = 0; + cls.downloadtype = dl_sound; + Sound_NextDownload (); +} + +/* +================== +CL_ParseModellist +================== +*/ +void CL_ParseModellist (void) +{ + int nummodels; + char *str; + int n; + +// precache models and note certain default indexes + nummodels = MSG_ReadByte(); + + for (;;) + { + str = MSG_ReadString (); + if (!str[0]) + break; + nummodels++; + if (nummodels==MAX_MODELS) + Host_EndGame ("Server sent too many model_precache"); + strcpy (cl.model_name[nummodels], str); + + if (!strcmp(cl.model_name[nummodels],"progs/spike.mdl")) + cl_spikeindex = nummodels; + if (!strcmp(cl.model_name[nummodels],"progs/player.mdl")) + cl_playerindex = nummodels; + if (!strcmp(cl.model_name[nummodels],"progs/flag.mdl")) + cl_flagindex = nummodels; + } + + n = MSG_ReadByte(); + + if (n) { + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); +// MSG_WriteString (&cls.netchan.message, va("modellist %i %i", cl.servercount, n)); + MSG_WriteString (&cls.netchan.message, va(modellist_name, cl.servercount, n)); + return; + } + + cls.downloadnumber = 0; + cls.downloadtype = dl_model; + Model_NextDownload (); +} + +/* +================== +CL_ParseBaseline +================== +*/ +void CL_ParseBaseline (entity_state_t *es) +{ + int i; + + es->modelindex = MSG_ReadByte (); + es->frame = MSG_ReadByte (); + es->colormap = MSG_ReadByte(); + es->skinnum = MSG_ReadByte(); + for (i=0 ; i<3 ; i++) + { + es->origin[i] = MSG_ReadCoord (); + es->angles[i] = MSG_ReadAngle (); + } +} + + + +/* +===================== +CL_ParseStatic + +Static entities are non-interactive world objects +like torches +===================== +*/ +void CL_ParseStatic (void) +{ + entity_t *ent; + int i; + entity_state_t es; + + CL_ParseBaseline (&es); + + i = cl.num_statics; + if (i >= MAX_STATIC_ENTITIES) + Host_EndGame ("Too many static entities"); + ent = &cl_static_entities[i]; + cl.num_statics++; + +// copy it to the current state + ent->model = cl.model_precache[es.modelindex]; + ent->frame = es.frame; + ent->colormap = vid.colormap; + ent->skinnum = es.skinnum; + + VectorCopy (es.origin, ent->origin); + VectorCopy (es.angles, ent->angles); + + R_AddEfrags (ent); +} + +/* +=================== +CL_ParseStaticSound +=================== +*/ +void CL_ParseStaticSound (void) +{ + vec3_t org; + int sound_num, vol, atten; + int i; + + for (i=0 ; i<3 ; i++) + org[i] = MSG_ReadCoord (); + sound_num = MSG_ReadByte (); + vol = MSG_ReadByte (); + atten = MSG_ReadByte (); + + S_StaticSound (cl.sound_precache[sound_num], org, vol, atten); +} + + + +/* +===================================================================== + +ACTION MESSAGES + +===================================================================== +*/ + +/* +================== +CL_ParseStartSoundPacket +================== +*/ +void CL_ParseStartSoundPacket(void) +{ + vec3_t pos; + int channel, ent; + int sound_num; + int volume; + float attenuation; + int i; + + channel = MSG_ReadShort(); + + if (channel & SND_VOLUME) + volume = MSG_ReadByte (); + else + volume = DEFAULT_SOUND_PACKET_VOLUME; + + if (channel & SND_ATTENUATION) + attenuation = MSG_ReadByte () / 64.0; + else + attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; + + sound_num = MSG_ReadByte (); + + for (i=0 ; i<3 ; i++) + pos[i] = MSG_ReadCoord (); + + ent = (channel>>3)&1023; + channel &= 7; + + if (ent > MAX_EDICTS) + Host_EndGame ("CL_ParseStartSoundPacket: ent = %i", ent); + + S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation); +} + + +/* +================== +CL_ParseClientdata + +Server information pertaining to this client only, sent every frame +================== +*/ +void CL_ParseClientdata (void) +{ + int i; + float latency; + frame_t *frame; + +// calculate simulated time of message + oldparsecountmod = parsecountmod; + + i = cls.netchan.incoming_acknowledged; + cl.parsecount = i; + i &= UPDATE_MASK; + parsecountmod = i; + frame = &cl.frames[i]; + parsecounttime = cl.frames[i].senttime; + + frame->receivedtime = realtime; + +// calculate latency + latency = frame->receivedtime - frame->senttime; + + if (latency < 0 || latency > 1.0) + { +// Con_Printf ("Odd latency: %5.2f\n", latency); + } + else + { + // drift the average latency towards the observed latency + if (latency < cls.latency) + cls.latency = latency; + else + cls.latency += 0.001; // drift up, so correction are needed + } +} + +/* +===================== +CL_NewTranslation +===================== +*/ +void CL_NewTranslation (int slot) +{ +#ifdef GLQUAKE + if (slot > MAX_CLIENTS) + Sys_Error ("CL_NewTranslation: slot > MAX_CLIENTS"); + + R_TranslatePlayerSkin(slot); +#else + + int i, j; + int top, bottom; + byte *dest, *source; + player_info_t *player; + char s[512]; + + if (slot > MAX_CLIENTS) + Sys_Error ("CL_NewTranslation: slot > MAX_CLIENTS"); + + player = &cl.players[slot]; + + strcpy(s, Info_ValueForKey(player->userinfo, "skin")); + COM_StripExtension(s, s); + if (player->skin && !stricmp(s, player->skin->name)) + player->skin = NULL; + + if (player->_topcolor != player->topcolor || + player->_bottomcolor != player->bottomcolor || !player->skin) { + player->_topcolor = player->topcolor; + player->_bottomcolor = player->bottomcolor; + + dest = player->translations; + source = vid.colormap; + memcpy (dest, vid.colormap, sizeof(player->translations)); + top = player->topcolor; + if (top > 13 || top < 0) + top = 13; + top *= 16; + bottom = player->bottomcolor; + if (bottom > 13 || bottom < 0) + bottom = 13; + bottom *= 16; + + for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256) + { + if (top < 128) // the artists made some backwards ranges. sigh. + memcpy (dest + TOP_RANGE, source + top, 16); + else + for (j=0 ; j<16 ; j++) + dest[TOP_RANGE+j] = source[top+15-j]; + + if (bottom < 128) + memcpy (dest + BOTTOM_RANGE, source + bottom, 16); + else + for (j=0 ; j<16 ; j++) + dest[BOTTOM_RANGE+j] = source[bottom+15-j]; + } + } +#endif +} + +/* +============== +CL_UpdateUserinfo +============== +*/ +void CL_ProcessUserInfo (int slot, player_info_t *player) +{ + strncpy (player->name, Info_ValueForKey (player->userinfo, "name"), sizeof(player->name)-1); + player->topcolor = atoi(Info_ValueForKey (player->userinfo, "topcolor")); + player->bottomcolor = atoi(Info_ValueForKey (player->userinfo, "bottomcolor")); + if (Info_ValueForKey (player->userinfo, "*spectator")[0]) + player->spectator = true; + else + player->spectator = false; + + if (cls.state == ca_active) + Skin_Find (player); + + Sbar_Changed (); + CL_NewTranslation (slot); +} + +/* +============== +CL_UpdateUserinfo +============== +*/ +void CL_UpdateUserinfo (void) +{ + int slot; + player_info_t *player; + + slot = MSG_ReadByte (); + if (slot >= MAX_CLIENTS) + Host_EndGame ("CL_ParseServerMessage: svc_updateuserinfo > MAX_SCOREBOARD"); + + player = &cl.players[slot]; + player->userid = MSG_ReadLong (); + strncpy (player->userinfo, MSG_ReadString(), sizeof(player->userinfo)-1); + + CL_ProcessUserInfo (slot, player); +} + +/* +============== +CL_SetInfo +============== +*/ +void CL_SetInfo (void) +{ + int slot; + player_info_t *player; + char key[MAX_MSGLEN]; + char value[MAX_MSGLEN]; + + slot = MSG_ReadByte (); + if (slot >= MAX_CLIENTS) + Host_EndGame ("CL_ParseServerMessage: svc_setinfo > MAX_SCOREBOARD"); + + player = &cl.players[slot]; + + strncpy (key, MSG_ReadString(), sizeof(key) - 1); + key[sizeof(key) - 1] = 0; + strncpy (value, MSG_ReadString(), sizeof(value) - 1); + key[sizeof(value) - 1] = 0; + + Con_DPrintf("SETINFO %s: %s=%s\n", player->name, key, value); + + Info_SetValueForKey (player->userinfo, key, value, MAX_INFO_STRING); + + CL_ProcessUserInfo (slot, player); +} + +/* +============== +CL_ServerInfo +============== +*/ +void CL_ServerInfo (void) +{ + int slot; + player_info_t *player; + char key[MAX_MSGLEN]; + char value[MAX_MSGLEN]; + + strncpy (key, MSG_ReadString(), sizeof(key) - 1); + key[sizeof(key) - 1] = 0; + strncpy (value, MSG_ReadString(), sizeof(value) - 1); + key[sizeof(value) - 1] = 0; + + Con_DPrintf("SERVERINFO: %s=%s\n", key, value); + + Info_SetValueForKey (cl.serverinfo, key, value, MAX_SERVERINFO_STRING); +} + +/* +===================== +CL_SetStat +===================== +*/ +void CL_SetStat (int stat, int value) +{ + int j; + if (stat < 0 || stat >= MAX_CL_STATS) + Sys_Error ("CL_SetStat: %i is invalid", stat); + + Sbar_Changed (); + + if (stat == STAT_ITEMS) + { // set flash times + Sbar_Changed (); + for (j=0 ; j<32 ; j++) + if ( (value & (1<<j)) && !(cl.stats[stat] & (1<<j))) + cl.item_gettime[j] = cl.time; + } + + cl.stats[stat] = value; +} + +/* +============== +CL_MuzzleFlash +============== +*/ +void CL_MuzzleFlash (void) +{ + vec3_t fv, rv, uv; + dlight_t *dl; + int i; + player_state_t *pl; + + i = MSG_ReadShort (); + + if ((unsigned)(i-1) >= MAX_CLIENTS) + return; + +#ifdef GLQUAKE + // don't draw our own muzzle flash in gl if flashblending + if (i-1 == cl.playernum && gl_flashblend.value) + return; +#endif + + pl = &cl.frames[parsecountmod].playerstate[i-1]; + + dl = CL_AllocDlight (i); + VectorCopy (pl->origin, dl->origin); + AngleVectors (pl->viewangles, fv, rv, uv); + + VectorMA (dl->origin, 18, fv, dl->origin); + dl->radius = 200 + (rand()&31); + dl->minlight = 32; + dl->die = cl.time + 0.1; + dl->color[0] = 0.2; + dl->color[1] = 0.1; + dl->color[2] = 0.05; + dl->color[3] = 0.7; +} + + +#define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x); +/* +===================== +CL_ParseServerMessage +===================== +*/ +int received_framecount; +void CL_ParseServerMessage (void) +{ + int cmd; + char *s; + int i, j; + + received_framecount = host_framecount; + cl.last_servermessage = realtime; + CL_ClearProjectiles (); + +// +// if recording demos, copy the message out +// + if (cl_shownet.value == 1) + Con_Printf ("%i ",net_message.cursize); + else if (cl_shownet.value == 2) + Con_Printf ("------------------\n"); + + + CL_ParseClientdata (); + +// +// parse the message +// + while (1) + { + if (msg_badread) + { + Host_EndGame ("CL_ParseServerMessage: Bad server message"); + break; + } + + cmd = MSG_ReadByte (); + + if (cmd == -1) + { + msg_readcount++; // so the EOM showner has the right value + SHOWNET("END OF MESSAGE"); + break; + } + + SHOWNET(svc_strings[cmd]); + + // other commands + switch (cmd) + { + default: + Host_EndGame ("CL_ParseServerMessage: Illegible server message"); + break; + + case svc_nop: +// Con_Printf ("svc_nop\n"); + break; + + case svc_disconnect: + if (cls.state == ca_connected) + Host_EndGame ("Server disconnected\n" + "Server version may not be compatible"); + else + Host_EndGame ("Server disconnected"); + break; + + case svc_print: + i = MSG_ReadByte (); + if (i == PRINT_CHAT) + { + S_LocalSound ("misc/talk.wav"); + con_ormask = 128; + } + Con_Printf ("%s", MSG_ReadString ()); + con_ormask = 0; + break; + + case svc_centerprint: + SCR_CenterPrint (MSG_ReadString ()); + break; + + case svc_stufftext: + s = MSG_ReadString (); + Con_DPrintf ("stufftext: %s\n", s); + Cbuf_AddText (s); + break; + + case svc_damage: + V_ParseDamage (); + break; + + case svc_serverdata: + Cbuf_Execute (); // make sure any stuffed commands are done + CL_ParseServerData (); + vid.recalc_refdef = true; // leave full screen intermission + break; + + case svc_setangle: + for (i=0 ; i<3 ; i++) + cl.viewangles[i] = MSG_ReadAngle (); +// cl.viewangles[PITCH] = cl.viewangles[ROLL] = 0; + break; + + case svc_lightstyle: + i = MSG_ReadByte (); + if (i >= MAX_LIGHTSTYLES) + Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES"); + Q_strcpy (cl_lightstyle[i].map, MSG_ReadString()); + cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map); + break; + + case svc_sound: + CL_ParseStartSoundPacket(); + break; + + case svc_stopsound: + i = MSG_ReadShort(); + S_StopSound(i>>3, i&7); + break; + + case svc_updatefrags: + Sbar_Changed (); + i = MSG_ReadByte (); + if (i >= MAX_CLIENTS) + Host_EndGame ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD"); + cl.players[i].frags = MSG_ReadShort (); + break; + + case svc_updateping: + i = MSG_ReadByte (); + if (i >= MAX_CLIENTS) + Host_EndGame ("CL_ParseServerMessage: svc_updateping > MAX_SCOREBOARD"); + cl.players[i].ping = MSG_ReadShort (); + break; + + case svc_updatepl: + i = MSG_ReadByte (); + if (i >= MAX_CLIENTS) + Host_EndGame ("CL_ParseServerMessage: svc_updatepl > MAX_SCOREBOARD"); + cl.players[i].pl = MSG_ReadByte (); + break; + + case svc_updateentertime: + // time is sent over as seconds ago + i = MSG_ReadByte (); + if (i >= MAX_CLIENTS) + Host_EndGame ("CL_ParseServerMessage: svc_updateentertime > MAX_SCOREBOARD"); + cl.players[i].entertime = realtime - MSG_ReadFloat (); + break; + + case svc_spawnbaseline: + i = MSG_ReadShort (); + CL_ParseBaseline (&cl_baselines[i]); + break; + case svc_spawnstatic: + CL_ParseStatic (); + break; + case svc_temp_entity: + CL_ParseTEnt (); + break; + + case svc_killedmonster: + cl.stats[STAT_MONSTERS]++; + break; + + case svc_foundsecret: + cl.stats[STAT_SECRETS]++; + break; + + case svc_updatestat: + i = MSG_ReadByte (); + j = MSG_ReadByte (); + CL_SetStat (i, j); + break; + case svc_updatestatlong: + i = MSG_ReadByte (); + j = MSG_ReadLong (); + CL_SetStat (i, j); + break; + + case svc_spawnstaticsound: + CL_ParseStaticSound (); + break; + + case svc_cdtrack: + cl.cdtrack = MSG_ReadByte (); + CDAudio_Play ((byte)cl.cdtrack, true); + break; + + case svc_intermission: + cl.intermission = 1; + cl.completed_time = realtime; + vid.recalc_refdef = true; // go to full screen + for (i=0 ; i<3 ; i++) + cl.simorg[i] = MSG_ReadCoord (); + for (i=0 ; i<3 ; i++) + cl.simangles[i] = MSG_ReadAngle (); + VectorCopy (vec3_origin, cl.simvel); + break; + + case svc_finale: + cl.intermission = 2; + cl.completed_time = realtime; + vid.recalc_refdef = true; // go to full screen + SCR_CenterPrint (MSG_ReadString ()); + break; + + case svc_sellscreen: + Cmd_ExecuteString ("help"); + break; + + case svc_smallkick: + cl.punchangle = -2; + break; + case svc_bigkick: + cl.punchangle = -4; + break; + + case svc_muzzleflash: + CL_MuzzleFlash (); + break; + + case svc_updateuserinfo: + CL_UpdateUserinfo (); + break; + + case svc_setinfo: + CL_SetInfo (); + break; + + case svc_serverinfo: + CL_ServerInfo (); + break; + + case svc_download: + CL_ParseDownload (); + break; + + case svc_playerinfo: + CL_ParsePlayerinfo (); + break; + + case svc_nails: + CL_ParseProjectiles (); + break; + + case svc_chokecount: // some preceding packets were choked + i = MSG_ReadByte (); + for (j=0 ; j<i ; j++) + cl.frames[ (cls.netchan.incoming_acknowledged-1-j)&UPDATE_MASK ].receivedtime = -2; + break; + + case svc_modellist: + CL_ParseModellist (); + break; + + case svc_soundlist: + CL_ParseSoundlist (); + break; + + case svc_packetentities: + CL_ParsePacketEntities (false); + break; + + case svc_deltapacketentities: + CL_ParsePacketEntities (true); + break; + + case svc_maxspeed : + movevars.maxspeed = MSG_ReadFloat(); + break; + + case svc_entgravity : + movevars.entgravity = MSG_ReadFloat(); + break; + + case svc_setpause: + cl.paused = MSG_ReadByte (); + if (cl.paused) + CDAudio_Pause (); + else + CDAudio_Resume (); + break; + + } + } + + CL_SetSolidEntities (); +} + + diff --git a/QW/client/cl_pred.c b/QW/client/cl_pred.c new file mode 100644 index 0000000..2b3d3d4 --- /dev/null +++ b/QW/client/cl_pred.c @@ -0,0 +1,225 @@ +/* +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. + +*/ +#include "quakedef.h" +#include "winquake.h" + +cvar_t cl_nopred = {"cl_nopred","0"}; +cvar_t cl_pushlatency = {"pushlatency","-999"}; + +extern frame_t *view_frame; + +/* +================= +CL_NudgePosition + +If pmove.origin is in a solid position, +try nudging slightly on all axis to +allow for the cut precision of the net coordinates +================= +*/ +void CL_NudgePosition (void) +{ + vec3_t base; + int x, y; + + if (PM_HullPointContents (&cl.model_precache[1]->hulls[1], 0, pmove.origin) == CONTENTS_EMPTY) + return; + + VectorCopy (pmove.origin, base); + for (x=-1 ; x<=1 ; x++) + { + for (y=-1 ; y<=1 ; y++) + { + pmove.origin[0] = base[0] + x * 1.0/8; + pmove.origin[1] = base[1] + y * 1.0/8; + if (PM_HullPointContents (&cl.model_precache[1]->hulls[1], 0, pmove.origin) == CONTENTS_EMPTY) + return; + } + } + Con_DPrintf ("CL_NudgePosition: stuck\n"); +} + +/* +============== +CL_PredictUsercmd +============== +*/ +void CL_PredictUsercmd (player_state_t *from, player_state_t *to, usercmd_t *u, qboolean spectator) +{ + // split up very long moves + if (u->msec > 50) + { + player_state_t temp; + usercmd_t split; + + split = *u; + split.msec /= 2; + + CL_PredictUsercmd (from, &temp, &split, spectator); + CL_PredictUsercmd (&temp, to, &split, spectator); + return; + } + + VectorCopy (from->origin, pmove.origin); +// VectorCopy (from->viewangles, pmove.angles); + VectorCopy (u->angles, pmove.angles); + VectorCopy (from->velocity, pmove.velocity); + + pmove.oldbuttons = from->oldbuttons; + pmove.waterjumptime = from->waterjumptime; + pmove.dead = cl.stats[STAT_HEALTH] <= 0; + pmove.spectator = spectator; + + pmove.cmd = *u; + + PlayerMove (); +//for (i=0 ; i<3 ; i++) +//pmove.origin[i] = ((int)(pmove.origin[i]*8))*0.125; + to->waterjumptime = pmove.waterjumptime; + to->oldbuttons = pmove.cmd.buttons; + VectorCopy (pmove.origin, to->origin); + VectorCopy (pmove.angles, to->viewangles); + VectorCopy (pmove.velocity, to->velocity); + to->onground = onground; + + to->weaponframe = from->weaponframe; +} + + + +/* +============== +CL_PredictMove +============== +*/ +void CL_PredictMove (void) +{ + int i; + float f; + frame_t *from, *to = NULL; + int oldphysent; + + if (cl_pushlatency.value > 0) + Cvar_Set ("pushlatency", "0"); + + if (cl.paused) + return; + + cl.time = realtime - cls.latency - cl_pushlatency.value*0.001; + if (cl.time > realtime) + cl.time = realtime; + + if (cl.intermission) + return; + + if (!cl.validsequence) + return; + + if (cls.netchan.outgoing_sequence - cls.netchan.incoming_sequence >= UPDATE_BACKUP-1) + return; + + VectorCopy (cl.viewangles, cl.simangles); + + // this is the last frame received from the server + from = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK]; + + // we can now render a frame + if (cls.state == ca_onserver) + { // first update is the final signon stage + char text[1024]; + + cls.state = ca_active; + sprintf (text, "QuakeWorld: %s", cls.servername); +#ifdef _WIN32 + SetWindowText (mainwindow, text); +#endif + } + + if (cl_nopred.value) + { + VectorCopy (from->playerstate[cl.playernum].velocity, cl.simvel); + VectorCopy (from->playerstate[cl.playernum].origin, cl.simorg); + return; + } + + // predict forward until cl.time <= to->senttime + oldphysent = pmove.numphysent; + CL_SetSolidPlayers (cl.playernum); + +// to = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK]; + + for (i=1 ; i<UPDATE_BACKUP-1 && cls.netchan.incoming_sequence+i < + cls.netchan.outgoing_sequence; i++) + { + to = &cl.frames[(cls.netchan.incoming_sequence+i) & UPDATE_MASK]; + CL_PredictUsercmd (&from->playerstate[cl.playernum] + , &to->playerstate[cl.playernum], &to->cmd, cl.spectator); + if (to->senttime >= cl.time) + break; + from = to; + } + + pmove.numphysent = oldphysent; + + if (i == UPDATE_BACKUP-1 || !to) + return; // net hasn't deliver packets in a long time... + + // now interpolate some fraction of the final frame + if (to->senttime == from->senttime) + f = 0; + else + { + f = (cl.time - from->senttime) / (to->senttime - from->senttime); + + if (f < 0) + f = 0; + if (f > 1) + f = 1; + } + + for (i=0 ; i<3 ; i++) + if ( fabs(from->playerstate[cl.playernum].origin[i] - to->playerstate[cl.playernum].origin[i]) > 128) + { // teleported, so don't lerp + VectorCopy (to->playerstate[cl.playernum].velocity, cl.simvel); + VectorCopy (to->playerstate[cl.playernum].origin, cl.simorg); + return; + } + + for (i=0 ; i<3 ; i++) + { + cl.simorg[i] = from->playerstate[cl.playernum].origin[i] + + f*(to->playerstate[cl.playernum].origin[i] - from->playerstate[cl.playernum].origin[i]); + cl.simvel[i] = from->playerstate[cl.playernum].velocity[i] + + f*(to->playerstate[cl.playernum].velocity[i] - from->playerstate[cl.playernum].velocity[i]); + } +} + + +/* +============== +CL_InitPrediction +============== +*/ +void CL_InitPrediction (void) +{ + Cvar_RegisterVariable (&cl_pushlatency); + Cvar_RegisterVariable (&cl_nopred); +} + diff --git a/QW/client/cl_tent.c b/QW/client/cl_tent.c new file mode 100644 index 0000000..2941c2f --- /dev/null +++ b/QW/client/cl_tent.c @@ -0,0 +1,459 @@ +/* +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. + +*/ +// cl_tent.c -- client side temporary entities + +#include "quakedef.h" + + +#define MAX_BEAMS 8 +typedef struct +{ + int entity; + struct model_s *model; + float endtime; + vec3_t start, end; +} beam_t; + +beam_t cl_beams[MAX_BEAMS]; + +#define MAX_EXPLOSIONS 8 +typedef struct +{ + vec3_t origin; + float start; + model_t *model; +} explosion_t; + +explosion_t cl_explosions[MAX_EXPLOSIONS]; + + +sfx_t *cl_sfx_wizhit; +sfx_t *cl_sfx_knighthit; +sfx_t *cl_sfx_tink1; +sfx_t *cl_sfx_ric1; +sfx_t *cl_sfx_ric2; +sfx_t *cl_sfx_ric3; +sfx_t *cl_sfx_r_exp3; + +/* +================= +CL_ParseTEnts +================= +*/ +void CL_InitTEnts (void) +{ + cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav"); + cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav"); + cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav"); + cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav"); + cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav"); + cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav"); + cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav"); +} + +/* +================= +CL_ClearTEnts +================= +*/ +void CL_ClearTEnts (void) +{ + memset (&cl_beams, 0, sizeof(cl_beams)); + memset (&cl_explosions, 0, sizeof(cl_explosions)); +} + +/* +================= +CL_AllocExplosion +================= +*/ +explosion_t *CL_AllocExplosion (void) +{ + int i; + float time; + int index; + + for (i=0 ; i<MAX_EXPLOSIONS ; i++) + if (!cl_explosions[i].model) + return &cl_explosions[i]; +// find the oldest explosion + time = cl.time; + index = 0; + + for (i=0 ; i<MAX_EXPLOSIONS ; i++) + if (cl_explosions[i].start < time) + { + time = cl_explosions[i].start; + index = i; + } + return &cl_explosions[index]; +} + +/* +================= +CL_ParseBeam +================= +*/ +void CL_ParseBeam (model_t *m) +{ + int ent; + vec3_t start, end; + beam_t *b; + int i; + + ent = MSG_ReadShort (); + + start[0] = MSG_ReadCoord (); + start[1] = MSG_ReadCoord (); + start[2] = MSG_ReadCoord (); + + end[0] = MSG_ReadCoord (); + end[1] = MSG_ReadCoord (); + end[2] = MSG_ReadCoord (); + +// override any beam with the same entity + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + if (b->entity == ent) + { + b->entity = ent; + b->model = m; + b->endtime = cl.time + 0.2; + VectorCopy (start, b->start); + VectorCopy (end, b->end); + return; + } + +// find a free beam + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + { + if (!b->model || b->endtime < cl.time) + { + b->entity = ent; + b->model = m; + b->endtime = cl.time + 0.2; + VectorCopy (start, b->start); + VectorCopy (end, b->end); + return; + } + } + Con_Printf ("beam list overflow!\n"); +} + +/* +================= +CL_ParseTEnt +================= +*/ +void CL_ParseTEnt (void) +{ + int type; + vec3_t pos; + dlight_t *dl; + int rnd; + explosion_t *ex; + int cnt; + + type = MSG_ReadByte (); + switch (type) + { + case TE_WIZSPIKE: // spike hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 20, 30); + S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1); + break; + + case TE_KNIGHTSPIKE: // spike hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 226, 20); + S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1); + break; + + case TE_SPIKE: // spike hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 0, 10); + + if ( rand() % 5 ) + S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); + else + { + rnd = rand() & 3; + if (rnd == 1) + S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); + else if (rnd == 2) + S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); + else + S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); + } + break; + case TE_SUPERSPIKE: // super spike hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 0, 20); + + if ( rand() % 5 ) + S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); + else + { + rnd = rand() & 3; + if (rnd == 1) + S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); + else if (rnd == 2) + S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); + else + S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); + } + break; + + case TE_EXPLOSION: // rocket explosion + // particles + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_ParticleExplosion (pos); + + // light + dl = CL_AllocDlight (0); + VectorCopy (pos, dl->origin); + dl->radius = 350; + dl->die = cl.time + 0.5; + dl->decay = 300; + dl->color[0] = 0.2; + dl->color[1] = 0.1; + dl->color[2] = 0.05; + dl->color[3] = 0.7; + + // sound + S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); + + // sprite + ex = CL_AllocExplosion (); + VectorCopy (pos, ex->origin); + ex->start = cl.time; + ex->model = Mod_ForName ("progs/s_explod.spr", true); + break; + + case TE_TAREXPLOSION: // tarbaby explosion + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_BlobExplosion (pos); + + S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); + break; + + case TE_LIGHTNING1: // lightning bolts + CL_ParseBeam (Mod_ForName("progs/bolt.mdl", true)); + break; + + case TE_LIGHTNING2: // lightning bolts + CL_ParseBeam (Mod_ForName("progs/bolt2.mdl", true)); + break; + + case TE_LIGHTNING3: // lightning bolts + CL_ParseBeam (Mod_ForName("progs/bolt3.mdl", true)); + break; + + case TE_LAVASPLASH: + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_LavaSplash (pos); + break; + + case TE_TELEPORT: + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_TeleportSplash (pos); + break; + + case TE_GUNSHOT: // bullet hitting wall + cnt = MSG_ReadByte (); + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 0, 20*cnt); + break; + + case TE_BLOOD: // bullets hitting body + cnt = MSG_ReadByte (); + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 73, 20*cnt); + break; + + case TE_LIGHTNINGBLOOD: // lightning hitting body + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 225, 50); + break; + + default: + Sys_Error ("CL_ParseTEnt: bad type"); + } +} + + +/* +================= +CL_NewTempEntity +================= +*/ +entity_t *CL_NewTempEntity (void) +{ + entity_t *ent; + + if (cl_numvisedicts == MAX_VISEDICTS) + return NULL; + ent = &cl_visedicts[cl_numvisedicts]; + cl_numvisedicts++; + ent->keynum = 0; + + memset (ent, 0, sizeof(*ent)); + + ent->colormap = vid.colormap; + return ent; +} + + +/* +================= +CL_UpdateBeams +================= +*/ +void CL_UpdateBeams (void) +{ + int i; + beam_t *b; + vec3_t dist, org; + float d; + entity_t *ent; + float yaw, pitch; + float forward; + +// update lightning + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + { + if (!b->model || b->endtime < cl.time) + continue; + + // if coming from the player, update the start position + if (b->entity == cl.playernum+1) // entity 0 is the world + { + VectorCopy (cl.simorg, b->start); +// b->start[2] -= 22; // adjust for view height + } + + // calculate pitch and yaw + VectorSubtract (b->end, b->start, dist); + + if (dist[1] == 0 && dist[0] == 0) + { + yaw = 0; + if (dist[2] > 0) + pitch = 90; + else + pitch = 270; + } + else + { + yaw = (int) (atan2(dist[1], dist[0]) * 180 / M_PI); + if (yaw < 0) + yaw += 360; + + forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]); + pitch = (int) (atan2(dist[2], forward) * 180 / M_PI); + if (pitch < 0) + pitch += 360; + } + + // add new entities for the lightning + VectorCopy (b->start, org); + d = VectorNormalize(dist); + while (d > 0) + { + ent = CL_NewTempEntity (); + if (!ent) + return; + VectorCopy (org, ent->origin); + ent->model = b->model; + ent->angles[0] = pitch; + ent->angles[1] = yaw; + ent->angles[2] = rand()%360; + + for (i=0 ; i<3 ; i++) + org[i] += dist[i]*30; + d -= 30; + } + } + +} + +/* +================= +CL_UpdateExplosions +================= +*/ +void CL_UpdateExplosions (void) +{ + int i; + int f; + explosion_t *ex; + entity_t *ent; + + for (i=0, ex=cl_explosions ; i< MAX_EXPLOSIONS ; i++, ex++) + { + if (!ex->model) + continue; + f = 10*(cl.time - ex->start); + if (f >= ex->model->numframes) + { + ex->model = NULL; + continue; + } + + ent = CL_NewTempEntity (); + if (!ent) + return; + VectorCopy (ex->origin, ent->origin); + ent->model = ex->model; + ent->frame = f; + } +} + +/* +================= +CL_UpdateTEnts +================= +*/ +void CL_UpdateTEnts (void) +{ + CL_UpdateBeams (); + CL_UpdateExplosions (); +} diff --git a/QW/client/client.h b/QW/client/client.h new file mode 100644 index 0000000..97ec71c --- /dev/null +++ b/QW/client/client.h @@ -0,0 +1,515 @@ +/* +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. + +*/ +// client.h + + +typedef struct +{ + char name[16]; + qboolean failedload; // the name isn't a valid skin + cache_user_t cache; +} skin_t; + +// player_state_t is the information needed by a player entity +// to do move prediction and to generate a drawable entity +typedef struct +{ + int messagenum; // all player's won't be updated each frame + + double state_time; // not the same as the packet time, + // because player commands come asyncronously + usercmd_t command; // last command for prediction + + vec3_t origin; + vec3_t viewangles; // only for demos, not from server + vec3_t velocity; + int weaponframe; + + int modelindex; + int frame; + int skinnum; + int effects; + + int flags; // dead, gib, etc + + float waterjumptime; + int onground; // -1 = in air, else pmove entity number + int oldbuttons; +} player_state_t; + + +#define MAX_SCOREBOARDNAME 16 +typedef struct player_info_s +{ + int userid; + char userinfo[MAX_INFO_STRING]; + + // scoreboard information + char name[MAX_SCOREBOARDNAME]; + float entertime; + int frags; + int ping; + byte pl; + + // skin information + int topcolor; + int bottomcolor; + + int _topcolor; + int _bottomcolor; + + int spectator; + byte translations[VID_GRADES*256]; + skin_t *skin; +} player_info_t; + + +typedef struct +{ + // generated on client side + usercmd_t cmd; // cmd that generated the frame + double senttime; // time cmd was sent off + int delta_sequence; // sequence number to delta from, -1 = full update + + // received from server + double receivedtime; // time message was received, or -1 + player_state_t playerstate[MAX_CLIENTS]; // message received that reflects performing + // the usercmd + packet_entities_t packet_entities; + qboolean invalid; // true if the packet_entities delta was invalid +} frame_t; + + +typedef struct +{ + int destcolor[3]; + int percent; // 0-256 +} cshift_t; + +#define CSHIFT_CONTENTS 0 +#define CSHIFT_DAMAGE 1 +#define CSHIFT_BONUS 2 +#define CSHIFT_POWERUP 3 +#define NUM_CSHIFTS 4 + + +// +// client_state_t should hold all pieces of the client state +// +#define MAX_DLIGHTS 32 +typedef struct +{ + int key; // so entities can reuse same entry + vec3_t origin; + float radius; + float die; // stop lighting after this time + float decay; // drop this each second + float minlight; // don't add when contributing less + float color[4]; +} dlight_t; + +typedef struct +{ + int length; + char map[MAX_STYLESTRING]; +} lightstyle_t; + + + +#define MAX_EFRAGS 512 + +#define MAX_DEMOS 8 +#define MAX_DEMONAME 16 + +typedef enum { +ca_disconnected, // full screen console with no connection +ca_demostart, // starting up a demo +ca_connected, // netchan_t established, waiting for svc_serverdata +ca_onserver, // processing data lists, donwloading, etc +ca_active // everything is in, so frames can be rendered +} cactive_t; + +typedef enum { + dl_none, + dl_model, + dl_sound, + dl_skin, + dl_single +} dltype_t; // download type + +// +// the client_static_t structure is persistant through an arbitrary number +// of server connections +// +typedef struct +{ +// connection information + cactive_t state; + +// network stuff + netchan_t netchan; + +// private userinfo for sending to masterless servers + char userinfo[MAX_INFO_STRING]; + + char servername[MAX_OSPATH]; // name of server from original connect + + int qport; + + FILE *download; // file transfer from server + char downloadtempname[MAX_OSPATH]; + char downloadname[MAX_OSPATH]; + int downloadnumber; + dltype_t downloadtype; + int downloadpercent; + +// demo loop control + int demonum; // -1 = don't play demos + char demos[MAX_DEMOS][MAX_DEMONAME]; // when not playing + +// demo recording info must be here, because record is started before +// entering a map (and clearing client_state_t) + qboolean demorecording; + qboolean demoplayback; + qboolean timedemo; + FILE *demofile; + float td_lastframe; // to meter out one message a frame + int td_startframe; // host_framecount at start + float td_starttime; // realtime at second frame of timedemo + + int challenge; + + float latency; // rolling average +} client_static_t; + +extern client_static_t cls; + +// +// the client_state_t structure is wiped completely at every +// server signon +// +typedef struct +{ + int servercount; // server identification for prespawns + + char serverinfo[MAX_SERVERINFO_STRING]; + + int parsecount; // server message counter + int validsequence; // this is the sequence number of the last good + // packetentity_t we got. If this is 0, we can't + // render a frame yet + int movemessages; // since connecting to this server + // throw out the first couple, so the player + // doesn't accidentally do something the + // first frame + + int spectator; + + double last_ping_request; // while showing scoreboard + double last_servermessage; + +// sentcmds[cl.netchan.outgoing_sequence & UPDATE_MASK] = cmd + frame_t frames[UPDATE_BACKUP]; + +// information for local display + int stats[MAX_CL_STATS]; // health, etc + float item_gettime[32]; // cl.time of aquiring item, for blinking + float faceanimtime; // use anim frame if cl.time < this + + cshift_t cshifts[NUM_CSHIFTS]; // color shifts for damage, powerups + cshift_t prev_cshifts[NUM_CSHIFTS]; // and content types + +// the client maintains its own idea of view angles, which are +// sent to the server each frame. And only reset at level change +// and teleport times + vec3_t viewangles; + +// the client simulates or interpolates movement to get these values + double time; // this is the time value that the client + // is rendering at. allways <= realtime + vec3_t simorg; + vec3_t simvel; + vec3_t simangles; + +// pitch drifting vars + float pitchvel; + qboolean nodrift; + float driftmove; + double laststop; + + + float crouch; // local amount for smoothing stepups + + qboolean paused; // send over by server + + float punchangle; // temporar yview kick from weapon firing + + int intermission; // don't change view angle, full screen, etc + int completed_time; // latched ffrom time at intermission start + +// +// information that is static for the entire time connected to a server +// + char model_name[MAX_MODELS][MAX_QPATH]; + char sound_name[MAX_SOUNDS][MAX_QPATH]; + + struct model_s *model_precache[MAX_MODELS]; + struct sfx_s *sound_precache[MAX_SOUNDS]; + + char levelname[40]; // for display on solo scoreboard + int playernum; + +// refresh related state + struct model_s *worldmodel; // cl_entitites[0].model + struct efrag_s *free_efrags; + int num_entities; // stored bottom up in cl_entities array + int num_statics; // stored top down in cl_entitiers + + int cdtrack; // cd audio + + entity_t viewent; // weapon model + +// all player information + player_info_t players[MAX_CLIENTS]; +} client_state_t; + + +// +// cvars +// +extern cvar_t cl_warncmd; +extern cvar_t cl_upspeed; +extern cvar_t cl_forwardspeed; +extern cvar_t cl_backspeed; +extern cvar_t cl_sidespeed; + +extern cvar_t cl_movespeedkey; + +extern cvar_t cl_yawspeed; +extern cvar_t cl_pitchspeed; + +extern cvar_t cl_anglespeedkey; + +extern cvar_t cl_shownet; +extern cvar_t cl_sbar; +extern cvar_t cl_hudswap; + +extern cvar_t cl_pitchdriftspeed; +extern cvar_t lookspring; +extern cvar_t lookstrafe; +extern cvar_t sensitivity; + +extern cvar_t m_pitch; +extern cvar_t m_yaw; +extern cvar_t m_forward; +extern cvar_t m_side; + +extern cvar_t _windowed_mouse; + +extern cvar_t name; + + +#define MAX_STATIC_ENTITIES 128 // torches, etc + +extern client_state_t cl; + +// FIXME, allocate dynamically +extern entity_state_t cl_baselines[MAX_EDICTS]; +extern efrag_t cl_efrags[MAX_EFRAGS]; +extern entity_t cl_static_entities[MAX_STATIC_ENTITIES]; +extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; +extern dlight_t cl_dlights[MAX_DLIGHTS]; + +extern qboolean nomaster; +extern float server_version; // version of server we connected to + +//============================================================================= + + +// +// cl_main +// +dlight_t *CL_AllocDlight (int key); +void CL_DecayLights (void); + +void CL_Init (void); +void Host_WriteConfiguration (void); + +void CL_EstablishConnection (char *host); + +void CL_Disconnect (void); +void CL_Disconnect_f (void); +void CL_NextDemo (void); +qboolean CL_DemoBehind(void); + +void CL_BeginServerConnect(void); + +#define MAX_VISEDICTS 256 +extern int cl_numvisedicts, cl_oldnumvisedicts; +extern entity_t *cl_visedicts, *cl_oldvisedicts; +extern entity_t cl_visedicts_list[2][MAX_VISEDICTS]; + +extern char emodel_name[], pmodel_name[], prespawn_name[], modellist_name[], soundlist_name[]; + +// +// cl_input +// +typedef struct +{ + int down[2]; // key nums holding it down + int state; // low bit is down state +} kbutton_t; + +extern kbutton_t in_mlook, in_klook; +extern kbutton_t in_strafe; +extern kbutton_t in_speed; + +void CL_InitInput (void); +void CL_SendCmd (void); +void CL_SendMove (usercmd_t *cmd); + +void CL_ParseTEnt (void); +void CL_UpdateTEnts (void); + +void CL_ClearState (void); + +void CL_ReadPackets (void); + +int CL_ReadFromServer (void); +void CL_WriteToServer (usercmd_t *cmd); +void CL_BaseMove (usercmd_t *cmd); + + +float CL_KeyState (kbutton_t *key); +char *Key_KeynumToString (int keynum); + +// +// cl_demo.c +// +void CL_StopPlayback (void); +qboolean CL_GetMessage (void); +void CL_WriteDemoCmd (usercmd_t *pcmd); + +void CL_Stop_f (void); +void CL_Record_f (void); +void CL_ReRecord_f (void); +void CL_PlayDemo_f (void); +void CL_TimeDemo_f (void); + +// +// cl_parse.c +// +#define NET_TIMINGS 256 +#define NET_TIMINGSMASK 255 +extern int packet_latency[NET_TIMINGS]; +int CL_CalcNet (void); +void CL_ParseServerMessage (void); +void CL_NewTranslation (int slot); +qboolean CL_CheckOrDownloadFile (char *filename); +qboolean CL_IsUploading(void); +void CL_NextUpload(void); +void CL_StartUpload (byte *data, int size); +void CL_StopUpload(void); + +// +// view.c +// +void V_StartPitchDrift (void); +void V_StopPitchDrift (void); + +void V_RenderView (void); +void V_UpdatePalette (void); +void V_Register (void); +void V_ParseDamage (void); +void V_SetContentsColor (int contents); +void V_CalcBlend (void); + + +// +// cl_tent +// +void CL_InitTEnts (void); +void CL_ClearTEnts (void); + +// +// cl_ents.c +// +void CL_SetSolidPlayers (int playernum); +void CL_SetUpPlayerPrediction(qboolean dopred); +void CL_EmitEntities (void); +void CL_ClearProjectiles (void); +void CL_ParseProjectiles (void); +void CL_ParsePacketEntities (qboolean delta); +void CL_SetSolidEntities (void); +void CL_ParsePlayerinfo (void); + +// +// cl_pred.c +// +void CL_InitPrediction (void); +void CL_PredictMove (void); +void CL_PredictUsercmd (player_state_t *from, player_state_t *to, usercmd_t *u, qboolean spectator); + +// +// cl_cam.c +// +#define CAM_NONE 0 +#define CAM_TRACK 1 + +extern int autocam; +extern int spec_track; // player# of who we are tracking + +qboolean Cam_DrawViewModel(void); +qboolean Cam_DrawPlayer(int playernum); +void Cam_Track(usercmd_t *cmd); +void Cam_FinishMove(usercmd_t *cmd); +void Cam_Reset(void); +void CL_InitCam(void); + +// +// skin.c +// + +typedef struct +{ + char manufacturer; + char version; + char encoding; + char bits_per_pixel; + unsigned short xmin,ymin,xmax,ymax; + unsigned short hres,vres; + unsigned char palette[48]; + char reserved; + char color_planes; + unsigned short bytes_per_line; + unsigned short palette_type; + char filler[58]; + unsigned char data; // unbounded +} pcx_t; + + +void Skin_Find (player_info_t *sc); +byte *Skin_Cache (skin_t *skin); +void Skin_Skins_f (void); +void Skin_AllSkins_f (void); +void Skin_NextDownload (void); + +#define RSSHOT_WIDTH 320 +#define RSSHOT_HEIGHT 200 diff --git a/QW/client/cmd.c b/QW/client/cmd.c new file mode 100644 index 0000000..ab6330c --- /dev/null +++ b/QW/client/cmd.c @@ -0,0 +1,748 @@ +/* +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. + +*/ +// cmd.c -- Quake script command processing module + +#include "quakedef.h" + +void Cmd_ForwardToServer (void); + +#define MAX_ALIAS_NAME 32 + +typedef struct cmdalias_s +{ + struct cmdalias_s *next; + char name[MAX_ALIAS_NAME]; + char *value; +} cmdalias_t; + +cmdalias_t *cmd_alias; + +qboolean cmd_wait; + +cvar_t cl_warncmd = {"cl_warncmd", "0"}; + +//============================================================================= + +/* +============ +Cmd_Wait_f + +Causes execution of the remainder of the command buffer to be delayed until +next frame. This allows commands like: +bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2" +============ +*/ +void Cmd_Wait_f (void) +{ + cmd_wait = true; +} + +/* +============================================================================= + + COMMAND BUFFER + +============================================================================= +*/ + +sizebuf_t cmd_text; +byte cmd_text_buf[8192]; + +/* +============ +Cbuf_Init +============ +*/ +void Cbuf_Init (void) +{ + cmd_text.data = cmd_text_buf; + cmd_text.maxsize = sizeof(cmd_text_buf); +} + +/* +============ +Cbuf_AddText + +Adds command text at the end of the buffer +============ +*/ +void Cbuf_AddText (char *text) +{ + int l; + + l = Q_strlen (text); + + if (cmd_text.cursize + l >= cmd_text.maxsize) + { + Con_Printf ("Cbuf_AddText: overflow\n"); + return; + } + SZ_Write (&cmd_text, text, Q_strlen (text)); +} + + +/* +============ +Cbuf_InsertText + +Adds command text immediately after the current command +Adds a \n to the text +FIXME: actually change the command buffer to do less copying +============ +*/ +void Cbuf_InsertText (char *text) +{ + char *temp; + int templen; + +// copy off any commands still remaining in the exec buffer + templen = cmd_text.cursize; + if (templen) + { + temp = Z_Malloc (templen); + Q_memcpy (temp, cmd_text.data, templen); + SZ_Clear (&cmd_text); + } + else + temp = NULL; // shut up compiler + +// add the entire text of the file + Cbuf_AddText (text); + SZ_Write (&cmd_text, "\n", 1); +// add the copied off data + if (templen) + { + SZ_Write (&cmd_text, temp, templen); + Z_Free (temp); + } +} + +/* +============ +Cbuf_Execute +============ +*/ +void Cbuf_Execute (void) +{ + int i; + char *text; + char line[1024]; + int quotes; + + while (cmd_text.cursize) + { +// find a \n or ; line break + text = (char *)cmd_text.data; + + quotes = 0; + for (i=0 ; i< cmd_text.cursize ; i++) + { + if (text[i] == '"') + quotes++; + if ( !(quotes&1) && text[i] == ';') + break; // don't break if inside a quoted string + if (text[i] == '\n') + break; + } + + + memcpy (line, text, i); + line[i] = 0; + +// delete the text from the command buffer and move remaining commands down +// this is necessary because commands (exec, alias) can insert data at the +// beginning of the text buffer + + if (i == cmd_text.cursize) + cmd_text.cursize = 0; + else + { + i++; + cmd_text.cursize -= i; + Q_memcpy (text, text+i, cmd_text.cursize); + } + +// execute the command line + Cmd_ExecuteString (line); + + if (cmd_wait) + { // skip out while text still remains in buffer, leaving it + // for next frame + cmd_wait = false; + break; + } + } +} + +/* +============================================================================== + + SCRIPT COMMANDS + +============================================================================== +*/ + +/* +=============== +Cmd_StuffCmds_f + +Adds command line parameters as script statements +Commands lead with a +, and continue until a - or another + +quake +prog jctest.qp +cmd amlev1 +quake -nosound +cmd amlev1 +=============== +*/ +void Cmd_StuffCmds_f (void) +{ + int i, j; + int s; + char *text, *build, c; + +// build the combined string to parse from + s = 0; + for (i=1 ; i<com_argc ; i++) + { + if (!com_argv[i]) + continue; // NEXTSTEP nulls out -NXHost + s += Q_strlen (com_argv[i]) + 1; + } + if (!s) + return; + + text = Z_Malloc (s+1); + text[0] = 0; + for (i=1 ; i<com_argc ; i++) + { + if (!com_argv[i]) + continue; // NEXTSTEP nulls out -NXHost + Q_strcat (text,com_argv[i]); + if (i != com_argc-1) + Q_strcat (text, " "); + } + +// pull out the commands + build = Z_Malloc (s+1); + build[0] = 0; + + for (i=0 ; i<s-1 ; i++) + { + if (text[i] == '+') + { + i++; + + for (j=i ; (text[j] != '+') && (text[j] != '-') && (text[j] != 0) ; j++) + ; + + c = text[j]; + text[j] = 0; + + Q_strcat (build, text+i); + Q_strcat (build, "\n"); + text[j] = c; + i = j-1; + } + } + + if (build[0]) + Cbuf_InsertText (build); + + Z_Free (text); + Z_Free (build); +} + + +/* +=============== +Cmd_Exec_f +=============== +*/ +void Cmd_Exec_f (void) +{ + char *f; + int mark; + + if (Cmd_Argc () != 2) + { + Con_Printf ("exec <filename> : execute a script file\n"); + return; + } + + // FIXME: is this safe freeing the hunk here??? + mark = Hunk_LowMark (); + f = (char *)COM_LoadHunkFile (Cmd_Argv(1)); + if (!f) + { + Con_Printf ("couldn't exec %s\n",Cmd_Argv(1)); + return; + } + if (!Cvar_Command () && (cl_warncmd.value || developer.value)) + Con_Printf ("execing %s\n",Cmd_Argv(1)); + + Cbuf_InsertText (f); + Hunk_FreeToLowMark (mark); +} + + +/* +=============== +Cmd_Echo_f + +Just prints the rest of the line to the console +=============== +*/ +void Cmd_Echo_f (void) +{ + int i; + + for (i=1 ; i<Cmd_Argc() ; i++) + Con_Printf ("%s ",Cmd_Argv(i)); + Con_Printf ("\n"); +} + +/* +=============== +Cmd_Alias_f + +Creates a new command that executes a command string (possibly ; seperated) +=============== +*/ + +char *CopyString (char *in) +{ + char *out; + + out = Z_Malloc (strlen(in)+1); + strcpy (out, in); + return out; +} + +void Cmd_Alias_f (void) +{ + cmdalias_t *a; + char cmd[1024]; + int i, c; + char *s; + + if (Cmd_Argc() == 1) + { + Con_Printf ("Current alias commands:\n"); + for (a = cmd_alias ; a ; a=a->next) + Con_Printf ("%s : %s\n", a->name, a->value); + return; + } + + s = Cmd_Argv(1); + if (strlen(s) >= MAX_ALIAS_NAME) + { + Con_Printf ("Alias name is too long\n"); + return; + } + + // if the alias allready exists, reuse it + for (a = cmd_alias ; a ; a=a->next) + { + if (!strcmp(s, a->name)) + { + Z_Free (a->value); + break; + } + } + + if (!a) + { + a = Z_Malloc (sizeof(cmdalias_t)); + a->next = cmd_alias; + cmd_alias = a; + } + strcpy (a->name, s); + +// copy the rest of the command line + cmd[0] = 0; // start out with a null string + c = Cmd_Argc(); + for (i=2 ; i< c ; i++) + { + strcat (cmd, Cmd_Argv(i)); + if (i != c) + strcat (cmd, " "); + } + strcat (cmd, "\n"); + + a->value = CopyString (cmd); +} + +/* +============================================================================= + + COMMAND EXECUTION + +============================================================================= +*/ + +typedef struct cmd_function_s +{ + struct cmd_function_s *next; + char *name; + xcommand_t function; +} cmd_function_t; + + +#define MAX_ARGS 80 + +static int cmd_argc; +static char *cmd_argv[MAX_ARGS]; +static char *cmd_null_string = ""; +static char *cmd_args = NULL; + + + +static cmd_function_t *cmd_functions; // possible commands to execute + +/* +============ +Cmd_Argc +============ +*/ +int Cmd_Argc (void) +{ + return cmd_argc; +} + +/* +============ +Cmd_Argv +============ +*/ +char *Cmd_Argv (int arg) +{ + if ( arg >= cmd_argc ) + return cmd_null_string; + return cmd_argv[arg]; +} + +/* +============ +Cmd_Args + +Returns a single string containing argv(1) to argv(argc()-1) +============ +*/ +char *Cmd_Args (void) +{ + if (!cmd_args) + return ""; + return cmd_args; +} + + +/* +============ +Cmd_TokenizeString + +Parses the given string into command line tokens. +============ +*/ +void Cmd_TokenizeString (char *text) +{ + int i; + +// clear the args from the last string + for (i=0 ; i<cmd_argc ; i++) + Z_Free (cmd_argv[i]); + + cmd_argc = 0; + cmd_args = NULL; + + while (1) + { +// skip whitespace up to a /n + while (*text && *text <= ' ' && *text != '\n') + { + text++; + } + + if (*text == '\n') + { // a newline seperates commands in the buffer + text++; + break; + } + + if (!*text) + return; + + if (cmd_argc == 1) + cmd_args = text; + + text = COM_Parse (text); + if (!text) + return; + + if (cmd_argc < MAX_ARGS) + { + cmd_argv[cmd_argc] = Z_Malloc (Q_strlen(com_token)+1); + Q_strcpy (cmd_argv[cmd_argc], com_token); + cmd_argc++; + } + } + +} + + +/* +============ +Cmd_AddCommand +============ +*/ +void Cmd_AddCommand (char *cmd_name, xcommand_t function) +{ + cmd_function_t *cmd; + + if (host_initialized) // because hunk allocation would get stomped + Sys_Error ("Cmd_AddCommand after host_initialized"); + +// fail if the command is a variable name + if (Cvar_VariableString(cmd_name)[0]) + { + Con_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name); + return; + } + +// fail if the command already exists + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + { + if (!Q_strcmp (cmd_name, cmd->name)) + { + Con_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name); + return; + } + } + + cmd = Hunk_Alloc (sizeof(cmd_function_t)); + cmd->name = cmd_name; + cmd->function = function; + cmd->next = cmd_functions; + cmd_functions = cmd; +} + +/* +============ +Cmd_Exists +============ +*/ +qboolean Cmd_Exists (char *cmd_name) +{ + cmd_function_t *cmd; + + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + { + if (!Q_strcmp (cmd_name,cmd->name)) + return true; + } + + return false; +} + + + +/* +============ +Cmd_CompleteCommand +============ +*/ +char *Cmd_CompleteCommand (char *partial) +{ + cmd_function_t *cmd; + int len; + cmdalias_t *a; + + len = Q_strlen(partial); + + if (!len) + return NULL; + +// check for exact match + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + if (!strcmp (partial,cmd->name)) + return cmd->name; + for (a=cmd_alias ; a ; a=a->next) + if (!strcmp (partial, a->name)) + return a->name; + +// check for partial match + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + if (!strncmp (partial,cmd->name, len)) + return cmd->name; + for (a=cmd_alias ; a ; a=a->next) + if (!strncmp (partial, a->name, len)) + return a->name; + + return NULL; +} + +#ifndef SERVERONLY // FIXME +/* +=================== +Cmd_ForwardToServer + +adds the current command line as a clc_stringcmd to the client message. +things like godmode, noclip, etc, are commands directed to the server, +so when they are typed in at the console, they will need to be forwarded. +=================== +*/ +void Cmd_ForwardToServer (void) +{ + if (cls.state == ca_disconnected) + { + Con_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0)); + return; + } + + if (cls.demoplayback) + return; // not really connected + + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + SZ_Print (&cls.netchan.message, Cmd_Argv(0)); + if (Cmd_Argc() > 1) + { + SZ_Print (&cls.netchan.message, " "); + SZ_Print (&cls.netchan.message, Cmd_Args()); + } +} + +// don't forward the first argument +void Cmd_ForwardToServer_f (void) +{ + if (cls.state == ca_disconnected) + { + Con_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0)); + return; + } + + if (Q_strcasecmp(Cmd_Argv(1), "snap") == 0) { + Cbuf_InsertText ("snap\n"); + return; + } + + if (cls.demoplayback) + return; // not really connected + + if (Cmd_Argc() > 1) + { + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + SZ_Print (&cls.netchan.message, Cmd_Args()); + } +} +#else +void Cmd_ForwardToServer (void) +{ +} +#endif + +/* +============ +Cmd_ExecuteString + +A complete command line has been parsed, so try to execute it +FIXME: lookupnoadd the token to speed search? +============ +*/ +void Cmd_ExecuteString (char *text) +{ + cmd_function_t *cmd; + cmdalias_t *a; + + Cmd_TokenizeString (text); + +// execute the command line + if (!Cmd_Argc()) + return; // no tokens + +// check functions + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + { + if (!Q_strcasecmp (cmd_argv[0],cmd->name)) + { + if (!cmd->function) + Cmd_ForwardToServer (); + else + cmd->function (); + return; + } + } + +// check alias + for (a=cmd_alias ; a ; a=a->next) + { + if (!Q_strcasecmp (cmd_argv[0], a->name)) + { + Cbuf_InsertText (a->value); + return; + } + } + +// check cvars + if (!Cvar_Command () && (cl_warncmd.value || developer.value)) + Con_Printf ("Unknown command \"%s\"\n", Cmd_Argv(0)); + +} + + + +/* +================ +Cmd_CheckParm + +Returns the position (1 to argc-1) in the command's argument list +where the given parameter apears, or 0 if not present +================ +*/ +int Cmd_CheckParm (char *parm) +{ + int i; + + if (!parm) + Sys_Error ("Cmd_CheckParm: NULL"); + + for (i = 1; i < Cmd_Argc (); i++) + if (! Q_strcasecmp (parm, Cmd_Argv (i))) + return i; + + return 0; +} + +/* +============ +Cmd_Init +============ +*/ +void Cmd_Init (void) +{ +// +// register our commands +// + Cmd_AddCommand ("stuffcmds",Cmd_StuffCmds_f); + Cmd_AddCommand ("exec",Cmd_Exec_f); + Cmd_AddCommand ("echo",Cmd_Echo_f); + Cmd_AddCommand ("alias",Cmd_Alias_f); + Cmd_AddCommand ("wait", Cmd_Wait_f); +#ifndef SERVERONLY + Cmd_AddCommand ("cmd", Cmd_ForwardToServer_f); +#endif +} + diff --git a/QW/client/cmd.h b/QW/client/cmd.h new file mode 100644 index 0000000..52eca54 --- /dev/null +++ b/QW/client/cmd.h @@ -0,0 +1,107 @@ +/* +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. + +*/ + +// cmd.h -- Command buffer and command execution + +//=========================================================================== + +/* + +Any number of commands can be added in a frame, from several different sources. +Most commands come from either keybindings or console line input, but remote +servers can also send across commands and entire text files can be execed. + +The + command line options are also added to the command buffer. + +The game starts with a Cbuf_AddText ("exec quake.rc\n"); Cbuf_Execute (); + +*/ + + +void Cbuf_Init (void); +// allocates an initial text buffer that will grow as needed + +void Cbuf_AddText (char *text); +// as new commands are generated from the console or keybindings, +// the text is added to the end of the command buffer. + +void Cbuf_InsertText (char *text); +// when a command wants to issue other commands immediately, the text is +// inserted at the beginning of the buffer, before any remaining unexecuted +// commands. + +void Cbuf_Execute (void); +// Pulls off \n terminated lines of text from the command buffer and sends +// them through Cmd_ExecuteString. Stops when the buffer is empty. +// Normally called once per frame, but may be explicitly invoked. +// Do not call inside a command function! + +//=========================================================================== + +/* + +Command execution takes a null terminated string, breaks it into tokens, +then searches for a command or variable that matches the first token. + +*/ + +typedef void (*xcommand_t) (void); + +void Cmd_Init (void); + +void Cmd_AddCommand (char *cmd_name, xcommand_t function); +// called by the init functions of other parts of the program to +// register commands and functions to call for them. +// The cmd_name is referenced later, so it should not be in temp memory +// if function is NULL, the command will be forwarded to the server +// as a clc_stringcmd instead of executed locally + +qboolean Cmd_Exists (char *cmd_name); +// used by the cvar code to check for cvar / command name overlap + +char *Cmd_CompleteCommand (char *partial); +// attempts to match a partial command for automatic command line completion +// returns NULL if nothing fits + +int Cmd_Argc (void); +char *Cmd_Argv (int arg); +char *Cmd_Args (void); +// The functions that execute commands get their parameters with these +// functions. Cmd_Argv () will return an empty string, not a NULL +// if arg > argc, so string operations are allways safe. + +int Cmd_CheckParm (char *parm); +// Returns the position (1 to argc-1) in the command's argument list +// where the given parameter apears, or 0 if not present + +void Cmd_TokenizeString (char *text); +// Takes a null terminated string. Does not need to be /n terminated. +// breaks the string up into arg tokens. + +void Cmd_ExecuteString (char *text); +// Parses a single line of text into arguments and tries to execute it +// as if it was typed at the console + +void Cmd_ForwardToServer (void); +// adds the current command line as a clc_stringcmd to the client message. +// things like godmode, noclip, etc, are commands directed to the server, +// so when they are typed in at the console, they will need to be forwarded. + +void Cmd_StuffCmds_f (void); diff --git a/QW/client/common.c b/QW/client/common.c new file mode 100644 index 0000000..c7e3ca7 --- /dev/null +++ b/QW/client/common.c @@ -0,0 +1,2299 @@ +/* +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. + +*/ +// common.c -- misc functions used in client and server + +#include <ctype.h> + +#ifdef SERVERONLY +#include "qwsvdef.h" +#else +#include "quakedef.h" +#endif + +#define MAX_NUM_ARGVS 50 +#define NUM_SAFE_ARGVS 6 + +usercmd_t nullcmd; // guarenteed to be zero + +static char *largv[MAX_NUM_ARGVS + NUM_SAFE_ARGVS + 1]; +static char *argvdummy = " "; + +static char *safeargvs[NUM_SAFE_ARGVS] = + {"-stdvid", "-nolan", "-nosound", "-nocdaudio", "-nojoy", "-nomouse"}; + +cvar_t registered = {"registered","0"}; + +qboolean com_modified; // set true if using non-id files + +int static_registered = 1; // only for startup check, then set + +qboolean msg_suppress_1 = 0; + +void COM_InitFilesystem (void); +void COM_Path_f (void); + + +// if a packfile directory differs from this, it is assumed to be hacked +#define PAK0_COUNT 339 +#define PAK0_CRC 52883 + +qboolean standard_quake = true, rogue, hipnotic; + +char gamedirfile[MAX_OSPATH]; + +// this graphic needs to be in the pak file to use registered features +unsigned short pop[] = +{ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 +,0x0000,0x0000,0x6600,0x0000,0x0000,0x0000,0x6600,0x0000 +,0x0000,0x0066,0x0000,0x0000,0x0000,0x0000,0x0067,0x0000 +,0x0000,0x6665,0x0000,0x0000,0x0000,0x0000,0x0065,0x6600 +,0x0063,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6563 +,0x0064,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6564 +,0x0064,0x6564,0x0000,0x6469,0x6969,0x6400,0x0064,0x6564 +,0x0063,0x6568,0x6200,0x0064,0x6864,0x0000,0x6268,0x6563 +,0x0000,0x6567,0x6963,0x0064,0x6764,0x0063,0x6967,0x6500 +,0x0000,0x6266,0x6769,0x6a68,0x6768,0x6a69,0x6766,0x6200 +,0x0000,0x0062,0x6566,0x6666,0x6666,0x6666,0x6562,0x0000 +,0x0000,0x0000,0x0062,0x6364,0x6664,0x6362,0x0000,0x0000 +,0x0000,0x0000,0x0000,0x0062,0x6662,0x0000,0x0000,0x0000 +,0x0000,0x0000,0x0000,0x0061,0x6661,0x0000,0x0000,0x0000 +,0x0000,0x0000,0x0000,0x0000,0x6500,0x0000,0x0000,0x0000 +,0x0000,0x0000,0x0000,0x0000,0x6400,0x0000,0x0000,0x0000 +}; + +/* + + +All of Quake's data access is through a hierchal file system, but the contents of the file system can be transparently merged from several sources. + +The "base directory" is the path to the directory holding the quake.exe and all game directories. The sys_* files pass this to host_init in quakeparms_t->basedir. This can be overridden with the "-basedir" command line parm to allow code debugging in a different directory. The base directory is +only used during filesystem initialization. + +The "game directory" is the first tree on the search path and directory that all generated files (savegames, screenshots, demos, config files) will be saved to. This can be overridden with the "-game" command line parameter. The game directory can never be changed while quake is executing. This is a precacution against having a malicious server instruct clients to write files over areas they shouldn't. + +The "cache directory" is only used during development to save network bandwidth, especially over ISDN / T1 lines. If there is a cache directory +specified, when a file is found by the normal search path, it will be mirrored +into the cache directory, then opened there. + +*/ + +//============================================================================ + + +// ClearLink is used for new headnodes +void ClearLink (link_t *l) +{ + l->prev = l->next = l; +} + +void RemoveLink (link_t *l) +{ + l->next->prev = l->prev; + l->prev->next = l->next; +} + +void InsertLinkBefore (link_t *l, link_t *before) +{ + l->next = before; + l->prev = before->prev; + l->prev->next = l; + l->next->prev = l; +} +void InsertLinkAfter (link_t *l, link_t *after) +{ + l->next = after->next; + l->prev = after; + l->prev->next = l; + l->next->prev = l; +} + +/* +============================================================================ + + LIBRARY REPLACEMENT FUNCTIONS + +============================================================================ +*/ + +#if 0 +void Q_memset (void *dest, int fill, int count) +{ + int i; + + if ( (((long)dest | count) & 3) == 0) + { + count >>= 2; + fill = fill | (fill<<8) | (fill<<16) | (fill<<24); + for (i=0 ; i<count ; i++) + ((int *)dest)[i] = fill; + } + else + for (i=0 ; i<count ; i++) + ((byte *)dest)[i] = fill; +} + +void Q_memcpy (void *dest, void *src, int count) +{ + int i; + + if (( ( (long)dest | (long)src | count) & 3) == 0 ) + { + count>>=2; + for (i=0 ; i<count ; i++) + ((int *)dest)[i] = ((int *)src)[i]; + } + else + for (i=0 ; i<count ; i++) + ((byte *)dest)[i] = ((byte *)src)[i]; +} + +int Q_memcmp (void *m1, void *m2, int count) +{ + while(count) + { + count--; + if (((byte *)m1)[count] != ((byte *)m2)[count]) + return -1; + } + return 0; +} + +void Q_strcpy (char *dest, char *src) +{ + while (*src) + { + *dest++ = *src++; + } + *dest++ = 0; +} + +void Q_strncpy (char *dest, char *src, int count) +{ + while (*src && count--) + { + *dest++ = *src++; + } + if (count) + *dest++ = 0; +} + +int Q_strlen (char *str) +{ + int count; + + count = 0; + while (str[count]) + count++; + + return count; +} + +char *Q_strrchr(char *s, char c) +{ + int len = Q_strlen(s); + s += len; + while (len--) + if (*--s == c) return s; + return 0; +} + +void Q_strcat (char *dest, char *src) +{ + dest += Q_strlen(dest); + Q_strcpy (dest, src); +} + +int Q_strcmp (char *s1, char *s2) +{ + while (1) + { + if (*s1 != *s2) + return -1; // strings not equal + if (!*s1) + return 0; // strings are equal + s1++; + s2++; + } + + return -1; +} + +int Q_strncmp (char *s1, char *s2, int count) +{ + while (1) + { + if (!count--) + return 0; + if (*s1 != *s2) + return -1; // strings not equal + if (!*s1) + return 0; // strings are equal + s1++; + s2++; + } + + return -1; +} + +int Q_strncasecmp (char *s1, char *s2, int n) +{ + int c1, c2; + + while (1) + { + c1 = *s1++; + c2 = *s2++; + + if (!n--) + return 0; // strings are equal until end point + + if (c1 != c2) + { + if (c1 >= 'a' && c1 <= 'z') + c1 -= ('a' - 'A'); + if (c2 >= 'a' && c2 <= 'z') + c2 -= ('a' - 'A'); + if (c1 != c2) + return -1; // strings not equal + } + if (!c1) + return 0; // strings are equal +// s1++; +// s2++; + } + + return -1; +} + +int Q_strcasecmp (char *s1, char *s2) +{ + return Q_strncasecmp (s1, s2, 99999); +} + +#endif + +int Q_atoi (char *str) +{ + int val; + int sign; + int c; + + if (*str == '-') + { + sign = -1; + str++; + } + else + sign = 1; + + val = 0; + +// +// check for hex +// + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) + { + str += 2; + while (1) + { + c = *str++; + if (c >= '0' && c <= '9') + val = (val<<4) + c - '0'; + else if (c >= 'a' && c <= 'f') + val = (val<<4) + c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + val = (val<<4) + c - 'A' + 10; + else + return val*sign; + } + } + +// +// check for character +// + if (str[0] == '\'') + { + return sign * str[1]; + } + +// +// assume decimal +// + while (1) + { + c = *str++; + if (c <'0' || c > '9') + return val*sign; + val = val*10 + c - '0'; + } + + return 0; +} + + +float Q_atof (char *str) +{ + double val; + int sign; + int c; + int decimal, total; + + if (*str == '-') + { + sign = -1; + str++; + } + else + sign = 1; + + val = 0; + +// +// check for hex +// + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) + { + str += 2; + while (1) + { + c = *str++; + if (c >= '0' && c <= '9') + val = (val*16) + c - '0'; + else if (c >= 'a' && c <= 'f') + val = (val*16) + c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + val = (val*16) + c - 'A' + 10; + else + return val*sign; + } + } + +// +// check for character +// + if (str[0] == '\'') + { + return sign * str[1]; + } + +// +// assume decimal +// + decimal = -1; + total = 0; + while (1) + { + c = *str++; + if (c == '.') + { + decimal = total; + continue; + } + if (c <'0' || c > '9') + break; + val = val*10 + c - '0'; + total++; + } + + if (decimal == -1) + return val*sign; + while (total > decimal) + { + val /= 10; + total--; + } + + return val*sign; +} + +/* +============================================================================ + + BYTE ORDER FUNCTIONS + +============================================================================ +*/ + +qboolean bigendien; + +short (*BigShort) (short l); +short (*LittleShort) (short l); +int (*BigLong) (int l); +int (*LittleLong) (int l); +float (*BigFloat) (float l); +float (*LittleFloat) (float l); + +short ShortSwap (short l) +{ + byte b1,b2; + + b1 = l&255; + b2 = (l>>8)&255; + + return (b1<<8) + b2; +} + +short ShortNoSwap (short l) +{ + return l; +} + +int LongSwap (int l) +{ + byte b1,b2,b3,b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int LongNoSwap (int l) +{ + return l; +} + +float FloatSwap (float f) +{ + union + { + float f; + byte b[4]; + } dat1, dat2; + + + dat1.f = f; + dat2.b[0] = dat1.b[3]; + dat2.b[1] = dat1.b[2]; + dat2.b[2] = dat1.b[1]; + dat2.b[3] = dat1.b[0]; + return dat2.f; +} + +float FloatNoSwap (float f) +{ + return f; +} + +/* +============================================================================== + + MESSAGE IO FUNCTIONS + +Handles byte ordering and avoids alignment errors +============================================================================== +*/ + +// +// writing functions +// + +void MSG_WriteChar (sizebuf_t *sb, int c) +{ + byte *buf; + +#ifdef PARANOID + if (c < -128 || c > 127) + Sys_Error ("MSG_WriteChar: range error"); +#endif + + buf = SZ_GetSpace (sb, 1); + buf[0] = c; +} + +void MSG_WriteByte (sizebuf_t *sb, int c) +{ + byte *buf; + +#ifdef PARANOID + if (c < 0 || c > 255) + Sys_Error ("MSG_WriteByte: range error"); +#endif + + buf = SZ_GetSpace (sb, 1); + buf[0] = c; +} + +void MSG_WriteShort (sizebuf_t *sb, int c) +{ + byte *buf; + +#ifdef PARANOID + if (c < ((short)0x8000) || c > (short)0x7fff) + Sys_Error ("MSG_WriteShort: range error"); +#endif + + buf = SZ_GetSpace (sb, 2); + buf[0] = c&0xff; + buf[1] = c>>8; +} + +void MSG_WriteLong (sizebuf_t *sb, int c) +{ + byte *buf; + + buf = SZ_GetSpace (sb, 4); + buf[0] = c&0xff; + buf[1] = (c>>8)&0xff; + buf[2] = (c>>16)&0xff; + buf[3] = c>>24; +} + +void MSG_WriteFloat (sizebuf_t *sb, float f) +{ + union + { + float f; + int l; + } dat; + + + dat.f = f; + dat.l = LittleLong (dat.l); + + SZ_Write (sb, &dat.l, 4); +} + +void MSG_WriteString (sizebuf_t *sb, char *s) +{ + if (!s) + SZ_Write (sb, "", 1); + else + SZ_Write (sb, s, Q_strlen(s)+1); +} + +void MSG_WriteCoord (sizebuf_t *sb, float f) +{ + MSG_WriteShort (sb, (int)(f*8)); +} + +void MSG_WriteAngle (sizebuf_t *sb, float f) +{ + MSG_WriteByte (sb, (int)(f*256/360) & 255); +} + +void MSG_WriteAngle16 (sizebuf_t *sb, float f) +{ + MSG_WriteShort (sb, (int)(f*65536/360) & 65535); +} + +void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd) +{ + int bits; + +// +// send the movement message +// + bits = 0; + if (cmd->angles[0] != from->angles[0]) + bits |= CM_ANGLE1; + if (cmd->angles[1] != from->angles[1]) + bits |= CM_ANGLE2; + if (cmd->angles[2] != from->angles[2]) + bits |= CM_ANGLE3; + if (cmd->forwardmove != from->forwardmove) + bits |= CM_FORWARD; + if (cmd->sidemove != from->sidemove) + bits |= CM_SIDE; + if (cmd->upmove != from->upmove) + bits |= CM_UP; + if (cmd->buttons != from->buttons) + bits |= CM_BUTTONS; + if (cmd->impulse != from->impulse) + bits |= CM_IMPULSE; + + MSG_WriteByte (buf, bits); + + if (bits & CM_ANGLE1) + MSG_WriteAngle16 (buf, cmd->angles[0]); + if (bits & CM_ANGLE2) + MSG_WriteAngle16 (buf, cmd->angles[1]); + if (bits & CM_ANGLE3) + MSG_WriteAngle16 (buf, cmd->angles[2]); + + if (bits & CM_FORWARD) + MSG_WriteShort (buf, cmd->forwardmove); + if (bits & CM_SIDE) + MSG_WriteShort (buf, cmd->sidemove); + if (bits & CM_UP) + MSG_WriteShort (buf, cmd->upmove); + + if (bits & CM_BUTTONS) + MSG_WriteByte (buf, cmd->buttons); + if (bits & CM_IMPULSE) + MSG_WriteByte (buf, cmd->impulse); + MSG_WriteByte (buf, cmd->msec); +} + + +// +// reading functions +// +int msg_readcount; +qboolean msg_badread; + +void MSG_BeginReading (void) +{ + msg_readcount = 0; + msg_badread = false; +} + +int MSG_GetReadCount(void) +{ + return msg_readcount; +} + +// returns -1 and sets msg_badread if no more characters are available +int MSG_ReadChar (void) +{ + int c; + + if (msg_readcount+1 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = (signed char)net_message.data[msg_readcount]; + msg_readcount++; + + return c; +} + +int MSG_ReadByte (void) +{ + int c; + + if (msg_readcount+1 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = (unsigned char)net_message.data[msg_readcount]; + msg_readcount++; + + return c; +} + +int MSG_ReadShort (void) +{ + int c; + + if (msg_readcount+2 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = (short)(net_message.data[msg_readcount] + + (net_message.data[msg_readcount+1]<<8)); + + msg_readcount += 2; + + return c; +} + +int MSG_ReadLong (void) +{ + int c; + + if (msg_readcount+4 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = net_message.data[msg_readcount] + + (net_message.data[msg_readcount+1]<<8) + + (net_message.data[msg_readcount+2]<<16) + + (net_message.data[msg_readcount+3]<<24); + + msg_readcount += 4; + + return c; +} + +float MSG_ReadFloat (void) +{ + union + { + byte b[4]; + float f; + int l; + } dat; + + dat.b[0] = net_message.data[msg_readcount]; + dat.b[1] = net_message.data[msg_readcount+1]; + dat.b[2] = net_message.data[msg_readcount+2]; + dat.b[3] = net_message.data[msg_readcount+3]; + msg_readcount += 4; + + dat.l = LittleLong (dat.l); + + return dat.f; +} + +char *MSG_ReadString (void) +{ + static char string[2048]; + int l,c; + + l = 0; + do + { + c = MSG_ReadChar (); + if (c == -1 || c == 0) + break; + string[l] = c; + l++; + } while (l < sizeof(string)-1); + + string[l] = 0; + + return string; +} + +char *MSG_ReadStringLine (void) +{ + static char string[2048]; + int l,c; + + l = 0; + do + { + c = MSG_ReadChar (); + if (c == -1 || c == 0 || c == '\n') + break; + string[l] = c; + l++; + } while (l < sizeof(string)-1); + + string[l] = 0; + + return string; +} + +float MSG_ReadCoord (void) +{ + return MSG_ReadShort() * (1.0/8); +} + +float MSG_ReadAngle (void) +{ + return MSG_ReadChar() * (360.0/256); +} + +float MSG_ReadAngle16 (void) +{ + return MSG_ReadShort() * (360.0/65536); +} + +void MSG_ReadDeltaUsercmd (usercmd_t *from, usercmd_t *move) +{ + int bits; + + memcpy (move, from, sizeof(*move)); + + bits = MSG_ReadByte (); + +// read current angles + if (bits & CM_ANGLE1) + move->angles[0] = MSG_ReadAngle16 (); + if (bits & CM_ANGLE2) + move->angles[1] = MSG_ReadAngle16 (); + if (bits & CM_ANGLE3) + move->angles[2] = MSG_ReadAngle16 (); + +// read movement + if (bits & CM_FORWARD) + move->forwardmove = MSG_ReadShort (); + if (bits & CM_SIDE) + move->sidemove = MSG_ReadShort (); + if (bits & CM_UP) + move->upmove = MSG_ReadShort (); + +// read buttons + if (bits & CM_BUTTONS) + move->buttons = MSG_ReadByte (); + + if (bits & CM_IMPULSE) + move->impulse = MSG_ReadByte (); + +// read time to run command + move->msec = MSG_ReadByte (); +} + + +//=========================================================================== + +void SZ_Clear (sizebuf_t *buf) +{ + buf->cursize = 0; + buf->overflowed = false; +} + +void *SZ_GetSpace (sizebuf_t *buf, int length) +{ + void *data; + + if (buf->cursize + length > buf->maxsize) + { + if (!buf->allowoverflow) + Sys_Error ("SZ_GetSpace: overflow without allowoverflow set (%d)", buf->maxsize); + + if (length > buf->maxsize) + Sys_Error ("SZ_GetSpace: %i is > full buffer size", length); + + Sys_Printf ("SZ_GetSpace: overflow\n"); // because Con_Printf may be redirected + SZ_Clear (buf); + buf->overflowed = true; + } + + data = buf->data + buf->cursize; + buf->cursize += length; + + return data; +} + +void SZ_Write (sizebuf_t *buf, void *data, int length) +{ + Q_memcpy (SZ_GetSpace(buf,length),data,length); +} + +void SZ_Print (sizebuf_t *buf, char *data) +{ + int len; + + len = Q_strlen(data)+1; + + if (!buf->cursize || buf->data[buf->cursize-1]) + Q_memcpy ((byte *)SZ_GetSpace(buf, len),data,len); // no trailing 0 + else + Q_memcpy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0 +} + + +//============================================================================ + + +/* +============ +COM_SkipPath +============ +*/ +char *COM_SkipPath (char *pathname) +{ + char *last; + + last = pathname; + while (*pathname) + { + if (*pathname=='/') + last = pathname+1; + pathname++; + } + return last; +} + +/* +============ +COM_StripExtension +============ +*/ +void COM_StripExtension (char *in, char *out) +{ + while (*in && *in != '.') + *out++ = *in++; + *out = 0; +} + +/* +============ +COM_FileExtension +============ +*/ +char *COM_FileExtension (char *in) +{ + static char exten[8]; + int i; + + while (*in && *in != '.') + in++; + if (!*in) + return ""; + in++; + for (i=0 ; i<7 && *in ; i++,in++) + exten[i] = *in; + exten[i] = 0; + return exten; +} + +/* +============ +COM_FileBase +============ +*/ +void COM_FileBase (char *in, char *out) +{ + char *s, *s2; + + s = in + strlen(in) - 1; + + while (s != in && *s != '.') + s--; + + for (s2 = s ; *s2 && *s2 != '/' ; s2--) + ; + + if (s-s2 < 2) + strcpy (out,"?model?"); + else + { + s--; + strncpy (out,s2+1, s-s2); + out[s-s2] = 0; + } +} + + +/* +================== +COM_DefaultExtension +================== +*/ +void COM_DefaultExtension (char *path, char *extension) +{ + char *src; +// +// if path doesn't have a .EXT, append extension +// (extension should include the .) +// + src = path + strlen(path) - 1; + + while (*src != '/' && src != path) + { + if (*src == '.') + return; // it has an extension + src--; + } + + strcat (path, extension); +} + +//============================================================================ + +char com_token[1024]; +int com_argc; +char **com_argv; + + +/* +============== +COM_Parse + +Parse a token out of a string +============== +*/ +char *COM_Parse (char *data) +{ + int c; + int len; + + len = 0; + com_token[0] = 0; + + if (!data) + return NULL; + +// skip whitespace +skipwhite: + while ( (c = *data) <= ' ') + { + if (c == 0) + return NULL; // end of file; + data++; + } + +// skip // comments + if (c=='/' && data[1] == '/') + { + while (*data && *data != '\n') + data++; + goto skipwhite; + } + + +// handle quoted strings specially + if (c == '\"') + { + data++; + while (1) + { + c = *data++; + if (c=='\"' || !c) + { + com_token[len] = 0; + return data; + } + com_token[len] = c; + len++; + } + } + +// parse a regular word + do + { + com_token[len] = c; + data++; + len++; + c = *data; + } while (c>32); + + com_token[len] = 0; + return data; +} + + +/* +================ +COM_CheckParm + +Returns the position (1 to argc-1) in the program's argument list +where the given parameter apears, or 0 if not present +================ +*/ +int COM_CheckParm (char *parm) +{ + int i; + + for (i=1 ; i<com_argc ; i++) + { + if (!com_argv[i]) + continue; // NEXTSTEP sometimes clears appkit vars. + if (!Q_strcmp (parm,com_argv[i])) + return i; + } + + return 0; +} + +/* +================ +COM_CheckRegistered + +Looks for the pop.txt file and verifies it. +Sets the "registered" cvar. +Immediately exits out if an alternate game was attempted to be started without +being registered. +================ +*/ +void COM_CheckRegistered (void) +{ + FILE *h; + unsigned short check[128]; + int i; + + COM_FOpenFile("gfx/pop.lmp", &h); + static_registered = 0; + + if (!h) + { + Con_Printf ("Playing shareware version.\n"); +#ifndef SERVERONLY +// FIXME DEBUG -- only temporary + if (com_modified) + Sys_Error ("You must have the registered version to play QuakeWorld"); +#endif + return; + } + + fread (check, 1, sizeof(check), h); + fclose (h); + + for (i=0 ; i<128 ; i++) + if (pop[i] != (unsigned short)BigShort (check[i])) + Sys_Error ("Corrupted data file."); + + Cvar_Set ("registered", "1"); + static_registered = 1; + Con_Printf ("Playing registered version.\n"); +} + + + +/* +================ +COM_InitArgv +================ +*/ +void COM_InitArgv (int argc, char **argv) +{ + qboolean safe; + int i; + + safe = false; + + for (com_argc=0 ; (com_argc<MAX_NUM_ARGVS) && (com_argc < argc) ; + com_argc++) + { + largv[com_argc] = argv[com_argc]; + if (!Q_strcmp ("-safe", argv[com_argc])) + safe = true; + } + + if (safe) + { + // force all the safe-mode switches. Note that we reserved extra space in + // case we need to add these, so we don't need an overflow check + for (i=0 ; i<NUM_SAFE_ARGVS ; i++) + { + largv[com_argc] = safeargvs[i]; + com_argc++; + } + } + + largv[com_argc] = argvdummy; + com_argv = largv; +} + +/* +================ +COM_AddParm + +Adds the given string at the end of the current argument list +================ +*/ +void COM_AddParm (char *parm) +{ + largv[com_argc++] = parm; +} + + +/* +================ +COM_Init +================ +*/ +void COM_Init (void) +{ + byte swaptest[2] = {1,0}; + +// set the byte swapping variables in a portable manner + if ( *(short *)swaptest == 1) + { + bigendien = false; + BigShort = ShortSwap; + LittleShort = ShortNoSwap; + BigLong = LongSwap; + LittleLong = LongNoSwap; + BigFloat = FloatSwap; + LittleFloat = FloatNoSwap; + } + else + { + bigendien = true; + BigShort = ShortNoSwap; + LittleShort = ShortSwap; + BigLong = LongNoSwap; + LittleLong = LongSwap; + BigFloat = FloatNoSwap; + LittleFloat = FloatSwap; + } + + Cvar_RegisterVariable (®istered); + Cmd_AddCommand ("path", COM_Path_f); + + COM_InitFilesystem (); + COM_CheckRegistered (); +} + + +/* +============ +va + +does a varargs printf into a temp buffer, so I don't need to have +varargs versions of all text functions. +FIXME: make this buffer size safe someday +============ +*/ +char *va(char *format, ...) +{ + va_list argptr; + static char string[1024]; + + va_start (argptr, format); + vsprintf (string, format,argptr); + va_end (argptr); + + return string; +} + + +/// just for debugging +int memsearch (byte *start, int count, int search) +{ + int i; + + for (i=0 ; i<count ; i++) + if (start[i] == search) + return i; + return -1; +} + +/* +============================================================================= + +QUAKE FILESYSTEM + +============================================================================= +*/ + +int com_filesize; + + +// +// in memory +// + +typedef struct +{ + char name[MAX_QPATH]; + int filepos, filelen; +} packfile_t; + +typedef struct pack_s +{ + char filename[MAX_OSPATH]; + FILE *handle; + int numfiles; + packfile_t *files; +} pack_t; + +// +// on disk +// +typedef struct +{ + char name[56]; + int filepos, filelen; +} dpackfile_t; + +typedef struct +{ + char id[4]; + int dirofs; + int dirlen; +} dpackheader_t; + +#define MAX_FILES_IN_PACK 2048 + +char com_gamedir[MAX_OSPATH]; +char com_basedir[MAX_OSPATH]; + +typedef struct searchpath_s +{ + char filename[MAX_OSPATH]; + pack_t *pack; // only one of filename / pack will be used + struct searchpath_s *next; +} searchpath_t; + +searchpath_t *com_searchpaths; +searchpath_t *com_base_searchpaths; // without gamedirs + +/* +================ +COM_filelength +================ +*/ +int COM_filelength (FILE *f) +{ + int pos; + int end; + + pos = ftell (f); + fseek (f, 0, SEEK_END); + end = ftell (f); + fseek (f, pos, SEEK_SET); + + return end; +} + +int COM_FileOpenRead (char *path, FILE **hndl) +{ + FILE *f; + + f = fopen(path, "rb"); + if (!f) + { + *hndl = NULL; + return -1; + } + *hndl = f; + + return COM_filelength(f); +} + +/* +============ +COM_Path_f + +============ +*/ +void COM_Path_f (void) +{ + searchpath_t *s; + + Con_Printf ("Current search path:\n"); + for (s=com_searchpaths ; s ; s=s->next) + { + if (s == com_base_searchpaths) + Con_Printf ("----------\n"); + if (s->pack) + Con_Printf ("%s (%i files)\n", s->pack->filename, s->pack->numfiles); + else + Con_Printf ("%s\n", s->filename); + } +} + +/* +============ +COM_WriteFile + +The filename will be prefixed by the current game directory +============ +*/ +void COM_WriteFile (char *filename, void *data, int len) +{ + FILE *f; + char name[MAX_OSPATH]; + + sprintf (name, "%s/%s", com_gamedir, filename); + + f = fopen (name, "wb"); + if (!f) { + Sys_mkdir(com_gamedir); + f = fopen (name, "wb"); + if (!f) + Sys_Error ("Error opening %s", filename); + } + + Sys_Printf ("COM_WriteFile: %s\n", name); + fwrite (data, 1, len, f); + fclose (f); +} + + +/* +============ +COM_CreatePath + +Only used for CopyFile and download +============ +*/ +void COM_CreatePath (char *path) +{ + char *ofs; + + for (ofs = path+1 ; *ofs ; ofs++) + { + if (*ofs == '/') + { // create the directory + *ofs = 0; + Sys_mkdir (path); + *ofs = '/'; + } + } +} + + +/* +=========== +COM_CopyFile + +Copies a file over from the net to the local cache, creating any directories +needed. This is for the convenience of developers using ISDN from home. +=========== +*/ +void COM_CopyFile (char *netpath, char *cachepath) +{ + FILE *in, *out; + int remaining, count; + char buf[4096]; + + remaining = COM_FileOpenRead (netpath, &in); + COM_CreatePath (cachepath); // create directories up to the cache file + out = fopen(cachepath, "wb"); + if (!out) + Sys_Error ("Error opening %s", cachepath); + + while (remaining) + { + if (remaining < sizeof(buf)) + count = remaining; + else + count = sizeof(buf); + fread (buf, 1, count, in); + fwrite (buf, 1, count, out); + remaining -= count; + } + + fclose (in); + fclose (out); +} + +/* +=========== +COM_FindFile + +Finds the file in the search path. +Sets com_filesize and one of handle or file +=========== +*/ +int file_from_pak; // global indicating file came from pack file ZOID + +int COM_FOpenFile (char *filename, FILE **file) +{ + searchpath_t *search; + char netpath[MAX_OSPATH]; + pack_t *pak; + int i; + int findtime; + + file_from_pak = 0; + +// +// search through the path, one element at a time +// + for (search = com_searchpaths ; search ; search = search->next) + { + // is the element a pak file? + if (search->pack) + { + // look through all the pak file elements + pak = search->pack; + for (i=0 ; i<pak->numfiles ; i++) + if (!strcmp (pak->files[i].name, filename)) + { // found it! + Sys_Printf ("PackFile: %s : %s\n",pak->filename, filename); + // open a new file on the pakfile + *file = fopen (pak->filename, "rb"); + if (!*file) + Sys_Error ("Couldn't reopen %s", pak->filename); + fseek (*file, pak->files[i].filepos, SEEK_SET); + com_filesize = pak->files[i].filelen; + file_from_pak = 1; + return com_filesize; + } + } + else + { + // check a file in the directory tree + if (!static_registered) + { // if not a registered version, don't ever go beyond base + if ( strchr (filename, '/') || strchr (filename,'\\')) + continue; + } + + sprintf (netpath, "%s/%s",search->filename, filename); + + findtime = Sys_FileTime (netpath); + if (findtime == -1) + continue; + + Sys_Printf ("FindFile: %s\n",netpath); + + *file = fopen (netpath, "rb"); + return COM_filelength (*file); + } + + } + + Sys_Printf ("FindFile: can't find %s\n", filename); + + *file = NULL; + com_filesize = -1; + return -1; +} + +/* +============ +COM_LoadFile + +Filename are reletive to the quake directory. +Allways appends a 0 byte to the loaded data. +============ +*/ +cache_user_t *loadcache; +byte *loadbuf; +int loadsize; +byte *COM_LoadFile (char *path, int usehunk) +{ + FILE *h; + byte *buf; + char base[32]; + int len; + + buf = NULL; // quiet compiler warning + +// look for it in the filesystem or pack files + len = com_filesize = COM_FOpenFile (path, &h); + if (!h) + return NULL; + +// extract the filename base name for hunk tag + COM_FileBase (path, base); + + if (usehunk == 1) + buf = Hunk_AllocName (len+1, base); + else if (usehunk == 2) + buf = Hunk_TempAlloc (len+1); + else if (usehunk == 0) + buf = Z_Malloc (len+1); + else if (usehunk == 3) + buf = Cache_Alloc (loadcache, len+1, base); + else if (usehunk == 4) + { + if (len+1 > loadsize) + buf = Hunk_TempAlloc (len+1); + else + buf = loadbuf; + } + else + Sys_Error ("COM_LoadFile: bad usehunk"); + + if (!buf) + Sys_Error ("COM_LoadFile: not enough space for %s", path); + + ((byte *)buf)[len] = 0; +#ifndef SERVERONLY + Draw_BeginDisc (); +#endif + fread (buf, 1, len, h); + fclose (h); +#ifndef SERVERONLY + Draw_EndDisc (); +#endif + + return buf; +} + +byte *COM_LoadHunkFile (char *path) +{ + return COM_LoadFile (path, 1); +} + +byte *COM_LoadTempFile (char *path) +{ + return COM_LoadFile (path, 2); +} + +void COM_LoadCacheFile (char *path, struct cache_user_s *cu) +{ + loadcache = cu; + COM_LoadFile (path, 3); +} + +// uses temp hunk if larger than bufsize +byte *COM_LoadStackFile (char *path, void *buffer, int bufsize) +{ + byte *buf; + + loadbuf = (byte *)buffer; + loadsize = bufsize; + buf = COM_LoadFile (path, 4); + + return buf; +} + +/* +================= +COM_LoadPackFile + +Takes an explicit (not game tree related) path to a pak file. + +Loads the header and directory, adding the files at the beginning +of the list so they override previous pack files. +================= +*/ +pack_t *COM_LoadPackFile (char *packfile) +{ + dpackheader_t header; + int i; + packfile_t *newfiles; + int numpackfiles; + pack_t *pack; + FILE *packhandle; + dpackfile_t info[MAX_FILES_IN_PACK]; + unsigned short crc; + + if (COM_FileOpenRead (packfile, &packhandle) == -1) + return NULL; + + fread (&header, 1, sizeof(header), packhandle); + if (header.id[0] != 'P' || header.id[1] != 'A' + || header.id[2] != 'C' || header.id[3] != 'K') + Sys_Error ("%s is not a packfile", packfile); + header.dirofs = LittleLong (header.dirofs); + header.dirlen = LittleLong (header.dirlen); + + numpackfiles = header.dirlen / sizeof(dpackfile_t); + + if (numpackfiles > MAX_FILES_IN_PACK) + Sys_Error ("%s has %i files", packfile, numpackfiles); + + if (numpackfiles != PAK0_COUNT) + com_modified = true; // not the original file + + newfiles = Z_Malloc (numpackfiles * sizeof(packfile_t)); + + fseek (packhandle, header.dirofs, SEEK_SET); + fread (&info, 1, header.dirlen, packhandle); + +// crc the directory to check for modifications + crc = CRC_Block((byte *)info, header.dirlen); + +// CRC_Init (&crc); +// for (i=0 ; i<header.dirlen ; i++) +// CRC_ProcessByte (&crc, ((byte *)info)[i]); + if (crc != PAK0_CRC) + com_modified = true; + +// parse the directory + for (i=0 ; i<numpackfiles ; i++) + { + strcpy (newfiles[i].name, info[i].name); + newfiles[i].filepos = LittleLong(info[i].filepos); + newfiles[i].filelen = LittleLong(info[i].filelen); + } + + pack = Z_Malloc (sizeof (pack_t)); + strcpy (pack->filename, packfile); + pack->handle = packhandle; + pack->numfiles = numpackfiles; + pack->files = newfiles; + + Con_Printf ("Added packfile %s (%i files)\n", packfile, numpackfiles); + return pack; +} + + +/* +================ +COM_AddGameDirectory + +Sets com_gamedir, adds the directory to the head of the path, +then loads and adds pak1.pak pak2.pak ... +================ +*/ +void COM_AddGameDirectory (char *dir) +{ + int i; + searchpath_t *search; + pack_t *pak; + char pakfile[MAX_OSPATH]; + char *p; + + if ((p = strrchr(dir, '/')) != NULL) + strcpy(gamedirfile, ++p); + else + strcpy(gamedirfile, p); + strcpy (com_gamedir, dir); + +// +// add the directory to the search path +// + search = Hunk_Alloc (sizeof(searchpath_t)); + strcpy (search->filename, dir); + search->next = com_searchpaths; + com_searchpaths = search; + +// +// add any pak files in the format pak0.pak pak1.pak, ... +// + for (i=0 ; ; i++) + { + sprintf (pakfile, "%s/pak%i.pak", dir, i); + pak = COM_LoadPackFile (pakfile); + if (!pak) + break; + search = Hunk_Alloc (sizeof(searchpath_t)); + search->pack = pak; + search->next = com_searchpaths; + com_searchpaths = search; + } + +} + +/* +================ +COM_Gamedir + +Sets the gamedir and path to a different directory. +================ +*/ +void COM_Gamedir (char *dir) +{ + searchpath_t *search, *next; + int i; + pack_t *pak; + char pakfile[MAX_OSPATH]; + + if (strstr(dir, "..") || strstr(dir, "/") + || strstr(dir, "\\") || strstr(dir, ":") ) + { + Con_Printf ("Gamedir should be a single filename, not a path\n"); + return; + } + + if (!strcmp(gamedirfile, dir)) + return; // still the same + strcpy (gamedirfile, dir); + + // + // free up any current game dir info + // + while (com_searchpaths != com_base_searchpaths) + { + if (com_searchpaths->pack) + { + fclose (com_searchpaths->pack->handle); + Z_Free (com_searchpaths->pack->files); + Z_Free (com_searchpaths->pack); + } + next = com_searchpaths->next; + Z_Free (com_searchpaths); + com_searchpaths = next; + } + + // + // flush all data, so it will be forced to reload + // + Cache_Flush (); + + if (!strcmp(dir,"id1") || !strcmp(dir, "qw")) + return; + + sprintf (com_gamedir, "%s/%s", com_basedir, dir); + + // + // add the directory to the search path + // + search = Z_Malloc (sizeof(searchpath_t)); + strcpy (search->filename, com_gamedir); + search->next = com_searchpaths; + com_searchpaths = search; + + // + // add any pak files in the format pak0.pak pak1.pak, ... + // + for (i=0 ; ; i++) + { + sprintf (pakfile, "%s/pak%i.pak", com_gamedir, i); + pak = COM_LoadPackFile (pakfile); + if (!pak) + break; + search = Z_Malloc (sizeof(searchpath_t)); + search->pack = pak; + search->next = com_searchpaths; + com_searchpaths = search; + } +} + +/* +================ +COM_InitFilesystem +================ +*/ +void COM_InitFilesystem (void) +{ + int i; + +// +// -basedir <path> +// Overrides the system supplied base directory (under id1) +// + i = COM_CheckParm ("-basedir"); + if (i && i < com_argc-1) + strcpy (com_basedir, com_argv[i+1]); + else + strcpy (com_basedir, host_parms.basedir); + +// +// start up with id1 by default +// + COM_AddGameDirectory (va("%s/id1", com_basedir) ); + COM_AddGameDirectory (va("%s/qw", com_basedir) ); + + // any set gamedirs will be freed up to here + com_base_searchpaths = com_searchpaths; +} + + + +/* +===================================================================== + + INFO STRINGS + +===================================================================== +*/ + +/* +=============== +Info_ValueForKey + +Searches the string for the given +key and returns the associated value, or an empty string. +=============== +*/ +char *Info_ValueForKey (char *s, char *key) +{ + char pkey[512]; + static char value[4][512]; // use two buffers so compares + // work without stomping on each other + static int valueindex; + char *o; + + valueindex = (valueindex + 1) % 4; + if (*s == '\\') + s++; + while (1) + { + o = pkey; + while (*s != '\\') + { + if (!*s) + return ""; + *o++ = *s++; + } + *o = 0; + s++; + + o = value[valueindex]; + + while (*s != '\\' && *s) + { + if (!*s) + return ""; + *o++ = *s++; + } + *o = 0; + + if (!strcmp (key, pkey) ) + return value[valueindex]; + + if (!*s) + return ""; + s++; + } +} + +void Info_RemoveKey (char *s, char *key) +{ + char *start; + char pkey[512]; + char value[512]; + char *o; + + if (strstr (key, "\\")) + { + Con_Printf ("Can't use a key with a \\\n"); + return; + } + + while (1) + { + start = s; + if (*s == '\\') + s++; + o = pkey; + while (*s != '\\') + { + if (!*s) + return; + *o++ = *s++; + } + *o = 0; + s++; + + o = value; + while (*s != '\\' && *s) + { + if (!*s) + return; + *o++ = *s++; + } + *o = 0; + + if (!strcmp (key, pkey) ) + { + strcpy (start, s); // remove this part + return; + } + + if (!*s) + return; + } + +} + +void Info_RemovePrefixedKeys (char *start, char prefix) +{ + char *s; + char pkey[512]; + char value[512]; + char *o; + + s = start; + + while (1) + { + if (*s == '\\') + s++; + o = pkey; + while (*s != '\\') + { + if (!*s) + return; + *o++ = *s++; + } + *o = 0; + s++; + + o = value; + while (*s != '\\' && *s) + { + if (!*s) + return; + *o++ = *s++; + } + *o = 0; + + if (pkey[0] == prefix) + { + Info_RemoveKey (start, pkey); + s = start; + } + + if (!*s) + return; + } + +} + + +void Info_SetValueForStarKey (char *s, char *key, char *value, int maxsize) +{ + char new[1024], *v; + int c; +#ifdef SERVERONLY + extern cvar_t sv_highchars; +#endif + + if (strstr (key, "\\") || strstr (value, "\\") ) + { + Con_Printf ("Can't use keys or values with a \\\n"); + return; + } + + if (strstr (key, "\"") || strstr (value, "\"") ) + { + Con_Printf ("Can't use keys or values with a \"\n"); + return; + } + + if (strlen(key) > 63 || strlen(value) > 63) + { + Con_Printf ("Keys and values must be < 64 characters.\n"); + return; + } + + // this next line is kinda trippy + if (*(v = Info_ValueForKey(s, key))) { + // key exists, make sure we have enough room for new value, if we don't, + // don't change it! + if (strlen(value) - strlen(v) + strlen(s) > maxsize) { + Con_Printf ("Info string length exceeded\n"); + return; + } + } + Info_RemoveKey (s, key); + if (!value || !strlen(value)) + return; + + sprintf (new, "\\%s\\%s", key, value); + + if ((int)(strlen(new) + strlen(s)) > maxsize) + { + Con_Printf ("Info string length exceeded\n"); + return; + } + + // only copy ascii values + s += strlen(s); + v = new; + while (*v) + { + c = (unsigned char)*v++; +#ifndef SERVERONLY + // client only allows highbits on name + if (stricmp(key, "name") != 0) { + c &= 127; + if (c < 32 || c > 127) + continue; + // auto lowercase team + if (stricmp(key, "team") == 0) + c = tolower(c); + } +#else + if (!sv_highchars.value) { + c &= 127; + if (c < 32 || c > 127) + continue; + } +#endif +// c &= 127; // strip high bits + if (c > 13) // && c < 127) + *s++ = c; + } + *s = 0; +} + +void Info_SetValueForKey (char *s, char *key, char *value, int maxsize) +{ + if (key[0] == '*') + { + Con_Printf ("Can't set * keys\n"); + return; + } + + Info_SetValueForStarKey (s, key, value, maxsize); +} + +void Info_Print (char *s) +{ + char key[512]; + char value[512]; + char *o; + int l; + + if (*s == '\\') + s++; + while (*s) + { + o = key; + while (*s && *s != '\\') + *o++ = *s++; + + l = o - key; + if (l < 20) + { + memset (o, ' ', 20-l); + key[20] = 0; + } + else + *o = 0; + Con_Printf ("%s", key); + + if (!*s) + { + Con_Printf ("MISSING VALUE\n"); + return; + } + + o = value; + s++; + while (*s && *s != '\\') + *o++ = *s++; + *o = 0; + + if (*s) + s++; + Con_Printf ("%s\n", value); + } +} + +static byte chktbl[1024 + 4] = { +0x78,0xd2,0x94,0xe3,0x41,0xec,0xd6,0xd5,0xcb,0xfc,0xdb,0x8a,0x4b,0xcc,0x85,0x01, +0x23,0xd2,0xe5,0xf2,0x29,0xa7,0x45,0x94,0x4a,0x62,0xe3,0xa5,0x6f,0x3f,0xe1,0x7a, +0x64,0xed,0x5c,0x99,0x29,0x87,0xa8,0x78,0x59,0x0d,0xaa,0x0f,0x25,0x0a,0x5c,0x58, +0xfb,0x00,0xa7,0xa8,0x8a,0x1d,0x86,0x80,0xc5,0x1f,0xd2,0x28,0x69,0x71,0x58,0xc3, +0x51,0x90,0xe1,0xf8,0x6a,0xf3,0x8f,0xb0,0x68,0xdf,0x95,0x40,0x5c,0xe4,0x24,0x6b, +0x29,0x19,0x71,0x3f,0x42,0x63,0x6c,0x48,0xe7,0xad,0xa8,0x4b,0x91,0x8f,0x42,0x36, +0x34,0xe7,0x32,0x55,0x59,0x2d,0x36,0x38,0x38,0x59,0x9b,0x08,0x16,0x4d,0x8d,0xf8, +0x0a,0xa4,0x52,0x01,0xbb,0x52,0xa9,0xfd,0x40,0x18,0x97,0x37,0xff,0xc9,0x82,0x27, +0xb2,0x64,0x60,0xce,0x00,0xd9,0x04,0xf0,0x9e,0x99,0xbd,0xce,0x8f,0x90,0x4a,0xdd, +0xe1,0xec,0x19,0x14,0xb1,0xfb,0xca,0x1e,0x98,0x0f,0xd4,0xcb,0x80,0xd6,0x05,0x63, +0xfd,0xa0,0x74,0xa6,0x86,0xf6,0x19,0x98,0x76,0x27,0x68,0xf7,0xe9,0x09,0x9a,0xf2, +0x2e,0x42,0xe1,0xbe,0x64,0x48,0x2a,0x74,0x30,0xbb,0x07,0xcc,0x1f,0xd4,0x91,0x9d, +0xac,0x55,0x53,0x25,0xb9,0x64,0xf7,0x58,0x4c,0x34,0x16,0xbc,0xf6,0x12,0x2b,0x65, +0x68,0x25,0x2e,0x29,0x1f,0xbb,0xb9,0xee,0x6d,0x0c,0x8e,0xbb,0xd2,0x5f,0x1d,0x8f, +0xc1,0x39,0xf9,0x8d,0xc0,0x39,0x75,0xcf,0x25,0x17,0xbe,0x96,0xaf,0x98,0x9f,0x5f, +0x65,0x15,0xc4,0x62,0xf8,0x55,0xfc,0xab,0x54,0xcf,0xdc,0x14,0x06,0xc8,0xfc,0x42, +0xd3,0xf0,0xad,0x10,0x08,0xcd,0xd4,0x11,0xbb,0xca,0x67,0xc6,0x48,0x5f,0x9d,0x59, +0xe3,0xe8,0x53,0x67,0x27,0x2d,0x34,0x9e,0x9e,0x24,0x29,0xdb,0x69,0x99,0x86,0xf9, +0x20,0xb5,0xbb,0x5b,0xb0,0xf9,0xc3,0x67,0xad,0x1c,0x9c,0xf7,0xcc,0xef,0xce,0x69, +0xe0,0x26,0x8f,0x79,0xbd,0xca,0x10,0x17,0xda,0xa9,0x88,0x57,0x9b,0x15,0x24,0xba, +0x84,0xd0,0xeb,0x4d,0x14,0xf5,0xfc,0xe6,0x51,0x6c,0x6f,0x64,0x6b,0x73,0xec,0x85, +0xf1,0x6f,0xe1,0x67,0x25,0x10,0x77,0x32,0x9e,0x85,0x6e,0x69,0xb1,0x83,0x00,0xe4, +0x13,0xa4,0x45,0x34,0x3b,0x40,0xff,0x41,0x82,0x89,0x79,0x57,0xfd,0xd2,0x8e,0xe8, +0xfc,0x1d,0x19,0x21,0x12,0x00,0xd7,0x66,0xe5,0xc7,0x10,0x1d,0xcb,0x75,0xe8,0xfa, +0xb6,0xee,0x7b,0x2f,0x1a,0x25,0x24,0xb9,0x9f,0x1d,0x78,0xfb,0x84,0xd0,0x17,0x05, +0x71,0xb3,0xc8,0x18,0xff,0x62,0xee,0xed,0x53,0xab,0x78,0xd3,0x65,0x2d,0xbb,0xc7, +0xc1,0xe7,0x70,0xa2,0x43,0x2c,0x7c,0xc7,0x16,0x04,0xd2,0x45,0xd5,0x6b,0x6c,0x7a, +0x5e,0xa1,0x50,0x2e,0x31,0x5b,0xcc,0xe8,0x65,0x8b,0x16,0x85,0xbf,0x82,0x83,0xfb, +0xde,0x9f,0x36,0x48,0x32,0x79,0xd6,0x9b,0xfb,0x52,0x45,0xbf,0x43,0xf7,0x0b,0x0b, +0x19,0x19,0x31,0xc3,0x85,0xec,0x1d,0x8c,0x20,0xf0,0x3a,0xfa,0x80,0x4d,0x2c,0x7d, +0xac,0x60,0x09,0xc0,0x40,0xee,0xb9,0xeb,0x13,0x5b,0xe8,0x2b,0xb1,0x20,0xf0,0xce, +0x4c,0xbd,0xc6,0x04,0x86,0x70,0xc6,0x33,0xc3,0x15,0x0f,0x65,0x19,0xfd,0xc2,0xd3, + +// map checksum goes here +0x00,0x00,0x00,0x00 +}; + +static byte chkbuf[16 + 60 + 4]; + +static unsigned last_mapchecksum = 0; + +#if 0 +/* +==================== +COM_BlockSequenceCheckByte + +For proxy protecting +==================== +*/ +byte COM_BlockSequenceCheckByte (byte *base, int length, int sequence, unsigned mapchecksum) +{ + int checksum; + byte *p; + + if (last_mapchecksum != mapchecksum) { + last_mapchecksum = mapchecksum; + chktbl[1024] = (mapchecksum & 0xff000000) >> 24; + chktbl[1025] = (mapchecksum & 0x00ff0000) >> 16; + chktbl[1026] = (mapchecksum & 0x0000ff00) >> 8; + chktbl[1027] = (mapchecksum & 0x000000ff); + + Com_BlockFullChecksum (chktbl, sizeof(chktbl), chkbuf); + } + + p = chktbl + (sequence % (sizeof(chktbl) - 8)); + + if (length > 60) + length = 60; + memcpy (chkbuf + 16, base, length); + + length += 16; + + chkbuf[length] = (sequence & 0xff) ^ p[0]; + chkbuf[length+1] = p[1]; + chkbuf[length+2] = ((sequence>>8) & 0xff) ^ p[2]; + chkbuf[length+3] = p[3]; + + length += 4; + + checksum = LittleLong(Com_BlockChecksum (chkbuf, length)); + + checksum &= 0xff; + + return checksum; +} +#endif + +/* +==================== +COM_BlockSequenceCRCByte + +For proxy protecting +==================== +*/ +byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence) +{ + unsigned short crc; + byte *p; + byte chkb[60 + 4]; + + p = chktbl + (sequence % (sizeof(chktbl) - 8)); + + if (length > 60) + length = 60; + memcpy (chkb, base, length); + + chkb[length] = (sequence & 0xff) ^ p[0]; + chkb[length+1] = p[1]; + chkb[length+2] = ((sequence>>8) & 0xff) ^ p[2]; + chkb[length+3] = p[3]; + + length += 4; + + crc = CRC_Block(chkb, length); + + crc &= 0xff; + + return crc; +} + +// char *date = "Oct 24 1996"; +static char *date = __DATE__ ; +static char *mon[12] = +{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +static char mond[12] = +{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +// returns days since Oct 24 1996 +int build_number( void ) +{ + int m = 0; + int d = 0; + int y = 0; + static int b = 0; + + if (b != 0) + return b; + + for (m = 0; m < 11; m++) + { + if (Q_strncasecmp( &date[0], mon[m], 3 ) == 0) + break; + d += mond[m]; + } + + d += atoi( &date[4] ) - 1; + + y = atoi( &date[7] ) - 1900; + + b = d + (int)((y - 1) * 365.25); + + if (((y % 4) == 0) && m > 1) + { + b += 1; + } + + b -= 35778; // Dec 16 1998 + + return b; +} + diff --git a/QW/client/common.h b/QW/client/common.h new file mode 100644 index 0000000..8cd2ced --- /dev/null +++ b/QW/client/common.h @@ -0,0 +1,222 @@ +/* +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. + +*/ +// comndef.h -- general definitions + +typedef unsigned char byte; +#define _DEF_BYTE_ + +// KJB Undefined true and false defined in SciTech's DEBUG.H header +#undef true +#undef false + +typedef enum {false, true} qboolean; + +#define MAX_INFO_STRING 196 +#define MAX_SERVERINFO_STRING 512 +#define MAX_LOCALINFO_STRING 32768 + +//============================================================================ + +typedef struct sizebuf_s +{ + qboolean allowoverflow; // if false, do a Sys_Error + qboolean overflowed; // set to true if the buffer size failed + byte *data; + int maxsize; + int cursize; +} sizebuf_t; + +void SZ_Clear (sizebuf_t *buf); +void *SZ_GetSpace (sizebuf_t *buf, int length); +void SZ_Write (sizebuf_t *buf, void *data, int length); +void SZ_Print (sizebuf_t *buf, char *data); // strcats onto the sizebuf + +//============================================================================ + +typedef struct link_s +{ + struct link_s *prev, *next; +} link_t; + + +void ClearLink (link_t *l); +void RemoveLink (link_t *l); +void InsertLinkBefore (link_t *l, link_t *before); +void InsertLinkAfter (link_t *l, link_t *after); + +// (type *)STRUCT_FROM_LINK(link_t *link, type, member) +// ent = STRUCT_FROM_LINK(link,entity_t,order) +// FIXME: remove this mess! +#define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m))) + +//============================================================================ + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#define Q_MAXCHAR ((char)0x7f) +#define Q_MAXSHORT ((short)0x7fff) +#define Q_MAXINT ((int)0x7fffffff) +#define Q_MAXLONG ((int)0x7fffffff) +#define Q_MAXFLOAT ((int)0x7fffffff) + +#define Q_MINCHAR ((char)0x80) +#define Q_MINSHORT ((short)0x8000) +#define Q_MININT ((int)0x80000000) +#define Q_MINLONG ((int)0x80000000) +#define Q_MINFLOAT ((int)0x7fffffff) + +//============================================================================ + +extern qboolean bigendien; + +extern short (*BigShort) (short l); +extern short (*LittleShort) (short l); +extern int (*BigLong) (int l); +extern int (*LittleLong) (int l); +extern float (*BigFloat) (float l); +extern float (*LittleFloat) (float l); + +//============================================================================ + +struct usercmd_s; + +extern struct usercmd_s nullcmd; + +void MSG_WriteChar (sizebuf_t *sb, int c); +void MSG_WriteByte (sizebuf_t *sb, int c); +void MSG_WriteShort (sizebuf_t *sb, int c); +void MSG_WriteLong (sizebuf_t *sb, int c); +void MSG_WriteFloat (sizebuf_t *sb, float f); +void MSG_WriteString (sizebuf_t *sb, char *s); +void MSG_WriteCoord (sizebuf_t *sb, float f); +void MSG_WriteAngle (sizebuf_t *sb, float f); +void MSG_WriteAngle16 (sizebuf_t *sb, float f); +void MSG_WriteDeltaUsercmd (sizebuf_t *sb, struct usercmd_s *from, struct usercmd_s *cmd); + +extern int msg_readcount; +extern qboolean msg_badread; // set if a read goes beyond end of message + +void MSG_BeginReading (void); +int MSG_GetReadCount(void); +int MSG_ReadChar (void); +int MSG_ReadByte (void); +int MSG_ReadShort (void); +int MSG_ReadLong (void); +float MSG_ReadFloat (void); +char *MSG_ReadString (void); +char *MSG_ReadStringLine (void); + +float MSG_ReadCoord (void); +float MSG_ReadAngle (void); +float MSG_ReadAngle16 (void); +void MSG_ReadDeltaUsercmd (struct usercmd_s *from, struct usercmd_s *cmd); + +//============================================================================ + +#define Q_memset(d, f, c) memset((d), (f), (c)) +#define Q_memcpy(d, s, c) memcpy((d), (s), (c)) +#define Q_memcmp(m1, m2, c) memcmp((m1), (m2), (c)) +#define Q_strcpy(d, s) strcpy((d), (s)) +#define Q_strncpy(d, s, n) strncpy((d), (s), (n)) +#define Q_strlen(s) ((int)strlen(s)) +#define Q_strrchr(s, c) strrchr((s), (c)) +#define Q_strcat(d, s) strcat((d), (s)) +#define Q_strcmp(s1, s2) strcmp((s1), (s2)) +#define Q_strncmp(s1, s2, n) strncmp((s1), (s2), (n)) + +#ifdef _WIN32 + +#define Q_strcasecmp(s1, s2) _stricmp((s1), (s2)) +#define Q_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n)) + +#else + +#define Q_strcasecmp(s1, s2) strcasecmp((s1), (s2)) +#define Q_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n)) + +#endif + +int Q_atoi (char *str); +float Q_atof (char *str); + + + +//============================================================================ + +extern char com_token[1024]; +extern qboolean com_eof; + +char *COM_Parse (char *data); + + +extern int com_argc; +extern char **com_argv; + +int COM_CheckParm (char *parm); +void COM_AddParm (char *parm); + +void COM_Init (void); +void COM_InitArgv (int argc, char **argv); + +char *COM_SkipPath (char *pathname); +void COM_StripExtension (char *in, char *out); +void COM_FileBase (char *in, char *out); +void COM_DefaultExtension (char *path, char *extension); + +char *va(char *format, ...); +// does a varargs printf into a temp buffer + + +//============================================================================ + +extern int com_filesize; +struct cache_user_s; + +extern char com_gamedir[MAX_OSPATH]; + +void COM_WriteFile (char *filename, void *data, int len); +int COM_FOpenFile (char *filename, FILE **file); +void COM_CloseFile (FILE *h); + +byte *COM_LoadStackFile (char *path, void *buffer, int bufsize); +byte *COM_LoadTempFile (char *path); +byte *COM_LoadHunkFile (char *path); +void COM_LoadCacheFile (char *path, struct cache_user_s *cu); +void COM_CreatePath (char *path); +void COM_Gamedir (char *dir); + +extern struct cvar_s registered; +extern qboolean standard_quake, rogue, hipnotic; + +char *Info_ValueForKey (char *s, char *key); +void Info_RemoveKey (char *s, char *key); +void Info_RemovePrefixedKeys (char *start, char prefix); +void Info_SetValueForKey (char *s, char *key, char *value, int maxsize); +void Info_SetValueForStarKey (char *s, char *key, char *value, int maxsize); +void Info_Print (char *s); + +unsigned Com_BlockChecksum (void *buffer, int length); +void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf); +byte COM_BlockSequenceCheckByte (byte *base, int length, int sequence, unsigned mapchecksum); +byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence); + +int build_number( void ); diff --git a/QW/client/console.c b/QW/client/console.c new file mode 100644 index 0000000..bb8083f --- /dev/null +++ b/QW/client/console.c @@ -0,0 +1,693 @@ +/* +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. + +*/ +// console.c + +#include "quakedef.h" + +int con_ormask; +console_t con_main; +console_t con_chat; +console_t *con; // point to either con_main or con_chat + +int con_linewidth; // characters across screen +int con_totallines; // total lines in console scrollback + +float con_cursorspeed = 4; + + +cvar_t con_notifytime = {"con_notifytime","3"}; //seconds + +#define NUM_CON_TIMES 4 +float con_times[NUM_CON_TIMES]; // realtime time the line was generated + // for transparent notify lines + +int con_vislines; +int con_notifylines; // scan lines to clear for notify lines + +qboolean con_debuglog; + +#define MAXCMDLINE 256 +extern char key_lines[32][MAXCMDLINE]; +extern int edit_line; +extern int key_linepos; + + +qboolean con_initialized; + + +void Key_ClearTyping (void) +{ + key_lines[edit_line][1] = 0; // clear any typing + key_linepos = 1; +} + +/* +================ +Con_ToggleConsole_f +================ +*/ +void Con_ToggleConsole_f (void) +{ + Key_ClearTyping (); + + if (key_dest == key_console) + { + if (cls.state == ca_active) + key_dest = key_game; + } + else + key_dest = key_console; + + Con_ClearNotify (); +} + +/* +================ +Con_ToggleChat_f +================ +*/ +void Con_ToggleChat_f (void) +{ + Key_ClearTyping (); + + if (key_dest == key_console) + { + if (cls.state == ca_active) + key_dest = key_game; + } + else + key_dest = key_console; + + Con_ClearNotify (); +} + +/* +================ +Con_Clear_f +================ +*/ +void Con_Clear_f (void) +{ + Q_memset (con_main.text, ' ', CON_TEXTSIZE); + Q_memset (con_chat.text, ' ', CON_TEXTSIZE); +} + + +/* +================ +Con_ClearNotify +================ +*/ +void Con_ClearNotify (void) +{ + int i; + + for (i=0 ; i<NUM_CON_TIMES ; i++) + con_times[i] = 0; +} + + +/* +================ +Con_MessageMode_f +================ +*/ +void Con_MessageMode_f (void) +{ + chat_team = false; + key_dest = key_message; +} + +/* +================ +Con_MessageMode2_f +================ +*/ +void Con_MessageMode2_f (void) +{ + chat_team = true; + key_dest = key_message; +} + +/* +================ +Con_Resize + +================ +*/ +void Con_Resize (console_t *con) +{ + int i, j, width, oldwidth, oldtotallines, numlines, numchars; + char tbuf[CON_TEXTSIZE]; + + width = (vid.width >> 3) - 2; + + if (width == con_linewidth) + return; + + if (width < 1) // video hasn't been initialized yet + { + width = 38; + con_linewidth = width; + con_totallines = CON_TEXTSIZE / con_linewidth; + Q_memset (con->text, ' ', CON_TEXTSIZE); + } + else + { + oldwidth = con_linewidth; + con_linewidth = width; + oldtotallines = con_totallines; + con_totallines = CON_TEXTSIZE / con_linewidth; + numlines = oldtotallines; + + if (con_totallines < numlines) + numlines = con_totallines; + + numchars = oldwidth; + + if (con_linewidth < numchars) + numchars = con_linewidth; + + Q_memcpy (tbuf, con->text, CON_TEXTSIZE); + Q_memset (con->text, ' ', CON_TEXTSIZE); + + for (i=0 ; i<numlines ; i++) + { + for (j=0 ; j<numchars ; j++) + { + con->text[(con_totallines - 1 - i) * con_linewidth + j] = + tbuf[((con->current - i + oldtotallines) % + oldtotallines) * oldwidth + j]; + } + } + + Con_ClearNotify (); + } + + con->current = con_totallines - 1; + con->display = con->current; +} + + +/* +================ +Con_CheckResize + +If the line width has changed, reformat the buffer. +================ +*/ +void Con_CheckResize (void) +{ + Con_Resize (&con_main); + Con_Resize (&con_chat); +} + + +/* +================ +Con_Init +================ +*/ +void Con_Init (void) +{ + con_debuglog = COM_CheckParm("-condebug"); + + con = &con_main; + con_linewidth = -1; + Con_CheckResize (); + + Con_Printf ("Console initialized.\n"); + +// +// register our commands +// + Cvar_RegisterVariable (&con_notifytime); + + Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f); + Cmd_AddCommand ("togglechat", Con_ToggleChat_f); + Cmd_AddCommand ("messagemode", Con_MessageMode_f); + Cmd_AddCommand ("messagemode2", Con_MessageMode2_f); + Cmd_AddCommand ("clear", Con_Clear_f); + con_initialized = true; +} + + +/* +=============== +Con_Linefeed +=============== +*/ +void Con_Linefeed (void) +{ + con->x = 0; + if (con->display == con->current) + con->display++; + con->current++; + Q_memset (&con->text[(con->current%con_totallines)*con_linewidth] + , ' ', con_linewidth); +} + +/* +================ +Con_Print + +Handles cursor positioning, line wrapping, etc +All console printing must go through this in order to be logged to disk +If no console is visible, the notify window will pop up. +================ +*/ +void Con_Print (char *txt) +{ + int y; + int c, l; + static int cr; + int mask; + + if (txt[0] == 1 || txt[0] == 2) + { + mask = 128; // go to colored text + txt++; + } + else + mask = 0; + + + while ( (c = *txt) ) + { + // count word length + for (l=0 ; l< con_linewidth ; l++) + if ( txt[l] <= ' ') + break; + + // word wrap + if (l != con_linewidth && (con->x + l > con_linewidth) ) + con->x = 0; + + txt++; + + if (cr) + { + con->current--; + cr = false; + } + + + if (!con->x) + { + Con_Linefeed (); + // mark time for transparent overlay + if (con->current >= 0) + con_times[con->current % NUM_CON_TIMES] = realtime; + } + + switch (c) + { + case '\n': + con->x = 0; + break; + + case '\r': + con->x = 0; + cr = 1; + break; + + default: // display character and advance + y = con->current % con_totallines; + con->text[y*con_linewidth+con->x] = c | mask | con_ormask; + con->x++; + if (con->x >= con_linewidth) + con->x = 0; + break; + } + + } +} + + +/* +================ +Con_Printf + +Handles cursor positioning, line wrapping, etc +================ +*/ +#define MAXPRINTMSG 4096 +// FIXME: make a buffer size safe vsprintf? +void Con_Printf (char *fmt, ...) +{ + va_list argptr; + char msg[MAXPRINTMSG]; + static qboolean inupdate; + + va_start (argptr,fmt); + vsprintf (msg,fmt,argptr); + va_end (argptr); + +// also echo to debugging console + Sys_Printf ("%s", msg); // also echo to debugging console + +// log all messages to file + if (con_debuglog) + Sys_DebugLog(va("%s/qconsole.log",com_gamedir), "%s", msg); + + if (!con_initialized) + return; + +// write it to the scrollable buffer + Con_Print (msg); + +// update the screen immediately if the console is displayed + if (cls.state != ca_active) + { + // protect against infinite loop if something in SCR_UpdateScreen calls + // Con_Printd + if (!inupdate) + { + inupdate = true; + SCR_UpdateScreen (); + inupdate = false; + } + } +} + +/* +================ +Con_DPrintf + +A Con_Printf that only shows up if the "developer" cvar is set +================ +*/ +void Con_DPrintf (char *fmt, ...) +{ + va_list argptr; + char msg[MAXPRINTMSG]; + + if (!developer.value) + return; // don't confuse non-developers with techie stuff... + + va_start (argptr,fmt); + vsprintf (msg,fmt,argptr); + va_end (argptr); + + Con_Printf ("%s", msg); +} + +/* +============================================================================== + +DRAWING + +============================================================================== +*/ + + +/* +================ +Con_DrawInput + +The input line scrolls horizontally if typing goes beyond the right edge +================ +*/ +void Con_DrawInput (void) +{ + int y; + int i; + char *text; + + if (key_dest != key_console && cls.state == ca_active) + return; // don't draw anything (allways draw if not active) + + text = key_lines[edit_line]; + +// add the cursor frame + text[key_linepos] = 10+((int)(realtime*con_cursorspeed)&1); + +// fill out remainder with spaces + for (i=key_linepos+1 ; i< con_linewidth ; i++) + text[i] = ' '; + +// prestep if horizontally scrolling + if (key_linepos >= con_linewidth) + text += 1 + key_linepos - con_linewidth; + +// draw it + y = con_vislines-22; + + for (i=0 ; i<con_linewidth ; i++) + Draw_Character ( (i+1)<<3, con_vislines - 22, text[i]); + +// remove cursor + key_lines[edit_line][key_linepos] = 0; +} + + +/* +================ +Con_DrawNotify + +Draws the last few lines of output transparently over the game top +================ +*/ +void Con_DrawNotify (void) +{ + int x, v; + char *text; + int i; + float time; + char *s; + int skip; + + v = 0; + for (i= con->current-NUM_CON_TIMES+1 ; i<=con->current ; i++) + { + if (i < 0) + continue; + time = con_times[i % NUM_CON_TIMES]; + if (time == 0) + continue; + time = realtime - time; + if (time > con_notifytime.value) + continue; + text = con->text + (i % con_totallines)*con_linewidth; + + clearnotify = 0; + scr_copytop = 1; + + for (x = 0 ; x < con_linewidth ; x++) + Draw_Character ( (x+1)<<3, v, text[x]); + + v += 8; + } + + + if (key_dest == key_message) + { + clearnotify = 0; + scr_copytop = 1; + + if (chat_team) + { + Draw_String (8, v, "say_team:"); + skip = 11; + } + else + { + Draw_String (8, v, "say:"); + skip = 5; + } + + s = chat_buffer; + if (chat_bufferlen > (vid.width>>3)-(skip+1)) + s += chat_bufferlen - ((vid.width>>3)-(skip+1)); + x = 0; + while(s[x]) + { + Draw_Character ( (x+skip)<<3, v, s[x]); + x++; + } + Draw_Character ( (x+skip)<<3, v, 10+((int)(realtime*con_cursorspeed)&1)); + v += 8; + } + + if (v > con_notifylines) + con_notifylines = v; +} + +/* +================ +Con_DrawConsole + +Draws the console with the solid background +================ +*/ +void Con_DrawConsole (int lines) +{ + int i, j, x, y, n; + int rows; + char *text; + int row; + char dlbar[1024]; + + if (lines <= 0) + return; + +// draw the background + Draw_ConsoleBackground (lines); + +// draw the text + con_vislines = lines; + +// changed to line things up better + rows = (lines-22)>>3; // rows of text to draw + + y = lines - 30; + +// draw from the bottom up + if (con->display != con->current) + { + // draw arrows to show the buffer is backscrolled + for (x=0 ; x<con_linewidth ; x+=4) + Draw_Character ( (x+1)<<3, y, '^'); + + y -= 8; + rows--; + } + + row = con->display; + for (i=0 ; i<rows ; i++, y-=8, row--) + { + if (row < 0) + break; + if (con->current - row >= con_totallines) + break; // past scrollback wrap point + + text = con->text + (row % con_totallines)*con_linewidth; + + for (x=0 ; x<con_linewidth ; x++) + Draw_Character ( (x+1)<<3, y, text[x]); + } + + // draw the download bar + // figure out width + if (cls.download) { + if ((text = strrchr(cls.downloadname, '/')) != NULL) + text++; + else + text = cls.downloadname; + + x = con_linewidth - ((con_linewidth * 7) / 40); + y = x - strlen(text) - 8; + i = con_linewidth/3; + if (strlen(text) > i) { + y = x - i - 11; + strncpy(dlbar, text, i); + dlbar[i] = 0; + strcat(dlbar, "..."); + } else + strcpy(dlbar, text); + strcat(dlbar, ": "); + i = strlen(dlbar); + dlbar[i++] = '\x80'; + // where's the dot go? + if (cls.downloadpercent == 0) + n = 0; + else + n = y * cls.downloadpercent / 100; + + for (j = 0; j < y; j++) + if (j == n) + dlbar[i++] = '\x83'; + else + dlbar[i++] = '\x81'; + dlbar[i++] = '\x82'; + dlbar[i] = 0; + + sprintf(dlbar + strlen(dlbar), " %02d%%", cls.downloadpercent); + + // draw it + y = con_vislines-22 + 8; + for (i = 0; i < strlen(dlbar); i++) + Draw_Character ( (i+1)<<3, y, dlbar[i]); + } + + +// draw the input prompt, user text, and cursor if desired + Con_DrawInput (); +} + + +/* +================== +Con_NotifyBox +================== +*/ +void Con_NotifyBox (char *text) +{ + double t1, t2; + +// during startup for sound / cd warnings + Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n"); + + Con_Printf (text); + + Con_Printf ("Press a key.\n"); + Con_Printf("\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n"); + + key_count = -2; // wait for a key down and up + key_dest = key_console; + + do + { + t1 = Sys_DoubleTime (); + SCR_UpdateScreen (); + Sys_SendKeyEvents (); + t2 = Sys_DoubleTime (); + realtime += t2-t1; // make the cursor blink + } while (key_count < 0); + + Con_Printf ("\n"); + key_dest = key_game; + realtime = 0; // put the cursor back to invisible +} + + +/* +================== +Con_SafePrintf + +Okay to call even when the screen can't be updated +================== +*/ +void Con_SafePrintf (char *fmt, ...) +{ + va_list argptr; + char msg[1024]; + int temp; + + va_start (argptr,fmt); + vsprintf (msg,fmt,argptr); + va_end (argptr); + + temp = scr_disabled_for_loading; + scr_disabled_for_loading = true; + Con_Printf ("%s", msg); + scr_disabled_for_loading = temp; +} + diff --git a/QW/client/console.h b/QW/client/console.h new file mode 100644 index 0000000..04bcc15 --- /dev/null +++ b/QW/client/console.h @@ -0,0 +1,60 @@ +/* +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. + +*/ + +// +// console +// + +#define CON_TEXTSIZE 16384 +typedef struct +{ + char text[CON_TEXTSIZE]; + int current; // line where next message will be printed + int x; // offset in current line for next print + int display; // bottom of console displays this line +} console_t; + +extern console_t con_main; +extern console_t con_chat; +extern console_t *con; // point to either con_main or con_chat + +extern int con_ormask; + +extern int con_totallines; +extern qboolean con_initialized; +extern byte *con_chars; +extern int con_notifylines; // scan lines to clear for notify lines + +void Con_DrawCharacter (int cx, int line, int num); + +void Con_CheckResize (void); +void Con_Init (void); +void Con_DrawConsole (int lines); +void Con_Print (char *txt); +void Con_Printf (char *fmt, ...); +void Con_DPrintf (char *fmt, ...); +void Con_SafePrintf (char *fmt, ...); +void Con_Clear_f (void); +void Con_DrawNotify (void); +void Con_ClearNotify (void); +void Con_ToggleConsole_f (void); + +void Con_NotifyBox (char *text); // during startup for sound / cd warnings + diff --git a/QW/client/crc.c b/QW/client/crc.c new file mode 100644 index 0000000..a43712e --- /dev/null +++ b/QW/client/crc.c @@ -0,0 +1,93 @@ +/* +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. + +*/ +/* crc.c */ + +#include "quakedef.h" +#include "crc.h" + +// this is a 16 bit, non-reflected CRC using the polynomial 0x1021 +// and the initial and final xor values shown below... in other words, the +// CCITT standard CRC used by XMODEM + +#define CRC_INIT_VALUE 0xffff +#define CRC_XOR_VALUE 0x0000 + +static unsigned short crctable[256] = +{ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +}; + +void CRC_Init(unsigned short *crcvalue) +{ + *crcvalue = CRC_INIT_VALUE; +} + +void CRC_ProcessByte(unsigned short *crcvalue, byte data) +{ + *crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data]; +} + +unsigned short CRC_Value(unsigned short crcvalue) +{ + return crcvalue ^ CRC_XOR_VALUE; +} + +unsigned short CRC_Block (byte *start, int count) +{ + unsigned short crc; + + CRC_Init (&crc); + while (count--) + crc = (crc << 8) ^ crctable[(crc >> 8) ^ *start++]; + + return crc; +} + diff --git a/QW/client/crc.h b/QW/client/crc.h new file mode 100644 index 0000000..d01fa3c --- /dev/null +++ b/QW/client/crc.h @@ -0,0 +1,25 @@ +/* +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. + +*/ +/* crc.h */ + +void CRC_Init(unsigned short *crcvalue); +void CRC_ProcessByte(unsigned short *crcvalue, byte data); +unsigned short CRC_Value(unsigned short crcvalue); +unsigned short CRC_Block (byte *start, int count); diff --git a/QW/client/cvar.c b/QW/client/cvar.c new file mode 100644 index 0000000..99a9821 --- /dev/null +++ b/QW/client/cvar.c @@ -0,0 +1,249 @@ +/* +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. + +*/ +// cvar.c -- dynamic variable tracking + +#ifdef SERVERONLY +#include "qwsvdef.h" +#else +#include "quakedef.h" +#endif + +cvar_t *cvar_vars; +char *cvar_null_string = ""; + +/* +============ +Cvar_FindVar +============ +*/ +cvar_t *Cvar_FindVar (char *var_name) +{ + cvar_t *var; + + for (var=cvar_vars ; var ; var=var->next) + if (!Q_strcmp (var_name, var->name)) + return var; + + return NULL; +} + +/* +============ +Cvar_VariableValue +============ +*/ +float Cvar_VariableValue (char *var_name) +{ + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + return 0; + return Q_atof (var->string); +} + + +/* +============ +Cvar_VariableString +============ +*/ +char *Cvar_VariableString (char *var_name) +{ + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + return cvar_null_string; + return var->string; +} + + +/* +============ +Cvar_CompleteVariable +============ +*/ +char *Cvar_CompleteVariable (char *partial) +{ + cvar_t *cvar; + int len; + + len = Q_strlen(partial); + + if (!len) + return NULL; + + // check exact match + for (cvar=cvar_vars ; cvar ; cvar=cvar->next) + if (!strcmp (partial,cvar->name)) + return cvar->name; + + // check partial match + for (cvar=cvar_vars ; cvar ; cvar=cvar->next) + if (!Q_strncmp (partial,cvar->name, len)) + return cvar->name; + + return NULL; +} + + +#ifdef SERVERONLY +void SV_SendServerInfoChange(char *key, char *value); +#endif + +/* +============ +Cvar_Set +============ +*/ +void Cvar_Set (char *var_name, char *value) +{ + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + { // there is an error in C code if this happens + Con_Printf ("Cvar_Set: variable %s not found\n", var_name); + return; + } + +#ifdef SERVERONLY + if (var->info) + { + Info_SetValueForKey (svs.info, var_name, value, MAX_SERVERINFO_STRING); + SV_SendServerInfoChange(var_name, value); +// SV_BroadcastCommand ("fullserverinfo \"%s\"\n", svs.info); + } +#else + if (var->info) + { + Info_SetValueForKey (cls.userinfo, var_name, value, MAX_INFO_STRING); + if (cls.state >= ca_connected) + { + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + SZ_Print (&cls.netchan.message, va("setinfo \"%s\" \"%s\"\n", var_name, value)); + } + } +#endif + + Z_Free (var->string); // free the old value string + + var->string = Z_Malloc (Q_strlen(value)+1); + Q_strcpy (var->string, value); + var->value = Q_atof (var->string); +} + +/* +============ +Cvar_SetValue +============ +*/ +void Cvar_SetValue (char *var_name, float value) +{ + char val[32]; + + sprintf (val, "%f",value); + Cvar_Set (var_name, val); +} + + +/* +============ +Cvar_RegisterVariable + +Adds a freestanding variable to the variable list. +============ +*/ +void Cvar_RegisterVariable (cvar_t *variable) +{ + char value[512]; + +// first check to see if it has allready been defined + if (Cvar_FindVar (variable->name)) + { + Con_Printf ("Can't register variable %s, allready defined\n", variable->name); + return; + } + +// check for overlap with a command + if (Cmd_Exists (variable->name)) + { + Con_Printf ("Cvar_RegisterVariable: %s is a command\n", variable->name); + return; + } + +// link the variable in + variable->next = cvar_vars; + cvar_vars = variable; + +// copy the value off, because future sets will Z_Free it + strcpy (value, variable->string); + variable->string = Z_Malloc (1); + +// set it through the function to be consistant + Cvar_Set (variable->name, value); +} + +/* +============ +Cvar_Command + +Handles variable inspection and changing from the console +============ +*/ +qboolean Cvar_Command (void) +{ + cvar_t *v; + +// check variables + v = Cvar_FindVar (Cmd_Argv(0)); + if (!v) + return false; + +// perform a variable print or set + if (Cmd_Argc() == 1) + { + Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->string); + return true; + } + + Cvar_Set (v->name, Cmd_Argv(1)); + return true; +} + + +/* +============ +Cvar_WriteVariables + +Writes lines containing "set variable value" for all variables +with the archive flag set to true. +============ +*/ +void Cvar_WriteVariables (FILE *f) +{ + cvar_t *var; + + for (var = cvar_vars ; var ; var = var->next) + if (var->archive) + fprintf (f, "%s \"%s\"\n", var->name, var->string); +} + diff --git a/QW/client/cvar.h b/QW/client/cvar.h new file mode 100644 index 0000000..bc72791 --- /dev/null +++ b/QW/client/cvar.h @@ -0,0 +1,97 @@ +/* +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. + +*/ +// cvar.h + +/* + +cvar_t variables are used to hold scalar or string variables that can be changed or displayed at the console or prog code as well as accessed directly +in C code. + +it is sufficient to initialize a cvar_t with just the first two fields, or +you can add a ,true flag for variables that you want saved to the configuration +file when the game is quit: + +cvar_t r_draworder = {"r_draworder","1"}; +cvar_t scr_screensize = {"screensize","1",true}; + +Cvars must be registered before use, or they will have a 0 value instead of the float interpretation of the string. Generally, all cvar_t declarations should be registered in the apropriate init function before any console commands are executed: +Cvar_RegisterVariable (&host_framerate); + + +C code usually just references a cvar in place: +if ( r_draworder.value ) + +It could optionally ask for the value to be looked up for a string name: +if (Cvar_VariableValue ("r_draworder")) + +Interpreted prog code can access cvars with the cvar(name) or +cvar_set (name, value) internal functions: +teamplay = cvar("teamplay"); +cvar_set ("registered", "1"); + +The user can access cvars from the console in two ways: +r_draworder prints the current value +r_draworder 0 sets the current value to 0 +Cvars are restricted from having the same names as commands to keep this +interface from being ambiguous. +*/ + +typedef struct cvar_s +{ + char *name; + char *string; + qboolean archive; // set to true to cause it to be saved to vars.rc + qboolean info; // added to serverinfo or userinfo when changed + float value; + struct cvar_s *next; +} cvar_t; + +void Cvar_RegisterVariable (cvar_t *variable); +// registers a cvar that allready has the name, string, and optionally the +// archive elements set. + +void Cvar_Set (char *var_name, char *value); +// equivelant to "<name> <variable>" typed at the console + +void Cvar_SetValue (char *var_name, float value); +// expands value to a string and calls Cvar_Set + +float Cvar_VariableValue (char *var_name); +// returns 0 if not defined or non numeric + +char *Cvar_VariableString (char *var_name); +// returns an empty string if not defined + +char *Cvar_CompleteVariable (char *partial); +// attempts to match a partial variable name for command line completion +// returns NULL if nothing fits + +qboolean Cvar_Command (void); +// called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known +// command. Returns true if the command was a variable reference that +// was handled. (print or change) + +void Cvar_WriteVariables (FILE *f); +// Writes lines containing "set variable value" for all variables +// with the archive flag set to true. + +cvar_t *Cvar_FindVar (char *var_name); + +extern cvar_t *cvar_vars; diff --git a/QW/client/d_copy.s b/QW/client/d_copy.s new file mode 100644 index 0000000..92e414a --- /dev/null +++ b/QW/client/d_copy.s @@ -0,0 +1,149 @@ +// +// d_copy.s +// x86 assembly-language screen copying code. +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" + + .data + +LCopyWidth: .long 0 +LBlockSrcStep: .long 0 +LBlockDestStep: .long 0 +LSrcDelta: .long 0 +LDestDelta: .long 0 + +#define bufptr 4+16 + +// copies 16 rows per plane at a pop; idea is that 16*512 = 8k, and since +// no Mode X mode is wider than 360, all the data should fit in the cache for +// the passes for the next 3 planes + + .text + +.globl C(VGA_UpdatePlanarScreen) +C(VGA_UpdatePlanarScreen): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + + movl C(VGA_bufferrowbytes),%eax + shll $1,%eax + movl %eax,LBlockSrcStep + movl C(VGA_rowbytes),%eax + shll $1,%eax + movl %eax,LBlockDestStep + + movl $0x3C4,%edx + movb $2,%al + outb %al,%dx // point the SC to the Map Mask + incl %edx + + movl bufptr(%esp),%esi + movl C(VGA_pagebase),%edi + movl C(VGA_height),%ebp + shrl $1,%ebp + + movl C(VGA_width),%ecx + movl C(VGA_bufferrowbytes),%eax + subl %ecx,%eax + movl %eax,LSrcDelta + movl C(VGA_rowbytes),%eax + shll $2,%eax + subl %ecx,%eax + movl %eax,LDestDelta + shrl $4,%ecx + movl %ecx,LCopyWidth + +LRowLoop: + movb $1,%al + +LPlaneLoop: + outb %al,%dx + movb $2,%ah + + pushl %esi + pushl %edi +LRowSetLoop: + movl LCopyWidth,%ecx +LColumnLoop: + movb 12(%esi),%bh + movb 8(%esi),%bl + shll $16,%ebx + movb 4(%esi),%bh + movb (%esi),%bl + movl %ebx,(%edi) + addl $16,%esi + addl $4,%edi + decl %ecx + jnz LColumnLoop + + addl LDestDelta,%edi + addl LSrcDelta,%esi + decb %ah + jnz LRowSetLoop + + popl %edi + popl %esi + incl %esi + + shlb $1,%al + cmpb $16,%al + jnz LPlaneLoop + + subl $4,%esi + addl LBlockSrcStep,%esi + addl LBlockDestStep,%edi + decl %ebp + jnz LRowLoop + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + + ret + + +#define srcptr 4+16 +#define destptr 8+16 +#define width 12+16 +#define height 16+16 +#define srcrowbytes 20+16 +#define destrowbytes 24+16 + +.globl C(VGA_UpdateLinearScreen) +C(VGA_UpdateLinearScreen): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + + cld + movl srcptr(%esp),%esi + movl destptr(%esp),%edi + movl width(%esp),%ebx + movl srcrowbytes(%esp),%eax + subl %ebx,%eax + movl destrowbytes(%esp),%edx + subl %ebx,%edx + shrl $2,%ebx + movl height(%esp),%ebp +LLRowLoop: + movl %ebx,%ecx + rep/movsl (%esi),(%edi) + addl %eax,%esi + addl %edx,%edi + decl %ebp + jnz LLRowLoop + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + + ret + diff --git a/QW/client/d_draw.asm b/QW/client/d_draw.asm new file mode 100644 index 0000000..5f6d995 --- /dev/null +++ b/QW/client/d_draw.asm @@ -0,0 +1,949 @@ + .386P + .model FLAT + externdef _d_zistepu:dword + externdef _d_pzbuffer:dword + externdef _d_zistepv:dword + externdef _d_zrowbytes:dword + externdef _d_ziorigin:dword + externdef _r_turb_s:dword + externdef _r_turb_t:dword + externdef _r_turb_pdest:dword + externdef _r_turb_spancount:dword + externdef _r_turb_turb:dword + externdef _r_turb_pbase:dword + externdef _r_turb_sstep:dword + externdef _r_turb_tstep:dword + externdef _r_bmodelactive:dword + externdef _d_sdivzstepu:dword + externdef _d_tdivzstepu:dword + externdef _d_sdivzstepv:dword + externdef _d_tdivzstepv:dword + externdef _d_sdivzorigin:dword + externdef _d_tdivzorigin:dword + externdef _sadjust:dword + externdef _tadjust:dword + externdef _bbextents:dword + externdef _bbextentt:dword + externdef _cacheblock:dword + externdef _d_viewbuffer:dword + externdef _cachewidth:dword + externdef _d_pzbuffer:dword + externdef _d_zrowbytes:dword + externdef _d_zwidth:dword + externdef _d_scantable:dword + externdef _r_lightptr:dword + externdef _r_numvblocks:dword + externdef _prowdestbase:dword + externdef _pbasesource:dword + externdef _r_lightwidth:dword + externdef _lightright:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _lightdelta:dword + externdef _lightright:dword + externdef _lightdelta:dword + externdef _sourcetstep:dword + externdef _surfrowbytes:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _r_sourcemax:dword + externdef _r_stepback:dword + externdef _colormap:dword + externdef _blocksize:dword + externdef _sourcesstep:dword + externdef _lightleft:dword + externdef _blockdivshift:dword + externdef _blockdivmask:dword + externdef _lightleftstep:dword + externdef _r_origin:dword + externdef _r_ppn:dword + externdef _r_pup:dword + externdef _r_pright:dword + externdef _ycenter:dword + externdef _xcenter:dword + externdef _d_vrectbottom_particle:dword + externdef _d_vrectright_particle:dword + externdef _d_vrecty:dword + externdef _d_vrectx:dword + externdef _d_pix_shift:dword + externdef _d_pix_min:dword + externdef _d_pix_max:dword + externdef _d_y_aspect_shift:dword + externdef _screenwidth:dword + externdef _vright:dword + externdef _vup:dword + externdef _vpn:dword + externdef _BOPS_Error:dword + externdef _snd_scaletable:dword + externdef _paintbuffer:dword + externdef _snd_linear_count:dword + externdef _snd_p:dword + externdef _snd_vol:dword + externdef _snd_out:dword + externdef _r_leftclipped:dword + externdef _r_leftenter:dword + externdef _r_rightclipped:dword + externdef _r_rightenter:dword + externdef _modelorg:dword + externdef _xscale:dword + externdef _r_refdef:dword + externdef _yscale:dword + externdef _r_leftexit:dword + externdef _r_rightexit:dword + externdef _r_lastvertvalid:dword + externdef _cacheoffset:dword + externdef _newedges:dword + externdef _removeedges:dword + externdef _r_pedge:dword + externdef _r_framecount:dword + externdef _r_u1:dword + externdef _r_emitted:dword + externdef _edge_p:dword + externdef _surface_p:dword + externdef _surfaces:dword + externdef _r_lzi1:dword + externdef _r_v1:dword + externdef _r_ceilv1:dword + externdef _r_nearzi:dword + externdef _r_nearzionly:dword + externdef _edge_aftertail:dword + externdef _edge_tail:dword + externdef _current_iv:dword + externdef _edge_head_u_shift20:dword + externdef _span_p:dword + externdef _edge_head:dword + externdef _fv:dword + externdef _edge_tail_u_shift20:dword + externdef _r_apverts:dword + externdef _r_anumverts:dword + externdef _aliastransform:dword + externdef _r_avertexnormals:dword + externdef _r_plightvec:dword + externdef _r_ambientlight:dword + externdef _r_shadelight:dword + externdef _aliasxcenter:dword + externdef _aliasycenter:dword + externdef _a_sstepxfrac:dword + externdef _r_affinetridesc:dword + externdef _acolormap:dword + externdef _d_pcolormap:dword + externdef _r_affinetridesc:dword + externdef _d_sfrac:dword + externdef _d_ptex:dword + externdef _d_pedgespanpackage:dword + externdef _d_tfrac:dword + externdef _d_light:dword + externdef _d_zi:dword + externdef _d_pdest:dword + externdef _d_pz:dword + externdef _d_aspancount:dword + externdef _erroradjustup:dword + externdef _errorterm:dword + externdef _d_xdenom:dword + externdef _r_p0:dword + externdef _r_p1:dword + externdef _r_p2:dword + externdef _a_tstepxfrac:dword + externdef _r_sstepx:dword + externdef _r_tstepx:dword + externdef _a_ststepxwhole:dword + externdef _zspantable:dword + externdef _skintable:dword + externdef _r_zistepx:dword + externdef _erroradjustdown:dword + externdef _d_countextrastep:dword + externdef _ubasestep:dword + externdef _a_ststepxwhole:dword + externdef _a_tstepxfrac:dword + externdef _r_lstepx:dword + externdef _a_spans:dword + externdef _erroradjustdown:dword + externdef _d_pdestextrastep:dword + externdef _d_pzextrastep:dword + externdef _d_sfracextrastep:dword + externdef _d_ptexextrastep:dword + externdef _d_countextrastep:dword + externdef _d_tfracextrastep:dword + externdef _d_lightextrastep:dword + externdef _d_ziextrastep:dword + externdef _d_pdestbasestep:dword + externdef _d_pzbasestep:dword + externdef _d_sfracbasestep:dword + externdef _d_ptexbasestep:dword + externdef _ubasestep:dword + externdef _d_tfracbasestep:dword + externdef _d_lightbasestep:dword + externdef _d_zibasestep:dword + externdef _zspantable:dword + externdef _r_lstepy:dword + externdef _r_sstepy:dword + externdef _r_tstepy:dword + externdef _r_zistepy:dword + externdef _D_PolysetSetEdgeTable:dword + externdef _D_RasterizeAliasPolySmooth:dword + externdef float_point5:dword + externdef Float2ToThe31nd:dword + externdef izistep:dword + externdef izi:dword + externdef FloatMinus2ToThe31nd:dword + externdef float_1:dword + externdef float_particle_z_clip:dword + externdef float_minus_1:dword + externdef float_0:dword + externdef fp_16:dword + externdef fp_64k:dword + externdef fp_1m:dword + externdef fp_1m_minus_1:dword + externdef fp_8:dword + externdef entryvec_table:dword + externdef advancetable:dword + externdef sstep:dword + externdef tstep:dword + externdef pspantemp:dword + externdef counttemp:dword + externdef jumptemp:dword + externdef reciprocal_table:dword + externdef DP_Count:dword + externdef DP_u:dword + externdef DP_v:dword + externdef DP_32768:dword + externdef DP_Color:dword + externdef DP_Pix:dword + externdef DP_EntryTable:dword + externdef pbase:dword + externdef s:dword + externdef t:dword + externdef sfracf:dword + externdef tfracf:dword + externdef snext:dword + externdef tnext:dword + externdef spancountminus1:dword + externdef zi16stepu:dword + externdef sdivz16stepu:dword + externdef tdivz16stepu:dword + externdef zi8stepu:dword + externdef sdivz8stepu:dword + externdef tdivz8stepu:dword + externdef reciprocal_table_16:dword + externdef entryvec_table_16:dword + externdef ceil_cw:dword + externdef single_cw:dword + externdef fp_64kx64k:dword + externdef pz:dword + externdef spr8entryvec_table:dword +_TEXT SEGMENT +LClampHigh0: + mov esi,ds:dword ptr[_bbextents] + jmp LClampReentry0 +LClampHighOrLow0: + jg LClampHigh0 + xor esi,esi + jmp LClampReentry0 +LClampHigh1: + mov edx,ds:dword ptr[_bbextentt] + jmp LClampReentry1 +LClampHighOrLow1: + jg LClampHigh1 + xor edx,edx + jmp LClampReentry1 +LClampLow2: + mov ebp,2048 + jmp LClampReentry2 +LClampHigh2: + mov ebp,ds:dword ptr[_bbextents] + jmp LClampReentry2 +LClampLow3: + mov ecx,2048 + jmp LClampReentry3 +LClampHigh3: + mov ecx,ds:dword ptr[_bbextentt] + jmp LClampReentry3 +LClampLow4: + mov eax,2048 + jmp LClampReentry4 +LClampHigh4: + mov eax,ds:dword ptr[_bbextents] + jmp LClampReentry4 +LClampLow5: + mov ebx,2048 + jmp LClampReentry5 +LClampHigh5: + mov ebx,ds:dword ptr[_bbextentt] + jmp LClampReentry5 + align 4 + public _D_DrawSpans8 +_D_DrawSpans8: + push ebp + push edi + push esi + push ebx + fld ds:dword ptr[_d_sdivzstepu] + fmul ds:dword ptr[fp_8] + mov edx,ds:dword ptr[_cacheblock] + fld ds:dword ptr[_d_tdivzstepu] + fmul ds:dword ptr[fp_8] + mov ebx,ds:dword ptr[4+16+esp] + fld ds:dword ptr[_d_zistepu] + fmul ds:dword ptr[fp_8] + mov ds:dword ptr[pbase],edx + fstp ds:dword ptr[zi8stepu] + fstp ds:dword ptr[tdivz8stepu] + fstp ds:dword ptr[sdivz8stepu] +LSpanLoop: + fild ds:dword ptr[4+ebx] + fild ds:dword ptr[0+ebx] + fld st(1) + fmul ds:dword ptr[_d_sdivzstepv] + fld st(1) + fmul ds:dword ptr[_d_sdivzstepu] + fld st(2) + fmul ds:dword ptr[_d_tdivzstepu] + fxch st(1) + faddp st(2),st(0) + fxch st(1) + fld st(3) + fmul ds:dword ptr[_d_tdivzstepv] + fxch st(1) + fadd ds:dword ptr[_d_sdivzorigin] + fxch st(4) + fmul ds:dword ptr[_d_zistepv] + fxch st(1) + faddp st(2),st(0) + fxch st(2) + fmul ds:dword ptr[_d_zistepu] + fxch st(1) + fadd ds:dword ptr[_d_tdivzorigin] + fxch st(2) + faddp st(1),st(0) + fld ds:dword ptr[fp_64k] + fxch st(1) + fadd ds:dword ptr[_d_ziorigin] + fdiv st(1),st(0) + mov ecx,ds:dword ptr[_d_viewbuffer] + mov eax,ds:dword ptr[4+ebx] + mov ds:dword ptr[pspantemp],ebx + mov edx,ds:dword ptr[_tadjust] + mov esi,ds:dword ptr[_sadjust] + mov edi,ds:dword ptr[_d_scantable+eax*4] + add edi,ecx + mov ecx,ds:dword ptr[0+ebx] + add edi,ecx + mov ecx,ds:dword ptr[8+ebx] + cmp ecx,8 + ja LSetupNotLast1 + dec ecx + jz LCleanup1 + mov ds:dword ptr[spancountminus1],ecx + fxch st(1) + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[s] + fistp ds:dword ptr[t] + fild ds:dword ptr[spancountminus1] + fld ds:dword ptr[_d_tdivzstepu] + fld ds:dword ptr[_d_zistepu] + fmul st(0),st(2) + fxch st(1) + fmul st(0),st(2) + fxch st(2) + fmul ds:dword ptr[_d_sdivzstepu] + fxch st(1) + faddp st(3),st(0) + fxch st(1) + faddp st(3),st(0) + faddp st(3),st(0) + fld ds:dword ptr[fp_64k] + fdiv st(0),st(1) + jmp LFDIVInFlight1 +LCleanup1: + fxch st(1) + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[s] + fistp ds:dword ptr[t] + jmp LFDIVInFlight1 + align 4 +LSetupNotLast1: + fxch st(1) + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[s] + fistp ds:dword ptr[t] + fadd ds:dword ptr[zi8stepu] + fxch st(2) + fadd ds:dword ptr[sdivz8stepu] + fxch st(2) + fld ds:dword ptr[tdivz8stepu] + faddp st(2),st(0) + fld ds:dword ptr[fp_64k] + fdiv st(0),st(1) +LFDIVInFlight1: + add esi,ds:dword ptr[s] + add edx,ds:dword ptr[t] + mov ebx,ds:dword ptr[_bbextents] + mov ebp,ds:dword ptr[_bbextentt] + cmp esi,ebx + ja LClampHighOrLow0 +LClampReentry0: + mov ds:dword ptr[s],esi + mov ebx,ds:dword ptr[pbase] + shl esi,16 + cmp edx,ebp + mov ds:dword ptr[sfracf],esi + ja LClampHighOrLow1 +LClampReentry1: + mov ds:dword ptr[t],edx + mov esi,ds:dword ptr[s] + shl edx,16 + mov eax,ds:dword ptr[t] + sar esi,16 + mov ds:dword ptr[tfracf],edx + sar eax,16 + mov edx,ds:dword ptr[_cachewidth] + imul eax,edx + add esi,ebx + add esi,eax + cmp ecx,8 + jna LLastSegment +LNotLastSegment: + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[snext] + fistp ds:dword ptr[tnext] + mov eax,ds:dword ptr[snext] + mov edx,ds:dword ptr[tnext] + mov bl,ds:byte ptr[esi] + sub ecx,8 + mov ebp,ds:dword ptr[_sadjust] + mov ds:dword ptr[counttemp],ecx + mov ecx,ds:dword ptr[_tadjust] + mov ds:byte ptr[edi],bl + add ebp,eax + add ecx,edx + mov eax,ds:dword ptr[_bbextents] + mov edx,ds:dword ptr[_bbextentt] + cmp ebp,2048 + jl LClampLow2 + cmp ebp,eax + ja LClampHigh2 +LClampReentry2: + cmp ecx,2048 + jl LClampLow3 + cmp ecx,edx + ja LClampHigh3 +LClampReentry3: + mov ds:dword ptr[snext],ebp + mov ds:dword ptr[tnext],ecx + sub ebp,ds:dword ptr[s] + sub ecx,ds:dword ptr[t] + mov eax,ecx + mov edx,ebp + sar eax,19 + jz LZero + sar edx,19 + mov ebx,ds:dword ptr[_cachewidth] + imul eax,ebx + jmp LSetUp1 +LZero: + sar edx,19 + mov ebx,ds:dword ptr[_cachewidth] +LSetUp1: + add eax,edx + mov edx,ds:dword ptr[tfracf] + mov ds:dword ptr[advancetable+4],eax + add eax,ebx + shl ebp,13 + mov ebx,ds:dword ptr[sfracf] + shl ecx,13 + mov ds:dword ptr[advancetable],eax + mov ds:dword ptr[tstep],ecx + add edx,ecx + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov al,ds:byte ptr[esi] + add ebx,ebp + mov ds:byte ptr[1+edi],al + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[2+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[3+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + mov ecx,ds:dword ptr[counttemp] + cmp ecx,8 + ja LSetupNotLast2 + dec ecx + jz LFDIVInFlight2 + mov ds:dword ptr[spancountminus1],ecx + fild ds:dword ptr[spancountminus1] + fld ds:dword ptr[_d_zistepu] + fmul st(0),st(1) + fld ds:dword ptr[_d_tdivzstepu] + fmul st(0),st(2) + fxch st(1) + faddp st(3),st(0) + fxch st(1) + fmul ds:dword ptr[_d_sdivzstepu] + fxch st(1) + faddp st(3),st(0) + fld ds:dword ptr[fp_64k] + fxch st(1) + faddp st(4),st(0) + fdiv st(0),st(1) + jmp LFDIVInFlight2 + align 4 +LSetupNotLast2: + fadd ds:dword ptr[zi8stepu] + fxch st(2) + fadd ds:dword ptr[sdivz8stepu] + fxch st(2) + fld ds:dword ptr[tdivz8stepu] + faddp st(2),st(0) + fld ds:dword ptr[fp_64k] + fdiv st(0),st(1) +LFDIVInFlight2: + mov ds:dword ptr[counttemp],ecx + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[4+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[5+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[6+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edi,8 + mov ds:dword ptr[tfracf],edx + mov edx,ds:dword ptr[snext] + mov ds:dword ptr[sfracf],ebx + mov ebx,ds:dword ptr[tnext] + mov ds:dword ptr[s],edx + mov ds:dword ptr[t],ebx + mov ecx,ds:dword ptr[counttemp] + cmp ecx,8 + mov ds:byte ptr[-1+edi],al + ja LNotLastSegment +LLastSegment: + test ecx,ecx + jz LNoSteps + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[snext] + fistp ds:dword ptr[tnext] + mov al,ds:byte ptr[esi] + mov ebx,ds:dword ptr[_tadjust] + mov ds:byte ptr[edi],al + mov eax,ds:dword ptr[_sadjust] + add eax,ds:dword ptr[snext] + add ebx,ds:dword ptr[tnext] + mov ebp,ds:dword ptr[_bbextents] + mov edx,ds:dword ptr[_bbextentt] + cmp eax,2048 + jl LClampLow4 + cmp eax,ebp + ja LClampHigh4 +LClampReentry4: + mov ds:dword ptr[snext],eax + cmp ebx,2048 + jl LClampLow5 + cmp ebx,edx + ja LClampHigh5 +LClampReentry5: + cmp ecx,1 + je LOnlyOneStep + sub eax,ds:dword ptr[s] + sub ebx,ds:dword ptr[t] + add eax,eax + add ebx,ebx + imul ds:dword ptr[reciprocal_table-8+ecx*4] + mov ebp,edx + mov eax,ebx + imul ds:dword ptr[reciprocal_table-8+ecx*4] +LSetEntryvec: + mov ebx,ds:dword ptr[entryvec_table+ecx*4] + mov eax,edx + mov ds:dword ptr[jumptemp],ebx + mov ecx,ebp + sar edx,16 + mov ebx,ds:dword ptr[_cachewidth] + sar ecx,16 + imul edx,ebx + add edx,ecx + mov ecx,ds:dword ptr[tfracf] + mov ds:dword ptr[advancetable+4],edx + add edx,ebx + shl ebp,16 + mov ebx,ds:dword ptr[sfracf] + shl eax,16 + mov ds:dword ptr[advancetable],edx + mov ds:dword ptr[tstep],eax + mov edx,ecx + add edx,eax + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + jmp dword ptr[jumptemp] +LNoSteps: + mov al,ds:byte ptr[esi] + sub edi,7 + jmp LEndSpan +LOnlyOneStep: + sub eax,ds:dword ptr[s] + sub ebx,ds:dword ptr[t] + mov ebp,eax + mov edx,ebx + jmp LSetEntryvec + public Entry2_8 +Entry2_8: + sub edi,6 + mov al,ds:byte ptr[esi] + jmp LLEntry2_8 + public Entry3_8 +Entry3_8: + sub edi,5 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + jmp LLEntry3_8 + public Entry4_8 +Entry4_8: + sub edi,4 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LLEntry4_8 + public Entry5_8 +Entry5_8: + sub edi,3 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LLEntry5_8 + public Entry6_8 +Entry6_8: + sub edi,2 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LLEntry6_8 + public Entry7_8 +Entry7_8: + dec edi + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LLEntry7_8 + public Entry8_8 +Entry8_8: + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[1+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LLEntry7_8: + sbb ecx,ecx + mov ds:byte ptr[2+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LLEntry6_8: + sbb ecx,ecx + mov ds:byte ptr[3+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LLEntry5_8: + sbb ecx,ecx + mov ds:byte ptr[4+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LLEntry4_8: + sbb ecx,ecx + mov ds:byte ptr[5+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] +LLEntry3_8: + mov ds:byte ptr[6+edi],al + mov al,ds:byte ptr[esi] +LLEntry2_8: +LEndSpan: + fstp st(0) + fstp st(0) + fstp st(0) + mov ebx,ds:dword ptr[pspantemp] + mov ebx,ds:dword ptr[12+ebx] + test ebx,ebx + mov ds:byte ptr[7+edi],al + jnz LSpanLoop + pop ebx + pop esi + pop edi + pop ebp + ret + +LClamp: + mov edx,040000000h + xor ebx,ebx + fstp st(0) + jmp LZDraw +LClampNeg: + mov edx,040000000h + xor ebx,ebx + fstp st(0) + jmp LZDrawNeg + public _D_DrawZSpans +_D_DrawZSpans: + push ebp + push edi + push esi + push ebx + fld ds:dword ptr[_d_zistepu] + mov eax,ds:dword ptr[_d_zistepu] + mov esi,ds:dword ptr[4+16+esp] + test eax,eax + jz LFNegSpan + fmul ds:dword ptr[Float2ToThe31nd] + fistp ds:dword ptr[izistep] + mov ebx,ds:dword ptr[izistep] +LFSpanLoop: + fild ds:dword ptr[4+esi] + fild ds:dword ptr[0+esi] + mov ecx,ds:dword ptr[4+esi] + mov edi,ds:dword ptr[_d_pzbuffer] + fmul ds:dword ptr[_d_zistepu] + fxch st(1) + fmul ds:dword ptr[_d_zistepv] + fxch st(1) + fadd ds:dword ptr[_d_ziorigin] + imul ecx,ds:dword ptr[_d_zrowbytes] + faddp st(1),st(0) + fcom ds:dword ptr[float_point5] + add edi,ecx + mov edx,ds:dword ptr[0+esi] + add edx,edx + mov ecx,ds:dword ptr[8+esi] + add edi,edx + push esi + fnstsw ax + test ah,045h + jz LClamp + fmul ds:dword ptr[Float2ToThe31nd] + fistp ds:dword ptr[izi] + mov edx,ds:dword ptr[izi] +LZDraw: + test edi,2 + jz LFMiddle + mov eax,edx + add edx,ebx + shr eax,16 + dec ecx + mov ds:word ptr[edi],ax + add edi,2 +LFMiddle: + push ecx + shr ecx,1 + jz LFLast + shr ecx,1 + jnc LFMiddleLoop + mov eax,edx + add edx,ebx + shr eax,16 + mov esi,edx + add edx,ebx + and esi,0FFFF0000h + or eax,esi + mov ds:dword ptr[edi],eax + add edi,4 + and ecx,ecx + jz LFLast +LFMiddleLoop: + mov eax,edx + add edx,ebx + shr eax,16 + mov esi,edx + add edx,ebx + and esi,0FFFF0000h + or eax,esi + mov ebp,edx + mov ds:dword ptr[edi],eax + add edx,ebx + shr ebp,16 + mov esi,edx + add edx,ebx + and esi,0FFFF0000h + or ebp,esi + mov ds:dword ptr[4+edi],ebp + add edi,8 + dec ecx + jnz LFMiddleLoop +LFLast: + pop ecx + pop esi + and ecx,1 + jz LFSpanDone + shr edx,16 + mov ds:word ptr[edi],dx +LFSpanDone: + mov esi,ds:dword ptr[12+esi] + test esi,esi + jnz LFSpanLoop + jmp LFDone +LFNegSpan: + fmul ds:dword ptr[FloatMinus2ToThe31nd] + fistp ds:dword ptr[izistep] + mov ebx,ds:dword ptr[izistep] +LFNegSpanLoop: + fild ds:dword ptr[4+esi] + fild ds:dword ptr[0+esi] + mov ecx,ds:dword ptr[4+esi] + mov edi,ds:dword ptr[_d_pzbuffer] + fmul ds:dword ptr[_d_zistepu] + fxch st(1) + fmul ds:dword ptr[_d_zistepv] + fxch st(1) + fadd ds:dword ptr[_d_ziorigin] + imul ecx,ds:dword ptr[_d_zrowbytes] + faddp st(1),st(0) + fcom ds:dword ptr[float_point5] + add edi,ecx + mov edx,ds:dword ptr[0+esi] + add edx,edx + mov ecx,ds:dword ptr[8+esi] + add edi,edx + push esi + fnstsw ax + test ah,045h + jz LClampNeg + fmul ds:dword ptr[Float2ToThe31nd] + fistp ds:dword ptr[izi] + mov edx,ds:dword ptr[izi] +LZDrawNeg: + test edi,2 + jz LFNegMiddle + mov eax,edx + sub edx,ebx + shr eax,16 + dec ecx + mov ds:word ptr[edi],ax + add edi,2 +LFNegMiddle: + push ecx + shr ecx,1 + jz LFNegLast + shr ecx,1 + jnc LFNegMiddleLoop + mov eax,edx + sub edx,ebx + shr eax,16 + mov esi,edx + sub edx,ebx + and esi,0FFFF0000h + or eax,esi + mov ds:dword ptr[edi],eax + add edi,4 + and ecx,ecx + jz LFNegLast +LFNegMiddleLoop: + mov eax,edx + sub edx,ebx + shr eax,16 + mov esi,edx + sub edx,ebx + and esi,0FFFF0000h + or eax,esi + mov ebp,edx + mov ds:dword ptr[edi],eax + sub edx,ebx + shr ebp,16 + mov esi,edx + sub edx,ebx + and esi,0FFFF0000h + or ebp,esi + mov ds:dword ptr[4+edi],ebp + add edi,8 + dec ecx + jnz LFNegMiddleLoop +LFNegLast: + pop ecx + pop esi + and ecx,1 + jz LFNegSpanDone + shr edx,16 + mov ds:word ptr[edi],dx +LFNegSpanDone: + mov esi,ds:dword ptr[12+esi] + test esi,esi + jnz LFNegSpanLoop +LFDone: + pop ebx + pop esi + pop edi + pop ebp + ret +_TEXT ENDS + END diff --git a/QW/client/d_draw.s b/QW/client/d_draw.s new file mode 100644 index 0000000..f0a6e2a --- /dev/null +++ b/QW/client/d_draw.s @@ -0,0 +1,1037 @@ +/* +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_draw.s +// x86 assembly-language horizontal 8-bpp span-drawing code. +// + +#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. +// +// Assumes there is at least one span in pspans, and that every span +// contains at least one pixel +//---------------------------------------------------------------------- + + .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_DrawSpans8) +C(D_DrawSpans8): + 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 +// +// TODO: 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 + fstps zi8stepu + fstps tdivz8stepu + fstps sdivz8stepu + +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 $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) // 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 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 + 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 $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 + + movb (%esi),%bl // get first source texel + subl $8,%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 $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,%eax // tstep >>= 16; + jz LZero + sarl $19,%edx // sstep >>= 16; + movl C(cachewidth),%ebx + imull %ebx,%eax + jmp LSetUp1 + +LZero: + sarl $19,%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 $13,%ebp // left-justify sstep fractional part + movl sfracf,%ebx + shll $13,%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 + + +// +// start FDIV for end of next segment in flight, so it can overlap +// + movl counttemp,%ecx + cmpl $8,%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 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: + movl %ecx,counttemp + + 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 $8,%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 $8,%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 $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 entryvec_table(,%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 $7,%edi // adjust for hardwired offset + jmp LEndSpan + + +LOnlyOneStep: + subl s,%eax + subl t,%ebx + movl %eax,%ebp + movl %ebx,%edx + jmp LSetEntryvec + +//---------------------------------------- + +.globl Entry2_8 +Entry2_8: + subl $6,%edi // adjust for hardwired offsets + movb (%esi),%al + jmp LLEntry2_8 + +//---------------------------------------- + +.globl Entry3_8 +Entry3_8: + 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 + jmp LLEntry3_8 + +//---------------------------------------- + +.globl Entry4_8 +Entry4_8: + 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 LLEntry4_8 + +//---------------------------------------- + +.globl Entry5_8 +Entry5_8: + 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 LLEntry5_8 + +//---------------------------------------- + +.globl Entry6_8 +Entry6_8: + 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 LLEntry6_8 + +//---------------------------------------- + +.globl Entry7_8 +Entry7_8: + 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 LLEntry7_8 + +//---------------------------------------- + +.globl Entry8_8 +Entry8_8: + 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 +LLEntry7_8: + sbbl %ecx,%ecx + movb %al,2(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LLEntry6_8: + sbbl %ecx,%ecx + movb %al,3(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LLEntry5_8: + sbbl %ecx,%ecx + movb %al,4(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LLEntry4_8: + sbbl %ecx,%ecx + movb %al,5(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi +LLEntry3_8: + movb %al,6(%edi) + movb (%esi),%al +LLEntry2_8: + +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,7(%edi) + jnz LSpanLoop // more spans + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + +//---------------------------------------------------------------------- +// 8-bpp horizontal span z drawing codefor polygons, with no transparency. +// +// Assumes there is at least one span in pzspans, and that every span +// contains at least one pixel +//---------------------------------------------------------------------- + + .text + +// z-clamp on a non-negative gradient span +LClamp: + movl $0x40000000,%edx + xorl %ebx,%ebx + fstp %st(0) + jmp LZDraw + +// z-clamp on a negative gradient span +LClampNeg: + movl $0x40000000,%edx + xorl %ebx,%ebx + fstp %st(0) + jmp LZDrawNeg + + +#define pzspans 4+16 + +.globl C(D_DrawZSpans) +C(D_DrawZSpans): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + + flds C(d_zistepu) + movl C(d_zistepu),%eax + movl pzspans(%esp),%esi + testl %eax,%eax + jz LFNegSpan + + fmuls Float2ToThe31nd + fistpl izistep // note: we are relying on FP exceptions being turned + // off here to avoid range problems + movl izistep,%ebx // remains loaded for all spans + +LFSpanLoop: +// set up the initial 1/z value + fildl espan_t_v(%esi) + fildl espan_t_u(%esi) + movl espan_t_v(%esi),%ecx + movl C(d_pzbuffer),%edi + fmuls C(d_zistepu) + fxch %st(1) + fmuls C(d_zistepv) + fxch %st(1) + fadds C(d_ziorigin) + imull C(d_zrowbytes),%ecx + faddp %st(0),%st(1) + +// clamp if z is nearer than 2 (1/z > 0.5) + fcoms float_point5 + addl %ecx,%edi + movl espan_t_u(%esi),%edx + addl %edx,%edx // word count + movl espan_t_count(%esi),%ecx + addl %edx,%edi // pdest = &pdestspan[scans->u]; + pushl %esi // preserve spans pointer + fnstsw %ax + testb $0x45,%ah + jz LClamp + + fmuls Float2ToThe31nd + fistpl izi // note: we are relying on FP exceptions being turned + // off here to avoid problems when the span is closer + // than 1/(2**31) + movl izi,%edx + +// at this point: +// %ebx = izistep +// %ecx = count +// %edx = izi +// %edi = pdest + +LZDraw: + +// do a single pixel up front, if necessary to dword align the destination + testl $2,%edi + jz LFMiddle + movl %edx,%eax + addl %ebx,%edx + shrl $16,%eax + decl %ecx + movw %ax,(%edi) + addl $2,%edi + +// do middle a pair of aligned dwords at a time +LFMiddle: + pushl %ecx + shrl $1,%ecx // count / 2 + jz LFLast // no aligned dwords to do + shrl $1,%ecx // (count / 2) / 2 + jnc LFMiddleLoop // even number of aligned dwords to do + + movl %edx,%eax + addl %ebx,%edx + shrl $16,%eax + movl %edx,%esi + addl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%eax + movl %eax,(%edi) + addl $4,%edi + andl %ecx,%ecx + jz LFLast + +LFMiddleLoop: + movl %edx,%eax + addl %ebx,%edx + shrl $16,%eax + movl %edx,%esi + addl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%eax + movl %edx,%ebp + movl %eax,(%edi) + addl %ebx,%edx + shrl $16,%ebp + movl %edx,%esi + addl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%ebp + movl %ebp,4(%edi) // FIXME: eliminate register contention + addl $8,%edi + + decl %ecx + jnz LFMiddleLoop + +LFLast: + popl %ecx // retrieve count + popl %esi // retrieve span pointer + +// do the last, unaligned pixel, if there is one + andl $1,%ecx // is there an odd pixel left to do? + jz LFSpanDone // no + shrl $16,%edx + movw %dx,(%edi) // do the final pixel's z + +LFSpanDone: + movl espan_t_pnext(%esi),%esi + testl %esi,%esi + jnz LFSpanLoop + + jmp LFDone + +LFNegSpan: + fmuls FloatMinus2ToThe31nd + fistpl izistep // note: we are relying on FP exceptions being turned + // off here to avoid range problems + movl izistep,%ebx // remains loaded for all spans + +LFNegSpanLoop: +// set up the initial 1/z value + fildl espan_t_v(%esi) + fildl espan_t_u(%esi) + movl espan_t_v(%esi),%ecx + movl C(d_pzbuffer),%edi + fmuls C(d_zistepu) + fxch %st(1) + fmuls C(d_zistepv) + fxch %st(1) + fadds C(d_ziorigin) + imull C(d_zrowbytes),%ecx + faddp %st(0),%st(1) + +// clamp if z is nearer than 2 (1/z > 0.5) + fcoms float_point5 + addl %ecx,%edi + movl espan_t_u(%esi),%edx + addl %edx,%edx // word count + movl espan_t_count(%esi),%ecx + addl %edx,%edi // pdest = &pdestspan[scans->u]; + pushl %esi // preserve spans pointer + fnstsw %ax + testb $0x45,%ah + jz LClampNeg + + fmuls Float2ToThe31nd + fistpl izi // note: we are relying on FP exceptions being turned + // off here to avoid problems when the span is closer + // than 1/(2**31) + movl izi,%edx + +// at this point: +// %ebx = izistep +// %ecx = count +// %edx = izi +// %edi = pdest + +LZDrawNeg: + +// do a single pixel up front, if necessary to dword align the destination + testl $2,%edi + jz LFNegMiddle + movl %edx,%eax + subl %ebx,%edx + shrl $16,%eax + decl %ecx + movw %ax,(%edi) + addl $2,%edi + +// do middle a pair of aligned dwords at a time +LFNegMiddle: + pushl %ecx + shrl $1,%ecx // count / 2 + jz LFNegLast // no aligned dwords to do + shrl $1,%ecx // (count / 2) / 2 + jnc LFNegMiddleLoop // even number of aligned dwords to do + + movl %edx,%eax + subl %ebx,%edx + shrl $16,%eax + movl %edx,%esi + subl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%eax + movl %eax,(%edi) + addl $4,%edi + andl %ecx,%ecx + jz LFNegLast + +LFNegMiddleLoop: + movl %edx,%eax + subl %ebx,%edx + shrl $16,%eax + movl %edx,%esi + subl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%eax + movl %edx,%ebp + movl %eax,(%edi) + subl %ebx,%edx + shrl $16,%ebp + movl %edx,%esi + subl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%ebp + movl %ebp,4(%edi) // FIXME: eliminate register contention + addl $8,%edi + + decl %ecx + jnz LFNegMiddleLoop + +LFNegLast: + popl %ecx // retrieve count + popl %esi // retrieve span pointer + +// do the last, unaligned pixel, if there is one + andl $1,%ecx // is there an odd pixel left to do? + jz LFNegSpanDone // no + shrl $16,%edx + movw %dx,(%edi) // do the final pixel's z + +LFNegSpanDone: + movl espan_t_pnext(%esi),%esi + testl %esi,%esi + jnz LFNegSpanLoop + +LFDone: + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + +#endif // id386 diff --git a/QW/client/d_draw16.asm b/QW/client/d_draw16.asm new file mode 100644 index 0000000..77b0ded --- /dev/null +++ b/QW/client/d_draw16.asm @@ -0,0 +1,924 @@ + .386P + .model FLAT + externdef _d_zistepu:dword + externdef _d_pzbuffer:dword + externdef _d_zistepv:dword + externdef _d_zrowbytes:dword + externdef _d_ziorigin:dword + externdef _r_turb_s:dword + externdef _r_turb_t:dword + externdef _r_turb_pdest:dword + externdef _r_turb_spancount:dword + externdef _r_turb_turb:dword + externdef _r_turb_pbase:dword + externdef _r_turb_sstep:dword + externdef _r_turb_tstep:dword + externdef _r_bmodelactive:dword + externdef _d_sdivzstepu:dword + externdef _d_tdivzstepu:dword + externdef _d_sdivzstepv:dword + externdef _d_tdivzstepv:dword + externdef _d_sdivzorigin:dword + externdef _d_tdivzorigin:dword + externdef _sadjust:dword + externdef _tadjust:dword + externdef _bbextents:dword + externdef _bbextentt:dword + externdef _cacheblock:dword + externdef _d_viewbuffer:dword + externdef _cachewidth:dword + externdef _d_pzbuffer:dword + externdef _d_zrowbytes:dword + externdef _d_zwidth:dword + externdef _d_scantable:dword + externdef _r_lightptr:dword + externdef _r_numvblocks:dword + externdef _prowdestbase:dword + externdef _pbasesource:dword + externdef _r_lightwidth:dword + externdef _lightright:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _lightdelta:dword + externdef _lightright:dword + externdef _lightdelta:dword + externdef _sourcetstep:dword + externdef _surfrowbytes:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _r_sourcemax:dword + externdef _r_stepback:dword + externdef _colormap:dword + externdef _blocksize:dword + externdef _sourcesstep:dword + externdef _lightleft:dword + externdef _blockdivshift:dword + externdef _blockdivmask:dword + externdef _lightleftstep:dword + externdef _r_origin:dword + externdef _r_ppn:dword + externdef _r_pup:dword + externdef _r_pright:dword + externdef _ycenter:dword + externdef _xcenter:dword + externdef _d_vrectbottom_particle:dword + externdef _d_vrectright_particle:dword + externdef _d_vrecty:dword + externdef _d_vrectx:dword + externdef _d_pix_shift:dword + externdef _d_pix_min:dword + externdef _d_pix_max:dword + externdef _d_y_aspect_shift:dword + externdef _screenwidth:dword + externdef _vright:dword + externdef _vup:dword + externdef _vpn:dword + externdef _BOPS_Error:dword + externdef _snd_scaletable:dword + externdef _paintbuffer:dword + externdef _snd_linear_count:dword + externdef _snd_p:dword + externdef _snd_vol:dword + externdef _snd_out:dword + externdef _r_leftclipped:dword + externdef _r_leftenter:dword + externdef _r_rightclipped:dword + externdef _r_rightenter:dword + externdef _modelorg:dword + externdef _xscale:dword + externdef _r_refdef:dword + externdef _yscale:dword + externdef _r_leftexit:dword + externdef _r_rightexit:dword + externdef _r_lastvertvalid:dword + externdef _cacheoffset:dword + externdef _newedges:dword + externdef _removeedges:dword + externdef _r_pedge:dword + externdef _r_framecount:dword + externdef _r_u1:dword + externdef _r_emitted:dword + externdef _edge_p:dword + externdef _surface_p:dword + externdef _surfaces:dword + externdef _r_lzi1:dword + externdef _r_v1:dword + externdef _r_ceilv1:dword + externdef _r_nearzi:dword + externdef _r_nearzionly:dword + externdef _edge_aftertail:dword + externdef _edge_tail:dword + externdef _current_iv:dword + externdef _edge_head_u_shift20:dword + externdef _span_p:dword + externdef _edge_head:dword + externdef _fv:dword + externdef _edge_tail_u_shift20:dword + externdef _r_apverts:dword + externdef _r_anumverts:dword + externdef _aliastransform:dword + externdef _r_avertexnormals:dword + externdef _r_plightvec:dword + externdef _r_ambientlight:dword + externdef _r_shadelight:dword + externdef _aliasxcenter:dword + externdef _aliasycenter:dword + externdef _a_sstepxfrac:dword + externdef _r_affinetridesc:dword + externdef _acolormap:dword + externdef _d_pcolormap:dword + externdef _r_affinetridesc:dword + externdef _d_sfrac:dword + externdef _d_ptex:dword + externdef _d_pedgespanpackage:dword + externdef _d_tfrac:dword + externdef _d_light:dword + externdef _d_zi:dword + externdef _d_pdest:dword + externdef _d_pz:dword + externdef _d_aspancount:dword + externdef _erroradjustup:dword + externdef _errorterm:dword + externdef _d_xdenom:dword + externdef _r_p0:dword + externdef _r_p1:dword + externdef _r_p2:dword + externdef _a_tstepxfrac:dword + externdef _r_sstepx:dword + externdef _r_tstepx:dword + externdef _a_ststepxwhole:dword + externdef _zspantable:dword + externdef _skintable:dword + externdef _r_zistepx:dword + externdef _erroradjustdown:dword + externdef _d_countextrastep:dword + externdef _ubasestep:dword + externdef _a_ststepxwhole:dword + externdef _a_tstepxfrac:dword + externdef _r_lstepx:dword + externdef _a_spans:dword + externdef _erroradjustdown:dword + externdef _d_pdestextrastep:dword + externdef _d_pzextrastep:dword + externdef _d_sfracextrastep:dword + externdef _d_ptexextrastep:dword + externdef _d_countextrastep:dword + externdef _d_tfracextrastep:dword + externdef _d_lightextrastep:dword + externdef _d_ziextrastep:dword + externdef _d_pdestbasestep:dword + externdef _d_pzbasestep:dword + externdef _d_sfracbasestep:dword + externdef _d_ptexbasestep:dword + externdef _ubasestep:dword + externdef _d_tfracbasestep:dword + externdef _d_lightbasestep:dword + externdef _d_zibasestep:dword + externdef _zspantable:dword + externdef _r_lstepy:dword + externdef _r_sstepy:dword + externdef _r_tstepy:dword + externdef _r_zistepy:dword + externdef _D_PolysetSetEdgeTable:dword + externdef _D_RasterizeAliasPolySmooth:dword + externdef float_point5:dword + externdef Float2ToThe31nd:dword + externdef izistep:dword + externdef izi:dword + externdef FloatMinus2ToThe31nd:dword + externdef float_1:dword + externdef float_particle_z_clip:dword + externdef float_minus_1:dword + externdef float_0:dword + externdef fp_16:dword + externdef fp_64k:dword + externdef fp_1m:dword + externdef fp_1m_minus_1:dword + externdef fp_8:dword + externdef entryvec_table:dword + externdef advancetable:dword + externdef sstep:dword + externdef tstep:dword + externdef pspantemp:dword + externdef counttemp:dword + externdef jumptemp:dword + externdef reciprocal_table:dword + externdef DP_Count:dword + externdef DP_u:dword + externdef DP_v:dword + externdef DP_32768:dword + externdef DP_Color:dword + externdef DP_Pix:dword + externdef DP_EntryTable:dword + externdef pbase:dword + externdef s:dword + externdef t:dword + externdef sfracf:dword + externdef tfracf:dword + externdef snext:dword + externdef tnext:dword + externdef spancountminus1:dword + externdef zi16stepu:dword + externdef sdivz16stepu:dword + externdef tdivz16stepu:dword + externdef zi8stepu:dword + externdef sdivz8stepu:dword + externdef tdivz8stepu:dword + externdef reciprocal_table_16:dword + externdef entryvec_table_16:dword + externdef ceil_cw:dword + externdef single_cw:dword + externdef fp_64kx64k:dword + externdef pz:dword + externdef spr8entryvec_table:dword +_DATA SEGMENT +_DATA ENDS +_TEXT SEGMENT +LClampHigh0: + mov esi,ds:dword ptr[_bbextents] + jmp LClampReentry0 +LClampHighOrLow0: + jg LClampHigh0 + xor esi,esi + jmp LClampReentry0 +LClampHigh1: + mov edx,ds:dword ptr[_bbextentt] + jmp LClampReentry1 +LClampHighOrLow1: + jg LClampHigh1 + xor edx,edx + jmp LClampReentry1 +LClampLow2: + mov ebp,4096 + jmp LClampReentry2 +LClampHigh2: + mov ebp,ds:dword ptr[_bbextents] + jmp LClampReentry2 +LClampLow3: + mov ecx,4096 + jmp LClampReentry3 +LClampHigh3: + mov ecx,ds:dword ptr[_bbextentt] + jmp LClampReentry3 +LClampLow4: + mov eax,4096 + jmp LClampReentry4 +LClampHigh4: + mov eax,ds:dword ptr[_bbextents] + jmp LClampReentry4 +LClampLow5: + mov ebx,4096 + jmp LClampReentry5 +LClampHigh5: + mov ebx,ds:dword ptr[_bbextentt] + jmp LClampReentry5 + align 4 + public _D_DrawSpans16 +_D_DrawSpans16: + push ebp + push edi + push esi + push ebx + fld ds:dword ptr[_d_sdivzstepu] + fmul ds:dword ptr[fp_16] + mov edx,ds:dword ptr[_cacheblock] + fld ds:dword ptr[_d_tdivzstepu] + fmul ds:dword ptr[fp_16] + mov ebx,ds:dword ptr[4+16+esp] + fld ds:dword ptr[_d_zistepu] + fmul ds:dword ptr[fp_16] + mov ds:dword ptr[pbase],edx + fstp ds:dword ptr[zi16stepu] + fstp ds:dword ptr[tdivz16stepu] + fstp ds:dword ptr[sdivz16stepu] +LSpanLoop: + fild ds:dword ptr[4+ebx] + fild ds:dword ptr[0+ebx] + fld st(1) + fmul ds:dword ptr[_d_sdivzstepv] + fld st(1) + fmul ds:dword ptr[_d_sdivzstepu] + fld st(2) + fmul ds:dword ptr[_d_tdivzstepu] + fxch st(1) + faddp st(2),st(0) + fxch st(1) + fld st(3) + fmul ds:dword ptr[_d_tdivzstepv] + fxch st(1) + fadd ds:dword ptr[_d_sdivzorigin] + fxch st(4) + fmul ds:dword ptr[_d_zistepv] + fxch st(1) + faddp st(2),st(0) + fxch st(2) + fmul ds:dword ptr[_d_zistepu] + fxch st(1) + fadd ds:dword ptr[_d_tdivzorigin] + fxch st(2) + faddp st(1),st(0) + fld ds:dword ptr[fp_64k] + fxch st(1) + fadd ds:dword ptr[_d_ziorigin] + fdiv st(1),st(0) + mov ecx,ds:dword ptr[_d_viewbuffer] + mov eax,ds:dword ptr[4+ebx] + mov ds:dword ptr[pspantemp],ebx + mov edx,ds:dword ptr[_tadjust] + mov esi,ds:dword ptr[_sadjust] + mov edi,ds:dword ptr[_d_scantable+eax*4] + add edi,ecx + mov ecx,ds:dword ptr[0+ebx] + add edi,ecx + mov ecx,ds:dword ptr[8+ebx] + cmp ecx,16 + ja LSetupNotLast1 + dec ecx + jz LCleanup1 + mov ds:dword ptr[spancountminus1],ecx + fxch st(1) + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[s] + fistp ds:dword ptr[t] + fild ds:dword ptr[spancountminus1] + fld ds:dword ptr[_d_tdivzstepu] + fld ds:dword ptr[_d_zistepu] + fmul st(0),st(2) + fxch st(1) + fmul st(0),st(2) + fxch st(2) + fmul ds:dword ptr[_d_sdivzstepu] + fxch st(1) + faddp st(3),st(0) + fxch st(1) + faddp st(3),st(0) + faddp st(3),st(0) + fld ds:dword ptr[fp_64k] + fdiv st(0),st(1) + jmp LFDIVInFlight1 +LCleanup1: + fxch st(1) + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[s] + fistp ds:dword ptr[t] + jmp LFDIVInFlight1 + align 4 +LSetupNotLast1: + fxch st(1) + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[s] + fistp ds:dword ptr[t] + fadd ds:dword ptr[zi16stepu] + fxch st(2) + fadd ds:dword ptr[sdivz16stepu] + fxch st(2) + fld ds:dword ptr[tdivz16stepu] + faddp st(2),st(0) + fld ds:dword ptr[fp_64k] + fdiv st(0),st(1) +LFDIVInFlight1: + add esi,ds:dword ptr[s] + add edx,ds:dword ptr[t] + mov ebx,ds:dword ptr[_bbextents] + mov ebp,ds:dword ptr[_bbextentt] + cmp esi,ebx + ja LClampHighOrLow0 +LClampReentry0: + mov ds:dword ptr[s],esi + mov ebx,ds:dword ptr[pbase] + shl esi,16 + cmp edx,ebp + mov ds:dword ptr[sfracf],esi + ja LClampHighOrLow1 +LClampReentry1: + mov ds:dword ptr[t],edx + mov esi,ds:dword ptr[s] + shl edx,16 + mov eax,ds:dword ptr[t] + sar esi,16 + mov ds:dword ptr[tfracf],edx + sar eax,16 + mov edx,ds:dword ptr[_cachewidth] + imul eax,edx + add esi,ebx + add esi,eax + cmp ecx,16 + jna LLastSegment +LNotLastSegment: + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[snext] + fistp ds:dword ptr[tnext] + mov eax,ds:dword ptr[snext] + mov edx,ds:dword ptr[tnext] + mov bl,ds:byte ptr[esi] + sub ecx,16 + mov ebp,ds:dword ptr[_sadjust] + mov ds:dword ptr[counttemp],ecx + mov ecx,ds:dword ptr[_tadjust] + mov ds:byte ptr[edi],bl + add ebp,eax + add ecx,edx + mov eax,ds:dword ptr[_bbextents] + mov edx,ds:dword ptr[_bbextentt] + cmp ebp,4096 + jl LClampLow2 + cmp ebp,eax + ja LClampHigh2 +LClampReentry2: + cmp ecx,4096 + jl LClampLow3 + cmp ecx,edx + ja LClampHigh3 +LClampReentry3: + mov ds:dword ptr[snext],ebp + mov ds:dword ptr[tnext],ecx + sub ebp,ds:dword ptr[s] + sub ecx,ds:dword ptr[t] + mov eax,ecx + mov edx,ebp + sar eax,20 + jz LZero + sar edx,20 + mov ebx,ds:dword ptr[_cachewidth] + imul eax,ebx + jmp LSetUp1 +LZero: + sar edx,20 + mov ebx,ds:dword ptr[_cachewidth] +LSetUp1: + add eax,edx + mov edx,ds:dword ptr[tfracf] + mov ds:dword ptr[advancetable+4],eax + add eax,ebx + shl ebp,12 + mov ebx,ds:dword ptr[sfracf] + shl ecx,12 + mov ds:dword ptr[advancetable],eax + mov ds:dword ptr[tstep],ecx + add edx,ecx + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov al,ds:byte ptr[esi] + add ebx,ebp + mov ds:byte ptr[1+edi],al + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[2+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[3+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[4+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[5+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[6+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[7+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + mov ecx,ds:dword ptr[counttemp] + cmp ecx,16 + ja LSetupNotLast2 + dec ecx + jz LFDIVInFlight2 + mov ds:dword ptr[spancountminus1],ecx + fild ds:dword ptr[spancountminus1] + fld ds:dword ptr[_d_zistepu] + fmul st(0),st(1) + fld ds:dword ptr[_d_tdivzstepu] + fmul st(0),st(2) + fxch st(1) + faddp st(3),st(0) + fxch st(1) + fmul ds:dword ptr[_d_sdivzstepu] + fxch st(1) + faddp st(3),st(0) + fld ds:dword ptr[fp_64k] + fxch st(1) + faddp st(4),st(0) + fdiv st(0),st(1) + jmp LFDIVInFlight2 + align 4 +LSetupNotLast2: + fadd ds:dword ptr[zi16stepu] + fxch st(2) + fadd ds:dword ptr[sdivz16stepu] + fxch st(2) + fld ds:dword ptr[tdivz16stepu] + faddp st(2),st(0) + fld ds:dword ptr[fp_64k] + fdiv st(0),st(1) +LFDIVInFlight2: + mov ds:dword ptr[counttemp],ecx + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[8+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[9+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[10+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[11+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[12+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[13+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[14+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edi,16 + mov ds:dword ptr[tfracf],edx + mov edx,ds:dword ptr[snext] + mov ds:dword ptr[sfracf],ebx + mov ebx,ds:dword ptr[tnext] + mov ds:dword ptr[s],edx + mov ds:dword ptr[t],ebx + mov ecx,ds:dword ptr[counttemp] + cmp ecx,16 + mov ds:byte ptr[-1+edi],al + ja LNotLastSegment +LLastSegment: + test ecx,ecx + jz LNoSteps + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[snext] + fistp ds:dword ptr[tnext] + mov al,ds:byte ptr[esi] + mov ebx,ds:dword ptr[_tadjust] + mov ds:byte ptr[edi],al + mov eax,ds:dword ptr[_sadjust] + add eax,ds:dword ptr[snext] + add ebx,ds:dword ptr[tnext] + mov ebp,ds:dword ptr[_bbextents] + mov edx,ds:dword ptr[_bbextentt] + cmp eax,4096 + jl LClampLow4 + cmp eax,ebp + ja LClampHigh4 +LClampReentry4: + mov ds:dword ptr[snext],eax + cmp ebx,4096 + jl LClampLow5 + cmp ebx,edx + ja LClampHigh5 +LClampReentry5: + cmp ecx,1 + je LOnlyOneStep + sub eax,ds:dword ptr[s] + sub ebx,ds:dword ptr[t] + add eax,eax + add ebx,ebx + imul ds:dword ptr[reciprocal_table_16-8+ecx*4] + mov ebp,edx + mov eax,ebx + imul ds:dword ptr[reciprocal_table_16-8+ecx*4] +LSetEntryvec: + mov ebx,ds:dword ptr[entryvec_table_16+ecx*4] + mov eax,edx + mov ds:dword ptr[jumptemp],ebx + mov ecx,ebp + sar edx,16 + mov ebx,ds:dword ptr[_cachewidth] + sar ecx,16 + imul edx,ebx + add edx,ecx + mov ecx,ds:dword ptr[tfracf] + mov ds:dword ptr[advancetable+4],edx + add edx,ebx + shl ebp,16 + mov ebx,ds:dword ptr[sfracf] + shl eax,16 + mov ds:dword ptr[advancetable],edx + mov ds:dword ptr[tstep],eax + mov edx,ecx + add edx,eax + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + jmp dword ptr[jumptemp] +LNoSteps: + mov al,ds:byte ptr[esi] + sub edi,15 + jmp LEndSpan +LOnlyOneStep: + sub eax,ds:dword ptr[s] + sub ebx,ds:dword ptr[t] + mov ebp,eax + mov edx,ebx + jmp LSetEntryvec + public Entry2_16, Entry3_16, Entry4_16, Entry5_16 + public Entry6_16, Entry7_16, Entry8_16, Entry9_16 + public Entry10_16, Entry11_16, Entry12_16, Entry13_16 + public Entry14_16, Entry15_16, Entry16_16 +Entry2_16: + sub edi,14 + mov al,ds:byte ptr[esi] + jmp LEntry2_16 +Entry3_16: + sub edi,13 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + jmp LEntry3_16 +Entry4_16: + sub edi,12 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry4_16 +Entry5_16: + sub edi,11 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry5_16 +Entry6_16: + sub edi,10 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry6_16 +Entry7_16: + sub edi,9 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry7_16 +Entry8_16: + sub edi,8 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry8_16 +Entry9_16: + sub edi,7 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry9_16 +Entry10_16: + sub edi,6 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry10_16 +Entry11_16: + sub edi,5 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry11_16 +Entry12_16: + sub edi,4 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry12_16 +Entry13_16: + sub edi,3 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry13_16 +Entry14_16: + sub edi,2 + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry14_16 +Entry15_16: + dec edi + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + jmp LEntry15_16 +Entry16_16: + add edx,eax + mov al,ds:byte ptr[esi] + sbb ecx,ecx + add ebx,ebp + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] + sbb ecx,ecx + mov ds:byte ptr[1+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry15_16: + sbb ecx,ecx + mov ds:byte ptr[2+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry14_16: + sbb ecx,ecx + mov ds:byte ptr[3+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry13_16: + sbb ecx,ecx + mov ds:byte ptr[4+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry12_16: + sbb ecx,ecx + mov ds:byte ptr[5+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry11_16: + sbb ecx,ecx + mov ds:byte ptr[6+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry10_16: + sbb ecx,ecx + mov ds:byte ptr[7+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry9_16: + sbb ecx,ecx + mov ds:byte ptr[8+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry8_16: + sbb ecx,ecx + mov ds:byte ptr[9+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry7_16: + sbb ecx,ecx + mov ds:byte ptr[10+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry6_16: + sbb ecx,ecx + mov ds:byte ptr[11+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry5_16: + sbb ecx,ecx + mov ds:byte ptr[12+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] + add edx,ds:dword ptr[tstep] +LEntry4_16: + sbb ecx,ecx + mov ds:byte ptr[13+edi],al + add ebx,ebp + mov al,ds:byte ptr[esi] + adc esi,ds:dword ptr[advancetable+4+ecx*4] +LEntry3_16: + mov ds:byte ptr[14+edi],al + mov al,ds:byte ptr[esi] +LEntry2_16: +LEndSpan: + fstp st(0) + fstp st(0) + fstp st(0) + mov ebx,ds:dword ptr[pspantemp] + mov ebx,ds:dword ptr[12+ebx] + test ebx,ebx + mov ds:byte ptr[15+edi],al + jnz LSpanLoop + pop ebx + pop esi + pop edi + pop ebp + ret +_TEXT ENDS + END diff --git a/QW/client/d_draw16.s b/QW/client/d_draw16.s new file mode 100644 index 0000000..cccfdbf --- /dev/null +++ b/QW/client/d_draw16.s @@ -0,0 +1,974 @@ +/* +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 8-bpp span-drawing code, with 16-pixel +// subdivision. +// + +#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_DrawSpans16) +C(D_DrawSpans16): + 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 diff --git a/QW/client/d_edge.c b/QW/client/d_edge.c new file mode 100644 index 0000000..7bd3c75 --- /dev/null +++ b/QW/client/d_edge.c @@ -0,0 +1,336 @@ +/* +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; + +// 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; + byte *pdest; + int u, u2, pix; + + pix = (color<<24) | (color<<16) | (color<<8) | color; + for (span=surf->spans ; span ; span=span->pnext) + { + pdest = (byte *)d_viewbuffer + screenwidth*span->v; + u = span->u; + u2 = span->u + span->count - 1; + ((byte *)pdest)[u] = pix; + + if (u2 - u < 8) + { + for (u++ ; u <= u2 ; u++) + ((byte *)pdest)[u] = pix; + } + else + { + for (u++ ; u & 3 ; u++) + ((byte *)pdest)[u] = pix; + + u2 -= 4; + for ( ; u <= u2 ; u+=4) + *(int *)((byte *)pdest + u) = pix; + u2 += 4; + for ( ; u <= u2 ; u++) + ((byte *)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; +} + + +/* +============== +D_DrawSurfaces +============== +*/ +void D_DrawSurfaces (void) +{ + surf_t *s; + msurface_t *pface; + surfcache_t *pcurrentcache; + vec3_t world_transformed_modelorg; + vec3_t local_modelorg; + + currententity = &r_worldentity; + TransformVector (modelorg, transformed_modelorg); + VectorCopy (transformed_modelorg, world_transformed_modelorg); + +// TODO: could preset a lot of this at mode set time + if (r_drawflat.value) + { + 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; + +#ifdef __alpha__ + D_DrawSolidSurface (s, (int)((long)s->data & 0xFF)); +#else + D_DrawSolidSurface (s, (int)s->data & 0xFF); +#endif + 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_skymade) + { + R_MakeSky (); + } + + D_DrawSkyScans8 (s->spans); + 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 *) + ((byte *)pface->texinfo->texture + + pface->texinfo->texture->offsets[0]); + cachewidth = 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); + + 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; + 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; + + D_CalcGradients (pface); + + (*d_drawspans) (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 + // + 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; + } + } + } + } +} + diff --git a/QW/client/d_fill.c b/QW/client/d_fill.c new file mode 100644 index 0000000..e6c1473 --- /dev/null +++ b/QW/client/d_fill.c @@ -0,0 +1,88 @@ +/* +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 = ((byte *)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 *)((byte*)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; + } + } +} + diff --git a/QW/client/d_iface.h b/QW/client/d_iface.h new file mode 100644 index 0000000..881175b --- /dev/null +++ b/QW/client/d_iface.h @@ -0,0 +1,229 @@ +/* +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 200 + +typedef struct +{ + float u, v; + float s, t; + float zi; +} emitpoint_t; + +typedef enum { + pt_static, pt_grav, pt_slowgrav, pt_fire, pt_explode, pt_explode2, pt_blob, pt_blob2 +} ptype_t; + +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +typedef struct particle_s +{ +// driver-usable fields + vec3_t org; + float color; +// drivers never touch the following fields + struct particle_s *next; + vec3_t vel; + float ramp; + float die; + ptype_t type; +} particle_t; + +#define PARTICLE_Z_CLIP 8.0 + +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; + 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 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; + + +void D_Aff8Patch (void *pcolormap); +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height); +void D_DisableBackBufferAccess (void); +void D_EndDirectRect (int x, int y, int width, int height); +void D_PolysetDraw (void); +void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts); +void D_DrawParticle (particle_t *pparticle); +void D_DrawPoly (void); +void D_DrawSprite (void); +void D_DrawSurfaces (void); +void D_DrawZPoint (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 byte *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 + +//=======================================================================// + +// 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_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 byte *r_warpbuffer; + diff --git a/QW/client/d_ifacea.h b/QW/client/d_ifacea.h new file mode 100644 index 0000000..241952a --- /dev/null +++ b/QW/client/d_ifacea.h @@ -0,0 +1,98 @@ +/* +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 0 +#define pt_color 12 +// 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_onseam 0 +#define stv_s 4 +#define stv_t 8 +#define stv_size 12 + + +// 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_seamfixupX16 32 +#define atd_size 36 + diff --git a/QW/client/d_init.c b/QW/client/d_init.c new file mode 100644 index 0000000..0d08392 --- /dev/null +++ b/QW/client/d_init.c @@ -0,0 +1,174 @@ +/* +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 = {"d_subdiv16", "1"}; +cvar_t d_mipcap = {"d_mipcap", "0"}; +cvar_t d_mipscale = {"d_mipscale", "1"}; + +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}; + +extern int d_aflatcolor; + +void (*d_drawspans) (espan_t *pspan); + + +/* +=============== +D_Init +=============== +*/ +void D_Init (void) +{ + + r_skydirect = 1; + + Cvar_RegisterVariable (&d_subdiv16); + Cvar_RegisterVariable (&d_mipcap); + Cvar_RegisterVariable (&d_mipscale); + + r_drawpolys = false; + r_worldpolysbacktofront = false; + r_recursiveaffinetriangles = true; + r_pixbytes = 1; + r_aliasuvscale = 1.0; +} + + +/* +=============== +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) +{ + int i; + + if (r_dowarp) + d_viewbuffer = r_warpbuffer; + else + d_viewbuffer = (void *)(byte *)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 (d_subdiv16.value) + d_drawspans = D_DrawSpans16; + else + d_drawspans = D_DrawSpans8; +#else + d_drawspans = D_DrawSpans8; +#endif + + d_aflatcolor = 0; +} + + +/* +=============== +D_UpdateRects +=============== +*/ +void D_UpdateRects (vrect_t *prect) +{ + +// the software driver draws these directly to the vid buffer + + UNUSED(prect); +} + diff --git a/QW/client/d_local.h b/QW/client/d_local.h new file mode 100644 index 0000000..af92489 --- /dev/null +++ b/QW/client/d_local.h @@ -0,0 +1,111 @@ +/* +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 + byte 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 (espan_t *pspans); +void D_DrawSpans16 (espan_t *pspans); +void D_DrawZSpans (espan_t *pspans); +void Turbulent8 (espan_t *pspan); +void D_SpriteDrawSpans (sspan_t *pspan); + +void D_DrawSkyScans8 (espan_t *pspan); +void D_DrawSkyScans16 (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); + diff --git a/QW/client/d_modech.c b/QW/client/d_modech.c new file mode 100644 index 0000000..75c188e --- /dev/null +++ b/QW/client/d_modech.c @@ -0,0 +1,107 @@ +/* +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_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 (); +} + diff --git a/QW/client/d_part.c b/QW/client/d_part.c new file mode 100644 index 0000000..176b76b --- /dev/null +++ b/QW/client/d_part.c @@ -0,0 +1,207 @@ +/* +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" + + +/* +============== +D_EndParticles +============== +*/ +void D_EndParticles (void) +{ +// not used by software driver +} + + +/* +============== +D_StartParticles +============== +*/ +void D_StartParticles (void) +{ +// not used by software driver +} + + +#if !id386 + +/* +============== +D_DrawParticle +============== +*/ +void D_DrawParticle (particle_t *pparticle) +{ + vec3_t local, transformed; + float zi; + byte *pdest; + short *pz; + int i, izi, pix, count, u, v; + +// transform point + VectorSubtract (pparticle->org, 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 * 0x8000); + + pix = izi >> d_pix_shift; + + 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] = pparticle->color; + } + } + 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] = pparticle->color; + } + + if (pz[1] <= izi) + { + pz[1] = izi; + pdest[1] = pparticle->color; + } + } + 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] = pparticle->color; + } + + if (pz[1] <= izi) + { + pz[1] = izi; + pdest[1] = pparticle->color; + } + + if (pz[2] <= izi) + { + pz[2] = izi; + pdest[2] = pparticle->color; + } + } + 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] = pparticle->color; + } + + if (pz[1] <= izi) + { + pz[1] = izi; + pdest[1] = pparticle->color; + } + + if (pz[2] <= izi) + { + pz[2] = izi; + pdest[2] = pparticle->color; + } + + if (pz[3] <= izi) + { + pz[3] = izi; + pdest[3] = pparticle->color; + } + } + 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] = pparticle->color; + } + } + } + break; + } +} + +#endif // !id386 + diff --git a/QW/client/d_parta.asm b/QW/client/d_parta.asm new file mode 100644 index 0000000..9f7ab94 --- /dev/null +++ b/QW/client/d_parta.asm @@ -0,0 +1,557 @@ + .386P + .model FLAT + externdef _d_zistepu:dword + externdef _d_pzbuffer:dword + externdef _d_zistepv:dword + externdef _d_zrowbytes:dword + externdef _d_ziorigin:dword + externdef _r_turb_s:dword + externdef _r_turb_t:dword + externdef _r_turb_pdest:dword + externdef _r_turb_spancount:dword + externdef _r_turb_turb:dword + externdef _r_turb_pbase:dword + externdef _r_turb_sstep:dword + externdef _r_turb_tstep:dword + externdef _r_bmodelactive:dword + externdef _d_sdivzstepu:dword + externdef _d_tdivzstepu:dword + externdef _d_sdivzstepv:dword + externdef _d_tdivzstepv:dword + externdef _d_sdivzorigin:dword + externdef _d_tdivzorigin:dword + externdef _sadjust:dword + externdef _tadjust:dword + externdef _bbextents:dword + externdef _bbextentt:dword + externdef _cacheblock:dword + externdef _d_viewbuffer:dword + externdef _cachewidth:dword + externdef _d_pzbuffer:dword + externdef _d_zrowbytes:dword + externdef _d_zwidth:dword + externdef _d_scantable:dword + externdef _r_lightptr:dword + externdef _r_numvblocks:dword + externdef _prowdestbase:dword + externdef _pbasesource:dword + externdef _r_lightwidth:dword + externdef _lightright:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _lightdelta:dword + externdef _lightright:dword + externdef _lightdelta:dword + externdef _sourcetstep:dword + externdef _surfrowbytes:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _r_sourcemax:dword + externdef _r_stepback:dword + externdef _colormap:dword + externdef _blocksize:dword + externdef _sourcesstep:dword + externdef _lightleft:dword + externdef _blockdivshift:dword + externdef _blockdivmask:dword + externdef _lightleftstep:dword + externdef _r_origin:dword + externdef _r_ppn:dword + externdef _r_pup:dword + externdef _r_pright:dword + externdef _ycenter:dword + externdef _xcenter:dword + externdef _d_vrectbottom_particle:dword + externdef _d_vrectright_particle:dword + externdef _d_vrecty:dword + externdef _d_vrectx:dword + externdef _d_pix_shift:dword + externdef _d_pix_min:dword + externdef _d_pix_max:dword + externdef _d_y_aspect_shift:dword + externdef _screenwidth:dword + externdef _vright:dword + externdef _vup:dword + externdef _vpn:dword + externdef _BOPS_Error:dword + externdef _snd_scaletable:dword + externdef _paintbuffer:dword + externdef _snd_linear_count:dword + externdef _snd_p:dword + externdef _snd_vol:dword + externdef _snd_out:dword + externdef _r_leftclipped:dword + externdef _r_leftenter:dword + externdef _r_rightclipped:dword + externdef _r_rightenter:dword + externdef _modelorg:dword + externdef _xscale:dword + externdef _r_refdef:dword + externdef _yscale:dword + externdef _r_leftexit:dword + externdef _r_rightexit:dword + externdef _r_lastvertvalid:dword + externdef _cacheoffset:dword + externdef _newedges:dword + externdef _removeedges:dword + externdef _r_pedge:dword + externdef _r_framecount:dword + externdef _r_u1:dword + externdef _r_emitted:dword + externdef _edge_p:dword + externdef _surface_p:dword + externdef _surfaces:dword + externdef _r_lzi1:dword + externdef _r_v1:dword + externdef _r_ceilv1:dword + externdef _r_nearzi:dword + externdef _r_nearzionly:dword + externdef _edge_aftertail:dword + externdef _edge_tail:dword + externdef _current_iv:dword + externdef _edge_head_u_shift20:dword + externdef _span_p:dword + externdef _edge_head:dword + externdef _fv:dword + externdef _edge_tail_u_shift20:dword + externdef _r_apverts:dword + externdef _r_anumverts:dword + externdef _aliastransform:dword + externdef _r_avertexnormals:dword + externdef _r_plightvec:dword + externdef _r_ambientlight:dword + externdef _r_shadelight:dword + externdef _aliasxcenter:dword + externdef _aliasycenter:dword + externdef _a_sstepxfrac:dword + externdef _r_affinetridesc:dword + externdef _acolormap:dword + externdef _d_pcolormap:dword + externdef _r_affinetridesc:dword + externdef _d_sfrac:dword + externdef _d_ptex:dword + externdef _d_pedgespanpackage:dword + externdef _d_tfrac:dword + externdef _d_light:dword + externdef _d_zi:dword + externdef _d_pdest:dword + externdef _d_pz:dword + externdef _d_aspancount:dword + externdef _erroradjustup:dword + externdef _errorterm:dword + externdef _d_xdenom:dword + externdef _r_p0:dword + externdef _r_p1:dword + externdef _r_p2:dword + externdef _a_tstepxfrac:dword + externdef _r_sstepx:dword + externdef _r_tstepx:dword + externdef _a_ststepxwhole:dword + externdef _zspantable:dword + externdef _skintable:dword + externdef _r_zistepx:dword + externdef _erroradjustdown:dword + externdef _d_countextrastep:dword + externdef _ubasestep:dword + externdef _a_ststepxwhole:dword + externdef _a_tstepxfrac:dword + externdef _r_lstepx:dword + externdef _a_spans:dword + externdef _erroradjustdown:dword + externdef _d_pdestextrastep:dword + externdef _d_pzextrastep:dword + externdef _d_sfracextrastep:dword + externdef _d_ptexextrastep:dword + externdef _d_countextrastep:dword + externdef _d_tfracextrastep:dword + externdef _d_lightextrastep:dword + externdef _d_ziextrastep:dword + externdef _d_pdestbasestep:dword + externdef _d_pzbasestep:dword + externdef _d_sfracbasestep:dword + externdef _d_ptexbasestep:dword + externdef _ubasestep:dword + externdef _d_tfracbasestep:dword + externdef _d_lightbasestep:dword + externdef _d_zibasestep:dword + externdef _zspantable:dword + externdef _r_lstepy:dword + externdef _r_sstepy:dword + externdef _r_tstepy:dword + externdef _r_zistepy:dword + externdef _D_PolysetSetEdgeTable:dword + externdef _D_RasterizeAliasPolySmooth:dword + externdef float_point5:dword + externdef Float2ToThe31nd:dword + externdef izistep:dword + externdef izi:dword + externdef FloatMinus2ToThe31nd:dword + externdef float_1:dword + externdef float_particle_z_clip:dword + externdef float_minus_1:dword + externdef float_0:dword + externdef fp_16:dword + externdef fp_64k:dword + externdef fp_1m:dword + externdef fp_1m_minus_1:dword + externdef fp_8:dword + externdef entryvec_table:dword + externdef advancetable:dword + externdef sstep:dword + externdef tstep:dword + externdef pspantemp:dword + externdef counttemp:dword + externdef jumptemp:dword + externdef reciprocal_table:dword + externdef DP_Count:dword + externdef DP_u:dword + externdef DP_v:dword + externdef DP_32768:dword + externdef DP_Color:dword + externdef DP_Pix:dword + externdef DP_EntryTable:dword + externdef pbase:dword + externdef s:dword + externdef t:dword + externdef sfracf:dword + externdef tfracf:dword + externdef snext:dword + externdef tnext:dword + externdef spancountminus1:dword + externdef zi16stepu:dword + externdef sdivz16stepu:dword + externdef tdivz16stepu:dword + externdef zi8stepu:dword + externdef sdivz8stepu:dword + externdef tdivz8stepu:dword + externdef reciprocal_table_16:dword + externdef entryvec_table_16:dword + externdef ceil_cw:dword + externdef single_cw:dword + externdef fp_64kx64k:dword + externdef pz:dword + externdef spr8entryvec_table:dword +_TEXT SEGMENT + align 4 + public _D_DrawParticle +_D_DrawParticle: + push ebp + push edi + push ebx + mov edi,ds:dword ptr[12+4+esp] + fld ds:dword ptr[_r_origin] + fsubr ds:dword ptr[0+edi] + fld ds:dword ptr[0+4+edi] + fsub ds:dword ptr[_r_origin+4] + fld ds:dword ptr[0+8+edi] + fsub ds:dword ptr[_r_origin+8] + fxch st(2) + fld ds:dword ptr[_r_ppn] + fmul st(0),st(1) + fld ds:dword ptr[_r_ppn+4] + fmul st(0),st(3) + fld ds:dword ptr[_r_ppn+8] + fmul st(0),st(5) + fxch st(2) + faddp st(1),st(0) + faddp st(1),st(0) + fld st(0) + fdivr ds:dword ptr[float_1] + fxch st(1) + fcomp ds:dword ptr[float_particle_z_clip] + fxch st(3) + fld ds:dword ptr[_r_pup] + fmul st(0),st(2) + fld ds:dword ptr[_r_pup+4] + fnstsw ax + test ah,1 + jnz LPop6AndDone + fmul st(0),st(4) + fld ds:dword ptr[_r_pup+8] + fmul st(0),st(3) + fxch st(2) + faddp st(1),st(0) + faddp st(1),st(0) + fxch st(3) + fmul ds:dword ptr[_r_pright+4] + fxch st(2) + fmul ds:dword ptr[_r_pright] + fxch st(1) + fmul ds:dword ptr[_r_pright+8] + fxch st(2) + faddp st(1),st(0) + faddp st(1),st(0) + fxch st(1) + fmul st(0),st(2) + fxch st(1) + fmul st(0),st(2) + fxch st(1) + fsubr ds:dword ptr[_ycenter] + fxch st(1) + fadd ds:dword ptr[_xcenter] + fxch st(1) + fadd ds:dword ptr[float_point5] + fxch st(1) + fadd ds:dword ptr[float_point5] + fxch st(2) + fmul ds:dword ptr[DP_32768] + fxch st(2) + fistp ds:dword ptr[DP_u] + fistp ds:dword ptr[DP_v] + mov eax,ds:dword ptr[DP_u] + mov edx,ds:dword ptr[DP_v] + mov ebx,ds:dword ptr[_d_vrectbottom_particle] + mov ecx,ds:dword ptr[_d_vrectright_particle] + cmp edx,ebx + jg LPop1AndDone + cmp eax,ecx + jg LPop1AndDone + mov ebx,ds:dword ptr[_d_vrecty] + mov ecx,ds:dword ptr[_d_vrectx] + cmp edx,ebx + jl LPop1AndDone + cmp eax,ecx + jl LPop1AndDone + fld ds:dword ptr[12+edi] + fistp ds:dword ptr[DP_Color] + mov ebx,ds:dword ptr[_d_viewbuffer] + add ebx,eax + mov edi,ds:dword ptr[_d_scantable+edx*4] + imul edx,ds:dword ptr[_d_zrowbytes] + lea edx,ds:dword ptr[edx+eax*2] + mov eax,ds:dword ptr[_d_pzbuffer] + fistp ds:dword ptr[izi] + add edi,ebx + add edx,eax + mov eax,ds:dword ptr[izi] + mov ecx,ds:dword ptr[_d_pix_shift] + shr eax,cl + mov ebp,ds:dword ptr[izi] + mov ebx,ds:dword ptr[_d_pix_min] + mov ecx,ds:dword ptr[_d_pix_max] + cmp eax,ebx + jnl LTestPixMax + mov eax,ebx + jmp LTestDone +LTestPixMax: + cmp eax,ecx + jng LTestDone + mov eax,ecx +LTestDone: + mov ch,ds:byte ptr[DP_Color] + mov ebx,ds:dword ptr[_d_y_aspect_shift] + test ebx,ebx + jnz LDefault + cmp eax,4 + ja LDefault + jmp dword ptr[DP_EntryTable-4+eax*4] + public DP_1x1 +DP_1x1: + cmp ds:word ptr[edx],bp + jg LDone + mov ds:word ptr[edx],bp + mov ds:byte ptr[edi],ch + jmp LDone + public DP_2x2 +DP_2x2: + push esi + mov ebx,ds:dword ptr[_screenwidth] + mov esi,ds:dword ptr[_d_zrowbytes] + cmp ds:word ptr[edx],bp + jg L2x2_1 + mov ds:word ptr[edx],bp + mov ds:byte ptr[edi],ch +L2x2_1: + cmp ds:word ptr[2+edx],bp + jg L2x2_2 + mov ds:word ptr[2+edx],bp + mov ds:byte ptr[1+edi],ch +L2x2_2: + cmp ds:word ptr[edx+esi*1],bp + jg L2x2_3 + mov ds:word ptr[edx+esi*1],bp + mov ds:byte ptr[edi+ebx*1],ch +L2x2_3: + cmp ds:word ptr[2+edx+esi*1],bp + jg L2x2_4 + mov ds:word ptr[2+edx+esi*1],bp + mov ds:byte ptr[1+edi+ebx*1],ch +L2x2_4: + pop esi + jmp LDone + public DP_3x3 +DP_3x3: + push esi + mov ebx,ds:dword ptr[_screenwidth] + mov esi,ds:dword ptr[_d_zrowbytes] + cmp ds:word ptr[edx],bp + jg L3x3_1 + mov ds:word ptr[edx],bp + mov ds:byte ptr[edi],ch +L3x3_1: + cmp ds:word ptr[2+edx],bp + jg L3x3_2 + mov ds:word ptr[2+edx],bp + mov ds:byte ptr[1+edi],ch +L3x3_2: + cmp ds:word ptr[4+edx],bp + jg L3x3_3 + mov ds:word ptr[4+edx],bp + mov ds:byte ptr[2+edi],ch +L3x3_3: + cmp ds:word ptr[edx+esi*1],bp + jg L3x3_4 + mov ds:word ptr[edx+esi*1],bp + mov ds:byte ptr[edi+ebx*1],ch +L3x3_4: + cmp ds:word ptr[2+edx+esi*1],bp + jg L3x3_5 + mov ds:word ptr[2+edx+esi*1],bp + mov ds:byte ptr[1+edi+ebx*1],ch +L3x3_5: + cmp ds:word ptr[4+edx+esi*1],bp + jg L3x3_6 + mov ds:word ptr[4+edx+esi*1],bp + mov ds:byte ptr[2+edi+ebx*1],ch +L3x3_6: + cmp ds:word ptr[edx+esi*2],bp + jg L3x3_7 + mov ds:word ptr[edx+esi*2],bp + mov ds:byte ptr[edi+ebx*2],ch +L3x3_7: + cmp ds:word ptr[2+edx+esi*2],bp + jg L3x3_8 + mov ds:word ptr[2+edx+esi*2],bp + mov ds:byte ptr[1+edi+ebx*2],ch +L3x3_8: + cmp ds:word ptr[4+edx+esi*2],bp + jg L3x3_9 + mov ds:word ptr[4+edx+esi*2],bp + mov ds:byte ptr[2+edi+ebx*2],ch +L3x3_9: + pop esi + jmp LDone + public DP_4x4 +DP_4x4: + push esi + mov ebx,ds:dword ptr[_screenwidth] + mov esi,ds:dword ptr[_d_zrowbytes] + cmp ds:word ptr[edx],bp + jg L4x4_1 + mov ds:word ptr[edx],bp + mov ds:byte ptr[edi],ch +L4x4_1: + cmp ds:word ptr[2+edx],bp + jg L4x4_2 + mov ds:word ptr[2+edx],bp + mov ds:byte ptr[1+edi],ch +L4x4_2: + cmp ds:word ptr[4+edx],bp + jg L4x4_3 + mov ds:word ptr[4+edx],bp + mov ds:byte ptr[2+edi],ch +L4x4_3: + cmp ds:word ptr[6+edx],bp + jg L4x4_4 + mov ds:word ptr[6+edx],bp + mov ds:byte ptr[3+edi],ch +L4x4_4: + cmp ds:word ptr[edx+esi*1],bp + jg L4x4_5 + mov ds:word ptr[edx+esi*1],bp + mov ds:byte ptr[edi+ebx*1],ch +L4x4_5: + cmp ds:word ptr[2+edx+esi*1],bp + jg L4x4_6 + mov ds:word ptr[2+edx+esi*1],bp + mov ds:byte ptr[1+edi+ebx*1],ch +L4x4_6: + cmp ds:word ptr[4+edx+esi*1],bp + jg L4x4_7 + mov ds:word ptr[4+edx+esi*1],bp + mov ds:byte ptr[2+edi+ebx*1],ch +L4x4_7: + cmp ds:word ptr[6+edx+esi*1],bp + jg L4x4_8 + mov ds:word ptr[6+edx+esi*1],bp + mov ds:byte ptr[3+edi+ebx*1],ch +L4x4_8: + lea edx,ds:dword ptr[edx+esi*2] + lea edi,ds:dword ptr[edi+ebx*2] + cmp ds:word ptr[edx],bp + jg L4x4_9 + mov ds:word ptr[edx],bp + mov ds:byte ptr[edi],ch +L4x4_9: + cmp ds:word ptr[2+edx],bp + jg L4x4_10 + mov ds:word ptr[2+edx],bp + mov ds:byte ptr[1+edi],ch +L4x4_10: + cmp ds:word ptr[4+edx],bp + jg L4x4_11 + mov ds:word ptr[4+edx],bp + mov ds:byte ptr[2+edi],ch +L4x4_11: + cmp ds:word ptr[6+edx],bp + jg L4x4_12 + mov ds:word ptr[6+edx],bp + mov ds:byte ptr[3+edi],ch +L4x4_12: + cmp ds:word ptr[edx+esi*1],bp + jg L4x4_13 + mov ds:word ptr[edx+esi*1],bp + mov ds:byte ptr[edi+ebx*1],ch +L4x4_13: + cmp ds:word ptr[2+edx+esi*1],bp + jg L4x4_14 + mov ds:word ptr[2+edx+esi*1],bp + mov ds:byte ptr[1+edi+ebx*1],ch +L4x4_14: + cmp ds:word ptr[4+edx+esi*1],bp + jg L4x4_15 + mov ds:word ptr[4+edx+esi*1],bp + mov ds:byte ptr[2+edi+ebx*1],ch +L4x4_15: + cmp ds:word ptr[6+edx+esi*1],bp + jg L4x4_16 + mov ds:word ptr[6+edx+esi*1],bp + mov ds:byte ptr[3+edi+ebx*1],ch +L4x4_16: + pop esi + jmp LDone +LDefault: + mov ebx,eax + mov ds:dword ptr[DP_Pix],eax + mov cl,ds:byte ptr[_d_y_aspect_shift] + shl ebx,cl +LGenRowLoop: + mov eax,ds:dword ptr[DP_Pix] +LGenColLoop: + cmp ds:word ptr[-2+edx+eax*2],bp + jg LGSkip + mov ds:word ptr[-2+edx+eax*2],bp + mov ds:byte ptr[-1+edi+eax*1],ch +LGSkip: + dec eax + jnz LGenColLoop + add edx,ds:dword ptr[_d_zrowbytes] + add edi,ds:dword ptr[_screenwidth] + dec ebx + jnz LGenRowLoop +LDone: + pop ebx + pop edi + pop ebp + ret +LPop6AndDone: + fstp st(0) + fstp st(0) + fstp st(0) + fstp st(0) + fstp st(0) +LPop1AndDone: + fstp st(0) + jmp LDone +_TEXT ENDS + END diff --git a/QW/client/d_parta.s b/QW/client/d_parta.s new file mode 100644 index 0000000..b32f1bc --- /dev/null +++ b/QW/client/d_parta.s @@ -0,0 +1,477 @@ +/* +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. +// + +#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 P 12+4 + + .align 4 +.globl C(D_DrawParticle) +C(D_DrawParticle): + pushl %ebp // preserve caller's stack frame + pushl %edi // preserve register variables + pushl %ebx + + movl P(%esp),%edi + +// FIXME: better FP overlap in general here + +// transform point +// VectorSubtract (p->org, r_origin, local); + flds C(r_origin) + fsubrs pt_org(%edi) + flds pt_org+4(%edi) + fsubs C(r_origin)+4 + flds pt_org+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_32768 // 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 + + flds pt_color(%edi) // 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 diff --git a/QW/client/d_polysa.asm b/QW/client/d_polysa.asm new file mode 100644 index 0000000..121d0e9 --- /dev/null +++ b/QW/client/d_polysa.asm @@ -0,0 +1,1120 @@ + .386P + .model FLAT + externdef _d_zistepu:dword + externdef _d_pzbuffer:dword + externdef _d_zistepv:dword + externdef _d_zrowbytes:dword + externdef _d_ziorigin:dword + externdef _r_turb_s:dword + externdef _r_turb_t:dword + externdef _r_turb_pdest:dword + externdef _r_turb_spancount:dword + externdef _r_turb_turb:dword + externdef _r_turb_pbase:dword + externdef _r_turb_sstep:dword + externdef _r_turb_tstep:dword + externdef _r_bmodelactive:dword + externdef _d_sdivzstepu:dword + externdef _d_tdivzstepu:dword + externdef _d_sdivzstepv:dword + externdef _d_tdivzstepv:dword + externdef _d_sdivzorigin:dword + externdef _d_tdivzorigin:dword + externdef _sadjust:dword + externdef _tadjust:dword + externdef _bbextents:dword + externdef _bbextentt:dword + externdef _cacheblock:dword + externdef _d_viewbuffer:dword + externdef _cachewidth:dword + externdef _d_pzbuffer:dword + externdef _d_zrowbytes:dword + externdef _d_zwidth:dword + externdef _d_scantable:dword + externdef _r_lightptr:dword + externdef _r_numvblocks:dword + externdef _prowdestbase:dword + externdef _pbasesource:dword + externdef _r_lightwidth:dword + externdef _lightright:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _lightdelta:dword + externdef _lightright:dword + externdef _lightdelta:dword + externdef _sourcetstep:dword + externdef _surfrowbytes:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _r_sourcemax:dword + externdef _r_stepback:dword + externdef _colormap:dword + externdef _blocksize:dword + externdef _sourcesstep:dword + externdef _lightleft:dword + externdef _blockdivshift:dword + externdef _blockdivmask:dword + externdef _lightleftstep:dword + externdef _r_origin:dword + externdef _r_ppn:dword + externdef _r_pup:dword + externdef _r_pright:dword + externdef _ycenter:dword + externdef _xcenter:dword + externdef _d_vrectbottom_particle:dword + externdef _d_vrectright_particle:dword + externdef _d_vrecty:dword + externdef _d_vrectx:dword + externdef _d_pix_shift:dword + externdef _d_pix_min:dword + externdef _d_pix_max:dword + externdef _d_y_aspect_shift:dword + externdef _screenwidth:dword + externdef _vright:dword + externdef _vup:dword + externdef _vpn:dword + externdef _BOPS_Error:dword + externdef _snd_scaletable:dword + externdef _paintbuffer:dword + externdef _snd_linear_count:dword + externdef _snd_p:dword + externdef _snd_vol:dword + externdef _snd_out:dword + externdef _r_leftclipped:dword + externdef _r_leftenter:dword + externdef _r_rightclipped:dword + externdef _r_rightenter:dword + externdef _modelorg:dword + externdef _xscale:dword + externdef _r_refdef:dword + externdef _yscale:dword + externdef _r_leftexit:dword + externdef _r_rightexit:dword + externdef _r_lastvertvalid:dword + externdef _cacheoffset:dword + externdef _newedges:dword + externdef _removeedges:dword + externdef _r_pedge:dword + externdef _r_framecount:dword + externdef _r_u1:dword + externdef _r_emitted:dword + externdef _edge_p:dword + externdef _surface_p:dword + externdef _surfaces:dword + externdef _r_lzi1:dword + externdef _r_v1:dword + externdef _r_ceilv1:dword + externdef _r_nearzi:dword + externdef _r_nearzionly:dword + externdef _edge_aftertail:dword + externdef _edge_tail:dword + externdef _current_iv:dword + externdef _edge_head_u_shift20:dword + externdef _span_p:dword + externdef _edge_head:dword + externdef _fv:dword + externdef _edge_tail_u_shift20:dword + externdef _r_apverts:dword + externdef _r_anumverts:dword + externdef _aliastransform:dword + externdef _r_avertexnormals:dword + externdef _r_plightvec:dword + externdef _r_ambientlight:dword + externdef _r_shadelight:dword + externdef _aliasxcenter:dword + externdef _aliasycenter:dword + externdef _a_sstepxfrac:dword + externdef _r_affinetridesc:dword + externdef _acolormap:dword + externdef _d_pcolormap:dword + externdef _r_affinetridesc:dword + externdef _d_sfrac:dword + externdef _d_ptex:dword + externdef _d_pedgespanpackage:dword + externdef _d_tfrac:dword + externdef _d_light:dword + externdef _d_zi:dword + externdef _d_pdest:dword + externdef _d_pz:dword + externdef _d_aspancount:dword + externdef _erroradjustup:dword + externdef _errorterm:dword + externdef _d_xdenom:dword + externdef _r_p0:dword + externdef _r_p1:dword + externdef _r_p2:dword + externdef _a_tstepxfrac:dword + externdef _r_sstepx:dword + externdef _r_tstepx:dword + externdef _a_ststepxwhole:dword + externdef _zspantable:dword + externdef _skintable:dword + externdef _r_zistepx:dword + externdef _erroradjustdown:dword + externdef _d_countextrastep:dword + externdef _ubasestep:dword + externdef _a_ststepxwhole:dword + externdef _a_tstepxfrac:dword + externdef _r_lstepx:dword + externdef _a_spans:dword + externdef _erroradjustdown:dword + externdef _d_pdestextrastep:dword + externdef _d_pzextrastep:dword + externdef _d_sfracextrastep:dword + externdef _d_ptexextrastep:dword + externdef _d_countextrastep:dword + externdef _d_tfracextrastep:dword + externdef _d_lightextrastep:dword + externdef _d_ziextrastep:dword + externdef _d_pdestbasestep:dword + externdef _d_pzbasestep:dword + externdef _d_sfracbasestep:dword + externdef _d_ptexbasestep:dword + externdef _ubasestep:dword + externdef _d_tfracbasestep:dword + externdef _d_lightbasestep:dword + externdef _d_zibasestep:dword + externdef _zspantable:dword + externdef _r_lstepy:dword + externdef _r_sstepy:dword + externdef _r_tstepy:dword + externdef _r_zistepy:dword + externdef _D_PolysetSetEdgeTable:dword + externdef _D_RasterizeAliasPolySmooth:dword + externdef float_point5:dword + externdef Float2ToThe31nd:dword + externdef izistep:dword + externdef izi:dword + externdef FloatMinus2ToThe31nd:dword + externdef float_1:dword + externdef float_particle_z_clip:dword + externdef float_minus_1:dword + externdef float_0:dword + externdef fp_16:dword + externdef fp_64k:dword + externdef fp_1m:dword + externdef fp_1m_minus_1:dword + externdef fp_8:dword + externdef entryvec_table:dword + externdef advancetable:dword + externdef sstep:dword + externdef tstep:dword + externdef pspantemp:dword + externdef counttemp:dword + externdef jumptemp:dword + externdef reciprocal_table:dword + externdef DP_Count:dword + externdef DP_u:dword + externdef DP_v:dword + externdef DP_32768:dword + externdef DP_Color:dword + externdef DP_Pix:dword + externdef DP_EntryTable:dword + externdef pbase:dword + externdef s:dword + externdef t:dword + externdef sfracf:dword + externdef tfracf:dword + externdef snext:dword + externdef tnext:dword + externdef spancountminus1:dword + externdef zi16stepu:dword + externdef sdivz16stepu:dword + externdef tdivz16stepu:dword + externdef zi8stepu:dword + externdef sdivz8stepu:dword + externdef tdivz8stepu:dword + externdef reciprocal_table_16:dword + externdef entryvec_table_16:dword + externdef ceil_cw:dword + externdef single_cw:dword + externdef fp_64kx64k:dword + externdef pz:dword + externdef spr8entryvec_table:dword +_DATA SEGMENT + align 4 +p10_minus_p20 dd 0 +p01_minus_p21 dd 0 +temp0 dd 0 +temp1 dd 0 +Ltemp dd 0 +aff8entryvec_table dd LDraw8, LDraw7, LDraw6, LDraw5 + dd LDraw4, LDraw3, LDraw2, LDraw1 +lzistepx dd 0 +_DATA ENDS +_TEXT SEGMENT + externdef _D_PolysetSetEdgeTable:dword + externdef _D_RasterizeAliasPolySmooth:dword + public _D_PolysetCalcGradients +_D_PolysetCalcGradients: + fild ds:dword ptr[_r_p0+0] + fild ds:dword ptr[_r_p2+0] + fild ds:dword ptr[_r_p0+4] + fild ds:dword ptr[_r_p2+4] + fild ds:dword ptr[_r_p1+0] + fild ds:dword ptr[_r_p1+4] + fxch st(3) + fsub st(0),st(2) + fxch st(1) + fsub st(0),st(4) + fxch st(5) + fsubrp st(4),st(0) + fxch st(2) + fsubrp st(1),st(0) + fxch st(1) + fld ds:dword ptr[_d_xdenom] + fxch st(4) + fstp ds:dword ptr[p10_minus_p20] + fstp ds:dword ptr[p01_minus_p21] + fxch st(2) + fild ds:dword ptr[_r_p2+16] + fild ds:dword ptr[_r_p0+16] + fild ds:dword ptr[_r_p1+16] + fxch st(2) + fld st(0) + fsubp st(2),st(0) + fsubp st(2),st(0) + fld st(0) + fmul st(0),st(5) + fxch st(2) + fld st(0) + fmul ds:dword ptr[p01_minus_p21] + fxch st(2) + fmul ds:dword ptr[p10_minus_p20] + fxch st(1) + fmul st(0),st(5) + fxch st(2) + fsubrp st(3),st(0) + fsubp st(1),st(0) + fld st(2) + fmul ds:dword ptr[float_minus_1] + fxch st(2) + fmul st(0),st(3) + fxch st(1) + fmul st(0),st(2) + fldcw ds:word ptr[ceil_cw] + fistp ds:dword ptr[_r_lstepy] + fistp ds:dword ptr[_r_lstepx] + fldcw ds:word ptr[single_cw] + fild ds:dword ptr[_r_p2+8] + fild ds:dword ptr[_r_p0+8] + fild ds:dword ptr[_r_p1+8] + fxch st(2) + fld st(0) + fsubp st(2),st(0) + fsubp st(2),st(0) + fld st(0) + fmul st(0),st(6) + fxch st(2) + fld st(0) + fmul ds:dword ptr[p01_minus_p21] + fxch st(2) + fmul ds:dword ptr[p10_minus_p20] + fxch st(1) + fmul st(0),st(6) + fxch st(2) + fsubrp st(3),st(0) + fsubp st(1),st(0) + fmul st(0),st(2) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[_r_sstepy] + fistp ds:dword ptr[_r_sstepx] + fild ds:dword ptr[_r_p2+12] + fild ds:dword ptr[_r_p0+12] + fild ds:dword ptr[_r_p1+12] + fxch st(2) + fld st(0) + fsubp st(2),st(0) + fsubp st(2),st(0) + fld st(0) + fmul st(0),st(6) + fxch st(2) + fld st(0) + fmul ds:dword ptr[p01_minus_p21] + fxch st(2) + fmul ds:dword ptr[p10_minus_p20] + fxch st(1) + fmul st(0),st(6) + fxch st(2) + fsubrp st(3),st(0) + fsubp st(1),st(0) + fmul st(0),st(2) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[_r_tstepy] + fistp ds:dword ptr[_r_tstepx] + fild ds:dword ptr[_r_p2+20] + fild ds:dword ptr[_r_p0+20] + fild ds:dword ptr[_r_p1+20] + fxch st(2) + fld st(0) + fsubp st(2),st(0) + fsubp st(2),st(0) + fld st(0) + fmulp st(6),st(0) + fxch st(1) + fld st(0) + fmul ds:dword ptr[p01_minus_p21] + fxch st(2) + fmul ds:dword ptr[p10_minus_p20] + fxch st(1) + fmulp st(5),st(0) + fxch st(5) + fsubp st(1),st(0) + fxch st(3) + fsubrp st(4),st(0) + fxch st(1) + fmulp st(2),st(0) + fmulp st(2),st(0) + fistp ds:dword ptr[_r_zistepx] + fistp ds:dword ptr[_r_zistepy] + mov eax,ds:dword ptr[_r_sstepx] + mov edx,ds:dword ptr[_r_tstepx] + shl eax,16 + shl edx,16 + mov ds:dword ptr[_a_sstepxfrac],eax + mov ds:dword ptr[_a_tstepxfrac],edx + mov ecx,ds:dword ptr[_r_sstepx] + mov eax,ds:dword ptr[_r_tstepx] + sar ecx,16 + sar eax,16 + imul ds:dword ptr[4+0+esp] + add eax,ecx + mov ds:dword ptr[_a_ststepxwhole],eax + ret + public _D_PolysetRecursiveTriangle +_D_PolysetRecursiveTriangle: + push ebp + push esi + push edi + push ebx + mov esi,ds:dword ptr[8+16+esp] + mov ebx,ds:dword ptr[4+16+esp] + mov edi,ds:dword ptr[12+16+esp] + mov eax,ds:dword ptr[0+esi] + mov edx,ds:dword ptr[0+ebx] + mov ebp,ds:dword ptr[4+esi] + sub eax,edx + mov ecx,ds:dword ptr[4+ebx] + sub ebp,ecx + inc eax + cmp eax,2 + ja LSplit + mov eax,ds:dword ptr[0+edi] + inc ebp + cmp ebp,2 + ja LSplit + mov edx,ds:dword ptr[0+esi] + mov ebp,ds:dword ptr[4+edi] + sub eax,edx + mov ecx,ds:dword ptr[4+esi] + sub ebp,ecx + inc eax + cmp eax,2 + ja LSplit2 + mov eax,ds:dword ptr[0+ebx] + inc ebp + cmp ebp,2 + ja LSplit2 + mov edx,ds:dword ptr[0+edi] + mov ebp,ds:dword ptr[4+ebx] + sub eax,edx + mov ecx,ds:dword ptr[4+edi] + sub ebp,ecx + inc eax + inc ebp + mov edx,ebx + cmp eax,2 + ja LSplit3 + cmp ebp,2 + jna LDone +LSplit3: + mov ebx,edi + mov edi,esi + mov esi,edx + jmp LSplit +LSplit2: + mov eax,ebx + mov ebx,esi + mov esi,edi + mov edi,eax +LSplit: + sub esp,24 + mov eax,ds:dword ptr[8+ebx] + mov edx,ds:dword ptr[8+esi] + mov ecx,ds:dword ptr[12+ebx] + add eax,edx + mov edx,ds:dword ptr[12+esi] + sar eax,1 + add ecx,edx + mov ds:dword ptr[8+esp],eax + mov eax,ds:dword ptr[20+ebx] + sar ecx,1 + mov edx,ds:dword ptr[20+esi] + mov ds:dword ptr[12+esp],ecx + add eax,edx + mov ecx,ds:dword ptr[0+ebx] + mov edx,ds:dword ptr[0+esi] + sar eax,1 + add edx,ecx + mov ds:dword ptr[20+esp],eax + mov eax,ds:dword ptr[4+ebx] + sar edx,1 + mov ebp,ds:dword ptr[4+esi] + mov ds:dword ptr[0+esp],edx + add ebp,eax + sar ebp,1 + mov ds:dword ptr[4+esp],ebp + cmp ds:dword ptr[4+esi],eax + jg LNoDraw + mov edx,ds:dword ptr[0+esi] + jnz LDraw + cmp edx,ecx + jl LNoDraw +LDraw: + mov edx,ds:dword ptr[20+esp] + mov ecx,ds:dword ptr[4+esp] + sar edx,16 + mov ebp,ds:dword ptr[0+esp] + mov eax,ds:dword ptr[_zspantable+ecx*4] + cmp dx,ds:word ptr[eax+ebp*2] + jnge LNoDraw + mov ds:word ptr[eax+ebp*2],dx + mov eax,ds:dword ptr[12+esp] + sar eax,16 + mov edx,ds:dword ptr[8+esp] + sar edx,16 + sub ecx,ecx + mov eax,ds:dword ptr[_skintable+eax*4] + mov ebp,ds:dword ptr[4+esp] + mov cl,ds:byte ptr[eax+edx] + mov edx,ds:dword ptr[_d_pcolormap] + mov dl,ds:byte ptr[edx+ecx] + mov ecx,ds:dword ptr[0+esp] + mov eax,ds:dword ptr[_d_scantable+ebp*4] + add ecx,eax + mov eax,ds:dword ptr[_d_viewbuffer] + mov ds:byte ptr[eax+ecx*1],dl +LNoDraw: + push esp + push ebx + push edi + call near ptr _D_PolysetRecursiveTriangle + mov ebx,esp + push esi + push ebx + push edi + call near ptr _D_PolysetRecursiveTriangle + add esp,24 +LDone: + pop ebx + pop edi + pop esi + pop ebp + ret 12 + public _D_PolysetAff8Start +_D_PolysetAff8Start: + public _D_PolysetDrawSpans8 +_D_PolysetDrawSpans8: + push esi + push ebx + mov esi,ds:dword ptr[4+8+esp] + mov ecx,ds:dword ptr[_r_zistepx] + push ebp + push edi + ror ecx,16 + mov edx,ds:dword ptr[8+esi] + mov ds:dword ptr[lzistepx],ecx +LSpanLoop: + mov eax,ds:dword ptr[_d_aspancount] + sub eax,edx + mov edx,ds:dword ptr[_erroradjustup] + mov ebx,ds:dword ptr[_errorterm] + add ebx,edx + js LNoTurnover + mov edx,ds:dword ptr[_erroradjustdown] + mov edi,ds:dword ptr[_d_countextrastep] + sub ebx,edx + mov ebp,ds:dword ptr[_d_aspancount] + mov ds:dword ptr[_errorterm],ebx + add ebp,edi + mov ds:dword ptr[_d_aspancount],ebp + jmp LRightEdgeStepped +LNoTurnover: + mov edi,ds:dword ptr[_d_aspancount] + mov edx,ds:dword ptr[_ubasestep] + mov ds:dword ptr[_errorterm],ebx + add edi,edx + mov ds:dword ptr[_d_aspancount],edi +LRightEdgeStepped: + cmp eax,1 + jl LNextSpan + jz LExactlyOneLong + mov ecx,ds:dword ptr[_a_ststepxwhole] + mov edx,ds:dword ptr[_r_affinetridesc+8] + mov ds:dword ptr[advancetable+4],ecx + add ecx,edx + mov ds:dword ptr[advancetable],ecx + mov ecx,ds:dword ptr[_a_tstepxfrac] + mov cx,ds:word ptr[_r_lstepx] + mov edx,eax + mov ds:dword ptr[tstep],ecx + add edx,7 + shr edx,3 + mov ebx,ds:dword ptr[16+esi] + mov bx,dx + mov ecx,ds:dword ptr[4+esi] + neg eax + mov edi,ds:dword ptr[0+esi] + and eax,7 + sub edi,eax + sub ecx,eax + sub ecx,eax + mov edx,ds:dword ptr[20+esi] + mov dx,ds:word ptr[24+esi] + mov ebp,ds:dword ptr[28+esi] + ror ebp,16 + push esi + mov esi,ds:dword ptr[12+esi] + jmp dword ptr[aff8entryvec_table+eax*4] +LDrawLoop: +LDraw8: + cmp bp,ds:word ptr[ecx] + jl Lp1 + xor eax,eax + mov ah,dh + mov al,ds:byte ptr[esi] + mov ds:word ptr[ecx],bp + mov al,ds:byte ptr[12345678h+eax] +LPatch8: + mov ds:byte ptr[edi],al +Lp1: + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebp,ds:dword ptr[lzistepx] + adc ebp,0 + add ebx,ds:dword ptr[_a_sstepxfrac] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LDraw7: + cmp bp,ds:word ptr[2+ecx] + jl Lp2 + xor eax,eax + mov ah,dh + mov al,ds:byte ptr[esi] + mov ds:word ptr[2+ecx],bp + mov al,ds:byte ptr[12345678h+eax] +LPatch7: + mov ds:byte ptr[1+edi],al +Lp2: + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebp,ds:dword ptr[lzistepx] + adc ebp,0 + add ebx,ds:dword ptr[_a_sstepxfrac] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LDraw6: + cmp bp,ds:word ptr[4+ecx] + jl Lp3 + xor eax,eax + mov ah,dh + mov al,ds:byte ptr[esi] + mov ds:word ptr[4+ecx],bp + mov al,ds:byte ptr[12345678h+eax] +LPatch6: + mov ds:byte ptr[2+edi],al +Lp3: + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebp,ds:dword ptr[lzistepx] + adc ebp,0 + add ebx,ds:dword ptr[_a_sstepxfrac] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LDraw5: + cmp bp,ds:word ptr[6+ecx] + jl Lp4 + xor eax,eax + mov ah,dh + mov al,ds:byte ptr[esi] + mov ds:word ptr[6+ecx],bp + mov al,ds:byte ptr[12345678h+eax] +LPatch5: + mov ds:byte ptr[3+edi],al +Lp4: + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebp,ds:dword ptr[lzistepx] + adc ebp,0 + add ebx,ds:dword ptr[_a_sstepxfrac] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LDraw4: + cmp bp,ds:word ptr[8+ecx] + jl Lp5 + xor eax,eax + mov ah,dh + mov al,ds:byte ptr[esi] + mov ds:word ptr[8+ecx],bp + mov al,ds:byte ptr[12345678h+eax] +LPatch4: + mov ds:byte ptr[4+edi],al +Lp5: + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebp,ds:dword ptr[lzistepx] + adc ebp,0 + add ebx,ds:dword ptr[_a_sstepxfrac] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LDraw3: + cmp bp,ds:word ptr[10+ecx] + jl Lp6 + xor eax,eax + mov ah,dh + mov al,ds:byte ptr[esi] + mov ds:word ptr[10+ecx],bp + mov al,ds:byte ptr[12345678h+eax] +LPatch3: + mov ds:byte ptr[5+edi],al +Lp6: + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebp,ds:dword ptr[lzistepx] + adc ebp,0 + add ebx,ds:dword ptr[_a_sstepxfrac] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LDraw2: + cmp bp,ds:word ptr[12+ecx] + jl Lp7 + xor eax,eax + mov ah,dh + mov al,ds:byte ptr[esi] + mov ds:word ptr[12+ecx],bp + mov al,ds:byte ptr[12345678h+eax] +LPatch2: + mov ds:byte ptr[6+edi],al +Lp7: + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebp,ds:dword ptr[lzistepx] + adc ebp,0 + add ebx,ds:dword ptr[_a_sstepxfrac] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LDraw1: + cmp bp,ds:word ptr[14+ecx] + jl Lp8 + xor eax,eax + mov ah,dh + mov al,ds:byte ptr[esi] + mov ds:word ptr[14+ecx],bp + mov al,ds:byte ptr[12345678h+eax] +LPatch1: + mov ds:byte ptr[7+edi],al +Lp8: + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebp,ds:dword ptr[lzistepx] + adc ebp,0 + add ebx,ds:dword ptr[_a_sstepxfrac] + adc esi,ds:dword ptr[advancetable+4+eax*4] + add edi,8 + add ecx,16 + dec bx + jnz LDrawLoop + pop esi +LNextSpan: + add esi,32 +LNextSpanESISet: + mov edx,ds:dword ptr[8+esi] + cmp edx,offset -999999 + jnz LSpanLoop + pop edi + pop ebp + pop ebx + pop esi + ret +LExactlyOneLong: + mov ecx,ds:dword ptr[4+esi] + mov ebp,ds:dword ptr[28+esi] + ror ebp,16 + mov ebx,ds:dword ptr[12+esi] + cmp bp,ds:word ptr[ecx] + jl LNextSpan + xor eax,eax + mov edi,ds:dword ptr[0+esi] + mov ah,ds:byte ptr[24+1+esi] + add esi,32 + mov al,ds:byte ptr[ebx] + mov ds:word ptr[ecx],bp + mov al,ds:byte ptr[12345678h+eax] +LPatch9: + mov ds:byte ptr[edi],al + jmp LNextSpanESISet + public _D_PolysetAff8End +_D_PolysetAff8End: + public _D_Aff8Patch +_D_Aff8Patch: + mov eax,ds:dword ptr[4+esp] + mov ds:dword ptr[LPatch1-4],eax + mov ds:dword ptr[LPatch2-4],eax + mov ds:dword ptr[LPatch3-4],eax + mov ds:dword ptr[LPatch4-4],eax + mov ds:dword ptr[LPatch5-4],eax + mov ds:dword ptr[LPatch6-4],eax + mov ds:dword ptr[LPatch7-4],eax + mov ds:dword ptr[LPatch8-4],eax + mov ds:dword ptr[LPatch9-4],eax + ret + public _D_PolysetDraw +_D_PolysetDraw: + sub esp,offset (((1024+1 + 1 + ((32 - 1) / 32)) + 1) * 32) + mov eax,esp + add eax,32 - 1 + and eax,offset not (32 - 1) + mov ds:dword ptr[_a_spans],eax + mov eax,ds:dword ptr[_r_affinetridesc+28] + test eax,eax + jz _D_DrawNonSubdiv + push ebp + mov ebp,ds:dword ptr[_r_affinetridesc+24] + push esi + shl ebp,4 + push ebx + mov ebx,ds:dword ptr[_r_affinetridesc+16] + push edi + mov edi,ds:dword ptr[_r_affinetridesc+20] +Llooptop: + mov ecx,ds:dword ptr[4-16+0+ebx+ebp] + mov esi,ds:dword ptr[4-16+4+ebx+ebp] + shl ecx,5 + mov edx,ds:dword ptr[4-16+8+ebx+ebp] + shl esi,5 + add ecx,edi + shl edx,5 + add esi,edi + add edx,edi + fild ds:dword ptr[0+4+ecx] + fild ds:dword ptr[0+4+esi] + fild ds:dword ptr[0+0+ecx] + fild ds:dword ptr[0+0+edx] + fxch st(2) + fsubr st(0),st(3) + fild ds:dword ptr[0+0+esi] + fxch st(2) + fsubr st(3),st(0) + fild ds:dword ptr[0+4+edx] + fxch st(1) + fsubrp st(3),st(0) + fxch st(1) + fmulp st(3),st(0) + fsubp st(3),st(0) + mov eax,ds:dword ptr[0+16+ecx] + and eax,0FF00h + fmulp st(2),st(0) + add eax,ds:dword ptr[_acolormap] + fsubrp st(1),st(0) + mov ds:dword ptr[_d_pcolormap],eax + fstp ds:dword ptr[Ltemp] + mov eax,ds:dword ptr[Ltemp] + sub eax,080000001h + jc Lskip + mov eax,ds:dword ptr[0-16+ebx+ebp] + test eax,eax + jz Lfacesback + push edx + push esi + push ecx + call near ptr _D_PolysetRecursiveTriangle + sub ebp,16 + jnz Llooptop + jmp Ldone2 +Lfacesback: + mov eax,ds:dword ptr[0+8+ecx] + push eax + mov eax,ds:dword ptr[0+8+esi] + push eax + mov eax,ds:dword ptr[0+8+edx] + push eax + push ecx + push edx + mov eax,ds:dword ptr[_r_affinetridesc+32] + test ds:dword ptr[24+ecx],00020h + jz Lp11 + add ds:dword ptr[0+8+ecx],eax +Lp11: + test ds:dword ptr[24+esi],00020h + jz Lp12 + add ds:dword ptr[0+8+esi],eax +Lp12: + test ds:dword ptr[24+edx],00020h + jz Lp13 + add ds:dword ptr[0+8+edx],eax +Lp13: + push edx + push esi + push ecx + call near ptr _D_PolysetRecursiveTriangle + pop edx + pop ecx + pop eax + mov ds:dword ptr[0+8+edx],eax + pop eax + mov ds:dword ptr[0+8+esi],eax + pop eax + mov ds:dword ptr[0+8+ecx],eax +Lskip: + sub ebp,16 + jnz Llooptop +Ldone2: + pop edi + pop ebx + pop esi + pop ebp + add esp,offset (((1024+1 + 1 + ((32 - 1) / 32)) + 1) * 32) + ret + public _D_PolysetScanLeftEdge +_D_PolysetScanLeftEdge: + push ebp + push esi + push edi + push ebx + mov eax,ds:dword ptr[4+16+esp] + mov ecx,ds:dword ptr[_d_sfrac] + and eax,0FFFFh + mov ebx,ds:dword ptr[_d_ptex] + or ecx,eax + mov esi,ds:dword ptr[_d_pedgespanpackage] + mov edx,ds:dword ptr[_d_tfrac] + mov edi,ds:dword ptr[_d_light] + mov ebp,ds:dword ptr[_d_zi] +LScanLoop: + mov ds:dword ptr[12+esi],ebx + mov eax,ds:dword ptr[_d_pdest] + mov ds:dword ptr[0+esi],eax + mov eax,ds:dword ptr[_d_pz] + mov ds:dword ptr[4+esi],eax + mov eax,ds:dword ptr[_d_aspancount] + mov ds:dword ptr[8+esi],eax + mov ds:dword ptr[24+esi],edi + mov ds:dword ptr[28+esi],ebp + mov ds:dword ptr[16+esi],ecx + mov ds:dword ptr[20+esi],edx + mov al,ds:byte ptr[32+esi] + add esi,32 + mov eax,ds:dword ptr[_erroradjustup] + mov ds:dword ptr[_d_pedgespanpackage],esi + mov esi,ds:dword ptr[_errorterm] + add esi,eax + mov eax,ds:dword ptr[_d_pdest] + js LNoLeftEdgeTurnover + sub esi,ds:dword ptr[_erroradjustdown] + add eax,ds:dword ptr[_d_pdestextrastep] + mov ds:dword ptr[_errorterm],esi + mov ds:dword ptr[_d_pdest],eax + mov eax,ds:dword ptr[_d_pz] + mov esi,ds:dword ptr[_d_aspancount] + add eax,ds:dword ptr[_d_pzextrastep] + add ecx,ds:dword ptr[_d_sfracextrastep] + adc ebx,ds:dword ptr[_d_ptexextrastep] + add esi,ds:dword ptr[_d_countextrastep] + mov ds:dword ptr[_d_pz],eax + mov eax,ds:dword ptr[_d_tfracextrastep] + mov ds:dword ptr[_d_aspancount],esi + add edx,eax + jnc LSkip1 + add ebx,ds:dword ptr[_r_affinetridesc+8] +LSkip1: + add edi,ds:dword ptr[_d_lightextrastep] + add ebp,ds:dword ptr[_d_ziextrastep] + mov esi,ds:dword ptr[_d_pedgespanpackage] + dec ecx + test ecx,0FFFFh + jnz LScanLoop + pop ebx + pop edi + pop esi + pop ebp + ret +LNoLeftEdgeTurnover: + mov ds:dword ptr[_errorterm],esi + add eax,ds:dword ptr[_d_pdestbasestep] + mov ds:dword ptr[_d_pdest],eax + mov eax,ds:dword ptr[_d_pz] + mov esi,ds:dword ptr[_d_aspancount] + add eax,ds:dword ptr[_d_pzbasestep] + add ecx,ds:dword ptr[_d_sfracbasestep] + adc ebx,ds:dword ptr[_d_ptexbasestep] + add esi,ds:dword ptr[_ubasestep] + mov ds:dword ptr[_d_pz],eax + mov ds:dword ptr[_d_aspancount],esi + mov esi,ds:dword ptr[_d_tfracbasestep] + add edx,esi + jnc LSkip2 + add ebx,ds:dword ptr[_r_affinetridesc+8] +LSkip2: + add edi,ds:dword ptr[_d_lightbasestep] + add ebp,ds:dword ptr[_d_zibasestep] + mov esi,ds:dword ptr[_d_pedgespanpackage] + dec ecx + test ecx,0FFFFh + jnz LScanLoop + pop ebx + pop edi + pop esi + pop ebp + ret + public _D_PolysetDrawFinalVerts +_D_PolysetDrawFinalVerts: + push ebp + push ebx + mov ecx,ds:dword ptr[8+8+esp] + mov ebx,ds:dword ptr[4+8+esp] + push esi + push edi +LFVLoop: + mov eax,ds:dword ptr[0+0+ebx] + mov edx,ds:dword ptr[_r_refdef+40] + cmp eax,edx + jge LNextVert + mov esi,ds:dword ptr[0+4+ebx] + mov edx,ds:dword ptr[_r_refdef+44] + cmp esi,edx + jge LNextVert + mov edi,ds:dword ptr[_zspantable+esi*4] + mov edx,ds:dword ptr[0+20+ebx] + shr edx,16 + cmp dx,ds:word ptr[edi+eax*2] + jl LNextVert + mov ds:word ptr[edi+eax*2],dx + mov edi,ds:dword ptr[0+12+ebx] + shr edi,16 + mov edi,ds:dword ptr[_skintable+edi*4] + mov edx,ds:dword ptr[0+8+ebx] + shr edx,16 + mov dl,ds:byte ptr[edi+edx] + mov edi,ds:dword ptr[0+16+ebx] + and edi,0FF00h + and edx,000FFh + add edi,edx + mov edx,ds:dword ptr[_acolormap] + mov dl,ds:byte ptr[edx+edi*1] + mov edi,ds:dword ptr[_d_scantable+esi*4] + mov esi,ds:dword ptr[_d_viewbuffer] + add edi,eax + mov ds:byte ptr[esi+edi],dl +LNextVert: + add ebx,32 + dec ecx + jnz LFVLoop + pop edi + pop esi + pop ebx + pop ebp + ret + public _D_DrawNonSubdiv +_D_DrawNonSubdiv: + push ebp + mov ebp,ds:dword ptr[_r_affinetridesc+24] + push ebx + shl ebp,4 + push esi + mov esi,ds:dword ptr[_r_affinetridesc+16] + push edi +LNDLoop: + mov edi,ds:dword ptr[_r_affinetridesc+20] + mov ecx,ds:dword ptr[4+0-16+esi+ebp*1] + shl ecx,5 + mov edx,ds:dword ptr[4+4-16+esi+ebp*1] + shl edx,5 + mov ebx,ds:dword ptr[4+8-16+esi+ebp*1] + shl ebx,5 + add ecx,edi + add edx,edi + add ebx,edi + mov eax,ds:dword ptr[0+4+ecx] + mov esi,ds:dword ptr[0+0+ecx] + sub eax,ds:dword ptr[0+4+edx] + sub esi,ds:dword ptr[0+0+ebx] + imul eax,esi + mov esi,ds:dword ptr[0+0+ecx] + mov edi,ds:dword ptr[0+4+ecx] + sub esi,ds:dword ptr[0+0+edx] + sub edi,ds:dword ptr[0+4+ebx] + imul edi,esi + sub eax,edi + jns LNextTri + mov ds:dword ptr[_d_xdenom],eax + fild ds:dword ptr[_d_xdenom] + mov eax,ds:dword ptr[0+0+ecx] + mov esi,ds:dword ptr[0+4+ecx] + mov ds:dword ptr[_r_p0+0],eax + mov ds:dword ptr[_r_p0+4],esi + mov eax,ds:dword ptr[0+8+ecx] + mov esi,ds:dword ptr[0+12+ecx] + mov ds:dword ptr[_r_p0+8],eax + mov ds:dword ptr[_r_p0+12],esi + mov eax,ds:dword ptr[0+16+ecx] + mov esi,ds:dword ptr[0+20+ecx] + mov ds:dword ptr[_r_p0+16],eax + mov ds:dword ptr[_r_p0+20],esi + fdivr ds:dword ptr[float_1] + mov eax,ds:dword ptr[0+0+edx] + mov esi,ds:dword ptr[0+4+edx] + mov ds:dword ptr[_r_p1+0],eax + mov ds:dword ptr[_r_p1+4],esi + mov eax,ds:dword ptr[0+8+edx] + mov esi,ds:dword ptr[0+12+edx] + mov ds:dword ptr[_r_p1+8],eax + mov ds:dword ptr[_r_p1+12],esi + mov eax,ds:dword ptr[0+16+edx] + mov esi,ds:dword ptr[0+20+edx] + mov ds:dword ptr[_r_p1+16],eax + mov ds:dword ptr[_r_p1+20],esi + mov eax,ds:dword ptr[0+0+ebx] + mov esi,ds:dword ptr[0+4+ebx] + mov ds:dword ptr[_r_p2+0],eax + mov ds:dword ptr[_r_p2+4],esi + mov eax,ds:dword ptr[0+8+ebx] + mov esi,ds:dword ptr[0+12+ebx] + mov ds:dword ptr[_r_p2+8],eax + mov ds:dword ptr[_r_p2+12],esi + mov eax,ds:dword ptr[0+16+ebx] + mov esi,ds:dword ptr[0+20+ebx] + mov ds:dword ptr[_r_p2+16],eax + mov edi,ds:dword ptr[_r_affinetridesc+16] + mov ds:dword ptr[_r_p2+20],esi + mov eax,ds:dword ptr[0-16+edi+ebp*1] + test eax,eax + jnz LFacesFront + mov eax,ds:dword ptr[24+ecx] + mov esi,ds:dword ptr[24+edx] + mov edi,ds:dword ptr[24+ebx] + test eax,00020h + mov eax,ds:dword ptr[_r_affinetridesc+32] + jz LOnseamDone0 + add ds:dword ptr[_r_p0+8],eax +LOnseamDone0: + test esi,00020h + jz LOnseamDone1 + add ds:dword ptr[_r_p1+8],eax +LOnseamDone1: + test edi,00020h + jz LOnseamDone2 + add ds:dword ptr[_r_p2+8],eax +LOnseamDone2: +LFacesFront: + fstp ds:dword ptr[_d_xdenom] + call near ptr _D_PolysetSetEdgeTable + call near ptr _D_RasterizeAliasPolySmooth +LNextTri: + mov esi,ds:dword ptr[_r_affinetridesc+16] + sub ebp,16 + jnz LNDLoop + pop edi + pop esi + pop ebx + pop ebp + add esp,offset (((1024+1 + 1 + ((32 - 1) / 32)) + 1) * 32) + ret +_TEXT ENDS + END diff --git a/QW/client/d_polysa.s b/QW/client/d_polysa.s new file mode 100644 index 0000000..208dd77 --- /dev/null +++ b/QW/client/d_polysa.s @@ -0,0 +1,1744 @@ +/* +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_polysa.s +// x86 assembly-language polygon model drawing code +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" +#include "d_ifacea.h" + +#if id386 + +// !!! if this is changed, it must be changed in d_polyse.c too !!! +#define DPS_MAXSPANS MAXHEIGHT+1 + // 1 extra for spanpackage that marks end + +//#define SPAN_SIZE (((DPS_MAXSPANS + 1 + ((CACHE_SIZE - 1) / spanpackage_t_size)) + 1) * spanpackage_t_size) +#define SPAN_SIZE (1024+1+1+1)*32 + + + .data + + .align 4 +p10_minus_p20: .single 0 +p01_minus_p21: .single 0 +temp0: .single 0 +temp1: .single 0 +Ltemp: .single 0 + +aff8entryvec_table: .long LDraw8, LDraw7, LDraw6, LDraw5 + .long LDraw4, LDraw3, LDraw2, LDraw1 + +lzistepx: .long 0 + + + .text + +#ifndef NeXT + .extern C(D_PolysetSetEdgeTable) + .extern C(D_RasterizeAliasPolySmooth) +#endif + +//---------------------------------------------------------------------- +// affine triangle gradient calculation code +//---------------------------------------------------------------------- + +#define skinwidth 4+0 + +.globl C(D_PolysetCalcGradients) +C(D_PolysetCalcGradients): + +// p00_minus_p20 = r_p0[0] - r_p2[0]; +// p01_minus_p21 = r_p0[1] - r_p2[1]; +// p10_minus_p20 = r_p1[0] - r_p2[0]; +// p11_minus_p21 = r_p1[1] - r_p2[1]; +// +// xstepdenominv = 1.0 / (p10_minus_p20 * p01_minus_p21 - +// p00_minus_p20 * p11_minus_p21); +// +// ystepdenominv = -xstepdenominv; + + fildl C(r_p0)+0 // r_p0[0] + fildl C(r_p2)+0 // r_p2[0] | r_p0[0] + fildl C(r_p0)+4 // r_p0[1] | r_p2[0] | r_p0[0] + fildl C(r_p2)+4 // r_p2[1] | r_p0[1] | r_p2[0] | r_p0[0] + fildl C(r_p1)+0 // r_p1[0] | r_p2[1] | r_p0[1] | r_p2[0] | r_p0[0] + fildl C(r_p1)+4 // r_p1[1] | r_p1[0] | r_p2[1] | r_p0[1] | + // r_p2[0] | r_p0[0] + fxch %st(3) // r_p0[1] | r_p1[0] | r_p2[1] | r_p1[1] | + // r_p2[0] | r_p0[0] + fsub %st(2),%st(0) // p01_minus_p21 | r_p1[0] | r_p2[1] | r_p1[1] | + // r_p2[0] | r_p0[0] + fxch %st(1) // r_p1[0] | p01_minus_p21 | r_p2[1] | r_p1[1] | + // r_p2[0] | r_p0[0] + fsub %st(4),%st(0) // p10_minus_p20 | p01_minus_p21 | r_p2[1] | + // r_p1[1] | r_p2[0] | r_p0[0] + fxch %st(5) // r_p0[0] | p01_minus_p21 | r_p2[1] | + // r_p1[1] | r_p2[0] | p10_minus_p20 + fsubp %st(0),%st(4) // p01_minus_p21 | r_p2[1] | r_p1[1] | + // p00_minus_p20 | p10_minus_p20 + fxch %st(2) // r_p1[1] | r_p2[1] | p01_minus_p21 | + // p00_minus_p20 | p10_minus_p20 + fsubp %st(0),%st(1) // p11_minus_p21 | p01_minus_p21 | + // p00_minus_p20 | p10_minus_p20 + fxch %st(1) // p01_minus_p21 | p11_minus_p21 | + // p00_minus_p20 | p10_minus_p20 + flds C(d_xdenom) // d_xdenom | p01_minus_p21 | p11_minus_p21 | + // p00_minus_p20 | p10_minus_p20 + fxch %st(4) // p10_minus_p20 | p01_minus_p21 | p11_minus_p21 | + // p00_minus_p20 | d_xdenom + fstps p10_minus_p20 // p01_minus_p21 | p11_minus_p21 | + // p00_minus_p20 | d_xdenom + fstps p01_minus_p21 // p11_minus_p21 | p00_minus_p20 | xstepdenominv + fxch %st(2) // xstepdenominv | p00_minus_p20 | p11_minus_p21 + +//// ceil () for light so positive steps are exaggerated, negative steps +//// diminished, pushing us away from underflow toward overflow. Underflow is +//// very visible, overflow is very unlikely, because of ambient lighting +// t0 = r_p0[4] - r_p2[4]; +// t1 = r_p1[4] - r_p2[4]; + + fildl C(r_p2)+16 // r_p2[4] | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fildl C(r_p0)+16 // r_p0[4] | r_p2[4] | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fildl C(r_p1)+16 // r_p1[4] | r_p0[4] | r_p2[4] | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fxch %st(2) // r_p2[4] | r_p0[4] | r_p1[4] | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fld %st(0) // r_p2[4] | r_p2[4] | r_p0[4] | r_p1[4] | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fsubrp %st(0),%st(2) // r_p2[4] | t0 | r_p1[4] | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fsubrp %st(0),%st(2) // t0 | t1 | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + +// r_lstepx = (int) +// ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); +// r_lstepy = (int) +// ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + + fld %st(0) // t0 | t0 | t1 | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fmul %st(5),%st(0) // t0*p11_minus_p21 | t0 | t1 | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fxch %st(2) // t1 | t0 | t0*p11_minus_p21 | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fld %st(0) // t1 | t1 | t0 | t0*p11_minus_p21 | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fmuls p01_minus_p21 // t1*p01_minus_p21 | t1 | t0 | t0*p11_minus_p21 | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(2) // t0 | t1 | t1*p01_minus_p21 | t0*p11_minus_p21 | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fmuls p10_minus_p20 // t0*p10_minus_p20 | t1 | t1*p01_minus_p21 | + // t0*p11_minus_p21 | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fxch %st(1) // t1 | t0*p10_minus_p20 | t1*p01_minus_p21 | + // t0*p11_minus_p21 | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fmul %st(5),%st(0) // t1*p00_minus_p20 | t0*p10_minus_p20 | + // t1*p01_minus_p21 | t0*p11_minus_p21 | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(2) // t1*p01_minus_p21 | t0*p10_minus_p20 | + // t1*p00_minus_p20 | t0*p11_minus_p21 | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fsubp %st(0),%st(3) // t0*p10_minus_p20 | t1*p00_minus_p20 | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fsubrp %st(0),%st(1) // t1*p00_minus_p20 - t0*p10_minus_p20 | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fld %st(2) // xstepdenominv | + // t1*p00_minus_p20 - t0*p10_minus_p20 | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fmuls float_minus_1 // ystepdenominv | + // t1*p00_minus_p20 - t0*p10_minus_p20 | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(2) // t1*p01_minus_p21 - t0*p11_minus_p21 | + // t1*p00_minus_p20 - t0*p10_minus_p20 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fmul %st(3),%st(0) // (t1*p01_minus_p21 - t0*p11_minus_p21)* + // xstepdenominv | + // t1*p00_minus_p20 - t0*p10_minus_p20 | + // | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fxch %st(1) // t1*p00_minus_p20 - t0*p10_minus_p20 | + // (t1*p01_minus_p21 - t0*p11_minus_p21)* + // xstepdenominv | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fmul %st(2),%st(0) // (t1*p00_minus_p20 - t0*p10_minus_p20)* + // ystepdenominv | + // (t1*p01_minus_p21 - t0*p11_minus_p21)* + // xstepdenominv | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fldcw ceil_cw + fistpl C(r_lstepy) // r_lstepx | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fistpl C(r_lstepx) // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fldcw single_cw + +// t0 = r_p0[2] - r_p2[2]; +// t1 = r_p1[2] - r_p2[2]; + + fildl C(r_p2)+8 // r_p2[2] | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fildl C(r_p0)+8 // r_p0[2] | r_p2[2] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fildl C(r_p1)+8 // r_p1[2] | r_p0[2] | r_p2[2] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(2) // r_p2[2] | r_p0[2] | r_p1[2] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fld %st(0) // r_p2[2] | r_p2[2] | r_p0[2] | r_p1[2] | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fsubrp %st(0),%st(2) // r_p2[2] | t0 | r_p1[2] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fsubrp %st(0),%st(2) // t0 | t1 | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + +// r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * +// xstepdenominv); +// r_sstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * +// ystepdenominv); + + fld %st(0) // t0 | t0 | t1 | ystepdenominv | xstepdenominv + fmul %st(6),%st(0) // t0*p11_minus_p21 | t0 | t1 | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(2) // t1 | t0 | t0*p11_minus_p21 | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fld %st(0) // t1 | t1 | t0 | t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fmuls p01_minus_p21 // t1*p01_minus_p21 | t1 | t0 | t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fxch %st(2) // t0 | t1 | t1*p01_minus_p21 | t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fmuls p10_minus_p20 // t0*p10_minus_p20 | t1 | t1*p01_minus_p21 | + // t0*p11_minus_p21 | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(1) // t1 | t0*p10_minus_p20 | t1*p01_minus_p21 | + // t0*p11_minus_p21 | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fmul %st(6),%st(0) // t1*p00_minus_p20 | t0*p10_minus_p20 | + // t1*p01_minus_p21 | t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fxch %st(2) // t1*p01_minus_p21 | t0*p10_minus_p20 | + // t1*p00_minus_p20 | t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fsubp %st(0),%st(3) // t0*p10_minus_p20 | t1*p00_minus_p20 | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fsubrp %st(0),%st(1) // t1*p00_minus_p20 - t0*p10_minus_p20 | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fmul %st(2),%st(0) // (t1*p00_minus_p20 - t0*p10_minus_p20)* + // ystepdenominv | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fxch %st(1) // t1*p01_minus_p21 - t0*p11_minus_p21 | + // (t1*p00_minus_p20 - t0*p10_minus_p20)* + // ystepdenominv | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fmul %st(3),%st(0) // (t1*p01_minus_p21 - t0*p11_minus_p21)* + // xstepdenominv | + // (t1*p00_minus_p20 - t0*p10_minus_p20)* + // ystepdenominv | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(1) // (t1*p00_minus_p20 - t0*p10_minus_p20)* + // ystepdenominv | + // (t1*p01_minus_p21 - t0*p11_minus_p21)* + // xstepdenominv | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fistpl C(r_sstepy) // r_sstepx | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fistpl C(r_sstepx) // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + +// t0 = r_p0[3] - r_p2[3]; +// t1 = r_p1[3] - r_p2[3]; + + fildl C(r_p2)+12 // r_p2[3] | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fildl C(r_p0)+12 // r_p0[3] | r_p2[3] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fildl C(r_p1)+12 // r_p1[3] | r_p0[3] | r_p2[3] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(2) // r_p2[3] | r_p0[3] | r_p1[3] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fld %st(0) // r_p2[3] | r_p2[3] | r_p0[3] | r_p1[3] | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fsubrp %st(0),%st(2) // r_p2[3] | t0 | r_p1[3] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fsubrp %st(0),%st(2) // t0 | t1 | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + +// r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * +// xstepdenominv); +// r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * +// ystepdenominv); + + fld %st(0) // t0 | t0 | t1 | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fmul %st(6),%st(0) // t0*p11_minus_p21 | t0 | t1 | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(2) // t1 | t0 | t0*p11_minus_p21 | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fld %st(0) // t1 | t1 | t0 | t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fmuls p01_minus_p21 // t1*p01_minus_p21 | t1 | t0 | t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fxch %st(2) // t0 | t1 | t1*p01_minus_p21 | t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fmuls p10_minus_p20 // t0*p10_minus_p20 | t1 | t1*p01_minus_p21 | + // t0*p11_minus_p21 | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(1) // t1 | t0*p10_minus_p20 | t1*p01_minus_p21 | + // t0*p11_minus_p21 | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fmul %st(6),%st(0) // t1*p00_minus_p20 | t0*p10_minus_p20 | + // t1*p01_minus_p21 | t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fxch %st(2) // t1*p01_minus_p21 | t0*p10_minus_p20 | + // t1*p00_minus_p20 | t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fsubp %st(0),%st(3) // t0*p10_minus_p20 | t1*p00_minus_p20 | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fsubrp %st(0),%st(1) // t1*p00_minus_p20 - t0*p10_minus_p20 | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fmul %st(2),%st(0) // (t1*p00_minus_p20 - t0*p10_minus_p20)* + // ystepdenominv | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fxch %st(1) // t1*p01_minus_p21 - t0*p11_minus_p21 | + // (t1*p00_minus_p20 - t0*p10_minus_p20)* + // ystepdenominv | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fmul %st(3),%st(0) // (t1*p01_minus_p21 - t0*p11_minus_p21)* + // xstepdenominv | + // (t1*p00_minus_p20 - t0*p10_minus_p20)* + // ystepdenominv | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(1) // (t1*p00_minus_p20 - t0*p10_minus_p20)* + // ystepdenominv | + // (t1*p01_minus_p21 - t0*p11_minus_p21)* + // xstepdenominv | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fistpl C(r_tstepy) // r_tstepx | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fistpl C(r_tstepx) // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + +// t0 = r_p0[5] - r_p2[5]; +// t1 = r_p1[5] - r_p2[5]; + + fildl C(r_p2)+20 // r_p2[5] | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fildl C(r_p0)+20 // r_p0[5] | r_p2[5] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fildl C(r_p1)+20 // r_p1[5] | r_p0[5] | r_p2[5] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fxch %st(2) // r_p2[5] | r_p0[5] | r_p1[5] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fld %st(0) // r_p2[5] | r_p2[5] | r_p0[5] | r_p1[5] | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // p11_minus_p21 + fsubrp %st(0),%st(2) // r_p2[5] | t0 | r_p1[5] | ystepdenominv | + // xstepdenominv | p00_minus_p20 | p11_minus_p21 + fsubrp %st(0),%st(2) // t0 | t1 | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + +// r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * +// xstepdenominv); +// r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * +// ystepdenominv); + + fld %st(0) // t0 | t0 | t1 | ystepdenominv | xstepdenominv | + // p00_minus_p20 | p11_minus_p21 + fmulp %st(0),%st(6) // t0 | t1 | ystepdenominv | xstepdenominv | + // p00_minus_p20 | t0*p11_minus_p21 + fxch %st(1) // t1 | t0 | ystepdenominv | xstepdenominv | + // p00_minus_p20 | t0*p11_minus_p21 + fld %st(0) // t1 | t1 | t0 | ystepdenominv | xstepdenominv | + // p00_minus_p20 | t0*p11_minus_p21 + fmuls p01_minus_p21 // t1*p01_minus_p21 | t1 | t0 | ystepdenominv | + // xstepdenominv | p00_minus_p20 | + // t0*p11_minus_p21 + fxch %st(2) // t0 | t1 | t1*p01_minus_p21 | ystepdenominv | + // xstepdenominv | p00_minus_p20 | + // t0*p11_minus_p21 + fmuls p10_minus_p20 // t0*p10_minus_p20 | t1 | t1*p01_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // t0*p11_minus_p21 + fxch %st(1) // t1 | t0*p10_minus_p20 | t1*p01_minus_p21 | + // ystepdenominv | xstepdenominv | p00_minus_p20 | + // t0*p11_minus_p21 + fmulp %st(0),%st(5) // t0*p10_minus_p20 | t1*p01_minus_p21 | + // ystepdenominv | xstepdenominv | + // t1*p00_minus_p20 | t0*p11_minus_p21 + fxch %st(5) // t0*p11_minus_p21 | t1*p01_minus_p21 | + // ystepdenominv | xstepdenominv | + // t1*p00_minus_p20 | t0*p10_minus_p20 + fsubrp %st(0),%st(1) // t1*p01_minus_p21 - t0*p11_minus_p21 | + // ystepdenominv | xstepdenominv | + // t1*p00_minus_p20 | t0*p10_minus_p20 + fxch %st(3) // t1*p00_minus_p20 | ystepdenominv | + // xstepdenominv | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // t0*p10_minus_p20 + fsubp %st(0),%st(4) // ystepdenominv | xstepdenominv | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // t1*p00_minus_p20 - t0*p10_minus_p20 + fxch %st(1) // xstepdenominv | ystepdenominv | + // t1*p01_minus_p21 - t0*p11_minus_p21 | + // t1*p00_minus_p20 - t0*p10_minus_p20 + fmulp %st(0),%st(2) // ystepdenominv | + // (t1*p01_minus_p21 - t0*p11_minus_p21) * + // xstepdenominv | + // t1*p00_minus_p20 - t0*p10_minus_p20 + fmulp %st(0),%st(2) // (t1*p01_minus_p21 - t0*p11_minus_p21) * + // xstepdenominv | + // (t1*p00_minus_p20 - t0*p10_minus_p20) * + // ystepdenominv + fistpl C(r_zistepx) // (t1*p00_minus_p20 - t0*p10_minus_p20) * + // ystepdenominv + fistpl C(r_zistepy) + +// a_sstepxfrac = r_sstepx << 16; +// a_tstepxfrac = r_tstepx << 16; +// +// a_ststepxwhole = r_affinetridesc.skinwidth * (r_tstepx >> 16) + +// (r_sstepx >> 16); + + movl C(r_sstepx),%eax + movl C(r_tstepx),%edx + shll $16,%eax + shll $16,%edx + movl %eax,C(a_sstepxfrac) + movl %edx,C(a_tstepxfrac) + + movl C(r_sstepx),%ecx + movl C(r_tstepx),%eax + sarl $16,%ecx + sarl $16,%eax + imull skinwidth(%esp) + addl %ecx,%eax + movl %eax,C(a_ststepxwhole) + + ret + + +//---------------------------------------------------------------------- +// recursive subdivision affine triangle drawing code +// +// not C-callable because of stdcall return +//---------------------------------------------------------------------- + +#define lp1 4+16 +#define lp2 8+16 +#define lp3 12+16 + +.globl C(D_PolysetRecursiveTriangle) +C(D_PolysetRecursiveTriangle): + pushl %ebp // preserve caller stack frame pointer + pushl %esi // preserve register variables + pushl %edi + pushl %ebx + +// int *temp; +// int d; +// int new[6]; +// int i; +// int z; +// short *zbuf; + movl lp2(%esp),%esi + movl lp1(%esp),%ebx + movl lp3(%esp),%edi + +// d = lp2[0] - lp1[0]; +// if (d < -1 || d > 1) +// goto split; + movl 0(%esi),%eax + + movl 0(%ebx),%edx + movl 4(%esi),%ebp + + subl %edx,%eax + movl 4(%ebx),%ecx + + subl %ecx,%ebp + incl %eax + + cmpl $2,%eax + ja LSplit + +// d = lp2[1] - lp1[1]; +// if (d < -1 || d > 1) +// goto split; + movl 0(%edi),%eax + incl %ebp + + cmpl $2,%ebp + ja LSplit + +// d = lp3[0] - lp2[0]; +// if (d < -1 || d > 1) +// goto split2; + movl 0(%esi),%edx + movl 4(%edi),%ebp + + subl %edx,%eax + movl 4(%esi),%ecx + + subl %ecx,%ebp + incl %eax + + cmpl $2,%eax + ja LSplit2 + +// d = lp3[1] - lp2[1]; +// if (d < -1 || d > 1) +// goto split2; + movl 0(%ebx),%eax + incl %ebp + + cmpl $2,%ebp + ja LSplit2 + +// d = lp1[0] - lp3[0]; +// if (d < -1 || d > 1) +// goto split3; + movl 0(%edi),%edx + movl 4(%ebx),%ebp + + subl %edx,%eax + movl 4(%edi),%ecx + + subl %ecx,%ebp + incl %eax + + incl %ebp + movl %ebx,%edx + + cmpl $2,%eax + ja LSplit3 + +// d = lp1[1] - lp3[1]; +// if (d < -1 || d > 1) +// { +//split3: +// temp = lp1; +// lp3 = lp2; +// lp1 = lp3; +// lp2 = temp; +// goto split; +// } +// +// return; // entire tri is filled +// + cmpl $2,%ebp + jna LDone + +LSplit3: + movl %edi,%ebx + movl %esi,%edi + movl %edx,%esi + jmp LSplit + +//split2: +LSplit2: + +// temp = lp1; +// lp1 = lp2; +// lp2 = lp3; +// lp3 = temp; + movl %ebx,%eax + movl %esi,%ebx + movl %edi,%esi + movl %eax,%edi + +//split: +LSplit: + + subl $24,%esp // allocate space for a new vertex + +//// split this edge +// new[0] = (lp1[0] + lp2[0]) >> 1; +// new[1] = (lp1[1] + lp2[1]) >> 1; +// new[2] = (lp1[2] + lp2[2]) >> 1; +// new[3] = (lp1[3] + lp2[3]) >> 1; +// new[5] = (lp1[5] + lp2[5]) >> 1; + movl 8(%ebx),%eax + + movl 8(%esi),%edx + movl 12(%ebx),%ecx + + addl %edx,%eax + movl 12(%esi),%edx + + sarl $1,%eax + addl %edx,%ecx + + movl %eax,8(%esp) + movl 20(%ebx),%eax + + sarl $1,%ecx + movl 20(%esi),%edx + + movl %ecx,12(%esp) + addl %edx,%eax + + movl 0(%ebx),%ecx + movl 0(%esi),%edx + + sarl $1,%eax + addl %ecx,%edx + + movl %eax,20(%esp) + movl 4(%ebx),%eax + + sarl $1,%edx + movl 4(%esi),%ebp + + movl %edx,0(%esp) + addl %eax,%ebp + + sarl $1,%ebp + movl %ebp,4(%esp) + +//// draw the point if splitting a leading edge +// if (lp2[1] > lp1[1]) +// goto nodraw; + cmpl %eax,4(%esi) + jg LNoDraw + +// if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0])) +// goto nodraw; + movl 0(%esi),%edx + jnz LDraw + + cmpl %ecx,%edx + jl LNoDraw + +LDraw: + +// z = new[5] >> 16; + movl 20(%esp),%edx + movl 4(%esp),%ecx + + sarl $16,%edx + movl 0(%esp),%ebp + +// zbuf = zspantable[new[1]] + new[0]; + movl C(zspantable)(,%ecx,4),%eax + +// if (z >= *zbuf) +// { + cmpw (%eax,%ebp,2),%dx + jnge LNoDraw + +// int pix; +// +// *zbuf = z; + movw %dx,(%eax,%ebp,2) + +// pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; + movl 12(%esp),%eax + + sarl $16,%eax + movl 8(%esp),%edx + + sarl $16,%edx + subl %ecx,%ecx + + movl C(skintable)(,%eax,4),%eax + movl 4(%esp),%ebp + + movb (%eax,%edx,),%cl + movl C(d_pcolormap),%edx + + movb (%edx,%ecx,),%dl + movl 0(%esp),%ecx + +// d_viewbuffer[d_scantable[new[1]] + new[0]] = pix; + movl C(d_scantable)(,%ebp,4),%eax + addl %eax,%ecx + movl C(d_viewbuffer),%eax + movb %dl,(%eax,%ecx,1) + +// } +// +//nodraw: +LNoDraw: + +//// recursively continue +// D_PolysetRecursiveTriangle (lp3, lp1, new); + pushl %esp + pushl %ebx + pushl %edi + call C(D_PolysetRecursiveTriangle) + +// D_PolysetRecursiveTriangle (lp3, new, lp2); + movl %esp,%ebx + pushl %esi + pushl %ebx + pushl %edi + call C(D_PolysetRecursiveTriangle) + addl $24,%esp + +LDone: + popl %ebx // restore register variables + popl %edi + popl %esi + popl %ebp // restore caller stack frame pointer + ret $12 + + +//---------------------------------------------------------------------- +// 8-bpp horizontal span drawing code for affine polygons, with smooth +// shading and no transparency +//---------------------------------------------------------------------- + +#define pspans 4+8 + +.globl C(D_PolysetAff8Start) +C(D_PolysetAff8Start): + +.globl C(D_PolysetDrawSpans8) +C(D_PolysetDrawSpans8): + pushl %esi // preserve register variables + pushl %ebx + + movl pspans(%esp),%esi // point to the first span descriptor + movl C(r_zistepx),%ecx + + pushl %ebp // preserve caller's stack frame + pushl %edi + + rorl $16,%ecx // put high 16 bits of 1/z step in low word + movl spanpackage_t_count(%esi),%edx + + movl %ecx,lzistepx + +LSpanLoop: + +// lcount = d_aspancount - pspanpackage->count; +// +// errorterm += erroradjustup; +// if (errorterm >= 0) +// { +// d_aspancount += d_countextrastep; +// errorterm -= erroradjustdown; +// } +// else +// { +// d_aspancount += ubasestep; +// } + movl C(d_aspancount),%eax + subl %edx,%eax + + movl C(erroradjustup),%edx + movl C(errorterm),%ebx + addl %edx,%ebx + js LNoTurnover + + movl C(erroradjustdown),%edx + movl C(d_countextrastep),%edi + subl %edx,%ebx + movl C(d_aspancount),%ebp + movl %ebx,C(errorterm) + addl %edi,%ebp + movl %ebp,C(d_aspancount) + jmp LRightEdgeStepped + +LNoTurnover: + movl C(d_aspancount),%edi + movl C(ubasestep),%edx + movl %ebx,C(errorterm) + addl %edx,%edi + movl %edi,C(d_aspancount) + +LRightEdgeStepped: + cmpl $1,%eax + + jl LNextSpan + jz LExactlyOneLong + +// +// set up advancetable +// + movl C(a_ststepxwhole),%ecx + movl C(r_affinetridesc)+atd_skinwidth,%edx + + movl %ecx,advancetable+4 // advance base in t + addl %edx,%ecx + + movl %ecx,advancetable // advance extra in t + movl C(a_tstepxfrac),%ecx + + movw C(r_lstepx),%cx + movl %eax,%edx // count + + movl %ecx,tstep + addl $7,%edx + + shrl $3,%edx // count of full and partial loops + movl spanpackage_t_sfrac(%esi),%ebx + + movw %dx,%bx + movl spanpackage_t_pz(%esi),%ecx + + negl %eax + + movl spanpackage_t_pdest(%esi),%edi + andl $7,%eax // 0->0, 1->7, 2->6, ... , 7->1 + + subl %eax,%edi // compensate for hardwired offsets + subl %eax,%ecx + + subl %eax,%ecx + movl spanpackage_t_tfrac(%esi),%edx + + movw spanpackage_t_light(%esi),%dx + movl spanpackage_t_zi(%esi),%ebp + + rorl $16,%ebp // put high 16 bits of 1/z in low word + pushl %esi + + movl spanpackage_t_ptex(%esi),%esi + jmp aff8entryvec_table(,%eax,4) + +// %bx = count of full and partial loops +// %ebx high word = sfrac +// %ecx = pz +// %dx = light +// %edx high word = tfrac +// %esi = ptex +// %edi = pdest +// %ebp = 1/z +// tstep low word = C(r_lstepx) +// tstep high word = C(a_tstepxfrac) +// C(a_sstepxfrac) low word = 0 +// C(a_sstepxfrac) high word = C(a_sstepxfrac) + +LDrawLoop: + +// FIXME: do we need to clamp light? We may need at least a buffer bit to +// keep it from poking into tfrac and causing problems + +LDraw8: + cmpw (%ecx),%bp + jl Lp1 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,(%ecx) + movb 0x12345678(%eax),%al +LPatch8: + movb %al,(%edi) +Lp1: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw7: + cmpw 2(%ecx),%bp + jl Lp2 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,2(%ecx) + movb 0x12345678(%eax),%al +LPatch7: + movb %al,1(%edi) +Lp2: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw6: + cmpw 4(%ecx),%bp + jl Lp3 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,4(%ecx) + movb 0x12345678(%eax),%al +LPatch6: + movb %al,2(%edi) +Lp3: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw5: + cmpw 6(%ecx),%bp + jl Lp4 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,6(%ecx) + movb 0x12345678(%eax),%al +LPatch5: + movb %al,3(%edi) +Lp4: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw4: + cmpw 8(%ecx),%bp + jl Lp5 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,8(%ecx) + movb 0x12345678(%eax),%al +LPatch4: + movb %al,4(%edi) +Lp5: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw3: + cmpw 10(%ecx),%bp + jl Lp6 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,10(%ecx) + movb 0x12345678(%eax),%al +LPatch3: + movb %al,5(%edi) +Lp6: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw2: + cmpw 12(%ecx),%bp + jl Lp7 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,12(%ecx) + movb 0x12345678(%eax),%al +LPatch2: + movb %al,6(%edi) +Lp7: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw1: + cmpw 14(%ecx),%bp + jl Lp8 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,14(%ecx) + movb 0x12345678(%eax),%al +LPatch1: + movb %al,7(%edi) +Lp8: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + + addl $8,%edi + addl $16,%ecx + + decw %bx + jnz LDrawLoop + + popl %esi // restore spans pointer +LNextSpan: + addl $(spanpackage_t_size),%esi // point to next span +LNextSpanESISet: + movl spanpackage_t_count(%esi),%edx + cmpl $-999999,%edx // any more spans? + jnz LSpanLoop // yes + + popl %edi + popl %ebp // restore the caller's stack frame + popl %ebx // restore register variables + popl %esi + ret + + +// draw a one-long span + +LExactlyOneLong: + + movl spanpackage_t_pz(%esi),%ecx + movl spanpackage_t_zi(%esi),%ebp + + rorl $16,%ebp // put high 16 bits of 1/z in low word + movl spanpackage_t_ptex(%esi),%ebx + + cmpw (%ecx),%bp + jl LNextSpan + xorl %eax,%eax + movl spanpackage_t_pdest(%esi),%edi + movb spanpackage_t_light+1(%esi),%ah + addl $(spanpackage_t_size),%esi // point to next span + movb (%ebx),%al + movw %bp,(%ecx) + movb 0x12345678(%eax),%al +LPatch9: + movb %al,(%edi) + + jmp LNextSpanESISet + +.globl C(D_PolysetAff8End) +C(D_PolysetAff8End): + + +#define pcolormap 4 + +.globl C(D_Aff8Patch) +C(D_Aff8Patch): + movl pcolormap(%esp),%eax + movl %eax,LPatch1-4 + movl %eax,LPatch2-4 + movl %eax,LPatch3-4 + movl %eax,LPatch4-4 + movl %eax,LPatch5-4 + movl %eax,LPatch6-4 + movl %eax,LPatch7-4 + movl %eax,LPatch8-4 + movl %eax,LPatch9-4 + + ret + + +//---------------------------------------------------------------------- +// Alias model polygon dispatching code, combined with subdivided affine +// triangle drawing code +//---------------------------------------------------------------------- + +.globl C(D_PolysetDraw) +C(D_PolysetDraw): + +// spanpackage_t spans[DPS_MAXSPANS + 1 + +// ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1]; +// // one extra because of cache line pretouching +// +// a_spans = (spanpackage_t *) +// (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + subl $(SPAN_SIZE),%esp + movl %esp,%eax + addl $(CACHE_SIZE - 1),%eax + andl $(~(CACHE_SIZE - 1)),%eax + movl %eax,C(a_spans) + +// if (r_affinetridesc.drawtype) +// D_DrawSubdiv (); +// else +// D_DrawNonSubdiv (); + movl C(r_affinetridesc)+atd_drawtype,%eax + testl %eax,%eax + jz C(D_DrawNonSubdiv) + + pushl %ebp // preserve caller stack frame pointer + +// lnumtriangles = r_affinetridesc.numtriangles; + movl C(r_affinetridesc)+atd_numtriangles,%ebp + + pushl %esi // preserve register variables + shll $4,%ebp + + pushl %ebx +// ptri = r_affinetridesc.ptriangles; + movl C(r_affinetridesc)+atd_ptriangles,%ebx + + pushl %edi + +// mtriangle_t *ptri; +// finalvert_t *pfv, *index0, *index1, *index2; +// int i; +// int lnumtriangles; +// int s0, s1, s2; + +// pfv = r_affinetridesc.pfinalverts; + movl C(r_affinetridesc)+atd_pfinalverts,%edi + +// for (i=0 ; i<lnumtriangles ; i++) +// { + +Llooptop: + +// index0 = pfv + ptri[i].vertindex[0]; +// index1 = pfv + ptri[i].vertindex[1]; +// index2 = pfv + ptri[i].vertindex[2]; + movl mtri_vertindex-16+0(%ebx,%ebp,),%ecx + movl mtri_vertindex-16+4(%ebx,%ebp,),%esi + + shll $(fv_shift),%ecx + movl mtri_vertindex-16+8(%ebx,%ebp,),%edx + + shll $(fv_shift),%esi + addl %edi,%ecx + + shll $(fv_shift),%edx + addl %edi,%esi + + addl %edi,%edx + +// if (((index0->v[1]-index1->v[1]) * +// (index0->v[0]-index2->v[0]) - +// (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1])) >= 0) +// { +// continue; +// } +// +// d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00]; + fildl fv_v+4(%ecx) // i0v1 + fildl fv_v+4(%esi) // i1v1 | i0v1 + fildl fv_v+0(%ecx) // i0v0 | i1v1 | i0v1 + fildl fv_v+0(%edx) // i2v0 | i0v0 | i1v1 | i0v1 + fxch %st(2) // i1v1 | i0v0 | i2v0 | i0v1 + fsubr %st(3),%st(0) // i0v1-i1v1 | i0v0 | i2v0 | i0v1 + fildl fv_v+0(%esi) // i1v0 | i0v1-i1v1 | i0v0 | i2v0 | i0v1 + fxch %st(2) // i0v0 | i0v1-i1v1 | i1v0 | i2v0 | i0v1 + fsub %st(0),%st(3) // i0v0 | i0v1-i1v1 | i1v0 | i0v0-i2v0 | i0v1 + fildl fv_v+4(%edx) // i2v1 | i0v0 | i0v1-i1v1 | i1v0 | i0v0-i2v0| i0v1 + fxch %st(1) // i0v0 | i2v1 | i0v1-i1v1 | i1v0 | i0v0-i2v0| i0v1 + fsubp %st(0),%st(3) // i2v1 | i0v1-i1v1 | i0v0-i1v0 | i0v0-i2v0 | i0v1 + fxch %st(1) // i0v1-i1v1 | i2v1 | i0v0-i1v0 | i0v0-i2v0 | i0v1 + fmulp %st(0),%st(3) // i2v1 | i0v0-i1v0 | i0v1-i1v1*i0v0-i2v0 | i0v1 + fsubrp %st(0),%st(3) // i0v0-i1v0 | i0v1-i1v1*i0v0-i2v0 | i0v1-i2v1 + movl fv_v+16(%ecx),%eax + andl $0xFF00,%eax + fmulp %st(0),%st(2) // i0v1-i1v1*i0v0-i2v0 | i0v0-i1v0*i0v1-i2v1 + addl C(acolormap),%eax + fsubp %st(0),%st(1) // (i0v1-i1v1)*(i0v0-i2v0)-(i0v0-i1v0)*(i0v1-i2v1) + movl %eax,C(d_pcolormap) + fstps Ltemp + movl Ltemp,%eax + subl $0x80000001,%eax + jc Lskip + +// if (ptri[i].facesfront) +// { +// D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); + movl mtri_facesfront-16(%ebx,%ebp,),%eax + testl %eax,%eax + jz Lfacesback + + pushl %edx + pushl %esi + pushl %ecx + call C(D_PolysetRecursiveTriangle) + + subl $16,%ebp + jnz Llooptop + jmp Ldone2 + +// } +// else +// { +Lfacesback: + +// s0 = index0->v[2]; +// s1 = index1->v[2]; +// s2 = index2->v[2]; + movl fv_v+8(%ecx),%eax + pushl %eax + movl fv_v+8(%esi),%eax + pushl %eax + movl fv_v+8(%edx),%eax + pushl %eax + pushl %ecx + pushl %edx + +// if (index0->flags & ALIAS_ONSEAM) +// index0->v[2] += r_affinetridesc.seamfixupX16; + movl C(r_affinetridesc)+atd_seamfixupX16,%eax + testl $(ALIAS_ONSEAM),fv_flags(%ecx) + jz Lp11 + addl %eax,fv_v+8(%ecx) +Lp11: + +// if (index1->flags & ALIAS_ONSEAM) +// index1->v[2] += r_affinetridesc.seamfixupX16; + testl $(ALIAS_ONSEAM),fv_flags(%esi) + jz Lp12 + addl %eax,fv_v+8(%esi) +Lp12: + +// if (index2->flags & ALIAS_ONSEAM) +// index2->v[2] += r_affinetridesc.seamfixupX16; + testl $(ALIAS_ONSEAM),fv_flags(%edx) + jz Lp13 + addl %eax,fv_v+8(%edx) +Lp13: + +// D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); + pushl %edx + pushl %esi + pushl %ecx + call C(D_PolysetRecursiveTriangle) + +// index0->v[2] = s0; +// index1->v[2] = s1; +// index2->v[2] = s2; + popl %edx + popl %ecx + popl %eax + movl %eax,fv_v+8(%edx) + popl %eax + movl %eax,fv_v+8(%esi) + popl %eax + movl %eax,fv_v+8(%ecx) + +// } +// } +Lskip: + subl $16,%ebp + jnz Llooptop + +Ldone2: + popl %edi // restore the caller's stack frame + popl %ebx + popl %esi // restore register variables + popl %ebp + + addl $(SPAN_SIZE),%esp + + ret + + +//---------------------------------------------------------------------- +// Alias model triangle left-edge scanning code +//---------------------------------------------------------------------- + +#define height 4+16 + +.globl C(D_PolysetScanLeftEdge) +C(D_PolysetScanLeftEdge): + pushl %ebp // preserve caller stack frame pointer + pushl %esi // preserve register variables + pushl %edi + pushl %ebx + + movl height(%esp),%eax + movl C(d_sfrac),%ecx + andl $0xFFFF,%eax + movl C(d_ptex),%ebx + orl %eax,%ecx + movl C(d_pedgespanpackage),%esi + movl C(d_tfrac),%edx + movl C(d_light),%edi + movl C(d_zi),%ebp + +// %eax: scratch +// %ebx: d_ptex +// %ecx: d_sfrac in high word, count in low word +// %edx: d_tfrac +// %esi: d_pedgespanpackage, errorterm, scratch alternately +// %edi: d_light +// %ebp: d_zi + +// do +// { + +LScanLoop: + +// d_pedgespanpackage->ptex = ptex; +// d_pedgespanpackage->pdest = d_pdest; +// d_pedgespanpackage->pz = d_pz; +// d_pedgespanpackage->count = d_aspancount; +// d_pedgespanpackage->light = d_light; +// d_pedgespanpackage->zi = d_zi; +// d_pedgespanpackage->sfrac = d_sfrac << 16; +// d_pedgespanpackage->tfrac = d_tfrac << 16; + movl %ebx,spanpackage_t_ptex(%esi) + movl C(d_pdest),%eax + movl %eax,spanpackage_t_pdest(%esi) + movl C(d_pz),%eax + movl %eax,spanpackage_t_pz(%esi) + movl C(d_aspancount),%eax + movl %eax,spanpackage_t_count(%esi) + movl %edi,spanpackage_t_light(%esi) + movl %ebp,spanpackage_t_zi(%esi) + movl %ecx,spanpackage_t_sfrac(%esi) + movl %edx,spanpackage_t_tfrac(%esi) + +// pretouch the next cache line + movb spanpackage_t_size(%esi),%al + +// d_pedgespanpackage++; + addl $(spanpackage_t_size),%esi + movl C(erroradjustup),%eax + movl %esi,C(d_pedgespanpackage) + +// errorterm += erroradjustup; + movl C(errorterm),%esi + addl %eax,%esi + movl C(d_pdest),%eax + +// if (errorterm >= 0) +// { + js LNoLeftEdgeTurnover + +// errorterm -= erroradjustdown; +// d_pdest += d_pdestextrastep; + subl C(erroradjustdown),%esi + addl C(d_pdestextrastep),%eax + movl %esi,C(errorterm) + movl %eax,C(d_pdest) + +// d_pz += d_pzextrastep; +// d_aspancount += d_countextrastep; +// d_ptex += d_ptexextrastep; +// d_sfrac += d_sfracextrastep; +// d_ptex += d_sfrac >> 16; +// d_sfrac &= 0xFFFF; +// d_tfrac += d_tfracextrastep; + movl C(d_pz),%eax + movl C(d_aspancount),%esi + addl C(d_pzextrastep),%eax + addl C(d_sfracextrastep),%ecx + adcl C(d_ptexextrastep),%ebx + addl C(d_countextrastep),%esi + movl %eax,C(d_pz) + movl C(d_tfracextrastep),%eax + movl %esi,C(d_aspancount) + addl %eax,%edx + +// if (d_tfrac & 0x10000) +// { + jnc LSkip1 + +// d_ptex += r_affinetridesc.skinwidth; +// d_tfrac &= 0xFFFF; + addl C(r_affinetridesc)+atd_skinwidth,%ebx + +// } + +LSkip1: + +// d_light += d_lightextrastep; +// d_zi += d_ziextrastep; + addl C(d_lightextrastep),%edi + addl C(d_ziextrastep),%ebp + +// } + movl C(d_pedgespanpackage),%esi + decl %ecx + testl $0xFFFF,%ecx + jnz LScanLoop + + popl %ebx + popl %edi + popl %esi + popl %ebp + ret + +// else +// { + +LNoLeftEdgeTurnover: + movl %esi,C(errorterm) + +// d_pdest += d_pdestbasestep; + addl C(d_pdestbasestep),%eax + movl %eax,C(d_pdest) + +// d_pz += d_pzbasestep; +// d_aspancount += ubasestep; +// d_ptex += d_ptexbasestep; +// d_sfrac += d_sfracbasestep; +// d_ptex += d_sfrac >> 16; +// d_sfrac &= 0xFFFF; + movl C(d_pz),%eax + movl C(d_aspancount),%esi + addl C(d_pzbasestep),%eax + addl C(d_sfracbasestep),%ecx + adcl C(d_ptexbasestep),%ebx + addl C(ubasestep),%esi + movl %eax,C(d_pz) + movl %esi,C(d_aspancount) + +// d_tfrac += d_tfracbasestep; + movl C(d_tfracbasestep),%esi + addl %esi,%edx + +// if (d_tfrac & 0x10000) +// { + jnc LSkip2 + +// d_ptex += r_affinetridesc.skinwidth; +// d_tfrac &= 0xFFFF; + addl C(r_affinetridesc)+atd_skinwidth,%ebx + +// } + +LSkip2: + +// d_light += d_lightbasestep; +// d_zi += d_zibasestep; + addl C(d_lightbasestep),%edi + addl C(d_zibasestep),%ebp + +// } +// } while (--height); + movl C(d_pedgespanpackage),%esi + decl %ecx + testl $0xFFFF,%ecx + jnz LScanLoop + + popl %ebx + popl %edi + popl %esi + popl %ebp + ret + + +//---------------------------------------------------------------------- +// Alias model vertex drawing code +//---------------------------------------------------------------------- + +#define fv 4+8 +#define numverts 8+8 + +.globl C(D_PolysetDrawFinalVerts) +C(D_PolysetDrawFinalVerts): + pushl %ebp // preserve caller stack frame pointer + pushl %ebx + +// int i, z; +// short *zbuf; + + movl numverts(%esp),%ecx + movl fv(%esp),%ebx + + pushl %esi // preserve register variables + pushl %edi + +LFVLoop: + +// for (i=0 ; i<numverts ; i++, fv++) +// { +// // valid triangle coordinates for filling can include the bottom and +// // right clip edges, due to the fill rule; these shouldn't be drawn +// if ((fv->v[0] < r_refdef.vrectright) && +// (fv->v[1] < r_refdef.vrectbottom)) +// { + movl fv_v+0(%ebx),%eax + movl C(r_refdef)+rd_vrectright,%edx + cmpl %edx,%eax + jge LNextVert + movl fv_v+4(%ebx),%esi + movl C(r_refdef)+rd_vrectbottom,%edx + cmpl %edx,%esi + jge LNextVert + +// zbuf = zspantable[fv->v[1]] + fv->v[0]; + movl C(zspantable)(,%esi,4),%edi + +// z = fv->v[5]>>16; + movl fv_v+20(%ebx),%edx + shrl $16,%edx + +// if (z >= *zbuf) +// { +// int pix; + cmpw (%edi,%eax,2),%dx + jl LNextVert + +// *zbuf = z; + movw %dx,(%edi,%eax,2) + +// pix = skintable[fv->v[3]>>16][fv->v[2]>>16]; + movl fv_v+12(%ebx),%edi + shrl $16,%edi + movl C(skintable)(,%edi,4),%edi + movl fv_v+8(%ebx),%edx + shrl $16,%edx + movb (%edi,%edx),%dl + +// pix = ((byte *)acolormap)[pix + (fv->v[4] & 0xFF00)]; + movl fv_v+16(%ebx),%edi + andl $0xFF00,%edi + andl $0x00FF,%edx + addl %edx,%edi + movl C(acolormap),%edx + movb (%edx,%edi,1),%dl + +// d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix; + movl C(d_scantable)(,%esi,4),%edi + movl C(d_viewbuffer),%esi + addl %eax,%edi + movb %dl,(%esi,%edi) + +// } +// } +// } +LNextVert: + addl $(fv_size),%ebx + decl %ecx + jnz LFVLoop + + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + + +//---------------------------------------------------------------------- +// Alias model non-subdivided polygon dispatching code +// +// not C-callable because of stack buffer cleanup +//---------------------------------------------------------------------- + +.globl C(D_DrawNonSubdiv) +C(D_DrawNonSubdiv): + pushl %ebp // preserve caller stack frame pointer + movl C(r_affinetridesc)+atd_numtriangles,%ebp + pushl %ebx + shll $(mtri_shift),%ebp + pushl %esi // preserve register variables + movl C(r_affinetridesc)+atd_ptriangles,%esi + pushl %edi + +// mtriangle_t *ptri; +// finalvert_t *pfv, *index0, *index1, *index2; +// int i; +// int lnumtriangles; + +// pfv = r_affinetridesc.pfinalverts; +// ptri = r_affinetridesc.ptriangles; +// lnumtriangles = r_affinetridesc.numtriangles; + +LNDLoop: + +// for (i=0 ; i<lnumtriangles ; i++, ptri++) +// { +// index0 = pfv + ptri->vertindex[0]; +// index1 = pfv + ptri->vertindex[1]; +// index2 = pfv + ptri->vertindex[2]; + movl C(r_affinetridesc)+atd_pfinalverts,%edi + movl mtri_vertindex+0-mtri_size(%esi,%ebp,1),%ecx + shll $(fv_shift),%ecx + movl mtri_vertindex+4-mtri_size(%esi,%ebp,1),%edx + shll $(fv_shift),%edx + movl mtri_vertindex+8-mtri_size(%esi,%ebp,1),%ebx + shll $(fv_shift),%ebx + addl %edi,%ecx + addl %edi,%edx + addl %edi,%ebx + +// d_xdenom = (index0->v[1]-index1->v[1]) * +// (index0->v[0]-index2->v[0]) - +// (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]); + movl fv_v+4(%ecx),%eax + movl fv_v+0(%ecx),%esi + subl fv_v+4(%edx),%eax + subl fv_v+0(%ebx),%esi + imull %esi,%eax + movl fv_v+0(%ecx),%esi + movl fv_v+4(%ecx),%edi + subl fv_v+0(%edx),%esi + subl fv_v+4(%ebx),%edi + imull %esi,%edi + subl %edi,%eax + +// if (d_xdenom >= 0) +// { +// continue; + jns LNextTri + +// } + + movl %eax,C(d_xdenom) + fildl C(d_xdenom) + +// r_p0[0] = index0->v[0]; // u +// r_p0[1] = index0->v[1]; // v +// r_p0[2] = index0->v[2]; // s +// r_p0[3] = index0->v[3]; // t +// r_p0[4] = index0->v[4]; // light +// r_p0[5] = index0->v[5]; // iz + movl fv_v+0(%ecx),%eax + movl fv_v+4(%ecx),%esi + movl %eax,C(r_p0)+0 + movl %esi,C(r_p0)+4 + movl fv_v+8(%ecx),%eax + movl fv_v+12(%ecx),%esi + movl %eax,C(r_p0)+8 + movl %esi,C(r_p0)+12 + movl fv_v+16(%ecx),%eax + movl fv_v+20(%ecx),%esi + movl %eax,C(r_p0)+16 + movl %esi,C(r_p0)+20 + + fdivrs float_1 + +// r_p1[0] = index1->v[0]; +// r_p1[1] = index1->v[1]; +// r_p1[2] = index1->v[2]; +// r_p1[3] = index1->v[3]; +// r_p1[4] = index1->v[4]; +// r_p1[5] = index1->v[5]; + movl fv_v+0(%edx),%eax + movl fv_v+4(%edx),%esi + movl %eax,C(r_p1)+0 + movl %esi,C(r_p1)+4 + movl fv_v+8(%edx),%eax + movl fv_v+12(%edx),%esi + movl %eax,C(r_p1)+8 + movl %esi,C(r_p1)+12 + movl fv_v+16(%edx),%eax + movl fv_v+20(%edx),%esi + movl %eax,C(r_p1)+16 + movl %esi,C(r_p1)+20 + +// r_p2[0] = index2->v[0]; +// r_p2[1] = index2->v[1]; +// r_p2[2] = index2->v[2]; +// r_p2[3] = index2->v[3]; +// r_p2[4] = index2->v[4]; +// r_p2[5] = index2->v[5]; + movl fv_v+0(%ebx),%eax + movl fv_v+4(%ebx),%esi + movl %eax,C(r_p2)+0 + movl %esi,C(r_p2)+4 + movl fv_v+8(%ebx),%eax + movl fv_v+12(%ebx),%esi + movl %eax,C(r_p2)+8 + movl %esi,C(r_p2)+12 + movl fv_v+16(%ebx),%eax + movl fv_v+20(%ebx),%esi + movl %eax,C(r_p2)+16 + movl C(r_affinetridesc)+atd_ptriangles,%edi + movl %esi,C(r_p2)+20 + movl mtri_facesfront-mtri_size(%edi,%ebp,1),%eax + +// if (!ptri->facesfront) +// { + testl %eax,%eax + jnz LFacesFront + +// if (index0->flags & ALIAS_ONSEAM) +// r_p0[2] += r_affinetridesc.seamfixupX16; + movl fv_flags(%ecx),%eax + movl fv_flags(%edx),%esi + movl fv_flags(%ebx),%edi + testl $(ALIAS_ONSEAM),%eax + movl C(r_affinetridesc)+atd_seamfixupX16,%eax + jz LOnseamDone0 + addl %eax,C(r_p0)+8 +LOnseamDone0: + +// if (index1->flags & ALIAS_ONSEAM) +// r_p1[2] += r_affinetridesc.seamfixupX16; + testl $(ALIAS_ONSEAM),%esi + jz LOnseamDone1 + addl %eax,C(r_p1)+8 +LOnseamDone1: + +// if (index2->flags & ALIAS_ONSEAM) +// r_p2[2] += r_affinetridesc.seamfixupX16; + testl $(ALIAS_ONSEAM),%edi + jz LOnseamDone2 + addl %eax,C(r_p2)+8 +LOnseamDone2: + +// } + +LFacesFront: + + fstps C(d_xdenom) + +// D_PolysetSetEdgeTable (); +// D_RasterizeAliasPolySmooth (); + call C(D_PolysetSetEdgeTable) + call C(D_RasterizeAliasPolySmooth) + +LNextTri: + movl C(r_affinetridesc)+atd_ptriangles,%esi + subl $16,%ebp + jnz LNDLoop +// } + + popl %edi + popl %esi + popl %ebx + popl %ebp + + addl $(SPAN_SIZE),%esp + + ret + + +#endif // id386 + diff --git a/QW/client/d_polyse.c b/QW/client/d_polyse.c new file mode 100644 index 0000000..1923968 --- /dev/null +++ b/QW/client/d_polyse.c @@ -0,0 +1,1064 @@ +/* +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_polyset.c: routines for drawing sets of polygons sharing the same +// texture (used for Alias models) + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + +// TODO: put in span spilling to shrink list size +// !!! if this is changed, it must be changed in d_polysa.s too !!! +#define DPS_MAXSPANS MAXHEIGHT+1 + // 1 extra for spanpackage that marks end + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct { + void *pdest; + short *pz; + int count; + byte *ptex; + int sfrac, tfrac, light, zi; +} spanpackage_t; + +typedef struct { + int isflattop; + int numleftedges; + int *pleftedgevert0; + int *pleftedgevert1; + int *pleftedgevert2; + int numrightedges; + int *prightedgevert0; + int *prightedgevert1; + int *prightedgevert2; +} edgetable; + +int r_p0[6], r_p1[6], r_p2[6]; + +byte *d_pcolormap; + +int d_aflatcolor; +int d_xdenom; + +edgetable *pedgetable; + +edgetable edgetables[12] = { + {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 }, + {0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL}, + {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL}, + {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 }, + {0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL}, + {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL}, + {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 }, + {0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL}, + {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL}, + {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL}, + {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL}, + {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL}, +}; + +// FIXME: some of these can become statics +int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole; +int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy; +int r_zistepx, r_zistepy; +int d_aspancount, d_countextrastep; + +spanpackage_t *a_spans; +spanpackage_t *d_pedgespanpackage; +static int ystart; +byte *d_pdest, *d_ptex; +short *d_pz; +int d_sfrac, d_tfrac, d_light, d_zi; +int d_ptexextrastep, d_sfracextrastep; +int d_tfracextrastep, d_lightextrastep, d_pdestextrastep; +int d_lightbasestep, d_pdestbasestep, d_ptexbasestep; +int d_sfracbasestep, d_tfracbasestep; +int d_ziextrastep, d_zibasestep; +int d_pzextrastep, d_pzbasestep; + +typedef struct { + int quotient; + int remainder; +} adivtab_t; + +static adivtab_t adivtab[32*32] = { +#include "adivtab.h" +}; + +byte *skintable[MAX_LBM_HEIGHT]; +int skinwidth; +byte *skinstart; + +void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage); +void D_PolysetCalcGradients (int skinwidth); +void D_DrawSubdiv (void); +void D_DrawNonSubdiv (void); +void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3); +void D_PolysetSetEdgeTable (void); +void D_RasterizeAliasPolySmooth (void); +void D_PolysetScanLeftEdge (int height); + +#if !id386 + +/* +================ +D_PolysetDraw +================ +*/ +void D_PolysetDraw (void) +{ + spanpackage_t spans[DPS_MAXSPANS + 1 + + ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1]; + // one extra because of cache line pretouching + + a_spans = (spanpackage_t *) + (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + + if (r_affinetridesc.drawtype) + { + D_DrawSubdiv (); + } + else + { + D_DrawNonSubdiv (); + } +} + + +/* +================ +D_PolysetDrawFinalVerts +================ +*/ +void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts) +{ + int i, z; + short *zbuf; + + for (i=0 ; i<numverts ; i++, fv++) + { + // valid triangle coordinates for filling can include the bottom and + // right clip edges, due to the fill rule; these shouldn't be drawn + if ((fv->v[0] < r_refdef.vrectright) && + (fv->v[1] < r_refdef.vrectbottom)) + { + z = fv->v[5]>>16; + zbuf = zspantable[fv->v[1]] + fv->v[0]; + if (z >= *zbuf) + { + int pix; + + *zbuf = z; + pix = skintable[fv->v[3]>>16][fv->v[2]>>16]; + pix = ((byte *)acolormap)[pix + (fv->v[4] & 0xFF00) ]; + d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix; + } + } + } +} + + +/* +================ +D_DrawSubdiv +================ +*/ +void D_DrawSubdiv (void) +{ + mtriangle_t *ptri; + finalvert_t *pfv, *index0, *index1, *index2; + int i; + int lnumtriangles; + + pfv = r_affinetridesc.pfinalverts; + ptri = r_affinetridesc.ptriangles; + lnumtriangles = r_affinetridesc.numtriangles; + + for (i=0 ; i<lnumtriangles ; i++) + { + index0 = pfv + ptri[i].vertindex[0]; + index1 = pfv + ptri[i].vertindex[1]; + index2 = pfv + ptri[i].vertindex[2]; + + if (((index0->v[1]-index1->v[1]) * + (index0->v[0]-index2->v[0]) - + (index0->v[0]-index1->v[0]) * + (index0->v[1]-index2->v[1])) >= 0) + { + continue; + } + + d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00]; + + if (ptri[i].facesfront) + { + D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); + } + else + { + int s0, s1, s2; + + s0 = index0->v[2]; + s1 = index1->v[2]; + s2 = index2->v[2]; + + if (index0->flags & ALIAS_ONSEAM) + index0->v[2] += r_affinetridesc.seamfixupX16; + if (index1->flags & ALIAS_ONSEAM) + index1->v[2] += r_affinetridesc.seamfixupX16; + if (index2->flags & ALIAS_ONSEAM) + index2->v[2] += r_affinetridesc.seamfixupX16; + + D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); + + index0->v[2] = s0; + index1->v[2] = s1; + index2->v[2] = s2; + } + } +} + + +/* +================ +D_DrawNonSubdiv +================ +*/ +void D_DrawNonSubdiv (void) +{ + mtriangle_t *ptri; + finalvert_t *pfv, *index0, *index1, *index2; + int i; + int lnumtriangles; + + pfv = r_affinetridesc.pfinalverts; + ptri = r_affinetridesc.ptriangles; + lnumtriangles = r_affinetridesc.numtriangles; + + for (i=0 ; i<lnumtriangles ; i++, ptri++) + { + index0 = pfv + ptri->vertindex[0]; + index1 = pfv + ptri->vertindex[1]; + index2 = pfv + ptri->vertindex[2]; + + d_xdenom = (index0->v[1]-index1->v[1]) * + (index0->v[0]-index2->v[0]) - + (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]); + + if (d_xdenom >= 0) + { + continue; + } + + r_p0[0] = index0->v[0]; // u + r_p0[1] = index0->v[1]; // v + r_p0[2] = index0->v[2]; // s + r_p0[3] = index0->v[3]; // t + r_p0[4] = index0->v[4]; // light + r_p0[5] = index0->v[5]; // iz + + r_p1[0] = index1->v[0]; + r_p1[1] = index1->v[1]; + r_p1[2] = index1->v[2]; + r_p1[3] = index1->v[3]; + r_p1[4] = index1->v[4]; + r_p1[5] = index1->v[5]; + + r_p2[0] = index2->v[0]; + r_p2[1] = index2->v[1]; + r_p2[2] = index2->v[2]; + r_p2[3] = index2->v[3]; + r_p2[4] = index2->v[4]; + r_p2[5] = index2->v[5]; + + if (!ptri->facesfront) + { + if (index0->flags & ALIAS_ONSEAM) + r_p0[2] += r_affinetridesc.seamfixupX16; + if (index1->flags & ALIAS_ONSEAM) + r_p1[2] += r_affinetridesc.seamfixupX16; + if (index2->flags & ALIAS_ONSEAM) + r_p2[2] += r_affinetridesc.seamfixupX16; + } + + D_PolysetSetEdgeTable (); + D_RasterizeAliasPolySmooth (); + } +} + + +/* +================ +D_PolysetRecursiveTriangle +================ +*/ +void D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3) +{ + int *temp; + int d; + int new[6]; + int z; + short *zbuf; + + d = lp2[0] - lp1[0]; + if (d < -1 || d > 1) + goto split; + d = lp2[1] - lp1[1]; + if (d < -1 || d > 1) + goto split; + + d = lp3[0] - lp2[0]; + if (d < -1 || d > 1) + goto split2; + d = lp3[1] - lp2[1]; + if (d < -1 || d > 1) + goto split2; + + d = lp1[0] - lp3[0]; + if (d < -1 || d > 1) + goto split3; + d = lp1[1] - lp3[1]; + if (d < -1 || d > 1) + { +split3: + temp = lp1; + lp1 = lp3; + lp3 = lp2; + lp2 = temp; + + goto split; + } + + return; // entire tri is filled + +split2: + temp = lp1; + lp1 = lp2; + lp2 = lp3; + lp3 = temp; + +split: +// split this edge + new[0] = (lp1[0] + lp2[0]) >> 1; + new[1] = (lp1[1] + lp2[1]) >> 1; + new[2] = (lp1[2] + lp2[2]) >> 1; + new[3] = (lp1[3] + lp2[3]) >> 1; + new[5] = (lp1[5] + lp2[5]) >> 1; + +// draw the point if splitting a leading edge + if (lp2[1] > lp1[1]) + goto nodraw; + if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0])) + goto nodraw; + + + z = new[5]>>16; + zbuf = zspantable[new[1]] + new[0]; + if (z >= *zbuf) + { + int pix; + + *zbuf = z; + pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; + d_viewbuffer[d_scantable[new[1]] + new[0]] = pix; + } + +nodraw: +// recursively continue + D_PolysetRecursiveTriangle (lp3, lp1, new); + D_PolysetRecursiveTriangle (lp3, new, lp2); +} + +#endif // !id386 + + +/* +================ +D_PolysetUpdateTables +================ +*/ +void D_PolysetUpdateTables (void) +{ + int i; + byte *s; + + if (r_affinetridesc.skinwidth != skinwidth || + r_affinetridesc.pskin != skinstart) + { + skinwidth = r_affinetridesc.skinwidth; + skinstart = r_affinetridesc.pskin; + s = skinstart; + for (i=0 ; i<MAX_LBM_HEIGHT ; i++, s+=skinwidth) + skintable[i] = s; + } +} + + +#if !id386 + +/* +=================== +D_PolysetScanLeftEdge +==================== +*/ +void D_PolysetScanLeftEdge (int height) +{ + + do + { + d_pedgespanpackage->pdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_pdest += d_pdestextrastep; + d_pz += d_pzextrastep; + d_aspancount += d_countextrastep; + d_ptex += d_ptexextrastep; + d_sfrac += d_sfracextrastep; + d_ptex += d_sfrac >> 16; + + d_sfrac &= 0xFFFF; + d_tfrac += d_tfracextrastep; + if (d_tfrac & 0x10000) + { + d_ptex += r_affinetridesc.skinwidth; + d_tfrac &= 0xFFFF; + } + d_light += d_lightextrastep; + d_zi += d_ziextrastep; + errorterm -= erroradjustdown; + } + else + { + d_pdest += d_pdestbasestep; + d_pz += d_pzbasestep; + d_aspancount += ubasestep; + d_ptex += d_ptexbasestep; + d_sfrac += d_sfracbasestep; + d_ptex += d_sfrac >> 16; + d_sfrac &= 0xFFFF; + d_tfrac += d_tfracbasestep; + if (d_tfrac & 0x10000) + { + d_ptex += r_affinetridesc.skinwidth; + d_tfrac &= 0xFFFF; + } + d_light += d_lightbasestep; + d_zi += d_zibasestep; + } + } while (--height); +} + +#endif // !id386 + + +/* +=================== +D_PolysetSetUpForLineScan +==================== +*/ +void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv, + fixed8_t endvertu, fixed8_t endvertv) +{ + double dm, dn; + int tm, tn; + adivtab_t *ptemp; + +// TODO: implement x86 version + + errorterm = -1; + + tm = endvertu - startvertu; + tn = endvertv - startvertv; + + if (((tm <= 16) && (tm >= -15)) && + ((tn <= 16) && (tn >= -15))) + { + ptemp = &adivtab[((tm+15) << 5) + (tn+15)]; + ubasestep = ptemp->quotient; + erroradjustup = ptemp->remainder; + erroradjustdown = tn; + } + else + { + dm = (double)tm; + dn = (double)tn; + + FloorDivMod (dm, dn, &ubasestep, &erroradjustup); + + erroradjustdown = dn; + } +} + + +#if !id386 + +/* +================ +D_PolysetCalcGradients +================ +*/ +void D_PolysetCalcGradients (int skinwidth) +{ + float xstepdenominv, ystepdenominv, t0, t1; + float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20; + + p00_minus_p20 = r_p0[0] - r_p2[0]; + p01_minus_p21 = r_p0[1] - r_p2[1]; + p10_minus_p20 = r_p1[0] - r_p2[0]; + p11_minus_p21 = r_p1[1] - r_p2[1]; + + xstepdenominv = 1.0 / (float)d_xdenom; + + ystepdenominv = -xstepdenominv; + +// ceil () for light so positive steps are exaggerated, negative steps +// diminished, pushing us away from underflow toward overflow. Underflow is +// very visible, overflow is very unlikely, because of ambient lighting + t0 = r_p0[4] - r_p2[4]; + t1 = r_p1[4] - r_p2[4]; + r_lstepx = (int) + ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); + r_lstepy = (int) + ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + + t0 = r_p0[2] - r_p2[2]; + t1 = r_p1[2] - r_p2[2]; + r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) * + ystepdenominv); + + t0 = r_p0[3] - r_p2[3]; + t1 = r_p1[3] - r_p2[3]; + r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * + ystepdenominv); + + t0 = r_p0[5] - r_p2[5]; + t1 = r_p1[5] - r_p2[5]; + r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * + ystepdenominv); + +#if id386 + a_sstepxfrac = r_sstepx << 16; + a_tstepxfrac = r_tstepx << 16; +#else + a_sstepxfrac = r_sstepx & 0xFFFF; + a_tstepxfrac = r_tstepx & 0xFFFF; +#endif + + a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16); +} + +#endif // !id386 + + +byte gelmap[256]; +void InitGel (byte *palette) +{ + int i; + int r; + + for (i=0 ; i<256 ; i++) + { +// r = (palette[i*3]>>4); + r = (palette[i*3] + palette[i*3+1] + palette[i*3+2])/(16*3); + gelmap[i] = /* 64 */ 0 + r; + } +} + + +#if !id386 + +/* +================ +D_PolysetDrawSpans8 +================ +*/ +void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage) +{ + int lcount; + byte *lpdest; + byte *lptex; + int lsfrac, ltfrac; + int llight; + int lzi; + short *lpz; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + lpdest = pspanpackage->pdest; + lptex = pspanpackage->ptex; + lpz = pspanpackage->pz; + lsfrac = pspanpackage->sfrac; + ltfrac = pspanpackage->tfrac; + llight = pspanpackage->light; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { + *lpdest = ((byte *)acolormap)[*lptex + (llight & 0xFF00)]; +// gel mapping *lpdest = gelmap[*lpdest]; + *lpz = lzi >> 16; + } + lpdest++; + lzi += r_zistepx; + lpz++; + llight += r_lstepx; + lptex += a_ststepxwhole; + lsfrac += a_sstepxfrac; + lptex += lsfrac >> 16; + lsfrac &= 0xFFFF; + ltfrac += a_tstepxfrac; + if (ltfrac & 0x10000) + { + lptex += r_affinetridesc.skinwidth; + ltfrac &= 0xFFFF; + } + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} +#endif // !id386 + + +/* +================ +D_PolysetFillSpans8 +================ +*/ +void D_PolysetFillSpans8 (spanpackage_t *pspanpackage) +{ + int color; + +// FIXME: do z buffering + + color = d_aflatcolor++; + + while (1) + { + int lcount; + byte *lpdest; + + lcount = pspanpackage->count; + + if (lcount == -1) + return; + + if (lcount) + { + lpdest = pspanpackage->pdest; + + do + { + *lpdest++ = color; + } while (--lcount); + } + + pspanpackage++; + } +} + +/* +================ +D_RasterizeAliasPolySmooth +================ +*/ +void D_RasterizeAliasPolySmooth (void) +{ + int initialleftheight, initialrightheight; + int *plefttop, *prighttop, *pleftbottom, *prightbottom; + int working_lstepx, originalcount; + + plefttop = pedgetable->pleftedgevert0; + prighttop = pedgetable->prightedgevert0; + + pleftbottom = pedgetable->pleftedgevert1; + prightbottom = pedgetable->prightedgevert1; + + initialleftheight = pleftbottom[1] - plefttop[1]; + initialrightheight = prightbottom[1] - prighttop[1]; + +// +// set the s, t, and light gradients, which are consistent across the triangle +// because being a triangle, things are affine +// + D_PolysetCalcGradients (r_affinetridesc.skinwidth); + +// +// rasterize the polygon +// + +// +// scan out the top (and possibly only) part of the left edge +// + D_PolysetSetUpForLineScan(plefttop[0], plefttop[1], + pleftbottom[0], pleftbottom[1]); + + d_pedgespanpackage = a_spans; + + ystart = plefttop[1]; + d_aspancount = plefttop[0] - prighttop[0]; + + d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + + (plefttop[3] >> 16) * r_affinetridesc.skinwidth; +#if id386 + d_sfrac = (plefttop[2] & 0xFFFF) << 16; + d_tfrac = (plefttop[3] & 0xFFFF) << 16; + d_pzbasestep = (d_zwidth + ubasestep) << 1; + d_pzextrastep = d_pzbasestep + 2; +#else + d_sfrac = plefttop[2] & 0xFFFF; + d_tfrac = plefttop[3] & 0xFFFF; + d_pzbasestep = d_zwidth + ubasestep; + d_pzextrastep = d_pzbasestep + 1; +#endif + d_light = plefttop[4]; + d_zi = plefttop[5]; + + d_pdestbasestep = screenwidth + ubasestep; + d_pdestextrastep = d_pdestbasestep + 1; + d_pdest = (byte *)d_viewbuffer + + ystart * screenwidth + plefttop[0]; + d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; + +// TODO: can reuse partial expressions here + +// for negative steps in x along left edge, bias toward overflow rather than +// underflow (sort of turning the floor () we did in the gradient calcs into +// ceil (), but plus a little bit) + if (ubasestep < 0) + working_lstepx = r_lstepx - 1; + else + working_lstepx = r_lstepx; + + d_countextrastep = ubasestep + 1; + d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + + ((r_tstepy + r_tstepx * ubasestep) >> 16) * + r_affinetridesc.skinwidth; +#if id386 + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16; +#else + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; +#endif + d_lightbasestep = r_lstepy + working_lstepx * ubasestep; + d_zibasestep = r_zistepy + r_zistepx * ubasestep; + + d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + + ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * + r_affinetridesc.skinwidth; +#if id386 + d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16; + d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16; +#else + d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF; + d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF; +#endif + d_lightextrastep = d_lightbasestep + working_lstepx; + d_ziextrastep = d_zibasestep + r_zistepx; + + D_PolysetScanLeftEdge (initialleftheight); + +// +// scan out the bottom part of the left edge, if it exists +// + if (pedgetable->numleftedges == 2) + { + int height; + + plefttop = pleftbottom; + pleftbottom = pedgetable->pleftedgevert2; + + D_PolysetSetUpForLineScan(plefttop[0], plefttop[1], + pleftbottom[0], pleftbottom[1]); + + height = pleftbottom[1] - plefttop[1]; + +// TODO: make this a function; modularize this function in general + + ystart = plefttop[1]; + d_aspancount = plefttop[0] - prighttop[0]; + d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + + (plefttop[3] >> 16) * r_affinetridesc.skinwidth; + d_sfrac = 0; + d_tfrac = 0; + d_light = plefttop[4]; + d_zi = plefttop[5]; + + d_pdestbasestep = screenwidth + ubasestep; + d_pdestextrastep = d_pdestbasestep + 1; + d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0]; +#if id386 + d_pzbasestep = (d_zwidth + ubasestep) << 1; + d_pzextrastep = d_pzbasestep + 2; +#else + d_pzbasestep = d_zwidth + ubasestep; + d_pzextrastep = d_pzbasestep + 1; +#endif + d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; + + if (ubasestep < 0) + working_lstepx = r_lstepx - 1; + else + working_lstepx = r_lstepx; + + d_countextrastep = ubasestep + 1; + d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + + ((r_tstepy + r_tstepx * ubasestep) >> 16) * + r_affinetridesc.skinwidth; +#if id386 + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16; +#else + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; +#endif + d_lightbasestep = r_lstepy + working_lstepx * ubasestep; + d_zibasestep = r_zistepy + r_zistepx * ubasestep; + + d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + + ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * + r_affinetridesc.skinwidth; +#if id386 + d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16; + d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16; +#else + d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF; + d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF; +#endif + d_lightextrastep = d_lightbasestep + working_lstepx; + d_ziextrastep = d_zibasestep + r_zistepx; + + D_PolysetScanLeftEdge (height); + } + +// scan out the top (and possibly only) part of the right edge, updating the +// count field + d_pedgespanpackage = a_spans; + + D_PolysetSetUpForLineScan(prighttop[0], prighttop[1], + prightbottom[0], prightbottom[1]); + d_aspancount = 0; + d_countextrastep = ubasestep + 1; + originalcount = a_spans[initialrightheight].count; + a_spans[initialrightheight].count = -999999; // mark end of the spanpackages + D_PolysetDrawSpans8 (a_spans); + +// scan out the bottom part of the right edge, if it exists + if (pedgetable->numrightedges == 2) + { + int height; + spanpackage_t *pstart; + + pstart = a_spans + initialrightheight; + pstart->count = originalcount; + + d_aspancount = prightbottom[0] - prighttop[0]; + + prighttop = prightbottom; + prightbottom = pedgetable->prightedgevert2; + + height = prightbottom[1] - prighttop[1]; + + D_PolysetSetUpForLineScan(prighttop[0], prighttop[1], + prightbottom[0], prightbottom[1]); + + d_countextrastep = ubasestep + 1; + a_spans[initialrightheight + height].count = -999999; + // mark end of the spanpackages + D_PolysetDrawSpans8 (pstart); + } +} + + +/* +================ +D_PolysetSetEdgeTable +================ +*/ +void D_PolysetSetEdgeTable (void) +{ + int edgetableindex; + + edgetableindex = 0; // assume the vertices are already in + // top to bottom order + +// +// determine which edges are right & left, and the order in which +// to rasterize them +// + if (r_p0[1] >= r_p1[1]) + { + if (r_p0[1] == r_p1[1]) + { + if (r_p0[1] < r_p2[1]) + pedgetable = &edgetables[2]; + else + pedgetable = &edgetables[5]; + + return; + } + else + { + edgetableindex = 1; + } + } + + if (r_p0[1] == r_p2[1]) + { + if (edgetableindex) + pedgetable = &edgetables[8]; + else + pedgetable = &edgetables[9]; + + return; + } + else if (r_p1[1] == r_p2[1]) + { + if (edgetableindex) + pedgetable = &edgetables[10]; + else + pedgetable = &edgetables[11]; + + return; + } + + if (r_p0[1] > r_p2[1]) + edgetableindex += 2; + + if (r_p1[1] > r_p2[1]) + edgetableindex += 4; + + pedgetable = &edgetables[edgetableindex]; +} + + +#if 0 + +void D_PolysetRecursiveDrawLine (int *lp1, int *lp2) +{ + int d; + int new[6]; + int ofs; + + d = lp2[0] - lp1[0]; + if (d < -1 || d > 1) + goto split; + d = lp2[1] - lp1[1]; + if (d < -1 || d > 1) + goto split; + + return; // line is completed + +split: +// split this edge + new[0] = (lp1[0] + lp2[0]) >> 1; + new[1] = (lp1[1] + lp2[1]) >> 1; + new[5] = (lp1[5] + lp2[5]) >> 1; + new[2] = (lp1[2] + lp2[2]) >> 1; + new[3] = (lp1[3] + lp2[3]) >> 1; + new[4] = (lp1[4] + lp2[4]) >> 1; + +// draw the point + ofs = d_scantable[new[1]] + new[0]; + if (new[5] > d_pzbuffer[ofs]) + { + int pix; + + d_pzbuffer[ofs] = new[5]; + pix = skintable[new[3]>>16][new[2]>>16]; +// pix = ((byte *)acolormap)[pix + (new[4] & 0xFF00)]; + d_viewbuffer[ofs] = pix; + } + +// recursively continue + D_PolysetRecursiveDrawLine (lp1, new); + D_PolysetRecursiveDrawLine (new, lp2); +} + +void D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3) +{ + int d; + int new[4]; + + d = lp2[0] - lp1[0]; + if (d < -1 || d > 1) + goto split; + d = lp2[1] - lp1[1]; + if (d < -1 || d > 1) + goto split; + return; + +split: +// split this edge + new[0] = (lp1[0] + lp2[0]) >> 1; + new[1] = (lp1[1] + lp2[1]) >> 1; + new[5] = (lp1[5] + lp2[5]) >> 1; + new[2] = (lp1[2] + lp2[2]) >> 1; + new[3] = (lp1[3] + lp2[3]) >> 1; + new[4] = (lp1[4] + lp2[4]) >> 1; + + D_PolysetRecursiveDrawLine (new, lp3); + +// recursively continue + D_PolysetRecursiveTriangle (lp1, new, lp3); + D_PolysetRecursiveTriangle (new, lp2, lp3); +} + +#endif + diff --git a/QW/client/d_scan.c b/QW/client/d_scan.c new file mode 100644 index 0000000..292bb56 --- /dev/null +++ b/QW/client/d_scan.c @@ -0,0 +1,446 @@ +/* +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_scan.c +// +// Portable C scan-level rasterization code, all pixel depths. + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + +unsigned char *r_turb_pbase, *r_turb_pdest; +fixed16_t r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep; +int *r_turb_turb; +int r_turb_spancount; + +void D_DrawTurbulent8Span (void); + + +/* +============= +D_WarpScreen + +// this performs a slight compression of the screen at the same time as +// the sine warp, to keep the edges from wrapping +============= +*/ +void D_WarpScreen (void) +{ + int w, h; + int u,v; + byte *dest; + int *turb; + int *col; + byte **row; + byte *rowptr[1024]; + int column[1280]; + float wratio, hratio; + + w = r_refdef.vrect.width; + h = r_refdef.vrect.height; + + wratio = w / (float)scr_vrect.width; + hratio = h / (float)scr_vrect.height; + + for (v=0 ; v<scr_vrect.height+AMP2*2 ; v++) + { + rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) + + (screenwidth * (int)((float)v * hratio * h / (h + AMP2 * 2))); + } + + for (u=0 ; u<scr_vrect.width+AMP2*2 ; u++) + { + column[u] = r_refdef.vrect.x + + (int)((float)u * wratio * w / (w + AMP2 * 2)); + } + + turb = intsintable + ((int)(cl.time*SPEED)&(CYCLE-1)); + dest = vid.buffer + scr_vrect.y * vid.rowbytes + scr_vrect.x; + + for (v=0 ; v<scr_vrect.height ; v++, dest += vid.rowbytes) + { + col = &column[turb[v]]; + row = &rowptr[v]; + for (u=0 ; u<scr_vrect.width ; u+=4) + { + dest[u+0] = row[turb[u+0]][col[u+0]]; + dest[u+1] = row[turb[u+1]][col[u+1]]; + dest[u+2] = row[turb[u+2]][col[u+2]]; + dest[u+3] = row[turb[u+3]][col[u+3]]; + } + } +} + + +#if !id386 + +/* +============= +D_DrawTurbulent8Span +============= +*/ +void D_DrawTurbulent8Span (void) +{ + int sturb, tturb; + + do + { + sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63; + tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63; + *r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb); + r_turb_s += r_turb_sstep; + r_turb_t += r_turb_tstep; + } while (--r_turb_spancount > 0); +} + +#endif // !id386 + +/* +============= +Turbulent8 +============= +*/ +void Turbulent8 (espan_t *pspan) +{ + int count; + fixed16_t snext, tnext; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz16stepu, tdivz16stepu, zi16stepu; + + r_turb_turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1)); + + r_turb_sstep = 0; // keep compiler happy + r_turb_tstep = 0; // ditto + + r_turb_pbase = (unsigned char *)cacheblock; + + sdivz16stepu = d_sdivzstepu * 16; + tdivz16stepu = d_tdivzstepu * 16; + zi16stepu = d_zistepu * 16; + + do + { + r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer + + (screenwidth * pspan->v) + pspan->u); + + count = pspan->count; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + r_turb_s = (int)(sdivz * z) + sadjust; + if (r_turb_s > bbextents) + r_turb_s = bbextents; + else if (r_turb_s < 0) + r_turb_s = 0; + + r_turb_t = (int)(tdivz * z) + tadjust; + if (r_turb_t > bbextentt) + r_turb_t = bbextentt; + else if (r_turb_t < 0) + r_turb_t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 16) + r_turb_spancount = 16; + else + r_turb_spancount = count; + + count -= r_turb_spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz16stepu; + tdivz += tdivz16stepu; + zi += zi16stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 16) + snext = 16; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 16) + tnext = 16; // guard against round-off error on <0 steps + + r_turb_sstep = (snext - r_turb_s) >> 4; + r_turb_tstep = (tnext - r_turb_t) >> 4; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(r_turb_spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 16) + snext = 16; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 16) + tnext = 16; // guard against round-off error on <0 steps + + if (r_turb_spancount > 1) + { + r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1); + r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1); + } + } + + r_turb_s = r_turb_s & ((CYCLE<<16)-1); + r_turb_t = r_turb_t & ((CYCLE<<16)-1); + + D_DrawTurbulent8Span (); + + r_turb_s = snext; + r_turb_t = tnext; + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + + +#if !id386 + +/* +============= +D_DrawSpans8 +============= +*/ +void D_DrawSpans8 (espan_t *pspan) +{ + int count, spancount; + unsigned char *pbase, *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz8stepu, tdivz8stepu, zi8stepu; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + pbase = (unsigned char *)cacheblock; + + sdivz8stepu = d_sdivzstepu * 8; + tdivz8stepu = d_tdivzstepu * 8; + zi8stepu = d_zistepu * 8; + + do + { + pdest = (unsigned char *)((byte *)d_viewbuffer + + (screenwidth * pspan->v) + pspan->u); + + count = pspan->count; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + s = (int)(sdivz * z) + sadjust; + if (s > bbextents) + s = bbextents; + else if (s < 0) + s = 0; + + t = (int)(tdivz * z) + tadjust; + if (t > bbextentt) + t = bbextentt; + else if (t < 0) + t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 8) + spancount = 8; + else + spancount = count; + + count -= spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz8stepu; + tdivz += tdivz8stepu; + zi += zi8stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + sstep = (snext - s) >> 3; + tstep = (tnext - t) >> 3; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + if (spancount > 1) + { + sstep = (snext - s) / (spancount - 1); + tstep = (tnext - t) / (spancount - 1); + } + } + + do + { + *pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth); + s += sstep; + t += tstep; + } while (--spancount > 0); + + s = snext; + t = tnext; + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + +#endif + + +#if !id386 + +/* +============= +D_DrawZSpans +============= +*/ +void D_DrawZSpans (espan_t *pspan) +{ + int count, doublecount, izistep; + int izi; + short *pdest; + unsigned ltemp; + double zi; + float du, dv; + +// FIXME: check for clamping/range problems +// we count on FP exceptions being turned off to avoid range problems + izistep = (int)(d_zistepu * 0x8000 * 0x10000); + + do + { + pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + + count = pspan->count; + + // calculate the initial 1/z + du = (float)pspan->u; + dv = (float)pspan->v; + + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + // we count on FP exceptions being turned off to avoid range problems + izi = (int)(zi * 0x8000 * 0x10000); + + if ((long)pdest & 0x02) + { + *pdest++ = (short)(izi >> 16); + izi += izistep; + count--; + } + + if ((doublecount = count >> 1) > 0) + { + do + { + ltemp = izi >> 16; + izi += izistep; + ltemp |= izi & 0xFFFF0000; + izi += izistep; + *(int *)pdest = ltemp; + pdest += 2; + } while (--doublecount > 0); + } + + if (count & 1) + *pdest = (short)(izi >> 16); + + } while ((pspan = pspan->pnext) != NULL); +} + +#endif diff --git a/QW/client/d_scana.asm b/QW/client/d_scana.asm new file mode 100644 index 0000000..6cebf09 --- /dev/null +++ b/QW/client/d_scana.asm @@ -0,0 +1,281 @@ + .386P + .model FLAT + externdef _d_zistepu:dword + externdef _d_pzbuffer:dword + externdef _d_zistepv:dword + externdef _d_zrowbytes:dword + externdef _d_ziorigin:dword + externdef _r_turb_s:dword + externdef _r_turb_t:dword + externdef _r_turb_pdest:dword + externdef _r_turb_spancount:dword + externdef _r_turb_turb:dword + externdef _r_turb_pbase:dword + externdef _r_turb_sstep:dword + externdef _r_turb_tstep:dword + externdef _r_bmodelactive:dword + externdef _d_sdivzstepu:dword + externdef _d_tdivzstepu:dword + externdef _d_sdivzstepv:dword + externdef _d_tdivzstepv:dword + externdef _d_sdivzorigin:dword + externdef _d_tdivzorigin:dword + externdef _sadjust:dword + externdef _tadjust:dword + externdef _bbextents:dword + externdef _bbextentt:dword + externdef _cacheblock:dword + externdef _d_viewbuffer:dword + externdef _cachewidth:dword + externdef _d_pzbuffer:dword + externdef _d_zrowbytes:dword + externdef _d_zwidth:dword + externdef _d_scantable:dword + externdef _r_lightptr:dword + externdef _r_numvblocks:dword + externdef _prowdestbase:dword + externdef _pbasesource:dword + externdef _r_lightwidth:dword + externdef _lightright:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _lightdelta:dword + externdef _lightright:dword + externdef _lightdelta:dword + externdef _sourcetstep:dword + externdef _surfrowbytes:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _r_sourcemax:dword + externdef _r_stepback:dword + externdef _colormap:dword + externdef _blocksize:dword + externdef _sourcesstep:dword + externdef _lightleft:dword + externdef _blockdivshift:dword + externdef _blockdivmask:dword + externdef _lightleftstep:dword + externdef _r_origin:dword + externdef _r_ppn:dword + externdef _r_pup:dword + externdef _r_pright:dword + externdef _ycenter:dword + externdef _xcenter:dword + externdef _d_vrectbottom_particle:dword + externdef _d_vrectright_particle:dword + externdef _d_vrecty:dword + externdef _d_vrectx:dword + externdef _d_pix_shift:dword + externdef _d_pix_min:dword + externdef _d_pix_max:dword + externdef _d_y_aspect_shift:dword + externdef _screenwidth:dword + externdef _vright:dword + externdef _vup:dword + externdef _vpn:dword + externdef _BOPS_Error:dword + externdef _snd_scaletable:dword + externdef _paintbuffer:dword + externdef _snd_linear_count:dword + externdef _snd_p:dword + externdef _snd_vol:dword + externdef _snd_out:dword + externdef _r_leftclipped:dword + externdef _r_leftenter:dword + externdef _r_rightclipped:dword + externdef _r_rightenter:dword + externdef _modelorg:dword + externdef _xscale:dword + externdef _r_refdef:dword + externdef _yscale:dword + externdef _r_leftexit:dword + externdef _r_rightexit:dword + externdef _r_lastvertvalid:dword + externdef _cacheoffset:dword + externdef _newedges:dword + externdef _removeedges:dword + externdef _r_pedge:dword + externdef _r_framecount:dword + externdef _r_u1:dword + externdef _r_emitted:dword + externdef _edge_p:dword + externdef _surface_p:dword + externdef _surfaces:dword + externdef _r_lzi1:dword + externdef _r_v1:dword + externdef _r_ceilv1:dword + externdef _r_nearzi:dword + externdef _r_nearzionly:dword + externdef _edge_aftertail:dword + externdef _edge_tail:dword + externdef _current_iv:dword + externdef _edge_head_u_shift20:dword + externdef _span_p:dword + externdef _edge_head:dword + externdef _fv:dword + externdef _edge_tail_u_shift20:dword + externdef _r_apverts:dword + externdef _r_anumverts:dword + externdef _aliastransform:dword + externdef _r_avertexnormals:dword + externdef _r_plightvec:dword + externdef _r_ambientlight:dword + externdef _r_shadelight:dword + externdef _aliasxcenter:dword + externdef _aliasycenter:dword + externdef _a_sstepxfrac:dword + externdef _r_affinetridesc:dword + externdef _acolormap:dword + externdef _d_pcolormap:dword + externdef _r_affinetridesc:dword + externdef _d_sfrac:dword + externdef _d_ptex:dword + externdef _d_pedgespanpackage:dword + externdef _d_tfrac:dword + externdef _d_light:dword + externdef _d_zi:dword + externdef _d_pdest:dword + externdef _d_pz:dword + externdef _d_aspancount:dword + externdef _erroradjustup:dword + externdef _errorterm:dword + externdef _d_xdenom:dword + externdef _r_p0:dword + externdef _r_p1:dword + externdef _r_p2:dword + externdef _a_tstepxfrac:dword + externdef _r_sstepx:dword + externdef _r_tstepx:dword + externdef _a_ststepxwhole:dword + externdef _zspantable:dword + externdef _skintable:dword + externdef _r_zistepx:dword + externdef _erroradjustdown:dword + externdef _d_countextrastep:dword + externdef _ubasestep:dword + externdef _a_ststepxwhole:dword + externdef _a_tstepxfrac:dword + externdef _r_lstepx:dword + externdef _a_spans:dword + externdef _erroradjustdown:dword + externdef _d_pdestextrastep:dword + externdef _d_pzextrastep:dword + externdef _d_sfracextrastep:dword + externdef _d_ptexextrastep:dword + externdef _d_countextrastep:dword + externdef _d_tfracextrastep:dword + externdef _d_lightextrastep:dword + externdef _d_ziextrastep:dword + externdef _d_pdestbasestep:dword + externdef _d_pzbasestep:dword + externdef _d_sfracbasestep:dword + externdef _d_ptexbasestep:dword + externdef _ubasestep:dword + externdef _d_tfracbasestep:dword + externdef _d_lightbasestep:dword + externdef _d_zibasestep:dword + externdef _zspantable:dword + externdef _r_lstepy:dword + externdef _r_sstepy:dword + externdef _r_tstepy:dword + externdef _r_zistepy:dword + externdef _D_PolysetSetEdgeTable:dword + externdef _D_RasterizeAliasPolySmooth:dword + externdef float_point5:dword + externdef Float2ToThe31nd:dword + externdef izistep:dword + externdef izi:dword + externdef FloatMinus2ToThe31nd:dword + externdef float_1:dword + externdef float_particle_z_clip:dword + externdef float_minus_1:dword + externdef float_0:dword + externdef fp_16:dword + externdef fp_64k:dword + externdef fp_1m:dword + externdef fp_1m_minus_1:dword + externdef fp_8:dword + externdef entryvec_table:dword + externdef advancetable:dword + externdef sstep:dword + externdef tstep:dword + externdef pspantemp:dword + externdef counttemp:dword + externdef jumptemp:dword + externdef reciprocal_table:dword + externdef DP_Count:dword + externdef DP_u:dword + externdef DP_v:dword + externdef DP_32768:dword + externdef DP_Color:dword + externdef DP_Pix:dword + externdef DP_EntryTable:dword + externdef pbase:dword + externdef s:dword + externdef t:dword + externdef sfracf:dword + externdef tfracf:dword + externdef snext:dword + externdef tnext:dword + externdef spancountminus1:dword + externdef zi16stepu:dword + externdef sdivz16stepu:dword + externdef tdivz16stepu:dword + externdef zi8stepu:dword + externdef sdivz8stepu:dword + externdef tdivz8stepu:dword + externdef reciprocal_table_16:dword + externdef entryvec_table_16:dword + externdef ceil_cw:dword + externdef single_cw:dword + externdef fp_64kx64k:dword + externdef pz:dword + externdef spr8entryvec_table:dword +_DATA SEGMENT +_DATA ENDS +_TEXT SEGMENT + align 4 + public _D_DrawTurbulent8Span +_D_DrawTurbulent8Span: + push ebp + push esi + push edi + push ebx + mov esi,ds:dword ptr[_r_turb_s] + mov ecx,ds:dword ptr[_r_turb_t] + mov edi,ds:dword ptr[_r_turb_pdest] + mov ebx,ds:dword ptr[_r_turb_spancount] +Llp: + mov eax,ecx + mov edx,esi + sar eax,16 + mov ebp,ds:dword ptr[_r_turb_turb] + sar edx,16 + and eax,128-1 + and edx,128-1 + mov eax,ds:dword ptr[ebp+eax*4] + mov edx,ds:dword ptr[ebp+edx*4] + add eax,esi + sar eax,16 + add edx,ecx + sar edx,16 + and eax,64-1 + and edx,64-1 + shl edx,6 + mov ebp,ds:dword ptr[_r_turb_pbase] + add edx,eax + inc edi + add esi,ds:dword ptr[_r_turb_sstep] + add ecx,ds:dword ptr[_r_turb_tstep] + mov dl,ds:byte ptr[ebp+edx*1] + dec ebx + mov ds:byte ptr[-1+edi],dl + jnz Llp + mov ds:dword ptr[_r_turb_pdest],edi + pop ebx + pop edi + pop esi + pop ebp + ret +_TEXT ENDS + END diff --git a/QW/client/d_scana.s b/QW/client/d_scana.s new file mode 100644 index 0000000..bd4fd74 --- /dev/null +++ b/QW/client/d_scana.s @@ -0,0 +1,89 @@ +/* +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 +// + +#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 + diff --git a/QW/client/d_sky.c b/QW/client/d_sky.c new file mode 100644 index 0000000..2f77d93 --- /dev/null +++ b/QW/client/d_sky.c @@ -0,0 +1,138 @@ +/* +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 *)((byte *)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; + } + } + + 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); +} + diff --git a/QW/client/d_spr8.asm b/QW/client/d_spr8.asm new file mode 100644 index 0000000..fef43d0 --- /dev/null +++ b/QW/client/d_spr8.asm @@ -0,0 +1,886 @@ + .386P + .model FLAT + externdef _d_zistepu:dword + externdef _d_pzbuffer:dword + externdef _d_zistepv:dword + externdef _d_zrowbytes:dword + externdef _d_ziorigin:dword + externdef _r_turb_s:dword + externdef _r_turb_t:dword + externdef _r_turb_pdest:dword + externdef _r_turb_spancount:dword + externdef _r_turb_turb:dword + externdef _r_turb_pbase:dword + externdef _r_turb_sstep:dword + externdef _r_turb_tstep:dword + externdef _r_bmodelactive:dword + externdef _d_sdivzstepu:dword + externdef _d_tdivzstepu:dword + externdef _d_sdivzstepv:dword + externdef _d_tdivzstepv:dword + externdef _d_sdivzorigin:dword + externdef _d_tdivzorigin:dword + externdef _sadjust:dword + externdef _tadjust:dword + externdef _bbextents:dword + externdef _bbextentt:dword + externdef _cacheblock:dword + externdef _d_viewbuffer:dword + externdef _cachewidth:dword + externdef _d_pzbuffer:dword + externdef _d_zrowbytes:dword + externdef _d_zwidth:dword + externdef _d_scantable:dword + externdef _r_lightptr:dword + externdef _r_numvblocks:dword + externdef _prowdestbase:dword + externdef _pbasesource:dword + externdef _r_lightwidth:dword + externdef _lightright:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _lightdelta:dword + externdef _lightright:dword + externdef _lightdelta:dword + externdef _sourcetstep:dword + externdef _surfrowbytes:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _r_sourcemax:dword + externdef _r_stepback:dword + externdef _colormap:dword + externdef _blocksize:dword + externdef _sourcesstep:dword + externdef _lightleft:dword + externdef _blockdivshift:dword + externdef _blockdivmask:dword + externdef _lightleftstep:dword + externdef _r_origin:dword + externdef _r_ppn:dword + externdef _r_pup:dword + externdef _r_pright:dword + externdef _ycenter:dword + externdef _xcenter:dword + externdef _d_vrectbottom_particle:dword + externdef _d_vrectright_particle:dword + externdef _d_vrecty:dword + externdef _d_vrectx:dword + externdef _d_pix_shift:dword + externdef _d_pix_min:dword + externdef _d_pix_max:dword + externdef _d_y_aspect_shift:dword + externdef _screenwidth:dword + externdef _vright:dword + externdef _vup:dword + externdef _vpn:dword + externdef _BOPS_Error:dword + externdef _snd_scaletable:dword + externdef _paintbuffer:dword + externdef _snd_linear_count:dword + externdef _snd_p:dword + externdef _snd_vol:dword + externdef _snd_out:dword + externdef _r_leftclipped:dword + externdef _r_leftenter:dword + externdef _r_rightclipped:dword + externdef _r_rightenter:dword + externdef _modelorg:dword + externdef _xscale:dword + externdef _r_refdef:dword + externdef _yscale:dword + externdef _r_leftexit:dword + externdef _r_rightexit:dword + externdef _r_lastvertvalid:dword + externdef _cacheoffset:dword + externdef _newedges:dword + externdef _removeedges:dword + externdef _r_pedge:dword + externdef _r_framecount:dword + externdef _r_u1:dword + externdef _r_emitted:dword + externdef _edge_p:dword + externdef _surface_p:dword + externdef _surfaces:dword + externdef _r_lzi1:dword + externdef _r_v1:dword + externdef _r_ceilv1:dword + externdef _r_nearzi:dword + externdef _r_nearzionly:dword + externdef _edge_aftertail:dword + externdef _edge_tail:dword + externdef _current_iv:dword + externdef _edge_head_u_shift20:dword + externdef _span_p:dword + externdef _edge_head:dword + externdef _fv:dword + externdef _edge_tail_u_shift20:dword + externdef _r_apverts:dword + externdef _r_anumverts:dword + externdef _aliastransform:dword + externdef _r_avertexnormals:dword + externdef _r_plightvec:dword + externdef _r_ambientlight:dword + externdef _r_shadelight:dword + externdef _aliasxcenter:dword + externdef _aliasycenter:dword + externdef _a_sstepxfrac:dword + externdef _r_affinetridesc:dword + externdef _acolormap:dword + externdef _d_pcolormap:dword + externdef _r_affinetridesc:dword + externdef _d_sfrac:dword + externdef _d_ptex:dword + externdef _d_pedgespanpackage:dword + externdef _d_tfrac:dword + externdef _d_light:dword + externdef _d_zi:dword + externdef _d_pdest:dword + externdef _d_pz:dword + externdef _d_aspancount:dword + externdef _erroradjustup:dword + externdef _errorterm:dword + externdef _d_xdenom:dword + externdef _r_p0:dword + externdef _r_p1:dword + externdef _r_p2:dword + externdef _a_tstepxfrac:dword + externdef _r_sstepx:dword + externdef _r_tstepx:dword + externdef _a_ststepxwhole:dword + externdef _zspantable:dword + externdef _skintable:dword + externdef _r_zistepx:dword + externdef _erroradjustdown:dword + externdef _d_countextrastep:dword + externdef _ubasestep:dword + externdef _a_ststepxwhole:dword + externdef _a_tstepxfrac:dword + externdef _r_lstepx:dword + externdef _a_spans:dword + externdef _erroradjustdown:dword + externdef _d_pdestextrastep:dword + externdef _d_pzextrastep:dword + externdef _d_sfracextrastep:dword + externdef _d_ptexextrastep:dword + externdef _d_countextrastep:dword + externdef _d_tfracextrastep:dword + externdef _d_lightextrastep:dword + externdef _d_ziextrastep:dword + externdef _d_pdestbasestep:dword + externdef _d_pzbasestep:dword + externdef _d_sfracbasestep:dword + externdef _d_ptexbasestep:dword + externdef _ubasestep:dword + externdef _d_tfracbasestep:dword + externdef _d_lightbasestep:dword + externdef _d_zibasestep:dword + externdef _zspantable:dword + externdef _r_lstepy:dword + externdef _r_sstepy:dword + externdef _r_tstepy:dword + externdef _r_zistepy:dword + externdef _D_PolysetSetEdgeTable:dword + externdef _D_RasterizeAliasPolySmooth:dword + externdef float_point5:dword + externdef Float2ToThe31nd:dword + externdef izistep:dword + externdef izi:dword + externdef FloatMinus2ToThe31nd:dword + externdef float_1:dword + externdef float_particle_z_clip:dword + externdef float_minus_1:dword + externdef float_0:dword + externdef fp_16:dword + externdef fp_64k:dword + externdef fp_1m:dword + externdef fp_1m_minus_1:dword + externdef fp_8:dword + externdef entryvec_table:dword + externdef advancetable:dword + externdef sstep:dword + externdef tstep:dword + externdef pspantemp:dword + externdef counttemp:dword + externdef jumptemp:dword + externdef reciprocal_table:dword + externdef DP_Count:dword + externdef DP_u:dword + externdef DP_v:dword + externdef DP_32768:dword + externdef DP_Color:dword + externdef DP_Pix:dword + externdef DP_EntryTable:dword + externdef pbase:dword + externdef s:dword + externdef t:dword + externdef sfracf:dword + externdef tfracf:dword + externdef snext:dword + externdef tnext:dword + externdef spancountminus1:dword + externdef zi16stepu:dword + externdef sdivz16stepu:dword + externdef tdivz16stepu:dword + externdef zi8stepu:dword + externdef sdivz8stepu:dword + externdef tdivz8stepu:dword + externdef reciprocal_table_16:dword + externdef entryvec_table_16:dword + externdef ceil_cw:dword + externdef single_cw:dword + externdef fp_64kx64k:dword + externdef pz:dword + externdef spr8entryvec_table:dword +_TEXT SEGMENT +LClampHigh0: + mov esi,ds:dword ptr[_bbextents] + jmp LClampReentry0 +LClampHighOrLow0: + jg LClampHigh0 + xor esi,esi + jmp LClampReentry0 +LClampHigh1: + mov edx,ds:dword ptr[_bbextentt] + jmp LClampReentry1 +LClampHighOrLow1: + jg LClampHigh1 + xor edx,edx + jmp LClampReentry1 +LClampLow2: + mov ebp,2048 + jmp LClampReentry2 +LClampHigh2: + mov ebp,ds:dword ptr[_bbextents] + jmp LClampReentry2 +LClampLow3: + mov ecx,2048 + jmp LClampReentry3 +LClampHigh3: + mov ecx,ds:dword ptr[_bbextentt] + jmp LClampReentry3 +LClampLow4: + mov eax,2048 + jmp LClampReentry4 +LClampHigh4: + mov eax,ds:dword ptr[_bbextents] + jmp LClampReentry4 +LClampLow5: + mov ebx,2048 + jmp LClampReentry5 +LClampHigh5: + mov ebx,ds:dword ptr[_bbextentt] + jmp LClampReentry5 + align 4 + public _D_SpriteDrawSpans +_D_SpriteDrawSpans: + push ebp + push edi + push esi + push ebx + fld ds:dword ptr[_d_sdivzstepu] + fmul ds:dword ptr[fp_8] + mov edx,ds:dword ptr[_cacheblock] + fld ds:dword ptr[_d_tdivzstepu] + fmul ds:dword ptr[fp_8] + mov ebx,ds:dword ptr[4+16+esp] + fld ds:dword ptr[_d_zistepu] + fmul ds:dword ptr[fp_8] + mov ds:dword ptr[pbase],edx + fld ds:dword ptr[_d_zistepu] + fmul ds:dword ptr[fp_64kx64k] + fxch st(3) + fstp ds:dword ptr[sdivz8stepu] + fstp ds:dword ptr[zi8stepu] + fstp ds:dword ptr[tdivz8stepu] + fistp ds:dword ptr[izistep] + mov eax,ds:dword ptr[izistep] + ror eax,16 + mov ecx,ds:dword ptr[8+ebx] + mov ds:dword ptr[izistep],eax + cmp ecx,0 + jle LNextSpan +LSpanLoop: + fild ds:dword ptr[4+ebx] + fild ds:dword ptr[0+ebx] + fld st(1) + fmul ds:dword ptr[_d_sdivzstepv] + fld st(1) + fmul ds:dword ptr[_d_sdivzstepu] + fld st(2) + fmul ds:dword ptr[_d_tdivzstepu] + fxch st(1) + faddp st(2),st(0) + fxch st(1) + fld st(3) + fmul ds:dword ptr[_d_tdivzstepv] + fxch st(1) + fadd ds:dword ptr[_d_sdivzorigin] + fxch st(4) + fmul ds:dword ptr[_d_zistepv] + fxch st(1) + faddp st(2),st(0) + fxch st(2) + fmul ds:dword ptr[_d_zistepu] + fxch st(1) + fadd ds:dword ptr[_d_tdivzorigin] + fxch st(2) + faddp st(1),st(0) + fld ds:dword ptr[fp_64k] + fxch st(1) + fadd ds:dword ptr[_d_ziorigin] + fld st(0) + fmul ds:dword ptr[fp_64kx64k] + fxch st(1) + fdiv st(2),st(0) + fxch st(1) + fistp ds:dword ptr[izi] + mov ebp,ds:dword ptr[izi] + ror ebp,16 + mov eax,ds:dword ptr[4+ebx] + mov ds:dword ptr[izi],ebp + mov ebp,ds:dword ptr[0+ebx] + imul ds:dword ptr[_d_zrowbytes] + shl ebp,1 + add eax,ds:dword ptr[_d_pzbuffer] + add eax,ebp + mov ds:dword ptr[pz],eax + mov ebp,ds:dword ptr[_d_viewbuffer] + mov eax,ds:dword ptr[4+ebx] + push ebx + mov edx,ds:dword ptr[_tadjust] + mov esi,ds:dword ptr[_sadjust] + mov edi,ds:dword ptr[_d_scantable+eax*4] + add edi,ebp + mov ebp,ds:dword ptr[0+ebx] + add edi,ebp + cmp ecx,8 + ja LSetupNotLast1 + dec ecx + jz LCleanup1 + mov ds:dword ptr[spancountminus1],ecx + fxch st(1) + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[s] + fistp ds:dword ptr[t] + fild ds:dword ptr[spancountminus1] + fld ds:dword ptr[_d_tdivzstepu] + fld ds:dword ptr[_d_zistepu] + fmul st(0),st(2) + fxch st(1) + fmul st(0),st(2) + fxch st(2) + fmul ds:dword ptr[_d_sdivzstepu] + fxch st(1) + faddp st(3),st(0) + fxch st(1) + faddp st(3),st(0) + faddp st(3),st(0) + fld ds:dword ptr[fp_64k] + fdiv st(0),st(1) + jmp LFDIVInFlight1 +LCleanup1: + fxch st(1) + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[s] + fistp ds:dword ptr[t] + jmp LFDIVInFlight1 + align 4 +LSetupNotLast1: + fxch st(1) + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[s] + fistp ds:dword ptr[t] + fadd ds:dword ptr[zi8stepu] + fxch st(2) + fadd ds:dword ptr[sdivz8stepu] + fxch st(2) + fld ds:dword ptr[tdivz8stepu] + faddp st(2),st(0) + fld ds:dword ptr[fp_64k] + fdiv st(0),st(1) +LFDIVInFlight1: + add esi,ds:dword ptr[s] + add edx,ds:dword ptr[t] + mov ebx,ds:dword ptr[_bbextents] + mov ebp,ds:dword ptr[_bbextentt] + cmp esi,ebx + ja LClampHighOrLow0 +LClampReentry0: + mov ds:dword ptr[s],esi + mov ebx,ds:dword ptr[pbase] + shl esi,16 + cmp edx,ebp + mov ds:dword ptr[sfracf],esi + ja LClampHighOrLow1 +LClampReentry1: + mov ds:dword ptr[t],edx + mov esi,ds:dword ptr[s] + shl edx,16 + mov eax,ds:dword ptr[t] + sar esi,16 + mov ds:dword ptr[tfracf],edx + sar eax,16 + add esi,ebx + imul eax,ds:dword ptr[_cachewidth] + add esi,eax + cmp ecx,8 + jna LLastSegment +LNotLastSegment: + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[snext] + fistp ds:dword ptr[tnext] + mov eax,ds:dword ptr[snext] + mov edx,ds:dword ptr[tnext] + sub ecx,8 + mov ebp,ds:dword ptr[_sadjust] + push ecx + mov ecx,ds:dword ptr[_tadjust] + add ebp,eax + add ecx,edx + mov eax,ds:dword ptr[_bbextents] + mov edx,ds:dword ptr[_bbextentt] + cmp ebp,2048 + jl LClampLow2 + cmp ebp,eax + ja LClampHigh2 +LClampReentry2: + cmp ecx,2048 + jl LClampLow3 + cmp ecx,edx + ja LClampHigh3 +LClampReentry3: + mov ds:dword ptr[snext],ebp + mov ds:dword ptr[tnext],ecx + sub ebp,ds:dword ptr[s] + sub ecx,ds:dword ptr[t] + mov eax,ecx + mov edx,ebp + sar edx,19 + mov ebx,ds:dword ptr[_cachewidth] + sar eax,19 + jz LIsZero + imul eax,ebx +LIsZero: + add eax,edx + mov edx,ds:dword ptr[tfracf] + mov ds:dword ptr[advancetable+4],eax + add eax,ebx + shl ebp,13 + mov ds:dword ptr[sstep],ebp + mov ebx,ds:dword ptr[sfracf] + shl ecx,13 + mov ds:dword ptr[advancetable],eax + mov ds:dword ptr[tstep],ecx + mov ecx,ds:dword ptr[pz] + mov ebp,ds:dword ptr[izi] + cmp bp,ds:word ptr[ecx] + jl Lp1 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp1 + mov ds:word ptr[ecx],bp + mov ds:byte ptr[edi],al +Lp1: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] + cmp bp,ds:word ptr[2+ecx] + jl Lp2 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp2 + mov ds:word ptr[2+ecx],bp + mov ds:byte ptr[1+edi],al +Lp2: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] + cmp bp,ds:word ptr[4+ecx] + jl Lp3 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp3 + mov ds:word ptr[4+ecx],bp + mov ds:byte ptr[2+edi],al +Lp3: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] + cmp bp,ds:word ptr[6+ecx] + jl Lp4 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp4 + mov ds:word ptr[6+ecx],bp + mov ds:byte ptr[3+edi],al +Lp4: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] + cmp bp,ds:word ptr[8+ecx] + jl Lp5 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp5 + mov ds:word ptr[8+ecx],bp + mov ds:byte ptr[4+edi],al +Lp5: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] + pop eax + cmp eax,8 + ja LSetupNotLast2 + dec eax + jz LFDIVInFlight2 + mov ds:dword ptr[spancountminus1],eax + fild ds:dword ptr[spancountminus1] + fld ds:dword ptr[_d_zistepu] + fmul st(0),st(1) + fld ds:dword ptr[_d_tdivzstepu] + fmul st(0),st(2) + fxch st(1) + faddp st(3),st(0) + fxch st(1) + fmul ds:dword ptr[_d_sdivzstepu] + fxch st(1) + faddp st(3),st(0) + fld ds:dword ptr[fp_64k] + fxch st(1) + faddp st(4),st(0) + fdiv st(0),st(1) + jmp LFDIVInFlight2 + align 4 +LSetupNotLast2: + fadd ds:dword ptr[zi8stepu] + fxch st(2) + fadd ds:dword ptr[sdivz8stepu] + fxch st(2) + fld ds:dword ptr[tdivz8stepu] + faddp st(2),st(0) + fld ds:dword ptr[fp_64k] + fdiv st(0),st(1) +LFDIVInFlight2: + push eax + cmp bp,ds:word ptr[10+ecx] + jl Lp6 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp6 + mov ds:word ptr[10+ecx],bp + mov ds:byte ptr[5+edi],al +Lp6: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] + cmp bp,ds:word ptr[12+ecx] + jl Lp7 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp7 + mov ds:word ptr[12+ecx],bp + mov ds:byte ptr[6+edi],al +Lp7: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] + cmp bp,ds:word ptr[14+ecx] + jl Lp8 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp8 + mov ds:word ptr[14+ecx],bp + mov ds:byte ptr[7+edi],al +Lp8: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] + add edi,8 + add ecx,16 + mov ds:dword ptr[tfracf],edx + mov edx,ds:dword ptr[snext] + mov ds:dword ptr[sfracf],ebx + mov ebx,ds:dword ptr[tnext] + mov ds:dword ptr[s],edx + mov ds:dword ptr[t],ebx + mov ds:dword ptr[pz],ecx + mov ds:dword ptr[izi],ebp + pop ecx + cmp ecx,8 + ja LNotLastSegment +LLastSegment: + test ecx,ecx + jz LNoSteps + fld st(0) + fmul st(0),st(4) + fxch st(1) + fmul st(0),st(3) + fxch st(1) + fistp ds:dword ptr[snext] + fistp ds:dword ptr[tnext] + mov ebx,ds:dword ptr[_tadjust] + mov eax,ds:dword ptr[_sadjust] + add eax,ds:dword ptr[snext] + add ebx,ds:dword ptr[tnext] + mov ebp,ds:dword ptr[_bbextents] + mov edx,ds:dword ptr[_bbextentt] + cmp eax,2048 + jl LClampLow4 + cmp eax,ebp + ja LClampHigh4 +LClampReentry4: + mov ds:dword ptr[snext],eax + cmp ebx,2048 + jl LClampLow5 + cmp ebx,edx + ja LClampHigh5 +LClampReentry5: + cmp ecx,1 + je LOnlyOneStep + sub eax,ds:dword ptr[s] + sub ebx,ds:dword ptr[t] + add eax,eax + add ebx,ebx + imul ds:dword ptr[reciprocal_table-8+ecx*4] + mov ebp,edx + mov eax,ebx + imul ds:dword ptr[reciprocal_table-8+ecx*4] +LSetEntryvec: + mov ebx,ds:dword ptr[spr8entryvec_table+ecx*4] + mov eax,edx + push ebx + mov ecx,ebp + sar ecx,16 + mov ebx,ds:dword ptr[_cachewidth] + sar edx,16 + jz LIsZeroLast + imul edx,ebx +LIsZeroLast: + add edx,ecx + mov ecx,ds:dword ptr[tfracf] + mov ds:dword ptr[advancetable+4],edx + add edx,ebx + shl ebp,16 + mov ebx,ds:dword ptr[sfracf] + shl eax,16 + mov ds:dword ptr[advancetable],edx + mov ds:dword ptr[tstep],eax + mov ds:dword ptr[sstep],ebp + mov edx,ecx + mov ecx,ds:dword ptr[pz] + mov ebp,ds:dword ptr[izi] + ret +LNoSteps: + mov ecx,ds:dword ptr[pz] + sub edi,7 + sub ecx,14 + jmp LEndSpan +LOnlyOneStep: + sub eax,ds:dword ptr[s] + sub ebx,ds:dword ptr[t] + mov ebp,eax + mov edx,ebx + jmp LSetEntryvec + public Spr8Entry2_8 +Spr8Entry2_8: + sub edi,6 + sub ecx,12 + mov al,ds:byte ptr[esi] + jmp LLEntry2_8 + public Spr8Entry3_8 +Spr8Entry3_8: + sub edi,5 + sub ecx,10 + jmp LLEntry3_8 + public Spr8Entry4_8 +Spr8Entry4_8: + sub edi,4 + sub ecx,8 + jmp LLEntry4_8 + public Spr8Entry5_8 +Spr8Entry5_8: + sub edi,3 + sub ecx,6 + jmp LLEntry5_8 + public Spr8Entry6_8 +Spr8Entry6_8: + sub edi,2 + sub ecx,4 + jmp LLEntry6_8 + public Spr8Entry7_8 +Spr8Entry7_8: + dec edi + sub ecx,2 + jmp LLEntry7_8 + public Spr8Entry8_8 +Spr8Entry8_8: + cmp bp,ds:word ptr[ecx] + jl Lp9 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp9 + mov ds:word ptr[ecx],bp + mov ds:byte ptr[edi],al +Lp9: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LLEntry7_8: + cmp bp,ds:word ptr[2+ecx] + jl Lp10 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp10 + mov ds:word ptr[2+ecx],bp + mov ds:byte ptr[1+edi],al +Lp10: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LLEntry6_8: + cmp bp,ds:word ptr[4+ecx] + jl Lp11 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp11 + mov ds:word ptr[4+ecx],bp + mov ds:byte ptr[2+edi],al +Lp11: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LLEntry5_8: + cmp bp,ds:word ptr[6+ecx] + jl Lp12 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp12 + mov ds:word ptr[6+ecx],bp + mov ds:byte ptr[3+edi],al +Lp12: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LLEntry4_8: + cmp bp,ds:word ptr[8+ecx] + jl Lp13 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp13 + mov ds:word ptr[8+ecx],bp + mov ds:byte ptr[4+edi],al +Lp13: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LLEntry3_8: + cmp bp,ds:word ptr[10+ecx] + jl Lp14 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp14 + mov ds:word ptr[10+ecx],bp + mov ds:byte ptr[5+edi],al +Lp14: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LLEntry2_8: + cmp bp,ds:word ptr[12+ecx] + jl Lp15 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp15 + mov ds:word ptr[12+ecx],bp + mov ds:byte ptr[6+edi],al +Lp15: + add ebp,ds:dword ptr[izistep] + adc ebp,0 + add edx,ds:dword ptr[tstep] + sbb eax,eax + add ebx,ds:dword ptr[sstep] + adc esi,ds:dword ptr[advancetable+4+eax*4] +LEndSpan: + cmp bp,ds:word ptr[14+ecx] + jl Lp16 + mov al,ds:byte ptr[esi] + cmp al,255 + jz Lp16 + mov ds:word ptr[14+ecx],bp + mov ds:byte ptr[7+edi],al +Lp16: + fstp st(0) + fstp st(0) + fstp st(0) + pop ebx +LNextSpan: + add ebx,12 + mov ecx,ds:dword ptr[8+ebx] + cmp ecx,0 + jg LSpanLoop + jz LNextSpan + pop ebx + pop esi + pop edi + pop ebp + ret +_TEXT ENDS + END diff --git a/QW/client/d_spr8.s b/QW/client/d_spr8.s new file mode 100644 index 0000000..a8d9845 --- /dev/null +++ b/QW/client/d_spr8.s @@ -0,0 +1,900 @@ +/* +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. +// + +#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 diff --git a/QW/client/d_sprite.c b/QW/client/d_sprite.c new file mode 100644 index 0000000..2f02ad2 --- /dev/null +++ b/QW/client/d_sprite.c @@ -0,0 +1,442 @@ +/* +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_sprite.c: software top-level rasterization driver module for drawing +// sprites + +#include "quakedef.h" +#include "d_local.h" + +static int sprite_height; +static int minindex, maxindex; +static sspan_t *sprite_spans; + +#if !id386 + +/* +===================== +D_SpriteDrawSpans +===================== +*/ +void D_SpriteDrawSpans (sspan_t *pspan) +{ + int count, spancount, izistep; + int izi; + byte *pbase, *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz8stepu, tdivz8stepu, zi8stepu; + byte btemp; + short *pz; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + pbase = cacheblock; + + sdivz8stepu = d_sdivzstepu * 8; + tdivz8stepu = d_tdivzstepu * 8; + zi8stepu = d_zistepu * 8; + +// we count on FP exceptions being turned off to avoid range problems + izistep = (int)(d_zistepu * 0x8000 * 0x10000); + + do + { + pdest = (byte *)d_viewbuffer + (screenwidth * pspan->v) + pspan->u; + pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + + count = pspan->count; + + if (count <= 0) + goto NextSpan; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + // we count on FP exceptions being turned off to avoid range problems + izi = (int)(zi * 0x8000 * 0x10000); + + s = (int)(sdivz * z) + sadjust; + if (s > bbextents) + s = bbextents; + else if (s < 0) + s = 0; + + t = (int)(tdivz * z) + tadjust; + if (t > bbextentt) + t = bbextentt; + else if (t < 0) + t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 8) + spancount = 8; + else + spancount = count; + + count -= spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz8stepu; + tdivz += tdivz8stepu; + zi += zi8stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + sstep = (snext - s) >> 3; + tstep = (tnext - t) >> 3; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + if (spancount > 1) + { + sstep = (snext - s) / (spancount - 1); + tstep = (tnext - t) / (spancount - 1); + } + } + + do + { + btemp = *(pbase + (s >> 16) + (t >> 16) * cachewidth); + if (btemp != 255) + { + if (*pz <= (izi >> 16)) + { + *pz = izi >> 16; + *pdest = btemp; + } + } + + izi += izistep; + pdest++; + pz++; + s += sstep; + t += tstep; + } while (--spancount > 0); + + s = snext; + t = tnext; + + } while (count > 0); + +NextSpan: + pspan++; + + } while (pspan->count != DS_SPAN_LIST_END); +} + +#endif + + +/* +===================== +D_SpriteScanLeftEdge +===================== +*/ +void D_SpriteScanLeftEdge (void) +{ + int i, v, itop, ibottom, lmaxindex; + emitpoint_t *pvert, *pnext; + sspan_t *pspan; + float du, dv, vtop, vbottom, slope; + fixed16_t u, u_step; + + pspan = sprite_spans; + i = minindex; + if (i == 0) + i = r_spritedesc.nump; + + lmaxindex = maxindex; + if (lmaxindex == 0) + lmaxindex = r_spritedesc.nump; + + vtop = ceil (r_spritedesc.pverts[i].v); + + do + { + pvert = &r_spritedesc.pverts[i]; + pnext = pvert - 1; + + vbottom = ceil (pnext->v); + + if (vtop < vbottom) + { + du = pnext->u - pvert->u; + dv = pnext->v - pvert->v; + slope = du / dv; + u_step = (int)(slope * 0x10000); + // adjust u to ceil the integer portion + u = (int)((pvert->u + (slope * (vtop - pvert->v))) * 0x10000) + + (0x10000 - 1); + itop = (int)vtop; + ibottom = (int)vbottom; + + for (v=itop ; v<ibottom ; v++) + { + pspan->u = u >> 16; + pspan->v = v; + u += u_step; + pspan++; + } + } + + vtop = vbottom; + + i--; + if (i == 0) + i = r_spritedesc.nump; + + } while (i != lmaxindex); +} + + +/* +===================== +D_SpriteScanRightEdge +===================== +*/ +void D_SpriteScanRightEdge (void) +{ + int i, v, itop, ibottom; + emitpoint_t *pvert, *pnext; + sspan_t *pspan; + float du, dv, vtop, vbottom, slope, uvert, unext, vvert, vnext; + fixed16_t u, u_step; + + pspan = sprite_spans; + i = minindex; + + vvert = r_spritedesc.pverts[i].v; + if (vvert < r_refdef.fvrecty_adj) + vvert = r_refdef.fvrecty_adj; + if (vvert > r_refdef.fvrectbottom_adj) + vvert = r_refdef.fvrectbottom_adj; + + vtop = ceil (vvert); + + do + { + pvert = &r_spritedesc.pverts[i]; + pnext = pvert + 1; + + vnext = pnext->v; + if (vnext < r_refdef.fvrecty_adj) + vnext = r_refdef.fvrecty_adj; + if (vnext > r_refdef.fvrectbottom_adj) + vnext = r_refdef.fvrectbottom_adj; + + vbottom = ceil (vnext); + + if (vtop < vbottom) + { + uvert = pvert->u; + if (uvert < r_refdef.fvrectx_adj) + uvert = r_refdef.fvrectx_adj; + if (uvert > r_refdef.fvrectright_adj) + uvert = r_refdef.fvrectright_adj; + + unext = pnext->u; + if (unext < r_refdef.fvrectx_adj) + unext = r_refdef.fvrectx_adj; + if (unext > r_refdef.fvrectright_adj) + unext = r_refdef.fvrectright_adj; + + du = unext - uvert; + dv = vnext - vvert; + slope = du / dv; + u_step = (int)(slope * 0x10000); + // adjust u to ceil the integer portion + u = (int)((uvert + (slope * (vtop - vvert))) * 0x10000) + + (0x10000 - 1); + itop = (int)vtop; + ibottom = (int)vbottom; + + for (v=itop ; v<ibottom ; v++) + { + pspan->count = (u >> 16) - pspan->u; + u += u_step; + pspan++; + } + } + + vtop = vbottom; + vvert = vnext; + + i++; + if (i == r_spritedesc.nump) + i = 0; + + } while (i != maxindex); + + pspan->count = DS_SPAN_LIST_END; // mark the end of the span list +} + + +/* +===================== +D_SpriteCalculateGradients +===================== +*/ +void D_SpriteCalculateGradients (void) +{ + vec3_t p_normal, p_saxis, p_taxis, p_temp1; + float distinv; + + TransformVector (r_spritedesc.vpn, p_normal); + TransformVector (r_spritedesc.vright, p_saxis); + TransformVector (r_spritedesc.vup, p_taxis); + VectorInverse (p_taxis); + + distinv = 1.0 / (-DotProduct (modelorg, r_spritedesc.vpn)); + + d_sdivzstepu = p_saxis[0] * xscaleinv; + d_tdivzstepu = p_taxis[0] * xscaleinv; + + d_sdivzstepv = -p_saxis[1] * yscaleinv; + d_tdivzstepv = -p_taxis[1] * yscaleinv; + + d_zistepu = p_normal[0] * xscaleinv * distinv; + d_zistepv = -p_normal[1] * yscaleinv * distinv; + + d_sdivzorigin = p_saxis[2] - xcenter * d_sdivzstepu - + ycenter * d_sdivzstepv; + d_tdivzorigin = p_taxis[2] - xcenter * d_tdivzstepu - + ycenter * d_tdivzstepv; + d_ziorigin = p_normal[2] * distinv - xcenter * d_zistepu - + ycenter * d_zistepv; + + TransformVector (modelorg, p_temp1); + + sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) - + (-(cachewidth >> 1) << 16); + tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) - + (-(sprite_height >> 1) << 16); + +// -1 (-epsilon) so we never wander off the edge of the texture + bbextents = (cachewidth << 16) - 1; + bbextentt = (sprite_height << 16) - 1; +} + + +/* +===================== +D_DrawSprite +===================== +*/ +void D_DrawSprite (void) +{ + int i, nump; + float ymin, ymax; + emitpoint_t *pverts; + sspan_t spans[MAXHEIGHT+1]; + + sprite_spans = spans; + +// find the top and bottom vertices, and make sure there's at least one scan to +// draw + ymin = 999999.9; + ymax = -999999.9; + pverts = r_spritedesc.pverts; + + for (i=0 ; i<r_spritedesc.nump ; i++) + { + if (pverts->v < ymin) + { + ymin = pverts->v; + minindex = i; + } + + if (pverts->v > ymax) + { + ymax = pverts->v; + maxindex = i; + } + + pverts++; + } + + ymin = ceil (ymin); + ymax = ceil (ymax); + + if (ymin >= ymax) + return; // doesn't cross any scans at all + + cachewidth = r_spritedesc.pspriteframe->width; + sprite_height = r_spritedesc.pspriteframe->height; + cacheblock = (byte *)&r_spritedesc.pspriteframe->pixels[0]; + +// copy the first vertex to the last vertex, so we don't have to deal with +// wrapping + nump = r_spritedesc.nump; + pverts = r_spritedesc.pverts; + pverts[nump] = pverts[0]; + + D_SpriteCalculateGradients (); + D_SpriteScanLeftEdge (); + D_SpriteScanRightEdge (); + D_SpriteDrawSpans (sprite_spans); +} + diff --git a/QW/client/d_surf.c b/QW/client/d_surf.c new file mode 100644 index 0000000..6d8d1f7 --- /dev/null +++ b/QW/client/d_surf.c @@ -0,0 +1,338 @@ +/* +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 sc_size; +surfcache_t *sc_rover, *sc_base; + +#define GUARDSIZE 4 + + +int D_SurfaceCacheForRes (int width, int height) +{ + int size, pix; + + if (COM_CheckParm ("-surfcachesize")) + { + size = Q_atoi(com_argv[COM_CheckParm("-surfcachesize")+1]) * 1024; + return size; + } + + size = SURFCACHE_SIZE_AT_320X200; + + pix = width*height; + if (pix > 64000) + size += (pix-64000)*3; + + + return size; +} + +void D_CheckCacheGuard (void) +{ + byte *s; + int i; + + s = (byte *)sc_base + sc_size; + for (i=0 ; i<GUARDSIZE ; i++) + if (s[i] != (byte)i) + Sys_Error ("D_CheckCacheGuard: failed"); +} + +void D_ClearCacheGuard (void) +{ + byte *s; + int i; + + s = (byte *)sc_base + sc_size; + for (i=0 ; i<GUARDSIZE ; i++) + s[i] = (byte)i; +} + + +/* +================ +D_InitCaches + +================ +*/ +void D_InitCaches (void *buffer, int size) +{ +// if (!msg_suppress_1) +// Con_Printf ("%ik 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 size) +{ + surfcache_t *new; + qboolean wrapped_this_time; + + if ((width < 0) || (width > 256)) + Sys_Error ("D_SCAlloc: bad cache width %d\n", width); + + if ((size <= 0) || (size > 0x10000)) + 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 || (byte *)sc_rover - (byte *)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 + new = sc_rover; + if (sc_rover->owner) + *sc_rover->owner = NULL; + + while (new->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; + + new->size += sc_rover->size; + new->next = sc_rover->next; + } + +// create a fragment out of any leftovers + if (new->size - size > 256) + { + sc_rover = (surfcache_t *)( (byte *)new + size); + sc_rover->size = new->size - size; + sc_rover->next = new->next; + sc_rover->width = 0; + sc_rover->owner = NULL; + new->next = sc_rover; + new->size = size; + } + else + sc_rover = new->next; + + new->width = width; +// DEBUG + if (width > 0) + new->height = (size - sizeof(*new) + sizeof(new->data)) / width; + + new->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 new; +} + + +/* +================= +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"); + printf ("%p : %i bytes %i width\n",test, test->size, test->width); + } +} + +//============================================================================= + +// if the num is not a power of 2, assume it will not repeat + +int MaskForNum (int num) +{ + if (num==128) + return 127; + if (num==64) + return 63; + if (num==32) + return 31; + if (num==16) + return 15; + return 255; +} + +int D_log2 (int num) +{ + int c; + + c = 0; + + while (num>>=1) + c++; + return c; +} + +//============================================================================= + +/* +================ +D_CacheSurface +================ +*/ +surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel) +{ + surfcache_t *cache; + +// +// if the surface is animating or flashing, flush the cache +// + r_drawsurf.texture = R_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->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; + +// +// allocate memory if needed +// + if (!cache) // if a texture just animated, don't reallocate it + { + cache = D_SCAlloc (r_drawsurf.surfwidth, + r_drawsurf.surfwidth * r_drawsurf.surfheight); + surface->cachespots[miplevel] = cache; + cache->owner = &surface->cachespots[miplevel]; + cache->mipscale = surfscale; + } + + if (surface->dlightframe == r_framecount) + cache->dlight = 1; + else + cache->dlight = 0; + + 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++; + R_DrawSurface (); + + return surface->cachespots[miplevel]; +} + + diff --git a/QW/client/d_vars.c b/QW/client/d_vars.c new file mode 100644 index 0000000..9c9805d --- /dev/null +++ b/QW/client/d_vars.c @@ -0,0 +1,50 @@ +/* +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 + +#if !id386 + +#include "quakedef.h" + +// 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; +pixel_t *d_viewbuffer; +short *d_pzbuffer; +unsigned int d_zrowbytes; +unsigned int d_zwidth; + +#endif // !id386 + diff --git a/QW/client/d_varsa.asm b/QW/client/d_varsa.asm new file mode 100644 index 0000000..b8ce189 --- /dev/null +++ b/QW/client/d_varsa.asm @@ -0,0 +1,362 @@ + .386P + .model FLAT + externdef _d_zistepu:dword + externdef _d_pzbuffer:dword + externdef _d_zistepv:dword + externdef _d_zrowbytes:dword + externdef _d_ziorigin:dword + externdef _r_turb_s:dword + externdef _r_turb_t:dword + externdef _r_turb_pdest:dword + externdef _r_turb_spancount:dword + externdef _r_turb_turb:dword + externdef _r_turb_pbase:dword + externdef _r_turb_sstep:dword + externdef _r_turb_tstep:dword + externdef _r_bmodelactive:dword + externdef _d_sdivzstepu:dword + externdef _d_tdivzstepu:dword + externdef _d_sdivzstepv:dword + externdef _d_tdivzstepv:dword + externdef _d_sdivzorigin:dword + externdef _d_tdivzorigin:dword + externdef _sadjust:dword + externdef _tadjust:dword + externdef _bbextents:dword + externdef _bbextentt:dword + externdef _cacheblock:dword + externdef _d_viewbuffer:dword + externdef _cachewidth:dword + externdef _d_pzbuffer:dword + externdef _d_zrowbytes:dword + externdef _d_zwidth:dword + externdef _d_scantable:dword + externdef _r_lightptr:dword + externdef _r_numvblocks:dword + externdef _prowdestbase:dword + externdef _pbasesource:dword + externdef _r_lightwidth:dword + externdef _lightright:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _lightdelta:dword + externdef _lightright:dword + externdef _lightdelta:dword + externdef _sourcetstep:dword + externdef _surfrowbytes:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _r_sourcemax:dword + externdef _r_stepback:dword + externdef _colormap:dword + externdef _blocksize:dword + externdef _sourcesstep:dword + externdef _lightleft:dword + externdef _blockdivshift:dword + externdef _blockdivmask:dword + externdef _lightleftstep:dword + externdef _r_origin:dword + externdef _r_ppn:dword + externdef _r_pup:dword + externdef _r_pright:dword + externdef _ycenter:dword + externdef _xcenter:dword + externdef _d_vrectbottom_particle:dword + externdef _d_vrectright_particle:dword + externdef _d_vrecty:dword + externdef _d_vrectx:dword + externdef _d_pix_shift:dword + externdef _d_pix_min:dword + externdef _d_pix_max:dword + externdef _d_y_aspect_shift:dword + externdef _screenwidth:dword + externdef _vright:dword + externdef _vup:dword + externdef _vpn:dword + externdef _BOPS_Error:dword + externdef _snd_scaletable:dword + externdef _paintbuffer:dword + externdef _snd_linear_count:dword + externdef _snd_p:dword + externdef _snd_vol:dword + externdef _snd_out:dword + externdef _r_leftclipped:dword + externdef _r_leftenter:dword + externdef _r_rightclipped:dword + externdef _r_rightenter:dword + externdef _modelorg:dword + externdef _xscale:dword + externdef _r_refdef:dword + externdef _yscale:dword + externdef _r_leftexit:dword + externdef _r_rightexit:dword + externdef _r_lastvertvalid:dword + externdef _cacheoffset:dword + externdef _newedges:dword + externdef _removeedges:dword + externdef _r_pedge:dword + externdef _r_framecount:dword + externdef _r_u1:dword + externdef _r_emitted:dword + externdef _edge_p:dword + externdef _surface_p:dword + externdef _surfaces:dword + externdef _r_lzi1:dword + externdef _r_v1:dword + externdef _r_ceilv1:dword + externdef _r_nearzi:dword + externdef _r_nearzionly:dword + externdef _edge_aftertail:dword + externdef _edge_tail:dword + externdef _current_iv:dword + externdef _edge_head_u_shift20:dword + externdef _span_p:dword + externdef _edge_head:dword + externdef _fv:dword + externdef _edge_tail_u_shift20:dword + externdef _r_apverts:dword + externdef _r_anumverts:dword + externdef _aliastransform:dword + externdef _r_avertexnormals:dword + externdef _r_plightvec:dword + externdef _r_ambientlight:dword + externdef _r_shadelight:dword + externdef _aliasxcenter:dword + externdef _aliasycenter:dword + externdef _a_sstepxfrac:dword + externdef _r_affinetridesc:dword + externdef _acolormap:dword + externdef _d_pcolormap:dword + externdef _r_affinetridesc:dword + externdef _d_sfrac:dword + externdef _d_ptex:dword + externdef _d_pedgespanpackage:dword + externdef _d_tfrac:dword + externdef _d_light:dword + externdef _d_zi:dword + externdef _d_pdest:dword + externdef _d_pz:dword + externdef _d_aspancount:dword + externdef _erroradjustup:dword + externdef _errorterm:dword + externdef _d_xdenom:dword + externdef _r_p0:dword + externdef _r_p1:dword + externdef _r_p2:dword + externdef _a_tstepxfrac:dword + externdef _r_sstepx:dword + externdef _r_tstepx:dword + externdef _a_ststepxwhole:dword + externdef _zspantable:dword + externdef _skintable:dword + externdef _r_zistepx:dword + externdef _erroradjustdown:dword + externdef _d_countextrastep:dword + externdef _ubasestep:dword + externdef _a_ststepxwhole:dword + externdef _a_tstepxfrac:dword + externdef _r_lstepx:dword + externdef _a_spans:dword + externdef _erroradjustdown:dword + externdef _d_pdestextrastep:dword + externdef _d_pzextrastep:dword + externdef _d_sfracextrastep:dword + externdef _d_ptexextrastep:dword + externdef _d_countextrastep:dword + externdef _d_tfracextrastep:dword + externdef _d_lightextrastep:dword + externdef _d_ziextrastep:dword + externdef _d_pdestbasestep:dword + externdef _d_pzbasestep:dword + externdef _d_sfracbasestep:dword + externdef _d_ptexbasestep:dword + externdef _ubasestep:dword + externdef _d_tfracbasestep:dword + externdef _d_lightbasestep:dword + externdef _d_zibasestep:dword + externdef _zspantable:dword + externdef _r_lstepy:dword + externdef _r_sstepy:dword + externdef _r_tstepy:dword + externdef _r_zistepy:dword + externdef _D_PolysetSetEdgeTable:dword + externdef _D_RasterizeAliasPolySmooth:dword + externdef float_point5:dword + externdef Float2ToThe31nd:dword + externdef izistep:dword + externdef izi:dword + externdef FloatMinus2ToThe31nd:dword + externdef float_1:dword + externdef float_particle_z_clip:dword + externdef float_minus_1:dword + externdef float_0:dword + externdef fp_16:dword + externdef fp_64k:dword + externdef fp_1m:dword + externdef fp_1m_minus_1:dword + externdef fp_8:dword + externdef entryvec_table:dword + externdef advancetable:dword + externdef sstep:dword + externdef tstep:dword + externdef pspantemp:dword + externdef counttemp:dword + externdef jumptemp:dword + externdef reciprocal_table:dword + externdef DP_Count:dword + externdef DP_u:dword + externdef DP_v:dword + externdef DP_32768:dword + externdef DP_Color:dword + externdef DP_Pix:dword + externdef DP_EntryTable:dword + externdef pbase:dword + externdef s:dword + externdef t:dword + externdef sfracf:dword + externdef tfracf:dword + externdef snext:dword + externdef tnext:dword + externdef spancountminus1:dword + externdef zi16stepu:dword + externdef sdivz16stepu:dword + externdef tdivz16stepu:dword + externdef zi8stepu:dword + externdef sdivz8stepu:dword + externdef tdivz8stepu:dword + externdef reciprocal_table_16:dword + externdef entryvec_table_16:dword + externdef ceil_cw:dword + externdef single_cw:dword + externdef fp_64kx64k:dword + externdef pz:dword + externdef spr8entryvec_table:dword +_DATA SEGMENT + align 4 + public _d_sdivzstepu + public _d_tdivzstepu + public _d_zistepu + public _d_sdivzstepv + public _d_tdivzstepv + public _d_zistepv + public _d_sdivzorigin + public _d_tdivzorigin + public _d_ziorigin +_d_sdivzstepu dd 0 +_d_tdivzstepu dd 0 +_d_zistepu dd 0 +_d_sdivzstepv dd 0 +_d_tdivzstepv dd 0 +_d_zistepv dd 0 +_d_sdivzorigin dd 0 +_d_tdivzorigin dd 0 +_d_ziorigin dd 0 + public _sadjust + public _tadjust + public _bbextents + public _bbextentt +_sadjust dd 0 +_tadjust dd 0 +_bbextents dd 0 +_bbextentt dd 0 + public _cacheblock + public _d_viewbuffer + public _cachewidth + public _d_pzbuffer + public _d_zrowbytes + public _d_zwidth +_cacheblock dd 0 +_cachewidth dd 0 +_d_viewbuffer dd 0 +_d_pzbuffer dd 0 +_d_zrowbytes dd 0 +_d_zwidth dd 0 + public izi +izi dd 0 + public pbase, s, t, sfracf, tfracf, snext, tnext + public spancountminus1, zi16stepu, sdivz16stepu, tdivz16stepu + public zi8stepu, sdivz8stepu, tdivz8stepu, pz +s dd 0 +t dd 0 +snext dd 0 +tnext dd 0 +sfracf dd 0 +tfracf dd 0 +pbase dd 0 +zi8stepu dd 0 +sdivz8stepu dd 0 +tdivz8stepu dd 0 +zi16stepu dd 0 +sdivz16stepu dd 0 +tdivz16stepu dd 0 +spancountminus1 dd 0 +pz dd 0 + public izistep +izistep dd 0 + public reciprocal_table_16, entryvec_table_16 +reciprocal_table_16 dd 040000000h, 02aaaaaaah, 020000000h + dd 019999999h, 015555555h, 012492492h + dd 010000000h, 0e38e38eh, 0ccccccch, 0ba2e8bah + dd 0aaaaaaah, 09d89d89h, 09249249h, 08888888h + externdef Entry2_16:dword + externdef Entry3_16:dword + externdef Entry4_16:dword + externdef Entry5_16:dword + externdef Entry6_16:dword + externdef Entry7_16:dword + externdef Entry8_16:dword + externdef Entry9_16:dword + externdef Entry10_16:dword + externdef Entry11_16:dword + externdef Entry12_16:dword + externdef Entry13_16:dword + externdef Entry14_16:dword + externdef Entry15_16:dword + externdef Entry16_16:dword +entryvec_table_16 dd 0, Entry2_16, Entry3_16, Entry4_16 + dd Entry5_16, Entry6_16, Entry7_16, Entry8_16 + dd Entry9_16, Entry10_16, Entry11_16, Entry12_16 + dd Entry13_16, Entry14_16, Entry15_16, Entry16_16 + public DP_Count, DP_u, DP_v, DP_32768, DP_Color, DP_Pix, DP_EntryTable +DP_Count dd 0 +DP_u dd 0 +DP_v dd 0 +DP_32768 dd 32768.0 +DP_Color dd 0 +DP_Pix dd 0 + externdef DP_1x1:dword + externdef DP_2x2:dword + externdef DP_3x3:dword + externdef DP_4x4:dword +DP_EntryTable dd DP_1x1, DP_2x2, DP_3x3, DP_4x4 + public advancetable, sstep, tstep, pspantemp, counttemp, jumptemp +advancetable dd 0, 0 +sstep dd 0 +tstep dd 0 +pspantemp dd 0 +counttemp dd 0 +jumptemp dd 0 + public reciprocal_table, entryvec_table +reciprocal_table dd 040000000h, 02aaaaaaah, 020000000h + dd 019999999h, 015555555h, 012492492h + externdef Entry2_8:dword + externdef Entry3_8:dword + externdef Entry4_8:dword + externdef Entry5_8:dword + externdef Entry6_8:dword + externdef Entry7_8:dword + externdef Entry8_8:dword +entryvec_table dd 0, Entry2_8, Entry3_8, Entry4_8 + dd Entry5_8, Entry6_8, Entry7_8, Entry8_8 + externdef Spr8Entry2_8:dword + externdef Spr8Entry3_8:dword + externdef Spr8Entry4_8:dword + externdef Spr8Entry5_8:dword + externdef Spr8Entry6_8:dword + externdef Spr8Entry7_8:dword + externdef Spr8Entry8_8:dword + public spr8entryvec_table +spr8entryvec_table dd 0, Spr8Entry2_8, Spr8Entry3_8, Spr8Entry4_8 + dd Spr8Entry5_8, Spr8Entry6_8, Spr8Entry7_8, Spr8Entry8_8 +_DATA ENDS + END diff --git a/QW/client/d_varsa.s b/QW/client/d_varsa.s new file mode 100644 index 0000000..537c6b4 --- /dev/null +++ b/QW/client/d_varsa.s @@ -0,0 +1,213 @@ +/* +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_32768, DP_Color, DP_Pix, DP_EntryTable +DP_Count: .long 0 +DP_u: .long 0 +DP_v: .long 0 +DP_32768: .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 + diff --git a/QW/client/d_zpoint.c b/QW/client/d_zpoint.c new file mode 100644 index 0000000..909f250 --- /dev/null +++ b/QW/client/d_zpoint.c @@ -0,0 +1,47 @@ +/* +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) +{ + byte *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; + } +} + diff --git a/QW/client/docs.txt b/QW/client/docs.txt new file mode 100644 index 0000000..808cf6a --- /dev/null +++ b/QW/client/docs.txt @@ -0,0 +1,118 @@ + +The QuakeWorld connection process: +--------------------------------- + +servercount +Each time a server changes maps, it will bump the servercount variable. The signon +messages sent from the client to the server will include a servercount, and if the +server detects that it has changed levels while the client is in the process of +connecting, the client connection process will be restarted. + +svc_skinlist + +MAX_SIGNON_BUFFERS... + ++attack;wait : this both does the attack and prints a chat? + +put frag counts in userinfo as *frags? + +no forward to server commands unless active? + +changelevel / reconnect confusion + +syncing the fixangle over the reliable channel with the first update + option to put the update in the reliable message? + + +-------------- +A "connect <server>" command is executed on the client. + +CL_Connect_f() disconnects from the current server if connected, +sets the current server to the new value, and sends the first connection packet. + +The connection packet will be resent by CL_CheckForResend() every two seconds until the server connects. + +A connection packet is an out of band packet containing "connect <userinfo>" with userinfo quoted. + +-------------- + +The server receives the OOB message in SVC_DirectConnect() + +It can respond with an OOB client print of "banned" or "server is full" if the client +cannot enter the game. + +If the client can get in, the server will initialize a new client_t structure with a +netchan_t, and respond with an OOB message containing S2C_CONNECTION. Further +communication will be through sequenced netchan_t messages instead of OOB messages. + +The client_t->state is set to cs_connected + +-------------- + +if S2C_CONNECTION packet is dropped, the connect message will be resent after two +seconds and the server will recognize the address and reuse the allocated client_t FIXME:bug?) + +When the client receives the S2C_CONNECTION, it initializes cls.netchan and sends +a "new" string command over the netchan to the server. + +cls.state is set to ca_connected FIXME: change to cs_connected? + +-------------- + +The "new" usercommand on the server is issued by the client every time they enter a level, +which is why none of the information is sent in the initial S2C_CONNECTION message. + +"new" sends over + +Before the client can begin playing in the server, the following information must be sent: + +gamedir +svc_serverinfo + PROTOCOL_VERSION + servercount // for detecting when the server + gamedir // for deciding the add-on directory (qw, ctf, etc) + playernumber // the client will allways be in this slot + the qc string of world.message // usually the level's full verbose name +cdtrack +fullserverinfo + +when received, the client changes state to ca_onserver. When the client receives +all the information needed to render a frame, the state will be changed to ca_active + +..... + +svc_soundlist + +..... + +svc_modellist + +..... + +prespawn passes the contents of the sv.signon_buffers, which hold +static entity spawning, static sound spawning, and all the entity baselines +FIXME: don't need to pass all baselines, uninitialized probs? + +..... + +"spawn" sends all dynamically changing state (fullclient updates, lightmaps, frags) +and ma + +FIXME: 32 clients could be up to 16k in updates, which overflows the 8k packet size + +FIXME: there is an updating hole between the sending of spawn data and the client +being notified + + +"begin" + +Actually spawns the client into the world as a visible entity. + +The client_t->state is set to cs_spawned, so normal datagram updates begin + +----------------------- + +When the first valid packetentities_t arrives at the client, cls.state is set +to ca_active, and rendering can begin. + +FIXME: make sure player and packets are both valid diff --git a/QW/client/draw.c b/QW/client/draw.c new file mode 100644 index 0000000..5580214 --- /dev/null +++ b/QW/client/draw.c @@ -0,0 +1,1020 @@ +/* +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.c -- this is the only file outside the refresh that touches the +// vid buffer + +#include "quakedef.h" + +typedef struct { + vrect_t rect; + int width; + int height; + byte *ptexbytes; + int rowbytes; +} rectdesc_t; + +static rectdesc_t r_rectdesc; + +byte *draw_chars; // 8*8 graphic characters +qpic_t *draw_disc; +qpic_t *draw_backtile; + +//============================================================================= +/* Support Routines */ + +typedef struct cachepic_s +{ + char name[MAX_QPATH]; + cache_user_t cache; +} cachepic_t; + +#define MAX_CACHED_PICS 128 +cachepic_t menu_cachepics[MAX_CACHED_PICS]; +int menu_numcachepics; + + +qpic_t *Draw_PicFromWad (char *name) +{ + return W_GetLumpName (name); +} + +/* +================ +Draw_CachePic +================ +*/ +qpic_t *Draw_CachePic (char *path) +{ + cachepic_t *pic; + int i; + qpic_t *dat; + + for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++) + if (!strcmp (path, pic->name)) + break; + + if (i == menu_numcachepics) + { + if (menu_numcachepics == MAX_CACHED_PICS) + Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); + menu_numcachepics++; + strcpy (pic->name, path); + } + + dat = Cache_Check (&pic->cache); + + if (dat) + return dat; + +// +// load the pic from disk +// + COM_LoadCacheFile (path, &pic->cache); + + dat = (qpic_t *)pic->cache.data; + if (!dat) + { + Sys_Error ("Draw_CachePic: failed to load %s", path); + } + + SwapPic (dat); + + return dat; +} + + + +/* +=============== +Draw_Init +=============== +*/ +void Draw_Init (void) +{ + draw_chars = W_GetLumpName ("conchars"); + draw_disc = W_GetLumpName ("disc"); + draw_backtile = W_GetLumpName ("backtile"); + + r_rectdesc.width = draw_backtile->width; + r_rectdesc.height = draw_backtile->height; + r_rectdesc.ptexbytes = draw_backtile->data; + r_rectdesc.rowbytes = draw_backtile->width; +} + + + +/* +================ +Draw_Character + +Draws one 8*8 graphics character with 0 being transparent. +It can be clipped to the top of the screen to allow the console to be +smoothly scrolled off. +================ +*/ +void Draw_Character (int x, int y, int num) +{ + byte *dest; + byte *source; + unsigned short *pusdest; + int drawline; + int row, col; + + num &= 255; + + if (y <= -8) + return; // totally off screen + + if (y > vid.height - 8 || x < 0 || x > vid.width - 8) + return; + if (num < 0 || num > 255) + return; + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + if (y < 0) + { // clipped + drawline = 8 + y; + source -= 128*y; + y = 0; + } + else + drawline = 8; + + + if (r_pixbytes == 1) + { + dest = vid.conbuffer + y*vid.conrowbytes + x; + + while (drawline--) + { + if (source[0]) + dest[0] = source[0]; + if (source[1]) + dest[1] = source[1]; + if (source[2]) + dest[2] = source[2]; + if (source[3]) + dest[3] = source[3]; + if (source[4]) + dest[4] = source[4]; + if (source[5]) + dest[5] = source[5]; + if (source[6]) + dest[6] = source[6]; + if (source[7]) + dest[7] = source[7]; + source += 128; + dest += vid.conrowbytes; + } + } + else + { + // FIXME: pre-expand to native format? + pusdest = (unsigned short *) + ((byte *)vid.conbuffer + y*vid.conrowbytes + (x<<1)); + + while (drawline--) + { + if (source[0]) + pusdest[0] = d_8to16table[source[0]]; + if (source[1]) + pusdest[1] = d_8to16table[source[1]]; + if (source[2]) + pusdest[2] = d_8to16table[source[2]]; + if (source[3]) + pusdest[3] = d_8to16table[source[3]]; + if (source[4]) + pusdest[4] = d_8to16table[source[4]]; + if (source[5]) + pusdest[5] = d_8to16table[source[5]]; + if (source[6]) + pusdest[6] = d_8to16table[source[6]]; + if (source[7]) + pusdest[7] = d_8to16table[source[7]]; + + source += 128; + pusdest += (vid.conrowbytes >> 1); + } + } +} + +/* +================ +Draw_String +================ +*/ +void Draw_String (int x, int y, char *str) +{ + while (*str) + { + Draw_Character (x, y, *str); + str++; + x += 8; + } +} + +/* +================ +Draw_Alt_String +================ +*/ +void Draw_Alt_String (int x, int y, char *str) +{ + while (*str) + { + Draw_Character (x, y, (*str) | 0x80); + str++; + x += 8; + } +} + +void Draw_Pixel(int x, int y, byte color) +{ + byte *dest; + unsigned short *pusdest; + + if (r_pixbytes == 1) + { + dest = vid.conbuffer + y*vid.conrowbytes + x; + *dest = color; + } + else + { + // FIXME: pre-expand to native format? + pusdest = (unsigned short *) + ((byte *)vid.conbuffer + y*vid.conrowbytes + (x<<1)); + *pusdest = d_8to16table[color]; + } +} + +void Draw_Crosshair(void) +{ + int x, y; + extern cvar_t crosshair, cl_crossx, cl_crossy, crosshaircolor; + extern vrect_t scr_vrect; + byte c = (byte)crosshaircolor.value; + + if (crosshair.value == 2) { + x = scr_vrect.x + scr_vrect.width/2 + cl_crossx.value; + y = scr_vrect.y + scr_vrect.height/2 + cl_crossy.value; + Draw_Pixel(x - 1, y, c); + Draw_Pixel(x - 3, y, c); + Draw_Pixel(x + 1, y, c); + Draw_Pixel(x + 3, y, c); + Draw_Pixel(x, y - 1, c); + Draw_Pixel(x, y - 3, c); + Draw_Pixel(x, y + 1, c); + Draw_Pixel(x, y + 3, c); + } else if (crosshair.value) + Draw_Character ( + scr_vrect.x + scr_vrect.width/2-4 + cl_crossx.value, + scr_vrect.y + scr_vrect.height/2-4 + cl_crossy.value, + '+'); +} + +/* +================ +Draw_DebugChar + +Draws a single character directly to the upper right corner of the screen. +This is for debugging lockups by drawing different chars in different parts +of the code. +================ +*/ +void Draw_DebugChar (char num) +{ + byte *dest; + byte *source; + int drawline; + extern byte *draw_chars; + int row, col; + + if (!vid.direct) + return; // don't have direct FB access, so no debugchars... + + drawline = 8; + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + dest = vid.direct + 312; + + while (drawline--) + { + dest[0] = source[0]; + dest[1] = source[1]; + dest[2] = source[2]; + dest[3] = source[3]; + dest[4] = source[4]; + dest[5] = source[5]; + dest[6] = source[6]; + dest[7] = source[7]; + source += 128; + dest += 320; + } +} + +/* +============= +Draw_Pic +============= +*/ +void Draw_Pic (int x, int y, qpic_t *pic) +{ + byte *dest, *source; + unsigned short *pusdest; + int v, u; + + if ((x < 0) || + (x + pic->width > vid.width) || + (y < 0) || + (y + pic->height > vid.height)) + { + Sys_Error ("Draw_Pic: bad coordinates"); + } + + source = pic->data; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y * vid.rowbytes + x; + + for (v=0 ; v<pic->height ; v++) + { + Q_memcpy (dest, source, pic->width); + dest += vid.rowbytes; + source += pic->width; + } + } + else + { + // FIXME: pretranslate at load time? + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + + for (v=0 ; v<pic->height ; v++) + { + for (u=0 ; u<pic->width ; u++) + { + pusdest[u] = d_8to16table[source[u]]; + } + + pusdest += vid.rowbytes >> 1; + source += pic->width; + } + } +} + + +/* +============= +Draw_SubPic +============= +*/ +void Draw_SubPic(int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height) +{ + byte *dest, *source; + unsigned short *pusdest; + int v, u; + + if ((x < 0) || + (x + width > vid.width) || + (y < 0) || + (y + height > vid.height)) + { + Sys_Error ("Draw_Pic: bad coordinates"); + } + + source = pic->data + srcy * pic->width + srcx; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y * vid.rowbytes + x; + + for (v=0 ; v<height ; v++) + { + Q_memcpy (dest, source, width); + dest += vid.rowbytes; + source += pic->width; + } + } + else + { + // FIXME: pretranslate at load time? + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + + for (v=0 ; v<height ; v++) + { + for (u=srcx ; u<(srcx+width) ; u++) + { + pusdest[u] = d_8to16table[source[u]]; + } + + pusdest += vid.rowbytes >> 1; + source += pic->width; + } + } +} + + +/* +============= +Draw_TransPic +============= +*/ +void Draw_TransPic (int x, int y, qpic_t *pic) +{ + byte *dest, *source, tbyte; + unsigned short *pusdest; + int v, u; + + if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || + (unsigned)(y + pic->height) > vid.height) + { + Sys_Error ("Draw_TransPic: bad coordinates"); + } + + source = pic->data; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y * vid.rowbytes + x; + + if (pic->width & 7) + { // general + for (v=0 ; v<pic->height ; v++) + { + for (u=0 ; u<pic->width ; u++) + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = tbyte; + + dest += vid.rowbytes; + source += pic->width; + } + } + else + { // unwound + for (v=0 ; v<pic->height ; v++) + { + for (u=0 ; u<pic->width ; u+=8) + { + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = tbyte; + if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR) + dest[u+1] = tbyte; + if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR) + dest[u+2] = tbyte; + if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR) + dest[u+3] = tbyte; + if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR) + dest[u+4] = tbyte; + if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR) + dest[u+5] = tbyte; + if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR) + dest[u+6] = tbyte; + if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR) + dest[u+7] = tbyte; + } + dest += vid.rowbytes; + source += pic->width; + } + } + } + else + { + // FIXME: pretranslate at load time? + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + + for (v=0 ; v<pic->height ; v++) + { + for (u=0 ; u<pic->width ; u++) + { + tbyte = source[u]; + + if (tbyte != TRANSPARENT_COLOR) + { + pusdest[u] = d_8to16table[tbyte]; + } + } + + pusdest += vid.rowbytes >> 1; + source += pic->width; + } + } +} + + +/* +============= +Draw_TransPicTranslate +============= +*/ +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation) +{ + byte *dest, *source, tbyte; + unsigned short *pusdest; + int v, u; + + if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || + (unsigned)(y + pic->height) > vid.height) + { + Sys_Error ("Draw_TransPic: bad coordinates"); + } + + source = pic->data; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y * vid.rowbytes + x; + + if (pic->width & 7) + { // general + for (v=0 ; v<pic->height ; v++) + { + for (u=0 ; u<pic->width ; u++) + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = translation[tbyte]; + + dest += vid.rowbytes; + source += pic->width; + } + } + else + { // unwound + for (v=0 ; v<pic->height ; v++) + { + for (u=0 ; u<pic->width ; u+=8) + { + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = translation[tbyte]; + if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR) + dest[u+1] = translation[tbyte]; + if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR) + dest[u+2] = translation[tbyte]; + if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR) + dest[u+3] = translation[tbyte]; + if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR) + dest[u+4] = translation[tbyte]; + if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR) + dest[u+5] = translation[tbyte]; + if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR) + dest[u+6] = translation[tbyte]; + if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR) + dest[u+7] = translation[tbyte]; + } + dest += vid.rowbytes; + source += pic->width; + } + } + } + else + { + // FIXME: pretranslate at load time? + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + + for (v=0 ; v<pic->height ; v++) + { + for (u=0 ; u<pic->width ; u++) + { + tbyte = source[u]; + + if (tbyte != TRANSPARENT_COLOR) + { + pusdest[u] = d_8to16table[tbyte]; + } + } + + pusdest += vid.rowbytes >> 1; + source += pic->width; + } + } +} + + +void Draw_CharToConback (int num, byte *dest) +{ + int row, col; + byte *source; + int drawline; + int x; + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + drawline = 8; + + while (drawline--) + { + for (x=0 ; x<8 ; x++) + if (source[x]) + dest[x] = 0x60 + source[x]; + source += 128; + dest += 320; + } + +} + +/* +================ +Draw_ConsoleBackground + +================ +*/ +void Draw_ConsoleBackground (int lines) +{ + int x, y, v; + byte *src, *dest; + unsigned short *pusdest; + int f, fstep; + qpic_t *conback; + char ver[100]; + static char saveback[320*8]; + + conback = Draw_CachePic ("gfx/conback.lmp"); + +// hack the version number directly into the pic + + //sprintf (ver, "start commands with a \\ character %4.2f", VERSION); + + if (cls.download) { + sprintf (ver, "%4.2f", VERSION); + dest = conback->data + 320 + 320*186 - 11 - 8*strlen(ver); + } else { +#if defined(__linux__) + sprintf (ver, "Linux (%4.2f) QuakeWorld %4.2f", LINUX_VERSION, VERSION); +#else + sprintf (ver, "QuakeWorld %4.2f", VERSION); +#endif + dest = conback->data + 320 - (strlen(ver)*8 + 11) + 320*186; + } + + memcpy(saveback, conback->data + 320*186, 320*8); + for (x=0 ; x<strlen(ver) ; x++) + Draw_CharToConback (ver[x], dest+(x<<3)); + +// draw the pic + if (r_pixbytes == 1) + { + dest = vid.conbuffer; + + for (y=0 ; y<lines ; y++, dest += vid.conrowbytes) + { + v = (vid.conheight - lines + y)*200/vid.conheight; + src = conback->data + v*320; + if (vid.conwidth == 320) + memcpy (dest, src, vid.conwidth); + else + { + f = 0; + fstep = 320*0x10000/vid.conwidth; + for (x=0 ; x<vid.conwidth ; x+=4) + { + dest[x] = src[f>>16]; + f += fstep; + dest[x+1] = src[f>>16]; + f += fstep; + dest[x+2] = src[f>>16]; + f += fstep; + dest[x+3] = src[f>>16]; + f += fstep; + } + } + } + } + else + { + pusdest = (unsigned short *)vid.conbuffer; + + for (y=0 ; y<lines ; y++, pusdest += (vid.conrowbytes >> 1)) + { + // FIXME: pre-expand to native format? + // FIXME: does the endian switching go away in production? + v = (vid.conheight - lines + y)*200/vid.conheight; + src = conback->data + v*320; + f = 0; + fstep = 320*0x10000/vid.conwidth; + for (x=0 ; x<vid.conwidth ; x+=4) + { + pusdest[x] = d_8to16table[src[f>>16]]; + f += fstep; + pusdest[x+1] = d_8to16table[src[f>>16]]; + f += fstep; + pusdest[x+2] = d_8to16table[src[f>>16]]; + f += fstep; + pusdest[x+3] = d_8to16table[src[f>>16]]; + f += fstep; + } + } + } + // put it back + memcpy(conback->data + 320*186, saveback, 320*8); +} + + +/* +============== +R_DrawRect8 +============== +*/ +void R_DrawRect8 (vrect_t *prect, int rowbytes, byte *psrc, + int transparent) +{ + byte t; + int i, j, srcdelta, destdelta; + byte *pdest; + + pdest = vid.buffer + (prect->y * vid.rowbytes) + prect->x; + + srcdelta = rowbytes - prect->width; + destdelta = vid.rowbytes - prect->width; + + if (transparent) + { + for (i=0 ; i<prect->height ; i++) + { + for (j=0 ; j<prect->width ; j++) + { + t = *psrc; + if (t != TRANSPARENT_COLOR) + { + *pdest = t; + } + + psrc++; + pdest++; + } + + psrc += srcdelta; + pdest += destdelta; + } + } + else + { + for (i=0 ; i<prect->height ; i++) + { + memcpy (pdest, psrc, prect->width); + psrc += rowbytes; + pdest += vid.rowbytes; + } + } +} + + +/* +============== +R_DrawRect16 +============== +*/ +void R_DrawRect16 (vrect_t *prect, int rowbytes, byte *psrc, + int transparent) +{ + byte t; + int i, j, srcdelta, destdelta; + unsigned short *pdest; + +// FIXME: would it be better to pre-expand native-format versions? + + pdest = (unsigned short *)vid.buffer + + (prect->y * (vid.rowbytes >> 1)) + prect->x; + + srcdelta = rowbytes - prect->width; + destdelta = (vid.rowbytes >> 1) - prect->width; + + if (transparent) + { + for (i=0 ; i<prect->height ; i++) + { + for (j=0 ; j<prect->width ; j++) + { + t = *psrc; + if (t != TRANSPARENT_COLOR) + { + *pdest = d_8to16table[t]; + } + + psrc++; + pdest++; + } + + psrc += srcdelta; + pdest += destdelta; + } + } + else + { + for (i=0 ; i<prect->height ; i++) + { + for (j=0 ; j<prect->width ; j++) + { + *pdest = d_8to16table[*psrc]; + psrc++; + pdest++; + } + + psrc += srcdelta; + pdest += destdelta; + } + } +} + + +/* +============= +Draw_TileClear + +This repeats a 64*64 tile graphic to fill the screen around a sized down +refresh window. +============= +*/ +void Draw_TileClear (int x, int y, int w, int h) +{ + int width, height, tileoffsetx, tileoffsety; + byte *psrc; + vrect_t vr; + + r_rectdesc.rect.x = x; + r_rectdesc.rect.y = y; + r_rectdesc.rect.width = w; + r_rectdesc.rect.height = h; + + vr.y = r_rectdesc.rect.y; + height = r_rectdesc.rect.height; + + tileoffsety = vr.y % r_rectdesc.height; + + while (height > 0) + { + vr.x = r_rectdesc.rect.x; + width = r_rectdesc.rect.width; + + if (tileoffsety != 0) + vr.height = r_rectdesc.height - tileoffsety; + else + vr.height = r_rectdesc.height; + + if (vr.height > height) + vr.height = height; + + tileoffsetx = vr.x % r_rectdesc.width; + + while (width > 0) + { + if (tileoffsetx != 0) + vr.width = r_rectdesc.width - tileoffsetx; + else + vr.width = r_rectdesc.width; + + if (vr.width > width) + vr.width = width; + + psrc = r_rectdesc.ptexbytes + + (tileoffsety * r_rectdesc.rowbytes) + tileoffsetx; + + if (r_pixbytes == 1) + { + R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0); + } + else + { + R_DrawRect16 (&vr, r_rectdesc.rowbytes, psrc, 0); + } + + vr.x += vr.width; + width -= vr.width; + tileoffsetx = 0; // only the left tile can be left-clipped + } + + vr.y += vr.height; + height -= vr.height; + tileoffsety = 0; // only the top tile can be top-clipped + } +} + + +/* +============= +Draw_Fill + +Fills a box of pixels with a single color +============= +*/ +void Draw_Fill (int x, int y, int w, int h, int c) +{ + byte *dest; + unsigned short *pusdest; + unsigned uc; + int u, v; + + if (x < 0 || x + w > vid.width || + y < 0 || y + h > vid.height) { + Con_Printf("Bad Draw_Fill(%d, %d, %d, %d, %c)\n", + x, y, w, h, c); + return; + } + + if (r_pixbytes == 1) + { + dest = vid.buffer + y*vid.rowbytes + x; + for (v=0 ; v<h ; v++, dest += vid.rowbytes) + for (u=0 ; u<w ; u++) + dest[u] = c; + } + else + { + uc = d_8to16table[c]; + + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + for (v=0 ; v<h ; v++, pusdest += (vid.rowbytes >> 1)) + for (u=0 ; u<w ; u++) + pusdest[u] = uc; + } +} +//============================================================================= + +/* +================ +Draw_FadeScreen + +================ +*/ +void Draw_FadeScreen (void) +{ + int x,y; + byte *pbuf; + + VID_UnlockBuffer (); + S_ExtraUpdate (); + VID_LockBuffer (); + + for (y=0 ; y<vid.height ; y++) + { + int t; + + pbuf = (byte *)(vid.buffer + vid.rowbytes*y); + t = (y & 1) << 1; + + for (x=0 ; x<vid.width ; x++) + { + if ((x & 3) != t) + pbuf[x] = 0; + } + } + + VID_UnlockBuffer (); + S_ExtraUpdate (); + VID_LockBuffer (); +} + +//============================================================================= + +/* +================ +Draw_BeginDisc + +Draws the little blue disc in the corner of the screen. +Call before beginning any disc IO. +================ +*/ +void Draw_BeginDisc (void) +{ + + D_BeginDirectRect (vid.width - 24, 0, draw_disc->data, 24, 24); +} + + +/* +================ +Draw_EndDisc + +Erases the disc icon. +Call after completing any disc IO +================ +*/ +void Draw_EndDisc (void) +{ + + D_EndDirectRect (vid.width - 24, 0, 24, 24); +} + diff --git a/QW/client/draw.h b/QW/client/draw.h new file mode 100644 index 0000000..35beb92 --- /dev/null +++ b/QW/client/draw.h @@ -0,0 +1,43 @@ +/* +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 + +extern qpic_t *draw_disc; // also used on sbar + +void Draw_Init (void); +void Draw_Character (int x, int y, int num); +void Draw_DebugChar (char num); +void Draw_SubPic(int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height); +void Draw_Pic (int x, int y, qpic_t *pic); +void Draw_TransPic (int x, int y, qpic_t *pic); +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation); +void Draw_ConsoleBackground (int lines); +void Draw_BeginDisc (void); +void Draw_EndDisc (void); +void Draw_TileClear (int x, int y, int w, int h); +void Draw_Fill (int x, int y, int w, int h, int c); +void Draw_FadeScreen (void); +void Draw_String (int x, int y, char *str); +void Draw_Alt_String (int x, int y, char *str); +qpic_t *Draw_PicFromWad (char *name); +qpic_t *Draw_CachePic (char *path); +void Draw_Crosshair(void); diff --git a/QW/client/exitscrn.txt b/QW/client/exitscrn.txt new file mode 100644 index 0000000..fee929f --- /dev/null +++ b/QW/client/exitscrn.txt @@ -0,0 +1,22 @@ + QuakeWorld + version 1.64 by id Software + +Programming + John Carmack Michael Abrash + John Cash Christian Antkow + +Additional Programming + Dave 'Zoid' Kirsch + Courtesy of ThreeWave Software + Jack 'morbid' Mathews + Courtesy of the QuakeSpy Team + +QuakeWorld is an unsupported +product of id Software. + +Quake is a trademark of Id Software, +inc., (c)1996, 1997 Id Software, inc. +All rights reserved. NIN logo is a +registered trademark licensed to +Nothing Interactive, Inc. All rights +reserved. Press y to exit diff --git a/QW/client/gl_draw.c b/QW/client/gl_draw.c new file mode 100644 index 0000000..07d8411 --- /dev/null +++ b/QW/client/gl_draw.c @@ -0,0 +1,1378 @@ +/* +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.c -- this is the only file outside the refresh that touches the +// vid buffer + +#include "quakedef.h" + +extern unsigned char d_15to8table[65536]; +extern cvar_t crosshair, cl_crossx, cl_crossy, crosshaircolor; + +cvar_t gl_nobind = {"gl_nobind", "0"}; +cvar_t gl_max_size = {"gl_max_size", "1024"}; +cvar_t gl_picmip = {"gl_picmip", "0"}; + +byte *draw_chars; // 8*8 graphic characters +qpic_t *draw_disc; +qpic_t *draw_backtile; + +int translate_texture; +int char_texture; +int cs_texture; // crosshair texture + +static byte cs_data[64] = { + 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + + +typedef struct +{ + int texnum; + float sl, tl, sh, th; +} glpic_t; + +byte conback_buffer[sizeof(qpic_t) + sizeof(glpic_t)]; +qpic_t *conback = (qpic_t *)&conback_buffer; + +int gl_lightmap_format = 4; +int gl_solid_format = 3; +int gl_alpha_format = 4; + +int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST; +int gl_filter_max = GL_LINEAR; + + +int texels; + +typedef struct +{ + int texnum; + char identifier[64]; + int width, height; + qboolean mipmap; +} gltexture_t; + +#define MAX_GLTEXTURES 1024 +gltexture_t gltextures[MAX_GLTEXTURES]; +int numgltextures; + +void GL_Bind (int texnum) +{ + if (gl_nobind.value) + texnum = char_texture; + if (currenttexture == texnum) + return; + currenttexture = texnum; +#ifdef _WIN32 + bindTexFunc (GL_TEXTURE_2D, texnum); +#else + glBindTexture (GL_TEXTURE_2D, texnum); +#endif +} + + +/* +============================================================================= + + scrap allocation + + Allocate all the little status bar obejcts into a single texture + to crutch up stupid hardware / drivers + +============================================================================= +*/ + +#define MAX_SCRAPS 1 +#define BLOCK_WIDTH 256 +#define BLOCK_HEIGHT 256 + +int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH]; +byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT*4]; +qboolean scrap_dirty; +int scrap_texnum; + +// returns a texture number and the position inside it +int Scrap_AllocBlock (int w, int h, int *x, int *y) +{ + int i, j; + int best, best2; + int texnum; + + for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++) + { + best = BLOCK_HEIGHT; + + for (i=0 ; i<BLOCK_WIDTH-w ; i++) + { + best2 = 0; + + for (j=0 ; j<w ; j++) + { + if (scrap_allocated[texnum][i+j] >= best) + break; + if (scrap_allocated[texnum][i+j] > best2) + best2 = scrap_allocated[texnum][i+j]; + } + if (j == w) + { // this is a valid spot + *x = i; + *y = best = best2; + } + } + + if (best + h > BLOCK_HEIGHT) + continue; + + for (i=0 ; i<w ; i++) + scrap_allocated[texnum][*x + i] = best + h; + + return texnum; + } + + Sys_Error ("Scrap_AllocBlock: full"); + return 0; +} + +int scrap_uploads; + +void Scrap_Upload (void) +{ + scrap_uploads++; + GL_Bind(scrap_texnum); + GL_Upload8 (scrap_texels[0], BLOCK_WIDTH, BLOCK_HEIGHT, false, true); + scrap_dirty = false; +} + +//============================================================================= +/* Support Routines */ + +typedef struct cachepic_s +{ + char name[MAX_QPATH]; + qpic_t pic; + byte padding[32]; // for appended glpic +} cachepic_t; + +#define MAX_CACHED_PICS 128 +cachepic_t menu_cachepics[MAX_CACHED_PICS]; +int menu_numcachepics; + +byte menuplyr_pixels[4096]; + +int pic_texels; +int pic_count; + +qpic_t *Draw_PicFromWad (char *name) +{ + qpic_t *p; + glpic_t *gl; + + p = W_GetLumpName (name); + gl = (glpic_t *)p->data; + + // load little ones into the scrap + if (p->width < 64 && p->height < 64) + { + int x, y; + int i, j, k; + int texnum; + + texnum = Scrap_AllocBlock (p->width, p->height, &x, &y); + scrap_dirty = true; + k = 0; + for (i=0 ; i<p->height ; i++) + for (j=0 ; j<p->width ; j++, k++) + scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = p->data[k]; + texnum += scrap_texnum; + gl->texnum = texnum; + gl->sl = (x+0.01)/(float)BLOCK_WIDTH; + gl->sh = (x+p->width-0.01)/(float)BLOCK_WIDTH; + gl->tl = (y+0.01)/(float)BLOCK_WIDTH; + gl->th = (y+p->height-0.01)/(float)BLOCK_WIDTH; + + pic_count++; + pic_texels += p->width*p->height; + } + else + { + gl->texnum = GL_LoadPicTexture (p); + gl->sl = 0; + gl->sh = 1; + gl->tl = 0; + gl->th = 1; + } + return p; +} + + +/* +================ +Draw_CachePic +================ +*/ +qpic_t *Draw_CachePic (char *path) +{ + cachepic_t *pic; + int i; + qpic_t *dat; + glpic_t *gl; + + for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++) + if (!strcmp (path, pic->name)) + return &pic->pic; + + if (menu_numcachepics == MAX_CACHED_PICS) + Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); + menu_numcachepics++; + strcpy (pic->name, path); + +// +// load the pic from disk +// + dat = (qpic_t *)COM_LoadTempFile (path); + if (!dat) + Sys_Error ("Draw_CachePic: failed to load %s", path); + SwapPic (dat); + + // HACK HACK HACK --- we need to keep the bytes for + // the translatable player picture just for the menu + // configuration dialog + if (!strcmp (path, "gfx/menuplyr.lmp")) + memcpy (menuplyr_pixels, dat->data, dat->width*dat->height); + + pic->pic.width = dat->width; + pic->pic.height = dat->height; + + gl = (glpic_t *)pic->pic.data; + gl->texnum = GL_LoadPicTexture (dat); + gl->sl = 0; + gl->sh = 1; + gl->tl = 0; + gl->th = 1; + + return &pic->pic; +} + + +void Draw_CharToConback (int num, byte *dest) +{ + int row, col; + byte *source; + int drawline; + int x; + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + drawline = 8; + + while (drawline--) + { + for (x=0 ; x<8 ; x++) + if (source[x] != 255) + dest[x] = 0x60 + source[x]; + source += 128; + dest += 320; + } + +} + +typedef struct +{ + char *name; + int minimize, maximize; +} glmode_t; + +glmode_t modes[] = { + {"GL_NEAREST", GL_NEAREST, GL_NEAREST}, + {"GL_LINEAR", GL_LINEAR, GL_LINEAR}, + {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST}, + {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR}, + {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST}, + {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR} +}; + +/* +=============== +Draw_TextureMode_f +=============== +*/ +void Draw_TextureMode_f (void) +{ + int i; + gltexture_t *glt; + + if (Cmd_Argc() == 1) + { + for (i=0 ; i< 6 ; i++) + if (gl_filter_min == modes[i].minimize) + { + Con_Printf ("%s\n", modes[i].name); + return; + } + Con_Printf ("current filter is unknown???\n"); + return; + } + + for (i=0 ; i< 6 ; i++) + { + if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) ) + break; + } + if (i == 6) + { + Con_Printf ("bad filter name\n"); + return; + } + + gl_filter_min = modes[i].minimize; + gl_filter_max = modes[i].maximize; + + // change all the existing mipmap texture objects + for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++) + { + if (glt->mipmap) + { + GL_Bind (glt->texnum); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + } + } +} + +/* +=============== +Draw_Init +=============== +*/ +void Draw_Init (void) +{ + int i; + qpic_t *cb; + byte *dest; + int x; + char ver[40]; + glpic_t *gl; + int start; + byte *ncdata; + + Cvar_RegisterVariable (&gl_nobind); + Cvar_RegisterVariable (&gl_max_size); + Cvar_RegisterVariable (&gl_picmip); + + // 3dfx can only handle 256 wide textures + if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4) || + !Q_strncasecmp ((char *)gl_renderer, "Mesa",4)) + Cvar_Set ("gl_max_size", "256"); + + Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f); + + // load the console background and the charset + // by hand, because we need to write the version + // string into the background before turning + // it into a texture + draw_chars = W_GetLumpName ("conchars"); + for (i=0 ; i<256*64 ; i++) + if (draw_chars[i] == 0) + draw_chars[i] = 255; // proper transparent color + + // now turn them into textures + char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true); +// Draw_CrosshairAdjust(); + cs_texture = GL_LoadTexture ("crosshair", 8, 8, cs_data, false, true); + + start = Hunk_LowMark (); + + cb = (qpic_t *)COM_LoadHunkFile ("gfx/conback.lmp"); + if (!cb) + Sys_Error ("Couldn't load gfx/conback.lmp"); + SwapPic (cb); + + sprintf (ver, "%4.2f", VERSION); + dest = cb->data + 320 + 320*186 - 11 - 8*strlen(ver); + for (x=0 ; x<strlen(ver) ; x++) + Draw_CharToConback (ver[x], dest+(x<<3)); + +#if 0 + conback->width = vid.conwidth; + conback->height = vid.conheight; + + // scale console to vid size + dest = ncdata = Hunk_AllocName(vid.conwidth * vid.conheight, "conback"); + + for (y=0 ; y<vid.conheight ; y++, dest += vid.conwidth) + { + src = cb->data + cb->width * (y*cb->height/vid.conheight); + if (vid.conwidth == cb->width) + memcpy (dest, src, vid.conwidth); + else + { + f = 0; + fstep = cb->width*0x10000/vid.conwidth; + for (x=0 ; x<vid.conwidth ; x+=4) + { + dest[x] = src[f>>16]; + f += fstep; + dest[x+1] = src[f>>16]; + f += fstep; + dest[x+2] = src[f>>16]; + f += fstep; + dest[x+3] = src[f>>16]; + f += fstep; + } + } + } +#else + conback->width = cb->width; + conback->height = cb->height; + ncdata = cb->data; +#endif + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + gl = (glpic_t *)conback->data; + gl->texnum = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, false, false); + gl->sl = 0; + gl->sh = 1; + gl->tl = 0; + gl->th = 1; + conback->width = vid.conwidth; + conback->height = vid.conheight; + + // free loaded console + Hunk_FreeToLowMark (start); + + // save a texture slot for translated picture + translate_texture = texture_extension_number++; + + // save slots for scraps + scrap_texnum = texture_extension_number; + texture_extension_number += MAX_SCRAPS; + + // + // get the other pics we need + // + draw_disc = Draw_PicFromWad ("disc"); + draw_backtile = Draw_PicFromWad ("backtile"); +} + + + +/* +================ +Draw_Character + +Draws one 8*8 graphics character with 0 being transparent. +It can be clipped to the top of the screen to allow the console to be +smoothly scrolled off. +================ +*/ +void Draw_Character (int x, int y, int num) +{ + int row, col; + float frow, fcol, size; + + if (num == 32) + return; // space + + num &= 255; + + if (y <= -8) + return; // totally off screen + + row = num>>4; + col = num&15; + + frow = row*0.0625; + fcol = col*0.0625; + size = 0.0625; + + GL_Bind (char_texture); + + glBegin (GL_QUADS); + glTexCoord2f (fcol, frow); + glVertex2f (x, y); + glTexCoord2f (fcol + size, frow); + glVertex2f (x+8, y); + glTexCoord2f (fcol + size, frow + size); + glVertex2f (x+8, y+8); + glTexCoord2f (fcol, frow + size); + glVertex2f (x, y+8); + glEnd (); +} + +/* +================ +Draw_String +================ +*/ +void Draw_String (int x, int y, char *str) +{ + while (*str) + { + Draw_Character (x, y, *str); + str++; + x += 8; + } +} + +/* +================ +Draw_Alt_String +================ +*/ +void Draw_Alt_String (int x, int y, char *str) +{ + while (*str) + { + Draw_Character (x, y, (*str) | 0x80); + str++; + x += 8; + } +} + +void Draw_Crosshair(void) +{ + int x, y; + extern vrect_t scr_vrect; + unsigned char *pColor; + + if (crosshair.value == 2) { + x = scr_vrect.x + scr_vrect.width/2 - 3 + cl_crossx.value; + y = scr_vrect.y + scr_vrect.height/2 - 3 + cl_crossy.value; + + glTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + pColor = (unsigned char *) &d_8to24table[(byte) crosshaircolor.value]; + glColor4ubv ( pColor ); + GL_Bind (cs_texture); + + glBegin (GL_QUADS); + glTexCoord2f (0, 0); + glVertex2f (x - 4, y - 4); + glTexCoord2f (1, 0); + glVertex2f (x+12, y-4); + glTexCoord2f (1, 1); + glVertex2f (x+12, y+12); + glTexCoord2f (0, 1); + glVertex2f (x - 4, y+12); + glEnd (); + + glTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); + } else if (crosshair.value) + Draw_Character (scr_vrect.x + scr_vrect.width/2-4 + cl_crossx.value, + scr_vrect.y + scr_vrect.height/2-4 + cl_crossy.value, + '+'); +} + + +/* +================ +Draw_DebugChar + +Draws a single character directly to the upper right corner of the screen. +This is for debugging lockups by drawing different chars in different parts +of the code. +================ +*/ +void Draw_DebugChar (char num) +{ +} + +/* +============= +Draw_Pic +============= +*/ +void Draw_Pic (int x, int y, qpic_t *pic) +{ + glpic_t *gl; + + if (scrap_dirty) + Scrap_Upload (); + gl = (glpic_t *)pic->data; + glColor4f (1,1,1,1); + GL_Bind (gl->texnum); + glBegin (GL_QUADS); + glTexCoord2f (gl->sl, gl->tl); + glVertex2f (x, y); + glTexCoord2f (gl->sh, gl->tl); + glVertex2f (x+pic->width, y); + glTexCoord2f (gl->sh, gl->th); + glVertex2f (x+pic->width, y+pic->height); + glTexCoord2f (gl->sl, gl->th); + glVertex2f (x, y+pic->height); + glEnd (); +} + +/* +============= +Draw_AlphaPic +============= +*/ +void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha) +{ + glpic_t *gl; + + if (scrap_dirty) + Scrap_Upload (); + gl = (glpic_t *)pic->data; + glDisable(GL_ALPHA_TEST); + glEnable (GL_BLEND); +// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glCullFace(GL_FRONT); + glColor4f (1,1,1,alpha); + GL_Bind (gl->texnum); + glBegin (GL_QUADS); + glTexCoord2f (gl->sl, gl->tl); + glVertex2f (x, y); + glTexCoord2f (gl->sh, gl->tl); + glVertex2f (x+pic->width, y); + glTexCoord2f (gl->sh, gl->th); + glVertex2f (x+pic->width, y+pic->height); + glTexCoord2f (gl->sl, gl->th); + glVertex2f (x, y+pic->height); + glEnd (); + glColor4f (1,1,1,1); + glEnable(GL_ALPHA_TEST); + glDisable (GL_BLEND); +} + +void Draw_SubPic(int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height) +{ + glpic_t *gl; + float newsl, newtl, newsh, newth; + float oldglwidth, oldglheight; + + if (scrap_dirty) + Scrap_Upload (); + gl = (glpic_t *)pic->data; + + oldglwidth = gl->sh - gl->sl; + oldglheight = gl->th - gl->tl; + + newsl = gl->sl + (srcx*oldglwidth)/pic->width; + newsh = newsl + (width*oldglwidth)/pic->width; + + newtl = gl->tl + (srcy*oldglheight)/pic->height; + newth = newtl + (height*oldglheight)/pic->height; + + glColor4f (1,1,1,1); + GL_Bind (gl->texnum); + glBegin (GL_QUADS); + glTexCoord2f (newsl, newtl); + glVertex2f (x, y); + glTexCoord2f (newsh, newtl); + glVertex2f (x+width, y); + glTexCoord2f (newsh, newth); + glVertex2f (x+width, y+height); + glTexCoord2f (newsl, newth); + glVertex2f (x, y+height); + glEnd (); +} + +/* +============= +Draw_TransPic +============= +*/ +void Draw_TransPic (int x, int y, qpic_t *pic) +{ + + if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || + (unsigned)(y + pic->height) > vid.height) + { + Sys_Error ("Draw_TransPic: bad coordinates"); + } + + Draw_Pic (x, y, pic); +} + + +/* +============= +Draw_TransPicTranslate + +Only used for the player color selection menu +============= +*/ +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation) +{ + int v, u, c; + unsigned trans[64*64], *dest; + byte *src; + int p; + + GL_Bind (translate_texture); + + c = pic->width * pic->height; + + dest = trans; + for (v=0 ; v<64 ; v++, dest += 64) + { + src = &menuplyr_pixels[ ((v*pic->height)>>6) *pic->width]; + for (u=0 ; u<64 ; u++) + { + p = src[(u*pic->width)>>6]; + if (p == 255) + dest[u] = p; + else + dest[u] = d_8to24table[translation[p]]; + } + } + + glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glColor3f (1,1,1); + glBegin (GL_QUADS); + glTexCoord2f (0, 0); + glVertex2f (x, y); + glTexCoord2f (1, 0); + glVertex2f (x+pic->width, y); + glTexCoord2f (1, 1); + glVertex2f (x+pic->width, y+pic->height); + glTexCoord2f (0, 1); + glVertex2f (x, y+pic->height); + glEnd (); +} + + +/* +================ +Draw_ConsoleBackground + +================ +*/ +void Draw_ConsoleBackground (int lines) +{ + char ver[80]; + int x, i; + int y; + + y = (vid.height * 3) >> 2; + if (lines > y) + Draw_Pic(0, lines-vid.height, conback); + else + Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y); + + // hack the version number directly into the pic +// y = lines-186; + y = lines-14; + if (!cls.download) { +#ifdef __linux__ + sprintf (ver, "LinuxGL (%4.2f) QuakeWorld", LINUX_VERSION); +#else + sprintf (ver, "GL (%4.2f) QuakeWorld", GLQUAKE_VERSION); +#endif + x = vid.conwidth - (strlen(ver)*8 + 11) - (vid.conwidth*8/320)*7; + for (i=0 ; i<strlen(ver) ; i++) + Draw_Character (x + i * 8, y, ver[i] | 0x80); + } +} + + +/* +============= +Draw_TileClear + +This repeats a 64*64 tile graphic to fill the screen around a sized down +refresh window. +============= +*/ +void Draw_TileClear (int x, int y, int w, int h) +{ + glColor3f (1,1,1); + GL_Bind (*(int *)draw_backtile->data); + glBegin (GL_QUADS); + glTexCoord2f (x/64.0, y/64.0); + glVertex2f (x, y); + glTexCoord2f ( (x+w)/64.0, y/64.0); + glVertex2f (x+w, y); + glTexCoord2f ( (x+w)/64.0, (y+h)/64.0); + glVertex2f (x+w, y+h); + glTexCoord2f ( x/64.0, (y+h)/64.0 ); + glVertex2f (x, y+h); + glEnd (); +} + + +/* +============= +Draw_Fill + +Fills a box of pixels with a single color +============= +*/ +void Draw_Fill (int x, int y, int w, int h, int c) +{ + glDisable (GL_TEXTURE_2D); + glColor3f (host_basepal[c*3]/255.0, + host_basepal[c*3+1]/255.0, + host_basepal[c*3+2]/255.0); + + glBegin (GL_QUADS); + + glVertex2f (x,y); + glVertex2f (x+w, y); + glVertex2f (x+w, y+h); + glVertex2f (x, y+h); + + glEnd (); + glColor3f (1,1,1); + glEnable (GL_TEXTURE_2D); +} +//============================================================================= + +/* +================ +Draw_FadeScreen + +================ +*/ +void Draw_FadeScreen (void) +{ + glEnable (GL_BLEND); + glDisable (GL_TEXTURE_2D); + glColor4f (0, 0, 0, 0.8); + glBegin (GL_QUADS); + + glVertex2f (0,0); + glVertex2f (vid.width, 0); + glVertex2f (vid.width, vid.height); + glVertex2f (0, vid.height); + + glEnd (); + glColor4f (1,1,1,1); + glEnable (GL_TEXTURE_2D); + glDisable (GL_BLEND); + + Sbar_Changed(); +} + +//============================================================================= + +/* +================ +Draw_BeginDisc + +Draws the little blue disc in the corner of the screen. +Call before beginning any disc IO. +================ +*/ +void Draw_BeginDisc (void) +{ + if (!draw_disc) + return; + glDrawBuffer (GL_FRONT); + Draw_Pic (vid.width - 24, 0, draw_disc); + glDrawBuffer (GL_BACK); +} + + +/* +================ +Draw_EndDisc + +Erases the disc icon. +Call after completing any disc IO +================ +*/ +void Draw_EndDisc (void) +{ +} + +/* +================ +GL_Set2D + +Setup as if the screen was 320*200 +================ +*/ +void GL_Set2D (void) +{ + glViewport (glx, gly, glwidth, glheight); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity (); + glOrtho (0, vid.width, vid.height, 0, -99999, 99999); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity (); + + glDisable (GL_DEPTH_TEST); + glDisable (GL_CULL_FACE); + glDisable (GL_BLEND); + glEnable (GL_ALPHA_TEST); +// glDisable (GL_ALPHA_TEST); + + glColor4f (1,1,1,1); +} + +//==================================================================== + +/* +================ +GL_FindTexture +================ +*/ +int GL_FindTexture (char *identifier) +{ + int i; + gltexture_t *glt; + + for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++) + { + if (!strcmp (identifier, glt->identifier)) + return gltextures[i].texnum; + } + + return -1; +} + +/* +================ +GL_ResampleTexture +================ +*/ +void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight) +{ + int i, j; + unsigned *inrow; + unsigned frac, fracstep; + + fracstep = inwidth*0x10000/outwidth; + for (i=0 ; i<outheight ; i++, out += outwidth) + { + inrow = in + inwidth*(i*inheight/outheight); + frac = fracstep >> 1; + for (j=0 ; j<outwidth ; j+=4) + { + out[j] = inrow[frac>>16]; + frac += fracstep; + out[j+1] = inrow[frac>>16]; + frac += fracstep; + out[j+2] = inrow[frac>>16]; + frac += fracstep; + out[j+3] = inrow[frac>>16]; + frac += fracstep; + } + } +} + +/* +================ +GL_Resample8BitTexture -- JACK +================ +*/ +void GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, unsigned char *out, int outwidth, int outheight) +{ + int i, j; + unsigned char *inrow; + unsigned frac, fracstep; + + fracstep = inwidth*0x10000/outwidth; + for (i=0 ; i<outheight ; i++, out += outwidth) + { + inrow = in + inwidth*(i*inheight/outheight); + frac = fracstep >> 1; + for (j=0 ; j<outwidth ; j+=4) + { + out[j] = inrow[frac>>16]; + frac += fracstep; + out[j+1] = inrow[frac>>16]; + frac += fracstep; + out[j+2] = inrow[frac>>16]; + frac += fracstep; + out[j+3] = inrow[frac>>16]; + frac += fracstep; + } + } +} + +/* +================ +GL_MipMap + +Operates in place, quartering the size of the texture +================ +*/ +void GL_MipMap (byte *in, int width, int height) +{ + int i, j; + byte *out; + + width <<=2; + height >>= 1; + out = in; + for (i=0 ; i<height ; i++, in+=width) + { + for (j=0 ; j<width ; j+=8, out+=4, in+=8) + { + out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2; + out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2; + out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2; + out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2; + } + } +} + +/* +================ +GL_MipMap8Bit + +Mipping for 8 bit textures +================ +*/ +void GL_MipMap8Bit (byte *in, int width, int height) +{ + int i, j; + byte *out; + unsigned short r,g,b; + byte *at1, *at2, *at3, *at4; + + height >>= 1; + out = in; + for (i=0 ; i<height ; i++, in+=width) + for (j=0 ; j<width ; j+=2, out+=1, in+=2) + { + at1 = (byte *) &d_8to24table[in[0]]; + at2 = (byte *) &d_8to24table[in[1]]; + at3 = (byte *) &d_8to24table[in[width+0]]; + at4 = (byte *) &d_8to24table[in[width+1]]; + + r = (at1[0]+at2[0]+at3[0]+at4[0]); r>>=5; + g = (at1[1]+at2[1]+at3[1]+at4[1]); g>>=5; + b = (at1[2]+at2[2]+at3[2]+at4[2]); b>>=5; + + out[0] = d_15to8table[(r<<0) + (g<<5) + (b<<10)]; + } +} + +/* +=============== +GL_Upload32 +=============== +*/ +void GL_Upload32 (unsigned *data, int width, int height, qboolean mipmap, qboolean alpha) +{ + int samples; +static unsigned scaled[1024*512]; // [512*256]; + int scaled_width, scaled_height; + + for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1) + ; + for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1) + ; + + scaled_width >>= (int)gl_picmip.value; + scaled_height >>= (int)gl_picmip.value; + + if (scaled_width > gl_max_size.value) + scaled_width = gl_max_size.value; + if (scaled_height > gl_max_size.value) + scaled_height = gl_max_size.value; + + if (scaled_width * scaled_height > sizeof(scaled)/4) + Sys_Error ("GL_LoadTexture: too big"); + + samples = alpha ? gl_alpha_format : gl_solid_format; + +#if 0 + if (mipmap) + gluBuild2DMipmaps (GL_TEXTURE_2D, samples, width, height, GL_RGBA, GL_UNSIGNED_BYTE, trans); + else if (scaled_width == width && scaled_height == height) + glTexImage2D (GL_TEXTURE_2D, 0, samples, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); + else + { + gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, trans, + scaled_width, scaled_height, GL_UNSIGNED_BYTE, scaled); + glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); + } +#else +texels += scaled_width * scaled_height; + + if (scaled_width == width && scaled_height == height) + { + if (!mipmap) + { + glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + goto done; + } + memcpy (scaled, data, width*height*4); + } + else + GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height); + + glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); + if (mipmap) + { + int miplevel; + + miplevel = 0; + while (scaled_width > 1 || scaled_height > 1) + { + GL_MipMap ((byte *)scaled, scaled_width, scaled_height); + scaled_width >>= 1; + scaled_height >>= 1; + if (scaled_width < 1) + scaled_width = 1; + if (scaled_height < 1) + scaled_height = 1; + miplevel++; + glTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); + } + } +done: ; +#endif + + + if (mipmap) + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + } + else + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + } +} + +void GL_Upload8_EXT (byte *data, int width, int height, qboolean mipmap, qboolean alpha) +{ + int i, s; + qboolean noalpha; + int samples; + static unsigned char scaled[1024*512]; // [512*256]; + int scaled_width, scaled_height; + + s = width*height; + // if there are no transparent pixels, make it a 3 component + // texture even if it was specified as otherwise + if (alpha) + { + noalpha = true; + for (i=0 ; i<s ; i++) + { + if (data[i] == 255) + noalpha = false; + } + + if (alpha && noalpha) + alpha = false; + } + for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1) + ; + for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1) + ; + + scaled_width >>= (int)gl_picmip.value; + scaled_height >>= (int)gl_picmip.value; + + if (scaled_width > gl_max_size.value) + scaled_width = gl_max_size.value; + if (scaled_height > gl_max_size.value) + scaled_height = gl_max_size.value; + + if (scaled_width * scaled_height > sizeof(scaled)) + Sys_Error ("GL_LoadTexture: too big"); + + samples = 1; // alpha ? gl_alpha_format : gl_solid_format; + + texels += scaled_width * scaled_height; + + if (scaled_width == width && scaled_height == height) + { + if (!mipmap) + { + glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX , GL_UNSIGNED_BYTE, data); + goto done; + } + memcpy (scaled, data, width*height); + } + else + GL_Resample8BitTexture (data, width, height, scaled, scaled_width, scaled_height); + + glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled); + if (mipmap) + { + int miplevel; + + miplevel = 0; + while (scaled_width > 1 || scaled_height > 1) + { + GL_MipMap8Bit ((byte *)scaled, scaled_width, scaled_height); + scaled_width >>= 1; + scaled_height >>= 1; + if (scaled_width < 1) + scaled_width = 1; + if (scaled_height < 1) + scaled_height = 1; + miplevel++; + glTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled); + } + } +done: ; + + if (mipmap) + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + } + else + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + } +} + +extern qboolean VID_Is8bit(); + +/* +=============== +GL_Upload8 +=============== +*/ +void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha) +{ +static unsigned trans[640*480]; // FIXME, temporary + int i, s; + qboolean noalpha; + int p; + + s = width*height; + // if there are no transparent pixels, make it a 3 component + // texture even if it was specified as otherwise + if (alpha) + { + noalpha = true; + for (i=0 ; i<s ; i++) + { + p = data[i]; + if (p == 255) + noalpha = false; + trans[i] = d_8to24table[p]; + } + + if (alpha && noalpha) + alpha = false; + } + else + { + if (s&3) + Sys_Error ("GL_Upload8: s&3"); + for (i=0 ; i<s ; i+=4) + { + trans[i] = d_8to24table[data[i]]; + trans[i+1] = d_8to24table[data[i+1]]; + trans[i+2] = d_8to24table[data[i+2]]; + trans[i+3] = d_8to24table[data[i+3]]; + } + } + + if (VID_Is8bit() && !alpha && (data!=scrap_texels[0])) { + GL_Upload8_EXT (data, width, height, mipmap, alpha); + return; + } + + GL_Upload32 (trans, width, height, mipmap, alpha); +} + +/* +================ +GL_LoadTexture +================ +*/ +int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha) +{ + int i; + gltexture_t *glt; + + // see if the texture is allready present + if (identifier[0]) + { + for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++) + { + if (!strcmp (identifier, glt->identifier)) + { + if (width != glt->width || height != glt->height) + Sys_Error ("GL_LoadTexture: cache mismatch"); + return gltextures[i].texnum; + } + } + } + else + glt = &gltextures[numgltextures]; + numgltextures++; + + strcpy (glt->identifier, identifier); + glt->texnum = texture_extension_number; + glt->width = width; + glt->height = height; + glt->mipmap = mipmap; + + GL_Bind(texture_extension_number ); + + GL_Upload8 (data, width, height, mipmap, alpha); + + texture_extension_number++; + + return texture_extension_number-1; +} + +/* +================ +GL_LoadPicTexture +================ +*/ +int GL_LoadPicTexture (qpic_t *pic) +{ + return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true); +} + +/****************************************/ + +static GLenum oldtarget = TEXTURE0_SGIS; + +void GL_SelectTexture (GLenum target) +{ + if (!gl_mtexable) + return; +#ifndef __linux__ // no multitexture under Linux yet + qglSelectTextureSGIS(target); +#endif + if (target == oldtarget) + return; + cnttextures[oldtarget-TEXTURE0_SGIS] = currenttexture; + currenttexture = cnttextures[target-TEXTURE0_SGIS]; + oldtarget = target; +} diff --git a/QW/client/gl_mesh.c b/QW/client/gl_mesh.c new file mode 100644 index 0000000..553ce78 --- /dev/null +++ b/QW/client/gl_mesh.c @@ -0,0 +1,359 @@ +/* +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. + +*/ +// gl_mesh.c: triangle model functions + +#include "quakedef.h" + +/* +================================================================= + +ALIAS MODEL DISPLAY LIST GENERATION + +================================================================= +*/ + +model_t *aliasmodel; +aliashdr_t *paliashdr; + +qboolean used[8192]; + +// the command list holds counts and s/t values that are valid for +// every frame +int commands[8192]; +int numcommands; + +// all frames will have their vertexes rearranged and expanded +// so they are in the order expected by the command list +int vertexorder[8192]; +int numorder; + +int allverts, alltris; + +int stripverts[128]; +int striptris[128]; +int stripcount; + +/* +================ +StripLength +================ +*/ +int StripLength (int starttri, int startv) +{ + int m1, m2; + int j; + mtriangle_t *last, *check; + int k; + + used[starttri] = 2; + + last = &triangles[starttri]; + + stripverts[0] = last->vertindex[(startv)%3]; + stripverts[1] = last->vertindex[(startv+1)%3]; + stripverts[2] = last->vertindex[(startv+2)%3]; + + striptris[0] = starttri; + stripcount = 1; + + m1 = last->vertindex[(startv+2)%3]; + m2 = last->vertindex[(startv+1)%3]; + + // look for a matching triangle +nexttri: + for (j=starttri+1, check=&triangles[starttri+1] ; j<pheader->numtris ; j++, check++) + { + if (check->facesfront != last->facesfront) + continue; + for (k=0 ; k<3 ; k++) + { + if (check->vertindex[k] != m1) + continue; + if (check->vertindex[ (k+1)%3 ] != m2) + continue; + + // this is the next part of the fan + + // if we can't use this triangle, this tristrip is done + if (used[j]) + goto done; + + // the new edge + if (stripcount & 1) + m2 = check->vertindex[ (k+2)%3 ]; + else + m1 = check->vertindex[ (k+2)%3 ]; + + stripverts[stripcount+2] = check->vertindex[ (k+2)%3 ]; + striptris[stripcount] = j; + stripcount++; + + used[j] = 2; + goto nexttri; + } + } +done: + + // clear the temp used flags + for (j=starttri+1 ; j<pheader->numtris ; j++) + if (used[j] == 2) + used[j] = 0; + + return stripcount; +} + +/* +=========== +FanLength +=========== +*/ +int FanLength (int starttri, int startv) +{ + int m1, m2; + int j; + mtriangle_t *last, *check; + int k; + + used[starttri] = 2; + + last = &triangles[starttri]; + + stripverts[0] = last->vertindex[(startv)%3]; + stripverts[1] = last->vertindex[(startv+1)%3]; + stripverts[2] = last->vertindex[(startv+2)%3]; + + striptris[0] = starttri; + stripcount = 1; + + m1 = last->vertindex[(startv+0)%3]; + m2 = last->vertindex[(startv+2)%3]; + + + // look for a matching triangle +nexttri: + for (j=starttri+1, check=&triangles[starttri+1] ; j<pheader->numtris ; j++, check++) + { + if (check->facesfront != last->facesfront) + continue; + for (k=0 ; k<3 ; k++) + { + if (check->vertindex[k] != m1) + continue; + if (check->vertindex[ (k+1)%3 ] != m2) + continue; + + // this is the next part of the fan + + // if we can't use this triangle, this tristrip is done + if (used[j]) + goto done; + + // the new edge + m2 = check->vertindex[ (k+2)%3 ]; + + stripverts[stripcount+2] = m2; + striptris[stripcount] = j; + stripcount++; + + used[j] = 2; + goto nexttri; + } + } +done: + + // clear the temp used flags + for (j=starttri+1 ; j<pheader->numtris ; j++) + if (used[j] == 2) + used[j] = 0; + + return stripcount; +} + + +/* +================ +BuildTris + +Generate a list of trifans or strips +for the model, which holds for all frames +================ +*/ +void BuildTris (void) +{ + int i, j, k; + int startv; + float s, t; + int len, bestlen, besttype; + int bestverts[1024]; + int besttris[1024]; + int type; + + // + // build tristrips + // + numorder = 0; + numcommands = 0; + memset (used, 0, sizeof(used)); + for (i=0 ; i<pheader->numtris ; i++) + { + // pick an unused triangle and start the trifan + if (used[i]) + continue; + + bestlen = 0; + for (type = 0 ; type < 2 ; type++) +// type = 1; + { + for (startv =0 ; startv < 3 ; startv++) + { + if (type == 1) + len = StripLength (i, startv); + else + len = FanLength (i, startv); + if (len > bestlen) + { + besttype = type; + bestlen = len; + for (j=0 ; j<bestlen+2 ; j++) + bestverts[j] = stripverts[j]; + for (j=0 ; j<bestlen ; j++) + besttris[j] = striptris[j]; + } + } + } + + // mark the tris on the best strip as used + for (j=0 ; j<bestlen ; j++) + used[besttris[j]] = 1; + + if (besttype == 1) + commands[numcommands++] = (bestlen+2); + else + commands[numcommands++] = -(bestlen+2); + + for (j=0 ; j<bestlen+2 ; j++) + { + // emit a vertex into the reorder buffer + k = bestverts[j]; + vertexorder[numorder++] = k; + + // emit s/t coords into the commands stream + s = stverts[k].s; + t = stverts[k].t; + if (!triangles[besttris[0]].facesfront && stverts[k].onseam) + s += pheader->skinwidth / 2; // on back side + s = (s + 0.5) / pheader->skinwidth; + t = (t + 0.5) / pheader->skinheight; + + *(float *)&commands[numcommands++] = s; + *(float *)&commands[numcommands++] = t; + } + } + + commands[numcommands++] = 0; // end of list marker + + Con_DPrintf ("%3i tri %3i vert %3i cmd\n", pheader->numtris, numorder, numcommands); + + allverts += numorder; + alltris += pheader->numtris; +} + + +/* +================ +GL_MakeAliasModelDisplayLists +================ +*/ +void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr) +{ + int i, j; + int *cmds; + trivertx_t *verts; + char cache[MAX_QPATH], fullpath[MAX_OSPATH]; + FILE *f; + + aliasmodel = m; + paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m); + + // + // look for a cached version + // + strcpy (cache, "glquake/"); + COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/")); + strcat (cache, ".ms2"); + + COM_FOpenFile (cache, &f); + if (f) + { + fread (&numcommands, 4, 1, f); + fread (&numorder, 4, 1, f); + fread (&commands, numcommands * sizeof(commands[0]), 1, f); + fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); + fclose (f); + } + else + { + // + // build it from scratch + // + Con_Printf ("meshing %s...\n",m->name); + + BuildTris (); // trifans or lists + + // + // save out the cached version + // + sprintf (fullpath, "%s/%s", com_gamedir, cache); + f = fopen (fullpath, "wb"); + if (!f) { + char gldir[MAX_OSPATH]; + + sprintf (gldir, "%s/glquake", com_gamedir); + Sys_mkdir (gldir); + f = fopen (fullpath, "wb"); + } + + if (f) + { + fwrite (&numcommands, 4, 1, f); + fwrite (&numorder, 4, 1, f); + fwrite (&commands, numcommands * sizeof(commands[0]), 1, f); + fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); + fclose (f); + } + } + + + // save the data out + + paliashdr->poseverts = numorder; + + cmds = Hunk_Alloc (numcommands * 4); + paliashdr->commands = (byte *)cmds - (byte *)paliashdr; + memcpy (cmds, commands, numcommands * 4); + + verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts + * sizeof(trivertx_t) ); + paliashdr->posedata = (byte *)verts - (byte *)paliashdr; + for (i=0 ; i<paliashdr->numposes ; i++) + for (j=0 ; j<numorder ; j++) + *verts++ = poseverts[i][vertexorder[j]]; +} + diff --git a/QW/client/gl_model.c b/QW/client/gl_model.c new file mode 100644 index 0000000..20afbec --- /dev/null +++ b/QW/client/gl_model.c @@ -0,0 +1,1884 @@ +/* +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. + +*/ +// models.c -- model loading and caching + +// models are the only shared resource between a client and server running +// on the same machine. + +#include "quakedef.h" + +model_t *loadmodel; +char loadname[32]; // for hunk tags + +void Mod_LoadSpriteModel (model_t *mod, void *buffer); +void Mod_LoadBrushModel (model_t *mod, void *buffer); +void Mod_LoadAliasModel (model_t *mod, void *buffer); +model_t *Mod_LoadModel (model_t *mod, qboolean crash); + +byte mod_novis[MAX_MAP_LEAFS/8]; + +#define MAX_MOD_KNOWN 512 +model_t mod_known[MAX_MOD_KNOWN]; +int mod_numknown; + +cvar_t gl_subdivide_size = {"gl_subdivide_size", "128", true}; + +/* +=============== +Mod_Init +=============== +*/ +void Mod_Init (void) +{ + Cvar_RegisterVariable (&gl_subdivide_size); + memset (mod_novis, 0xff, sizeof(mod_novis)); +} + +/* +=============== +Mod_Init + +Caches the data if needed +=============== +*/ +void *Mod_Extradata (model_t *mod) +{ + void *r; + + r = Cache_Check (&mod->cache); + if (r) + return r; + + Mod_LoadModel (mod, true); + + if (!mod->cache.data) + Sys_Error ("Mod_Extradata: caching failed"); + return mod->cache.data; +} + +/* +=============== +Mod_PointInLeaf +=============== +*/ +mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) +{ + mnode_t *node; + float d; + mplane_t *plane; + + if (!model || !model->nodes) + Sys_Error ("Mod_PointInLeaf: bad model"); + + node = model->nodes; + while (1) + { + if (node->contents < 0) + return (mleaf_t *)node; + plane = node->plane; + d = DotProduct (p,plane->normal) - plane->dist; + if (d > 0) + node = node->children[0]; + else + node = node->children[1]; + } + + return NULL; // never reached +} + + +/* +=================== +Mod_DecompressVis +=================== +*/ +byte *Mod_DecompressVis (byte *in, model_t *model) +{ + static byte decompressed[MAX_MAP_LEAFS/8]; + int c; + byte *out; + int row; + + row = (model->numleafs+7)>>3; + out = decompressed; + +#if 0 + memcpy (out, in, row); +#else + if (!in) + { // no vis info, so make all visible + while (row) + { + *out++ = 0xff; + row--; + } + return decompressed; + } + + do + { + if (*in) + { + *out++ = *in++; + continue; + } + + c = in[1]; + in += 2; + while (c) + { + *out++ = 0; + c--; + } + } while (out - decompressed < row); +#endif + + return decompressed; +} + +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) +{ + if (leaf == model->leafs) + return mod_novis; + return Mod_DecompressVis (leaf->compressed_vis, model); +} + +/* +=================== +Mod_ClearAll +=================== +*/ +void Mod_ClearAll (void) +{ + int i; + model_t *mod; + + for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) + if (mod->type != mod_alias) + mod->needload = true; +} + +/* +================== +Mod_FindName + +================== +*/ +model_t *Mod_FindName (char *name) +{ + int i; + model_t *mod; + + if (!name[0]) + Sys_Error ("Mod_ForName: NULL name"); + +// +// search the currently loaded models +// + for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) + if (!strcmp (mod->name, name) ) + break; + + if (i == mod_numknown) + { + if (mod_numknown == MAX_MOD_KNOWN) + Sys_Error ("mod_numknown == MAX_MOD_KNOWN"); + strcpy (mod->name, name); + mod->needload = true; + mod_numknown++; + } + + return mod; +} + +/* +================== +Mod_TouchModel + +================== +*/ +void Mod_TouchModel (char *name) +{ + model_t *mod; + + mod = Mod_FindName (name); + + if (!mod->needload) + { + if (mod->type == mod_alias) + Cache_Check (&mod->cache); + } +} + +/* +================== +Mod_LoadModel + +Loads a model into the cache +================== +*/ +model_t *Mod_LoadModel (model_t *mod, qboolean crash) +{ + void *d; + unsigned *buf; + byte stackbuf[1024]; // avoid dirtying the cache heap + + if (!mod->needload) + { + if (mod->type == mod_alias) + { + d = Cache_Check (&mod->cache); + if (d) + return mod; + } + else + return mod; // not cached at all + } + +// +// because the world is so huge, load it one piece at a time +// + if (!crash) + { + + } + +// +// load the file +// + buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf)); + if (!buf) + { + if (crash) + Sys_Error ("Mod_NumForName: %s not found", mod->name); + return NULL; + } + +// +// allocate a new model +// + COM_FileBase (mod->name, loadname); + + loadmodel = mod; + +// +// fill it in +// + +// call the apropriate loader + mod->needload = false; + + switch (LittleLong(*(unsigned *)buf)) + { + case IDPOLYHEADER: + Mod_LoadAliasModel (mod, buf); + break; + + case IDSPRITEHEADER: + Mod_LoadSpriteModel (mod, buf); + break; + + default: + Mod_LoadBrushModel (mod, buf); + break; + } + + return mod; +} + +/* +================== +Mod_ForName + +Loads in a model for the given name +================== +*/ +model_t *Mod_ForName (char *name, qboolean crash) +{ + model_t *mod; + + mod = Mod_FindName (name); + + return Mod_LoadModel (mod, crash); +} + + +/* +=============================================================================== + + BRUSHMODEL LOADING + +=============================================================================== +*/ + +byte *mod_base; + + +/* +================= +Mod_LoadTextures +================= +*/ +void Mod_LoadTextures (lump_t *l) +{ + int i, j, pixels, num, max, altmax; + miptex_t *mt; + texture_t *tx, *tx2; + texture_t *anims[10]; + texture_t *altanims[10]; + dmiptexlump_t *m; + + if (!l->filelen) + { + loadmodel->textures = NULL; + return; + } + m = (dmiptexlump_t *)(mod_base + l->fileofs); + + m->nummiptex = LittleLong (m->nummiptex); + + loadmodel->numtextures = m->nummiptex; + loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); + + for (i=0 ; i<m->nummiptex ; i++) + { + m->dataofs[i] = LittleLong(m->dataofs[i]); + if (m->dataofs[i] == -1) + continue; + mt = (miptex_t *)((byte *)m + m->dataofs[i]); + mt->width = LittleLong (mt->width); + mt->height = LittleLong (mt->height); + for (j=0 ; j<MIPLEVELS ; j++) + mt->offsets[j] = LittleLong (mt->offsets[j]); + + if ( (mt->width & 15) || (mt->height & 15) ) + Sys_Error ("Texture %s is not 16 aligned", mt->name); + pixels = mt->width*mt->height/64*85; + tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); + loadmodel->textures[i] = tx; + + memcpy (tx->name, mt->name, sizeof(tx->name)); + tx->width = mt->width; + tx->height = mt->height; + for (j=0 ; j<MIPLEVELS ; j++) + tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); + // the pixels immediately follow the structures + memcpy ( tx+1, mt+1, pixels); + + + if (!Q_strncmp(mt->name,"sky",3)) + R_InitSky (tx); + else + { + texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; + tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false); + texture_mode = GL_LINEAR; + } + } + +// +// sequence the animations +// + for (i=0 ; i<m->nummiptex ; i++) + { + tx = loadmodel->textures[i]; + if (!tx || tx->name[0] != '+') + continue; + if (tx->anim_next) + continue; // allready sequenced + + // find the number of frames in the animation + memset (anims, 0, sizeof(anims)); + memset (altanims, 0, sizeof(altanims)); + + max = tx->name[1]; + altmax = 0; + if (max >= 'a' && max <= 'z') + max -= 'a' - 'A'; + if (max >= '0' && max <= '9') + { + max -= '0'; + altmax = 0; + anims[max] = tx; + max++; + } + else if (max >= 'A' && max <= 'J') + { + altmax = max - 'A'; + max = 0; + altanims[altmax] = tx; + altmax++; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + + for (j=i+1 ; j<m->nummiptex ; j++) + { + tx2 = loadmodel->textures[j]; + if (!tx2 || tx2->name[0] != '+') + continue; + if (strcmp (tx2->name+2, tx->name+2)) + continue; + + num = tx2->name[1]; + if (num >= 'a' && num <= 'z') + num -= 'a' - 'A'; + if (num >= '0' && num <= '9') + { + num -= '0'; + anims[num] = tx2; + if (num+1 > max) + max = num + 1; + } + else if (num >= 'A' && num <= 'J') + { + num = num - 'A'; + altanims[num] = tx2; + if (num+1 > altmax) + altmax = num+1; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + } + +#define ANIM_CYCLE 2 + // link them all together + for (j=0 ; j<max ; j++) + { + tx2 = anims[j]; + if (!tx2) + Sys_Error ("Missing frame %i of %s",j, tx->name); + tx2->anim_total = max * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = anims[ (j+1)%max ]; + if (altmax) + tx2->alternate_anims = altanims[0]; + } + for (j=0 ; j<altmax ; j++) + { + tx2 = altanims[j]; + if (!tx2) + Sys_Error ("Missing frame %i of %s",j, tx->name); + tx2->anim_total = altmax * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = altanims[ (j+1)%altmax ]; + if (max) + tx2->alternate_anims = anims[0]; + } + } +} + +/* +================= +Mod_LoadLighting +================= +*/ +void Mod_LoadLighting (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->lightdata = NULL; + return; + } + loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadVisibility +================= +*/ +void Mod_LoadVisibility (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->visdata = NULL; + return; + } + loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadEntities +================= +*/ +void Mod_LoadEntities (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->entities = NULL; + return; + } + loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadVertexes +================= +*/ +void Mod_LoadVertexes (lump_t *l) +{ + dvertex_t *in; + mvertex_t *out; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->vertexes = out; + loadmodel->numvertexes = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + out->position[0] = LittleFloat (in->point[0]); + out->position[1] = LittleFloat (in->point[1]); + out->position[2] = LittleFloat (in->point[2]); + } +} + +/* +================= +Mod_LoadSubmodels +================= +*/ +void Mod_LoadSubmodels (lump_t *l) +{ + dmodel_t *in; + dmodel_t *out; + int i, j, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->submodels = out; + loadmodel->numsubmodels = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + for (j=0 ; j<3 ; j++) + { // spread the mins / maxs by a pixel + out->mins[j] = LittleFloat (in->mins[j]) - 1; + out->maxs[j] = LittleFloat (in->maxs[j]) + 1; + out->origin[j] = LittleFloat (in->origin[j]); + } + for (j=0 ; j<MAX_MAP_HULLS ; j++) + out->headnode[j] = LittleLong (in->headnode[j]); + out->visleafs = LittleLong (in->visleafs); + out->firstface = LittleLong (in->firstface); + out->numfaces = LittleLong (in->numfaces); + } +} + +/* +================= +Mod_LoadEdges +================= +*/ +void Mod_LoadEdges (lump_t *l) +{ + dedge_t *in; + medge_t *out; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); + + loadmodel->edges = out; + loadmodel->numedges = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + out->v[0] = (unsigned short)LittleShort(in->v[0]); + out->v[1] = (unsigned short)LittleShort(in->v[1]); + } +} + +/* +================= +Mod_LoadTexinfo +================= +*/ +void Mod_LoadTexinfo (lump_t *l) +{ + texinfo_t *in; + mtexinfo_t *out; + int i, j, count; + int miptex; + float len1, len2; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->texinfo = out; + loadmodel->numtexinfo = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + for (j=0 ; j<8 ; j++) + out->vecs[0][j] = LittleFloat (in->vecs[0][j]); + len1 = Length (out->vecs[0]); + len2 = Length (out->vecs[1]); + len1 = (len1 + len2)/2; + if (len1 < 0.32) + out->mipadjust = 4; + else if (len1 < 0.49) + out->mipadjust = 3; + else if (len1 < 0.99) + out->mipadjust = 2; + else + out->mipadjust = 1; +#if 0 + if (len1 + len2 < 0.001) + out->mipadjust = 1; // don't crash + else + out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 ); +#endif + + miptex = LittleLong (in->miptex); + out->flags = LittleLong (in->flags); + + if (!loadmodel->textures) + { + out->texture = r_notexture_mip; // checkerboard texture + out->flags = 0; + } + else + { + if (miptex >= loadmodel->numtextures) + Sys_Error ("miptex >= loadmodel->numtextures"); + out->texture = loadmodel->textures[miptex]; + if (!out->texture) + { + out->texture = r_notexture_mip; // texture not found + out->flags = 0; + } + } + } +} + +/* +================ +CalcSurfaceExtents + +Fills in s->texturemins[] and s->extents[] +================ +*/ +void CalcSurfaceExtents (msurface_t *s) +{ + float mins[2], maxs[2], val; + int i,j, e; + mvertex_t *v; + mtexinfo_t *tex; + int bmins[2], bmaxs[2]; + + mins[0] = mins[1] = 999999; + maxs[0] = maxs[1] = -99999; + + tex = s->texinfo; + + for (i=0 ; i<s->numedges ; i++) + { + e = loadmodel->surfedges[s->firstedge+i]; + if (e >= 0) + v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; + else + v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; + + for (j=0 ; j<2 ; j++) + { + val = v->position[0] * tex->vecs[j][0] + + v->position[1] * tex->vecs[j][1] + + v->position[2] * tex->vecs[j][2] + + tex->vecs[j][3]; + if (val < mins[j]) + mins[j] = val; + if (val > maxs[j]) + maxs[j] = val; + } + } + + for (i=0 ; i<2 ; i++) + { + bmins[i] = floor(mins[i]/16); + bmaxs[i] = ceil(maxs[i]/16); + + s->texturemins[i] = bmins[i] * 16; + s->extents[i] = (bmaxs[i] - bmins[i]) * 16; + if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 /* 256 */ ) + Sys_Error ("Bad surface extents"); + } +} + + +/* +================= +Mod_LoadFaces +================= +*/ +void Mod_LoadFaces (lump_t *l) +{ + dface_t *in; + msurface_t *out; + int i, count, surfnum; + int planenum, side; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++) + { + out->firstedge = LittleLong(in->firstedge); + out->numedges = LittleShort(in->numedges); + out->flags = 0; + + planenum = LittleShort(in->planenum); + side = LittleShort(in->side); + if (side) + out->flags |= SURF_PLANEBACK; + + out->plane = loadmodel->planes + planenum; + + out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); + + CalcSurfaceExtents (out); + + // lighting info + + for (i=0 ; i<MAXLIGHTMAPS ; i++) + out->styles[i] = in->styles[i]; + i = LittleLong(in->lightofs); + if (i == -1) + out->samples = NULL; + else + out->samples = loadmodel->lightdata + i; + + // set the drawing flags flag + + if (!Q_strncmp(out->texinfo->texture->name,"sky",3)) // sky + { + out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); +#ifndef QUAKE2 + GL_SubdivideSurface (out); // cut up polygon for warps +#endif + continue; + } + + if (!Q_strncmp(out->texinfo->texture->name,"*",1)) // turbulent + { + out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); + for (i=0 ; i<2 ; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + GL_SubdivideSurface (out); // cut up polygon for warps + continue; + } + + } +} + + +/* +================= +Mod_SetParent +================= +*/ +void Mod_SetParent (mnode_t *node, mnode_t *parent) +{ + node->parent = parent; + if (node->contents < 0) + return; + Mod_SetParent (node->children[0], node); + Mod_SetParent (node->children[1], node); +} + +/* +================= +Mod_LoadNodes +================= +*/ +void Mod_LoadNodes (lump_t *l) +{ + int i, j, count, p; + dnode_t *in; + mnode_t *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->nodes = out; + loadmodel->numnodes = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + for (j=0 ; j<3 ; j++) + { + out->minmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->planenum); + out->plane = loadmodel->planes + p; + + out->firstsurface = LittleShort (in->firstface); + out->numsurfaces = LittleShort (in->numfaces); + + for (j=0 ; j<2 ; j++) + { + p = LittleShort (in->children[j]); + if (p >= 0) + out->children[j] = loadmodel->nodes + p; + else + out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); + } + } + + Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs +} + +/* +================= +Mod_LoadLeafs +================= +*/ +void Mod_LoadLeafs (lump_t *l) +{ + dleaf_t *in; + mleaf_t *out; + int i, j, count, p; + char s[80]; + qboolean isnotmap = true; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->leafs = out; + loadmodel->numleafs = count; + sprintf(s, "maps/%s.bsp", Info_ValueForKey(cl.serverinfo,"map")); + if (!strcmp(s, loadmodel->name)) + isnotmap = false; + for ( i=0 ; i<count ; i++, in++, out++) + { + for (j=0 ; j<3 ; j++) + { + out->minmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->contents); + out->contents = p; + + out->firstmarksurface = loadmodel->marksurfaces + + LittleShort(in->firstmarksurface); + out->nummarksurfaces = LittleShort(in->nummarksurfaces); + + p = LittleLong(in->visofs); + if (p == -1) + out->compressed_vis = NULL; + else + out->compressed_vis = loadmodel->visdata + p; + out->efrags = NULL; + + for (j=0 ; j<4 ; j++) + out->ambient_sound_level[j] = in->ambient_level[j]; + + // gl underwater warp + if (out->contents != CONTENTS_EMPTY) + { + for (j=0 ; j<out->nummarksurfaces ; j++) + out->firstmarksurface[j]->flags |= SURF_UNDERWATER; + } + if (isnotmap) + { + for (j=0 ; j<out->nummarksurfaces ; j++) + out->firstmarksurface[j]->flags |= SURF_DONTWARP; + } + } +} + +/* +================= +Mod_LoadClipnodes +================= +*/ +void Mod_LoadClipnodes (lump_t *l) +{ + dclipnode_t *in, *out; + int i, count; + hull_t *hull; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->clipnodes = out; + loadmodel->numclipnodes = count; + + hull = &loadmodel->hulls[1]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -16; + hull->clip_mins[1] = -16; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 16; + hull->clip_maxs[1] = 16; + hull->clip_maxs[2] = 32; + + hull = &loadmodel->hulls[2]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -32; + hull->clip_mins[1] = -32; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 32; + hull->clip_maxs[1] = 32; + hull->clip_maxs[2] = 64; + + for (i=0 ; i<count ; i++, out++, in++) + { + out->planenum = LittleLong(in->planenum); + out->children[0] = LittleShort(in->children[0]); + out->children[1] = LittleShort(in->children[1]); + } +} + +/* +================= +Mod_MakeHull0 + +Deplicate the drawing hull structure as a clipping hull +================= +*/ +void Mod_MakeHull0 (void) +{ + mnode_t *in, *child; + dclipnode_t *out; + int i, j, count; + hull_t *hull; + + hull = &loadmodel->hulls[0]; + + in = loadmodel->nodes; + count = loadmodel->numnodes; + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + + for (i=0 ; i<count ; i++, out++, in++) + { + out->planenum = in->plane - loadmodel->planes; + for (j=0 ; j<2 ; j++) + { + child = in->children[j]; + if (child->contents < 0) + out->children[j] = child->contents; + else + out->children[j] = child - loadmodel->nodes; + } + } +} + +/* +================= +Mod_LoadMarksurfaces +================= +*/ +void Mod_LoadMarksurfaces (lump_t *l) +{ + int i, j, count; + short *in; + msurface_t **out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->marksurfaces = out; + loadmodel->nummarksurfaces = count; + + for ( i=0 ; i<count ; i++) + { + j = LittleShort(in[i]); + if (j >= loadmodel->numsurfaces) + Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); + out[i] = loadmodel->surfaces + j; + } +} + +/* +================= +Mod_LoadSurfedges +================= +*/ +void Mod_LoadSurfedges (lump_t *l) +{ + int i, count; + int *in, *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfedges = out; + loadmodel->numsurfedges = count; + + for ( i=0 ; i<count ; i++) + out[i] = LittleLong (in[i]); +} + + +/* +================= +Mod_LoadPlanes +================= +*/ +void Mod_LoadPlanes (lump_t *l) +{ + int i, j; + mplane_t *out; + dplane_t *in; + int count; + int bits; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*2*sizeof(*out), loadname); + + loadmodel->planes = out; + loadmodel->numplanes = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + bits = 0; + for (j=0 ; j<3 ; j++) + { + out->normal[j] = LittleFloat (in->normal[j]); + if (out->normal[j] < 0) + bits |= 1<<j; + } + + out->dist = LittleFloat (in->dist); + out->type = LittleLong (in->type); + out->signbits = bits; + } +} + +/* +================= +RadiusFromBounds +================= +*/ +float RadiusFromBounds (vec3_t mins, vec3_t maxs) +{ + int i; + vec3_t corner; + + for (i=0 ; i<3 ; i++) + { + corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]); + } + + return Length (corner); +} + +/* +================= +Mod_LoadBrushModel +================= +*/ +void Mod_LoadBrushModel (model_t *mod, void *buffer) +{ + int i, j; + dheader_t *header; + dmodel_t *bm; + + loadmodel->type = mod_brush; + + header = (dheader_t *)buffer; + + i = LittleLong (header->version); + if (i != BSPVERSION) + Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); + +// swap all the lumps + mod_base = (byte *)header; + + for (i=0 ; i<sizeof(dheader_t)/4 ; i++) + ((int *)header)[i] = LittleLong ( ((int *)header)[i]); + +// checksum all of the map, except for entities + mod->checksum = 0; + mod->checksum2 = 0; + + for (i = 0; i < HEADER_LUMPS; i++) { + if (i == LUMP_ENTITIES) + continue; + mod->checksum ^= Com_BlockChecksum(mod_base + header->lumps[i].fileofs, + header->lumps[i].filelen); + + if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES) + continue; + mod->checksum2 ^= Com_BlockChecksum(mod_base + header->lumps[i].fileofs, + header->lumps[i].filelen); + } + + +// load into heap + + Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); + Mod_LoadEdges (&header->lumps[LUMP_EDGES]); + Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); + Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); + Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); + Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); + Mod_LoadFaces (&header->lumps[LUMP_FACES]); + Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); + Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); + Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); + Mod_LoadNodes (&header->lumps[LUMP_NODES]); + Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); + Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); + Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); + + Mod_MakeHull0 (); + + mod->numframes = 2; // regular and alternate animation + +// +// set up the submodels (FIXME: this is confusing) +// + for (i=0 ; i<mod->numsubmodels ; i++) + { + bm = &mod->submodels[i]; + + mod->hulls[0].firstclipnode = bm->headnode[0]; + for (j=1 ; j<MAX_MAP_HULLS ; j++) + { + mod->hulls[j].firstclipnode = bm->headnode[j]; + mod->hulls[j].lastclipnode = mod->numclipnodes-1; + } + + mod->firstmodelsurface = bm->firstface; + mod->nummodelsurfaces = bm->numfaces; + + VectorCopy (bm->maxs, mod->maxs); + VectorCopy (bm->mins, mod->mins); + + mod->radius = RadiusFromBounds (mod->mins, mod->maxs); + + mod->numleafs = bm->visleafs; + + if (i < mod->numsubmodels-1) + { // duplicate the basic information + char name[10]; + + sprintf (name, "*%i", i+1); + loadmodel = Mod_FindName (name); + *loadmodel = *mod; + strcpy (loadmodel->name, name); + mod = loadmodel; + } + } +} + +/* +============================================================================== + +ALIAS MODELS + +============================================================================== +*/ + +aliashdr_t *pheader; + +stvert_t stverts[MAXALIASVERTS]; +mtriangle_t triangles[MAXALIASTRIS]; + +// a pose is a single set of vertexes. a frame may be +// an animating sequence of poses +trivertx_t *poseverts[MAXALIASFRAMES]; +int posenum; + +byte player_8bit_texels[320*200]; + +/* +================= +Mod_LoadAliasFrame +================= +*/ +void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame) +{ + trivertx_t *pinframe; + int i; + daliasframe_t *pdaliasframe; + + pdaliasframe = (daliasframe_t *)pin; + + strcpy (frame->name, pdaliasframe->name); + frame->firstpose = posenum; + frame->numposes = 1; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about + // endianness + frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; + frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i]; + } + + pinframe = (trivertx_t *)(pdaliasframe + 1); + + poseverts[posenum] = pinframe; + posenum++; + + pinframe += pheader->numverts; + + return (void *)pinframe; +} + + +/* +================= +Mod_LoadAliasGroup +================= +*/ +void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) +{ + daliasgroup_t *pingroup; + int i, numframes; + daliasinterval_t *pin_intervals; + void *ptemp; + + pingroup = (daliasgroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + frame->firstpose = posenum; + frame->numposes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; + frame->bboxmin.v[i] = pingroup->bboxmax.v[i]; + } + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + frame->interval = LittleFloat (pin_intervals->interval); + + pin_intervals += numframes; + + ptemp = (void *)pin_intervals; + + for (i=0 ; i<numframes ; i++) + { + poseverts[posenum] = (trivertx_t *)((daliasframe_t *)ptemp + 1); + posenum++; + + ptemp = (trivertx_t *)((daliasframe_t *)ptemp + 1) + pheader->numverts; + } + + return ptemp; +} + +//========================================================= + +/* +================= +Mod_FloodFillSkin + +Fill background pixels so mipmapping doesn't have haloes - Ed +================= +*/ + +typedef struct +{ + short x, y; +} floodfill_t; + +extern unsigned d_8to24table[]; + +// must be a power of 2 +#define FLOODFILL_FIFO_SIZE 0x1000 +#define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1) + +#define FLOODFILL_STEP( off, dx, dy ) \ +{ \ + if (pos[off] == fillcolor) \ + { \ + pos[off] = 255; \ + fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \ + inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \ + } \ + else if (pos[off] != 255) fdc = pos[off]; \ +} + +void Mod_FloodFillSkin( byte *skin, int skinwidth, int skinheight ) +{ + byte fillcolor = *skin; // assume this is the pixel to fill + floodfill_t fifo[FLOODFILL_FIFO_SIZE]; + int inpt = 0, outpt = 0; + int filledcolor = -1; + int i; + + if (filledcolor == -1) + { + filledcolor = 0; + // attempt to find opaque black + for (i = 0; i < 256; ++i) + if (d_8to24table[i] == (255 << 0)) // alpha 1.0 + { + filledcolor = i; + break; + } + } + + // can't fill to filled color or to transparent color (used as visited marker) + if ((fillcolor == filledcolor) || (fillcolor == 255)) + { + //printf( "not filling skin from %d to %d\n", fillcolor, filledcolor ); + return; + } + + fifo[inpt].x = 0, fifo[inpt].y = 0; + inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; + + while (outpt != inpt) + { + int x = fifo[outpt].x, y = fifo[outpt].y; + int fdc = filledcolor; + byte *pos = &skin[x + skinwidth * y]; + + outpt = (outpt + 1) & FLOODFILL_FIFO_MASK; + + if (x > 0) FLOODFILL_STEP( -1, -1, 0 ); + if (x < skinwidth - 1) FLOODFILL_STEP( 1, 1, 0 ); + if (y > 0) FLOODFILL_STEP( -skinwidth, 0, -1 ); + if (y < skinheight - 1) FLOODFILL_STEP( skinwidth, 0, 1 ); + skin[x + skinwidth * y] = fdc; + } +} + +/* +=============== +Mod_LoadAllSkins +=============== +*/ +void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) +{ + int i, j, k; + char name[32]; + int s; + byte *skin; + daliasskingroup_t *pinskingroup; + int groupskins; + daliasskininterval_t *pinskinintervals; + + skin = (byte *)(pskintype + 1); + + if (numskins < 1 || numskins > MAX_SKINS) + Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); + + s = pheader->skinwidth * pheader->skinheight; + + for (i=0 ; i<numskins ; i++) + { + if (pskintype->type == ALIAS_SKIN_SINGLE) { + Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); + + // save 8 bit texels for the player model to remap + // save 8 bit texels for the player model to remap + if (!strcmp(loadmodel->name,"progs/player.mdl")) + { + if (s > sizeof(player_8bit_texels)) + Sys_Error ("Player skin too large"); + memcpy (player_8bit_texels, (byte *)(pskintype + 1), s); + } + sprintf (name, "%s_%i", loadmodel->name, i); + pheader->gl_texturenum[i][0] = + pheader->gl_texturenum[i][1] = + pheader->gl_texturenum[i][2] = + pheader->gl_texturenum[i][3] = + GL_LoadTexture (name, pheader->skinwidth, + pheader->skinheight, (byte *)(pskintype + 1), true, false); + pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + s); + } else { + // animating skin group. yuck. + pskintype++; + pinskingroup = (daliasskingroup_t *)pskintype; + groupskins = LittleLong (pinskingroup->numskins); + pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); + + pskintype = (void *)(pinskinintervals + groupskins); + + for (j=0 ; j<groupskins ; j++) + { + Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); + sprintf (name, "%s_%i_%i", loadmodel->name, i,j); + pheader->gl_texturenum[i][j&3] = + GL_LoadTexture (name, pheader->skinwidth, + pheader->skinheight, (byte *)(pskintype), true, false); + pskintype = (daliasskintype_t *)((byte *)(pskintype) + s); + } + k = j; + for (/* */; j < 4; j++) + pheader->gl_texturenum[i][j&3] = + pheader->gl_texturenum[i][j - k]; + } + } + + return (void *)pskintype; +} + + +//========================================================================= + +/* +================= +Mod_LoadAliasModel +================= +*/ +void Mod_LoadAliasModel (model_t *mod, void *buffer) +{ + int i, j; + mdl_t *pinmodel; + stvert_t *pinstverts; + dtriangle_t *pintriangles; + int version, numframes; + int size; + daliasframetype_t *pframetype; + daliasskintype_t *pskintype; + int start, end, total; + + if (!strcmp(loadmodel->name, "progs/player.mdl") || + !strcmp(loadmodel->name, "progs/eyes.mdl")) { + unsigned short crc; + byte *p; + int len; + char st[40]; + + CRC_Init(&crc); + for (len = com_filesize, p = buffer; len; len--, p++) + CRC_ProcessByte(&crc, *p); + + sprintf(st, "%d", (int) crc); + Info_SetValueForKey (cls.userinfo, + !strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name, + st, MAX_INFO_STRING); + + if (cls.state >= ca_connected) { + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + sprintf(st, "setinfo %s %d", + !strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name, + (int)crc); + SZ_Print (&cls.netchan.message, st); + } + } + + start = Hunk_LowMark (); + + pinmodel = (mdl_t *)buffer; + + version = LittleLong (pinmodel->version); + if (version != ALIAS_VERSION) + Sys_Error ("%s has wrong version number (%i should be %i)", + mod->name, version, ALIAS_VERSION); + +// +// allocate space for a working header, plus all the data except the frames, +// skin and group info +// + size = sizeof (aliashdr_t) + + (LittleLong (pinmodel->numframes) - 1) * + sizeof (pheader->frames[0]); + pheader = Hunk_AllocName (size, loadname); + + mod->flags = LittleLong (pinmodel->flags); + +// +// endian-adjust and copy the data, starting with the alias model header +// + pheader->boundingradius = LittleFloat (pinmodel->boundingradius); + pheader->numskins = LittleLong (pinmodel->numskins); + pheader->skinwidth = LittleLong (pinmodel->skinwidth); + pheader->skinheight = LittleLong (pinmodel->skinheight); + + if (pheader->skinheight > MAX_LBM_HEIGHT) + Sys_Error ("model %s has a skin taller than %d", mod->name, + MAX_LBM_HEIGHT); + + pheader->numverts = LittleLong (pinmodel->numverts); + + if (pheader->numverts <= 0) + Sys_Error ("model %s has no vertices", mod->name); + + if (pheader->numverts > MAXALIASVERTS) + Sys_Error ("model %s has too many vertices", mod->name); + + pheader->numtris = LittleLong (pinmodel->numtris); + + if (pheader->numtris <= 0) + Sys_Error ("model %s has no triangles", mod->name); + + pheader->numframes = LittleLong (pinmodel->numframes); + numframes = pheader->numframes; + if (numframes < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); + + pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; + mod->synctype = LittleLong (pinmodel->synctype); + mod->numframes = pheader->numframes; + + for (i=0 ; i<3 ; i++) + { + pheader->scale[i] = LittleFloat (pinmodel->scale[i]); + pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); + pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); + } + + +// +// load the skins +// + pskintype = (daliasskintype_t *)&pinmodel[1]; + pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype); + +// +// load base s and t vertices +// + pinstverts = (stvert_t *)pskintype; + + for (i=0 ; i<pheader->numverts ; i++) + { + stverts[i].onseam = LittleLong (pinstverts[i].onseam); + stverts[i].s = LittleLong (pinstverts[i].s); + stverts[i].t = LittleLong (pinstverts[i].t); + } + +// +// load triangle lists +// + pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; + + for (i=0 ; i<pheader->numtris ; i++) + { + triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); + + for (j=0 ; j<3 ; j++) + { + triangles[i].vertindex[j] = + LittleLong (pintriangles[i].vertindex[j]); + } + } + +// +// load the frames +// + posenum = 0; + pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; + + for (i=0 ; i<numframes ; i++) + { + aliasframetype_t frametype; + + frametype = LittleLong (pframetype->type); + + if (frametype == ALIAS_SINGLE) + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); + } + else + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); + } + } + + pheader->numposes = posenum; + + mod->type = mod_alias; + +// FIXME: do this right + mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; + mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; + + // + // build the draw lists + // + GL_MakeAliasModelDisplayLists (mod, pheader); + +// +// move the complete, relocatable alias model to the cache +// + end = Hunk_LowMark (); + total = end - start; + + Cache_Alloc (&mod->cache, total, loadname); + if (!mod->cache.data) + return; + memcpy (mod->cache.data, pheader, total); + + Hunk_FreeToLowMark (start); +} + +//============================================================================= + +/* +================= +Mod_LoadSpriteFrame +================= +*/ +void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum) +{ + dspriteframe_t *pinframe; + mspriteframe_t *pspriteframe; + int width, height, size, origin[2]; + char name[64]; + + pinframe = (dspriteframe_t *)pin; + + width = LittleLong (pinframe->width); + height = LittleLong (pinframe->height); + size = width * height; + + pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t),loadname); + + Q_memset (pspriteframe, 0, sizeof (mspriteframe_t)); + + *ppframe = pspriteframe; + + pspriteframe->width = width; + pspriteframe->height = height; + origin[0] = LittleLong (pinframe->origin[0]); + origin[1] = LittleLong (pinframe->origin[1]); + + pspriteframe->up = origin[1]; + pspriteframe->down = origin[1] - height; + pspriteframe->left = origin[0]; + pspriteframe->right = width + origin[0]; + + sprintf (name, "%s_%i", loadmodel->name, framenum); + pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (byte *)(pinframe + 1), true, true); + + return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size); +} + + +/* +================= +Mod_LoadSpriteGroup +================= +*/ +void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum) +{ + dspritegroup_t *pingroup; + mspritegroup_t *pspritegroup; + int i, numframes; + dspriteinterval_t *pin_intervals; + float *poutintervals; + void *ptemp; + + pingroup = (dspritegroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + + (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); + + pspritegroup->numframes = numframes; + + *ppframe = (mspriteframe_t *)pspritegroup; + + pin_intervals = (dspriteinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + pspritegroup->intervals = poutintervals; + + for (i=0 ; i<numframes ; i++) + { + *poutintervals = LittleFloat (pin_intervals->interval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; i<numframes ; i++) + { + ptemp = Mod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i], framenum * 100 + i); + } + + return ptemp; +} + + +/* +================= +Mod_LoadSpriteModel +================= +*/ +void Mod_LoadSpriteModel (model_t *mod, void *buffer) +{ + int i; + int version; + dsprite_t *pin; + msprite_t *psprite; + int numframes; + int size; + dspriteframetype_t *pframetype; + + pin = (dsprite_t *)buffer; + + version = LittleLong (pin->version); + if (version != SPRITE_VERSION) + Sys_Error ("%s has wrong version number " + "(%i should be %i)", mod->name, version, SPRITE_VERSION); + + numframes = LittleLong (pin->numframes); + + size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); + + psprite = Hunk_AllocName (size, loadname); + + mod->cache.data = psprite; + + psprite->type = LittleLong (pin->type); + psprite->maxwidth = LittleLong (pin->width); + psprite->maxheight = LittleLong (pin->height); + psprite->beamlength = LittleFloat (pin->beamlength); + mod->synctype = LittleLong (pin->synctype); + psprite->numframes = numframes; + + mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; + mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; + mod->mins[2] = -psprite->maxheight/2; + mod->maxs[2] = psprite->maxheight/2; + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); + + mod->numframes = numframes; + + pframetype = (dspriteframetype_t *)(pin + 1); + + for (i=0 ; i<numframes ; i++) + { + spriteframetype_t frametype; + + frametype = LittleLong (pframetype->type); + psprite->frames[i].type = frametype; + + if (frametype == SPR_SINGLE) + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteFrame (pframetype + 1, + &psprite->frames[i].frameptr, i); + } + else + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteGroup (pframetype + 1, + &psprite->frames[i].frameptr, i); + } + } + + mod->type = mod_sprite; +} + +//============================================================================= + +/* +================ +Mod_Print +================ +*/ +void Mod_Print (void) +{ + int i; + model_t *mod; + + Con_Printf ("Cached models:\n"); + for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++) + { + Con_Printf ("%8p : %s\n",mod->cache.data, mod->name); + } +} + + diff --git a/QW/client/gl_model.h b/QW/client/gl_model.h new file mode 100644 index 0000000..65583e3 --- /dev/null +++ b/QW/client/gl_model.h @@ -0,0 +1,436 @@ +/* +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. + +*/ + +#ifndef __MODEL__ +#define __MODEL__ + +#include "modelgen.h" +#include "spritegn.h" + +/* + +d*_t structures are on-disk representations +m*_t structures are in-memory + +*/ + +// entity effects + +#define EF_BRIGHTFIELD 1 +#define EF_MUZZLEFLASH 2 +#define EF_BRIGHTLIGHT 4 +#define EF_DIMLIGHT 8 +#define EF_FLAG1 16 +#define EF_FLAG2 32 +#define EF_BLUE 64 +#define EF_RED 128 + +/* +============================================================================== + +BRUSH MODELS + +============================================================================== +*/ + + +// +// in memory representation +// +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + vec3_t position; +} mvertex_t; + +#define SIDE_FRONT 0 +#define SIDE_BACK 1 +#define SIDE_ON 2 + + +// plane_t structure +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct mplane_s +{ + vec3_t normal; + float dist; + byte type; // for texture axis selection and fast side tests + byte signbits; // signx + signy<<1 + signz<<1 + byte pad[2]; +} mplane_t; + +typedef struct texture_s +{ + char name[16]; + unsigned width, height; + int gl_texturenum; + struct msurface_s *texturechain; // for gl_texsort drawing + int anim_total; // total tenths in sequence ( 0 = no) + int anim_min, anim_max; // time for this frame min <=time< max + struct texture_s *anim_next; // in the animation sequence + struct texture_s *alternate_anims; // bmodels in frmae 1 use these + unsigned offsets[MIPLEVELS]; // four mip maps stored +} texture_t; + + +#define SURF_PLANEBACK 2 +#define SURF_DRAWSKY 4 +#define SURF_DRAWSPRITE 8 +#define SURF_DRAWTURB 0x10 +#define SURF_DRAWTILED 0x20 +#define SURF_DRAWBACKGROUND 0x40 +#define SURF_UNDERWATER 0x80 +#define SURF_DONTWARP 0x100 + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + unsigned short v[2]; + unsigned int cachededgeoffset; +} medge_t; + +typedef struct +{ + float vecs[2][4]; + float mipadjust; + texture_t *texture; + int flags; +} mtexinfo_t; + +#define VERTEXSIZE 7 + +typedef struct glpoly_s +{ + struct glpoly_s *next; + struct glpoly_s *chain; + int numverts; + int flags; // for SURF_UNDERWATER + float verts[4][VERTEXSIZE]; // variable sized (xyz s1t1 s2t2) +} glpoly_t; + +typedef struct msurface_s +{ + int visframe; // should be drawn when node is crossed + + mplane_t *plane; + int flags; + + int firstedge; // look up in model->surfedges[], negative numbers + int numedges; // are backwards edges + + short texturemins[2]; + short extents[2]; + + int light_s, light_t; // gl lightmap coordinates + + glpoly_t *polys; // multiple if warped + struct msurface_s *texturechain; + + mtexinfo_t *texinfo; + +// lighting info + int dlightframe; + int dlightbits; + + int lightmaptexturenum; + byte styles[MAXLIGHTMAPS]; + int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap + qboolean cached_dlight; // true if dynamic light in cache + byte *samples; // [numstyles*surfsize] +} msurface_t; + +typedef struct mnode_s +{ +// common with leaf + int contents; // 0, to differentiate from leafs + int visframe; // node needs to be traversed if current + + float minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// node specific + mplane_t *plane; + struct mnode_s *children[2]; + + unsigned short firstsurface; + unsigned short numsurfaces; +} mnode_t; + + + +typedef struct mleaf_s +{ +// common with node + int contents; // wil be a negative contents number + int visframe; // node needs to be traversed if current + + float minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// leaf specific + byte *compressed_vis; + efrag_t *efrags; + + msurface_t **firstmarksurface; + int nummarksurfaces; + int key; // BSP sequence number for leaf's contents + byte ambient_sound_level[NUM_AMBIENTS]; +} mleaf_t; + +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct +{ + dclipnode_t *clipnodes; + mplane_t *planes; + int firstclipnode; + int lastclipnode; + vec3_t clip_mins; + vec3_t clip_maxs; +} hull_t; + +/* +============================================================================== + +SPRITE MODELS + +============================================================================== +*/ + + +// FIXME: shorten these? +typedef struct mspriteframe_s +{ + int width; + int height; + float up, down, left, right; + int gl_texturenum; +} mspriteframe_t; + +typedef struct +{ + int numframes; + float *intervals; + mspriteframe_t *frames[1]; +} mspritegroup_t; + +typedef struct +{ + spriteframetype_t type; + mspriteframe_t *frameptr; +} mspriteframedesc_t; + +typedef struct +{ + int type; + int maxwidth; + int maxheight; + int numframes; + float beamlength; // remove? + void *cachespot; // remove? + mspriteframedesc_t frames[1]; +} msprite_t; + + +/* +============================================================================== + +ALIAS MODELS + +Alias models are position independent, so the cache manager can move them. +============================================================================== +*/ + +typedef struct +{ + int firstpose; + int numposes; + float interval; + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; + char name[16]; +} maliasframedesc_t; + +typedef struct +{ + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; +} maliasgroupframedesc_t; + +typedef struct +{ + int numframes; + int intervals; + maliasgroupframedesc_t frames[1]; +} maliasgroup_t; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct mtriangle_s { + int facesfront; + int vertindex[3]; +} mtriangle_t; + + +#define MAX_SKINS 32 +typedef struct { + int ident; + int version; + vec3_t scale; + vec3_t scale_origin; + float boundingradius; + vec3_t eyeposition; + int numskins; + int skinwidth; + int skinheight; + int numverts; + int numtris; + int numframes; + synctype_t synctype; + int flags; + float size; + + int numposes; + int poseverts; + int posedata; // numposes*poseverts trivert_t + int commands; // gl command list with embedded s/t + int gl_texturenum[MAX_SKINS][4]; + maliasframedesc_t frames[1]; // variable sized +} aliashdr_t; + +#define MAXALIASVERTS 1024 +#define MAXALIASFRAMES 256 +#define MAXALIASTRIS 2048 +extern aliashdr_t *pheader; +extern stvert_t stverts[MAXALIASVERTS]; +extern mtriangle_t triangles[MAXALIASTRIS]; +extern trivertx_t *poseverts[MAXALIASFRAMES]; + +//=================================================================== + +// +// Whole model +// + +typedef enum {mod_brush, mod_sprite, mod_alias} modtype_t; + +#define EF_ROCKET 1 // leave a trail +#define EF_GRENADE 2 // leave a trail +#define EF_GIB 4 // leave a trail +#define EF_ROTATE 8 // rotate (bonus items) +#define EF_TRACER 16 // green split trail +#define EF_ZOMGIB 32 // small blood trail +#define EF_TRACER2 64 // orange split trail + rotate +#define EF_TRACER3 128 // purple trail + +typedef struct model_s +{ + char name[MAX_QPATH]; + qboolean needload; // bmodels and sprites don't cache normally + + modtype_t type; + int numframes; + synctype_t synctype; + + int flags; + +// +// volume occupied by the model graphics +// + vec3_t mins, maxs; + float radius; + +// +// solid volume for clipping +// + qboolean clipbox; + vec3_t clipmins, clipmaxs; + +// +// brush model +// + int firstmodelsurface, nummodelsurfaces; + + int numsubmodels; + dmodel_t *submodels; + + int numplanes; + mplane_t *planes; + + int numleafs; // number of visible leafs, not counting 0 + mleaf_t *leafs; + + int numvertexes; + mvertex_t *vertexes; + + int numedges; + medge_t *edges; + + int numnodes; + mnode_t *nodes; + + int numtexinfo; + mtexinfo_t *texinfo; + + int numsurfaces; + msurface_t *surfaces; + + int numsurfedges; + int *surfedges; + + int numclipnodes; + dclipnode_t *clipnodes; + + int nummarksurfaces; + msurface_t **marksurfaces; + + hull_t hulls[MAX_MAP_HULLS]; + + int numtextures; + texture_t **textures; + + byte *visdata; + byte *lightdata; + char *entities; + + unsigned checksum; + unsigned checksum2; + +// +// additional model data +// + cache_user_t cache; // only access through Mod_Extradata + +} model_t; + +//============================================================================ + +void Mod_Init (void); +void Mod_ClearAll (void); +model_t *Mod_ForName (char *name, qboolean crash); +void *Mod_Extradata (model_t *mod); // handles caching +void Mod_TouchModel (char *name); + +mleaf_t *Mod_PointInLeaf (float *p, model_t *model); +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model); + +#endif // __MODEL__ diff --git a/QW/client/gl_ngraph.c b/QW/client/gl_ngraph.c new file mode 100644 index 0000000..29d1096 --- /dev/null +++ b/QW/client/gl_ngraph.c @@ -0,0 +1,141 @@ +/* +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. + +*/ +// gl_ngraph.c + +#include "quakedef.h" + +extern byte *draw_chars; // 8*8 graphic characters + +int netgraphtexture; // netgraph texture + +#define NET_GRAPHHEIGHT 32 + +static byte ngraph_texels[NET_GRAPHHEIGHT][NET_TIMINGS]; + +static void R_LineGraph (int x, int h) +{ + int i; + int s; + int color; + + s = NET_GRAPHHEIGHT; + + if (h == 10000) + color = 0x6f; // yellow + else if (h == 9999) + color = 0x4f; // red + else if (h == 9998) + color = 0xd0; // blue + else + color = 0xfe; // white + + if (h>s) + h = s; + + for (i=0 ; i<h ; i++) + if (i & 1) + ngraph_texels[NET_GRAPHHEIGHT - i - 1][x] = 0xff; + else + ngraph_texels[NET_GRAPHHEIGHT - i - 1][x] = (byte)color; + + for ( ; i<s ; i++) + ngraph_texels[NET_GRAPHHEIGHT - i - 1][x] = (byte)0xff; +} + +void Draw_CharToNetGraph (int x, int y, int num) +{ + int row, col; + byte *source; + int drawline; + int nx; + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + for (drawline = 8; drawline; drawline--, y++) + { + for (nx=0 ; nx<8 ; nx++) + if (source[nx] != 255) + ngraph_texels[y][nx+x] = 0x60 + source[nx]; + source += 128; + } +} + + +/* +============== +R_NetGraph +============== +*/ +void R_NetGraph (void) +{ + int a, x, i, y; + int lost; + char st[80]; + unsigned ngraph_pixels[NET_GRAPHHEIGHT][NET_TIMINGS]; + + x = 0; + lost = CL_CalcNet(); + for (a=0 ; a<NET_TIMINGS ; a++) + { + i = (cls.netchan.outgoing_sequence-a) & NET_TIMINGSMASK; + R_LineGraph (NET_TIMINGS-1-a, packet_latency[i]); + } + + // now load the netgraph texture into gl and draw it + for (y = 0; y < NET_GRAPHHEIGHT; y++) + for (x = 0; x < NET_TIMINGS; x++) + ngraph_pixels[y][x] = d_8to24table[ngraph_texels[y][x]]; + + x = -((vid.width - 320)>>1); + y = vid.height - sb_lines - 24 - NET_GRAPHHEIGHT - 1; + + M_DrawTextBox (x, y, NET_TIMINGS/8, NET_GRAPHHEIGHT/8 + 1); + y += 8; + + sprintf(st, "%3i%% packet loss", lost); + Draw_String(8, y, st); + y += 8; + + GL_Bind(netgraphtexture); + + glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, + NET_TIMINGS, NET_GRAPHHEIGHT, 0, GL_RGBA, + GL_UNSIGNED_BYTE, ngraph_pixels); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + x = 8; + glColor3f (1,1,1); + glBegin (GL_QUADS); + glTexCoord2f (0, 0); + glVertex2f (x, y); + glTexCoord2f (1, 0); + glVertex2f (x+NET_TIMINGS, y); + glTexCoord2f (1, 1); + glVertex2f (x+NET_TIMINGS, y+NET_GRAPHHEIGHT); + glTexCoord2f (0, 1); + glVertex2f (x, y+NET_GRAPHHEIGHT); + glEnd (); +} + diff --git a/QW/client/gl_refrag.c b/QW/client/gl_refrag.c new file mode 100644 index 0000000..6e2e2f0 --- /dev/null +++ b/QW/client/gl_refrag.c @@ -0,0 +1,234 @@ +/* +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_efrag.c + +#include "quakedef.h" + +mnode_t *r_pefragtopnode; + + +//=========================================================================== + +/* +=============================================================================== + + ENTITY FRAGMENT FUNCTIONS + +=============================================================================== +*/ + +efrag_t **lastlink; + +vec3_t r_emins, r_emaxs; + +entity_t *r_addent; + + +/* +================ +R_RemoveEfrags + +Call when removing an object from the world or moving it to another position +================ +*/ +void R_RemoveEfrags (entity_t *ent) +{ + efrag_t *ef, *old, *walk, **prev; + + ef = ent->efrag; + + while (ef) + { + prev = &ef->leaf->efrags; + while (1) + { + walk = *prev; + if (!walk) + break; + if (walk == ef) + { // remove this fragment + *prev = ef->leafnext; + break; + } + else + prev = &walk->leafnext; + } + + old = ef; + ef = ef->entnext; + + // put it on the free list + old->entnext = cl.free_efrags; + cl.free_efrags = old; + } + + ent->efrag = NULL; +} + +/* +=================== +R_SplitEntityOnNode +=================== +*/ +void R_SplitEntityOnNode (mnode_t *node) +{ + efrag_t *ef; + mplane_t *splitplane; + mleaf_t *leaf; + int sides; + + if (node->contents == CONTENTS_SOLID) + { + return; + } + +// add an efrag if the node is a leaf + + if ( node->contents < 0) + { + if (!r_pefragtopnode) + r_pefragtopnode = node; + + leaf = (mleaf_t *)node; + +// grab an efrag off the free list + ef = cl.free_efrags; + if (!ef) + { + Con_Printf ("Too many efrags!\n"); + return; // no free fragments... + } + cl.free_efrags = cl.free_efrags->entnext; + + ef->entity = r_addent; + +// add the entity link + *lastlink = ef; + lastlink = &ef->entnext; + ef->entnext = NULL; + +// set the leaf links + ef->leaf = leaf; + ef->leafnext = leaf->efrags; + leaf->efrags = ef; + + return; + } + +// NODE_MIXED + + splitplane = node->plane; + sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane); + + if (sides == 3) + { + // split on this plane + // if this is the first splitter of this bmodel, remember it + if (!r_pefragtopnode) + r_pefragtopnode = node; + } + +// recurse down the contacted sides + if (sides & 1) + R_SplitEntityOnNode (node->children[0]); + + if (sides & 2) + R_SplitEntityOnNode (node->children[1]); +} + + + +/* +=========== +R_AddEfrags +=========== +*/ +void R_AddEfrags (entity_t *ent) +{ + model_t *entmodel; + int i; + + if (!ent->model) + return; + + r_addent = ent; + + lastlink = &ent->efrag; + r_pefragtopnode = NULL; + + entmodel = ent->model; + + for (i=0 ; i<3 ; i++) + { + r_emins[i] = ent->origin[i] + entmodel->mins[i]; + r_emaxs[i] = ent->origin[i] + entmodel->maxs[i]; + } + + R_SplitEntityOnNode (cl.worldmodel->nodes); + + ent->topnode = r_pefragtopnode; +} + + +/* +================ +R_StoreEfrags + +// FIXME: a lot of this goes away with edge-based +================ +*/ +void R_StoreEfrags (efrag_t **ppefrag) +{ + entity_t *pent; + model_t *clmodel; + efrag_t *pefrag; + + + while ((pefrag = *ppefrag) != NULL) + { + pent = pefrag->entity; + clmodel = pent->model; + + switch (clmodel->type) + { + case mod_alias: + case mod_brush: + case mod_sprite: + pent = pefrag->entity; + + if ((pent->visframe != r_framecount) && + (cl_numvisedicts < MAX_VISEDICTS)) + { + cl_visedicts[cl_numvisedicts++] = *pent; + + // mark that we've recorded this entity for this frame + pent->visframe = r_framecount; + } + + ppefrag = &pefrag->leafnext; + break; + + default: + Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type); + } + } +} + + diff --git a/QW/client/gl_rlight.c b/QW/client/gl_rlight.c new file mode 100644 index 0000000..b2e4aff --- /dev/null +++ b/QW/client/gl_rlight.c @@ -0,0 +1,381 @@ +/* +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" + +int r_dlightframecount; + + +/* +================== +R_AnimateLight +================== +*/ +void R_AnimateLight (void) +{ + int i,j,k; + +// +// light animations +// 'm' is normal light, 'a' is no light, 'z' is double bright + i = (int)(cl.time*10); + for (j=0 ; j<MAX_LIGHTSTYLES ; j++) + { + if (!cl_lightstyle[j].length) + { + d_lightstylevalue[j] = 256; + continue; + } + k = i % cl_lightstyle[j].length; + k = cl_lightstyle[j].map[k] - 'a'; + k = k*22; + d_lightstylevalue[j] = k; + } +} + +/* +============================================================================= + +DYNAMIC LIGHTS BLEND RENDERING + +============================================================================= +*/ + +void AddLightBlend (float r, float g, float b, float a2) +{ + float a; + + v_blend[3] = a = v_blend[3] + a2*(1-v_blend[3]); + + a2 = a2/a; + + v_blend[0] = v_blend[1]*(1-a2) + r*a2; + v_blend[1] = v_blend[1]*(1-a2) + g*a2; + v_blend[2] = v_blend[2]*(1-a2) + b*a2; +//Con_Printf("AddLightBlend(): %4.2f %4.2f %4.2f %4.6f\n", v_blend[0], v_blend[1], v_blend[2], v_blend[3]); +} + +float bubble_sintable[17], bubble_costable[17]; + +void R_InitBubble() { + float a; + int i; + float *bub_sin, *bub_cos; + + bub_sin = bubble_sintable; + bub_cos = bubble_costable; + + for (i=16 ; i>=0 ; i--) + { + a = i/16.0 * M_PI*2; + *bub_sin++ = sin(a); + *bub_cos++ = cos(a); + } +} + +void R_RenderDlight (dlight_t *light) +{ + int i, j; +// float a; + vec3_t v; + float rad; + float *bub_sin, *bub_cos; + + bub_sin = bubble_sintable; + bub_cos = bubble_costable; + rad = light->radius * 0.35; + + VectorSubtract (light->origin, r_origin, v); + if (Length (v) < rad) + { // view is inside the dlight + AddLightBlend (1, 0.5, 0, light->radius * 0.0003); + return; + } + + glBegin (GL_TRIANGLE_FAN); +// glColor3f (0.2,0.1,0.0); +// glColor3f (0.2,0.1,0.05); // changed dimlight effect + glColor4f (light->color[0], light->color[1], light->color[2], + light->color[3]); + for (i=0 ; i<3 ; i++) + v[i] = light->origin[i] - vpn[i]*rad; + glVertex3fv (v); + glColor3f (0,0,0); + for (i=16 ; i>=0 ; i--) + { +// a = i/16.0 * M_PI*2; + for (j=0 ; j<3 ; j++) + v[j] = light->origin[j] + (vright[j]*(*bub_cos) + + + vup[j]*(*bub_sin)) * rad; + bub_sin++; + bub_cos++; + glVertex3fv (v); + } + glEnd (); +} + +/* +============= +R_RenderDlights +============= +*/ +void R_RenderDlights (void) +{ + int i; + dlight_t *l; + + if (!gl_flashblend.value) + return; + + r_dlightframecount = r_framecount + 1; // because the count hasn't + // advanced yet for this frame + glDepthMask (0); + glDisable (GL_TEXTURE_2D); + glShadeModel (GL_SMOOTH); + glEnable (GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); + + l = cl_dlights; + for (i=0 ; i<MAX_DLIGHTS ; i++, l++) + { + if (l->die < cl.time || !l->radius) + continue; + R_RenderDlight (l); + } + + glColor3f (1,1,1); + glDisable (GL_BLEND); + glEnable (GL_TEXTURE_2D); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask (1); +} + + +/* +============================================================================= + +DYNAMIC LIGHTS + +============================================================================= +*/ + +/* +============= +R_MarkLights +============= +*/ +void R_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) + { + R_MarkLights (light, bit, node->children[0]); + return; + } + if (dist < -light->radius) + { + R_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; + } + + R_MarkLights (light, bit, node->children[0]); + R_MarkLights (light, bit, node->children[1]); +} + + +/* +============= +R_PushDlights +============= +*/ +void R_PushDlights (void) +{ + int i; + dlight_t *l; + + if (gl_flashblend.value) + return; + + r_dlightframecount = r_framecount + 1; // because the count hasn't + // advanced yet for this frame + l = cl_dlights; + + for (i=0 ; i<MAX_DLIGHTS ; i++, l++) + { + if (l->die < cl.time || !l->radius) + continue; + R_MarkLights ( l, 1<<i, cl.worldmodel->nodes ); + } +} + + +/* +============================================================================= + +LIGHT SAMPLING + +============================================================================= +*/ + +mplane_t *lightplane; +vec3_t lightspot; + +int RecursiveLightPoint (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; + byte *lightmap; + unsigned scale; + int maps; + + 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 RecursiveLightPoint (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 = RecursiveLightPoint (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 + VectorCopy (mid, lightspot); + lightplane = plane; + + 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 RecursiveLightPoint (node->children[!side], mid, end); +} + +int R_LightPoint (vec3_t p) +{ + vec3_t end; + int r; + + if (!cl.worldmodel->lightdata) + return 255; + + end[0] = p[0]; + end[1] = p[1]; + end[2] = p[2] - 2048; + + r = RecursiveLightPoint (cl.worldmodel->nodes, p, end); + + if (r == -1) + r = 0; + + return r; +} + diff --git a/QW/client/gl_rmain.c b/QW/client/gl_rmain.c new file mode 100644 index 0000000..48a5a54 --- /dev/null +++ b/QW/client/gl_rmain.c @@ -0,0 +1,1144 @@ +/* +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_main.c + +#include "quakedef.h" + +entity_t r_worldentity; + +qboolean r_cache_thrash; // compatability + +vec3_t modelorg, r_entorigin; +entity_t *currententity; + +int r_visframecount; // bumped when going to a new PVS +int r_framecount; // used for dlight push checking + +mplane_t frustum[4]; + +int c_brush_polys, c_alias_polys; + +qboolean envmap; // true during envmap command capture + +int currenttexture = -1; // to avoid unnecessary texture sets + +int cnttextures[2] = {-1, -1}; // cached + +int particletexture; // little dot for particles +int playertextures; // up to 16 color translated skins + +int mirrortexturenum; // quake texturenum, not gltexturenum +qboolean mirror; +mplane_t *mirror_plane; + +// +// view origin +// +vec3_t vup; +vec3_t vpn; +vec3_t vright; +vec3_t r_origin; + +float r_world_matrix[16]; +float r_base_world_matrix[16]; + +// +// screen size info +// +refdef_t r_refdef; + +mleaf_t *r_viewleaf, *r_oldviewleaf; + +texture_t *r_notexture_mip; + +int d_lightstylevalue[256]; // 8.8 fraction of base light value + + +void R_MarkLeaves (void); + +cvar_t r_norefresh = {"r_norefresh","0"}; +cvar_t r_drawentities = {"r_drawentities","1"}; +cvar_t r_drawviewmodel = {"r_drawviewmodel","1"}; +cvar_t r_speeds = {"r_speeds","0"}; +cvar_t r_fullbright = {"r_fullbright","0"}; +cvar_t r_lightmap = {"r_lightmap","0"}; +cvar_t r_shadows = {"r_shadows","0"}; +cvar_t r_mirroralpha = {"r_mirroralpha","1"}; +cvar_t r_wateralpha = {"r_wateralpha","1"}; +cvar_t r_dynamic = {"r_dynamic","1"}; +cvar_t r_novis = {"r_novis","0"}; +cvar_t r_netgraph = {"r_netgraph","0"}; + +cvar_t gl_clear = {"gl_clear","0"}; +cvar_t gl_cull = {"gl_cull","1"}; +cvar_t gl_texsort = {"gl_texsort","1"}; +cvar_t gl_smoothmodels = {"gl_smoothmodels","1"}; +cvar_t gl_affinemodels = {"gl_affinemodels","0"}; +cvar_t gl_polyblend = {"gl_polyblend","1"}; +cvar_t gl_flashblend = {"gl_flashblend","1"}; +cvar_t gl_playermip = {"gl_playermip","0"}; +cvar_t gl_nocolors = {"gl_nocolors","0"}; +cvar_t gl_keeptjunctions = {"gl_keeptjunctions","1"}; +cvar_t gl_reporttjunctions = {"gl_reporttjunctions","0"}; +cvar_t gl_finish = {"gl_finish","0"}; + +extern cvar_t gl_ztrick; +extern cvar_t scr_fov; +/* +================= +R_CullBox + +Returns true if the box is completely outside the frustom +================= +*/ +qboolean R_CullBox (vec3_t mins, vec3_t maxs) +{ + int i; + + for (i=0 ; i<4 ; i++) + if (BoxOnPlaneSide (mins, maxs, &frustum[i]) == 2) + return true; + return false; +} + + +void R_RotateForEntity (entity_t *e) +{ + glTranslatef (e->origin[0], e->origin[1], e->origin[2]); + + glRotatef (e->angles[1], 0, 0, 1); + glRotatef (-e->angles[0], 0, 1, 0); + //ZOID: fixed z angle + glRotatef (e->angles[2], 1, 0, 0); +} + +/* +============================================================= + + SPRITE MODELS + +============================================================= +*/ + +/* +================ +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 = cl.time + currententity->syncbase; + + // 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_DrawSpriteModel + +================= +*/ +void R_DrawSpriteModel (entity_t *e) +{ + vec3_t point; + mspriteframe_t *frame; + float *up, *right; + vec3_t v_forward, v_right, v_up; + msprite_t *psprite; + + // don't even bother culling, because it's just a single + // polygon without a surface cache + frame = R_GetSpriteFrame (e); + psprite = currententity->model->cache.data; + + if (psprite->type == SPR_ORIENTED) + { // bullet marks on walls + AngleVectors (currententity->angles, v_forward, v_right, v_up); + up = v_up; + right = v_right; + } + else + { // normal sprite + up = vup; + right = vright; + } + + glColor3f (1,1,1); + + GL_DisableMultitexture(); + + GL_Bind(frame->gl_texturenum); + + glEnable (GL_ALPHA_TEST); + glBegin (GL_QUADS); + + glEnable (GL_ALPHA_TEST); + glBegin (GL_QUADS); + + glTexCoord2f (0, 1); + VectorMA (e->origin, frame->down, up, point); + VectorMA (point, frame->left, right, point); + glVertex3fv (point); + + glTexCoord2f (0, 0); + VectorMA (e->origin, frame->up, up, point); + VectorMA (point, frame->left, right, point); + glVertex3fv (point); + + glTexCoord2f (1, 0); + VectorMA (e->origin, frame->up, up, point); + VectorMA (point, frame->right, right, point); + glVertex3fv (point); + + glTexCoord2f (1, 1); + VectorMA (e->origin, frame->down, up, point); + VectorMA (point, frame->right, right, point); + glVertex3fv (point); + + glEnd (); + + glDisable (GL_ALPHA_TEST); +} + +/* +============================================================= + + ALIAS MODELS + +============================================================= +*/ + + +#define NUMVERTEXNORMALS 162 + +float r_avertexnormals[NUMVERTEXNORMALS][3] = { +#include "anorms.h" +}; + +vec3_t shadevector; +float shadelight, ambientlight; + +// precalculated dot products for quantized angles +#define SHADEDOT_QUANT 16 +float r_avertexnormal_dots[SHADEDOT_QUANT][256] = +#include "anorm_dots.h" +; + +float *shadedots = r_avertexnormal_dots[0]; + +int lastposenum; + +/* +============= +GL_DrawAliasFrame +============= +*/ +void GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum) +{ + float l; + trivertx_t *verts; + int *order; + int count; + +lastposenum = posenum; + + verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata); + verts += posenum * paliashdr->poseverts; + order = (int *)((byte *)paliashdr + paliashdr->commands); + + while (1) + { + // get the vertex count and primitive type + count = *order++; + if (!count) + break; // done + if (count < 0) + { + count = -count; + glBegin (GL_TRIANGLE_FAN); + } + else + glBegin (GL_TRIANGLE_STRIP); + + do + { + // texture coordinates come from the draw list + glTexCoord2f (((float *)order)[0], ((float *)order)[1]); + order += 2; + + // normals and vertexes come from the frame list + l = shadedots[verts->lightnormalindex] * shadelight; + glColor3f (l, l, l); + glVertex3f (verts->v[0], verts->v[1], verts->v[2]); + verts++; + } while (--count); + + glEnd (); + } +} + + +/* +============= +GL_DrawAliasShadow +============= +*/ +extern vec3_t lightspot; + +void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum) +{ + trivertx_t *verts; + int *order; + vec3_t point; + float height, lheight; + int count; + + lheight = currententity->origin[2] - lightspot[2]; + + height = 0; + verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata); + verts += posenum * paliashdr->poseverts; + order = (int *)((byte *)paliashdr + paliashdr->commands); + + height = -lheight + 1.0; + + while (1) + { + // get the vertex count and primitive type + count = *order++; + if (!count) + break; // done + if (count < 0) + { + count = -count; + glBegin (GL_TRIANGLE_FAN); + } + else + glBegin (GL_TRIANGLE_STRIP); + + do + { + // texture coordinates come from the draw list + // (skipped for shadows) glTexCoord2fv ((float *)order); + order += 2; + + // normals and vertexes come from the frame list + point[0] = verts->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0]; + point[1] = verts->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1]; + point[2] = verts->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2]; + + point[0] -= shadevector[0]*(point[2]+lheight); + point[1] -= shadevector[1]*(point[2]+lheight); + point[2] = height; +// height -= 0.001; + glVertex3fv (point); + + verts++; + } while (--count); + + glEnd (); + } +} + + + +/* +================= +R_SetupAliasFrame + +================= +*/ +void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr) +{ + int pose, numposes; + float interval; + + if ((frame >= paliashdr->numframes) || (frame < 0)) + { + Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame); + frame = 0; + } + + pose = paliashdr->frames[frame].firstpose; + numposes = paliashdr->frames[frame].numposes; + + if (numposes > 1) + { + interval = paliashdr->frames[frame].interval; + pose += (int)(cl.time / interval) % numposes; + } + + GL_DrawAliasFrame (paliashdr, pose); +} + + + +/* +================= +R_DrawAliasModel + +================= +*/ +void R_DrawAliasModel (entity_t *e) +{ + int i; + int lnum; + vec3_t dist; + float add; + model_t *clmodel; + vec3_t mins, maxs; + aliashdr_t *paliashdr; + float an; + int anim; + + clmodel = currententity->model; + + VectorAdd (currententity->origin, clmodel->mins, mins); + VectorAdd (currententity->origin, clmodel->maxs, maxs); + + if (R_CullBox (mins, maxs)) + return; + + + VectorCopy (currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + + // + // get lighting information + // + + ambientlight = shadelight = R_LightPoint (currententity->origin); + + // allways give the gun some light + if (e == &cl.viewent && ambientlight < 24) + ambientlight = shadelight = 24; + + for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++) + { + if (cl_dlights[lnum].die >= cl.time) + { + VectorSubtract (currententity->origin, + cl_dlights[lnum].origin, + dist); + add = cl_dlights[lnum].radius - Length(dist); + + if (add > 0) { + ambientlight += add; + //ZOID models should be affected by dlights as well + shadelight += add; + } + } + } + + // clamp lighting so it doesn't overbright as much + if (ambientlight > 128) + ambientlight = 128; + if (ambientlight + shadelight > 192) + shadelight = 192 - ambientlight; + + // ZOID: never allow players to go totally black + if (!strcmp(clmodel->name, "progs/player.mdl")) { + if (ambientlight < 8) + ambientlight = shadelight = 8; + + } else if (!strcmp (clmodel->name, "progs/flame2.mdl") + || !strcmp (clmodel->name, "progs/flame.mdl") ) + // HACK HACK HACK -- no fullbright colors, so make torches full light + ambientlight = shadelight = 256; + + shadedots = r_avertexnormal_dots[((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; + shadelight = shadelight / 200.0; + + an = e->angles[1]/180*M_PI; + shadevector[0] = cos(-an); + shadevector[1] = sin(-an); + shadevector[2] = 1; + VectorNormalize (shadevector); + + // + // locate the proper data + // + paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model); + + c_alias_polys += paliashdr->numtris; + + // + // draw all the triangles + // + + GL_DisableMultitexture(); + + glPushMatrix (); + R_RotateForEntity (e); + + if (!strcmp (clmodel->name, "progs/eyes.mdl") ) { + glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] - (22 + 8)); + // double size of eyes, since they are really hard to see in gl + glScalef (paliashdr->scale[0]*2, paliashdr->scale[1]*2, paliashdr->scale[2]*2); + } else { + glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]); + glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]); + } + + anim = (int)(cl.time*10) & 3; + GL_Bind(paliashdr->gl_texturenum[currententity->skinnum][anim]); + + // we can't dynamically colormap textures, so they are cached + // seperately for the players. Heads are just uncolored. + if (currententity->scoreboard && !gl_nocolors.value) + { + i = currententity->scoreboard - cl.players; + if (!currententity->scoreboard->skin) { + Skin_Find(currententity->scoreboard); + R_TranslatePlayerSkin(i); + } + if (i >= 0 && i<MAX_CLIENTS) + GL_Bind(playertextures + i); + } + + if (gl_smoothmodels.value) + glShadeModel (GL_SMOOTH); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + if (gl_affinemodels.value) + glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + + R_SetupAliasFrame (currententity->frame, paliashdr); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glShadeModel (GL_FLAT); + if (gl_affinemodels.value) + glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + glPopMatrix (); + + if (r_shadows.value) + { + glPushMatrix (); + R_RotateForEntity (e); + glDisable (GL_TEXTURE_2D); + glEnable (GL_BLEND); + glColor4f (0,0,0,0.5); + GL_DrawAliasShadow (paliashdr, lastposenum); + glEnable (GL_TEXTURE_2D); + glDisable (GL_BLEND); + glColor4f (1,1,1,1); + glPopMatrix (); + } + +} + +//================================================================================== + +/* +============= +R_DrawEntitiesOnList +============= +*/ +void R_DrawEntitiesOnList (void) +{ + int i; + + if (!r_drawentities.value) + return; + + // draw sprites seperately, because of alpha blending + for (i=0 ; i<cl_numvisedicts ; i++) + { + currententity = &cl_visedicts[i]; + + switch (currententity->model->type) + { + case mod_alias: + R_DrawAliasModel (currententity); + break; + + case mod_brush: + R_DrawBrushModel (currententity); + break; + + default: + break; + } + } + + for (i=0 ; i<cl_numvisedicts ; i++) + { + currententity = &cl_visedicts[i]; + + switch (currententity->model->type) + { + case mod_sprite: + R_DrawSpriteModel (currententity); + break; + + default : + break; + } + } +} + +/* +============= +R_DrawViewModel +============= +*/ +void R_DrawViewModel (void) +{ + float ambient[4], diffuse[4]; + int j; + int lnum; + vec3_t dist; + float add; + dlight_t *dl; + int ambientlight, shadelight; + + if (!r_drawviewmodel.value || !Cam_DrawViewModel()) + return; + + if (envmap) + return; + + if (!r_drawentities.value) + return; + + if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY) + return; + + if (cl.stats[STAT_HEALTH] <= 0) + return; + + currententity = &cl.viewent; + if (!currententity->model) + return; + + j = R_LightPoint (currententity->origin); + + if (j < 24) + j = 24; // allways give some light on gun + ambientlight = j; + shadelight = j; + +// add dynamic lights + for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++) + { + dl = &cl_dlights[lnum]; + if (!dl->radius) + continue; + if (!dl->radius) + continue; + if (dl->die < cl.time) + continue; + + VectorSubtract (currententity->origin, dl->origin, dist); + add = dl->radius - Length(dist); + if (add > 0) + ambientlight += add; + } + + ambient[0] = ambient[1] = ambient[2] = ambient[3] = (float)ambientlight / 128; + diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = (float)shadelight / 128; + + // hack the depth range to prevent view model from poking into walls + glDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); + R_DrawAliasModel (currententity); + glDepthRange (gldepthmin, gldepthmax); +} + + +/* +============ +R_PolyBlend +============ +*/ +void R_PolyBlend (void) +{ + if (!gl_polyblend.value) + return; + if (!v_blend[3]) + return; + +//Con_Printf("R_PolyBlend(): %4.2f %4.2f %4.2f %4.2f\n",v_blend[0], v_blend[1], v_blend[2], v_blend[3]); + + GL_DisableMultitexture(); + + glDisable (GL_ALPHA_TEST); + glEnable (GL_BLEND); + glDisable (GL_DEPTH_TEST); + glDisable (GL_TEXTURE_2D); + + glLoadIdentity (); + + glRotatef (-90, 1, 0, 0); // put Z going up + glRotatef (90, 0, 0, 1); // put Z going up + + glColor4fv (v_blend); + + glBegin (GL_QUADS); + + glVertex3f (10, 100, 100); + glVertex3f (10, -100, 100); + glVertex3f (10, -100, -100); + glVertex3f (10, 100, -100); + glEnd (); + + glDisable (GL_BLEND); + glEnable (GL_TEXTURE_2D); + glEnable (GL_ALPHA_TEST); +} + + +int SignbitsForPlane (mplane_t *out) +{ + int bits, j; + + // for fast box on planeside test + + bits = 0; + for (j=0 ; j<3 ; j++) + { + if (out->normal[j] < 0) + bits |= 1<<j; + } + return bits; +} + + +void R_SetFrustum (void) +{ + int i; + + if (r_refdef.fov_x == 90) + { + // front side is visible + + VectorAdd (vpn, vright, frustum[0].normal); + VectorSubtract (vpn, vright, frustum[1].normal); + + VectorAdd (vpn, vup, frustum[2].normal); + VectorSubtract (vpn, vup, frustum[3].normal); + } + else + { + + // rotate VPN right by FOV_X/2 degrees + RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_refdef.fov_x / 2 ) ); + // rotate VPN left by FOV_X/2 degrees + RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_refdef.fov_x / 2 ); + // rotate VPN up by FOV_X/2 degrees + RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_refdef.fov_y / 2 ); + // rotate VPN down by FOV_X/2 degrees + RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_refdef.fov_y / 2 ) ); + } + + for (i=0 ; i<4 ; i++) + { + frustum[i].type = PLANE_ANYZ; + frustum[i].dist = DotProduct (r_origin, frustum[i].normal); + frustum[i].signbits = SignbitsForPlane (&frustum[i]); + } +} + + + +/* +=============== +R_SetupFrame +=============== +*/ +void R_SetupFrame (void) +{ +// don't allow cheats in multiplayer + r_fullbright.value = 0; + r_lightmap.value = 0; + if (!atoi(Info_ValueForKey(cl.serverinfo, "watervis"))) + r_wateralpha.value = 1; + + R_AnimateLight (); + + r_framecount++; + +// build the transformation matrix for the given view angles + VectorCopy (r_refdef.vieworg, r_origin); + + AngleVectors (r_refdef.viewangles, vpn, vright, vup); + +// current viewleaf + r_oldviewleaf = r_viewleaf; + r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); + + V_SetContentsColor (r_viewleaf->contents); + V_CalcBlend (); + + r_cache_thrash = false; + + c_brush_polys = 0; + c_alias_polys = 0; + +} + + +void MYgluPerspective( GLdouble fovy, GLdouble aspect, + GLdouble zNear, GLdouble zFar ) +{ + GLdouble xmin, xmax, ymin, ymax; + + ymax = zNear * tan( fovy * M_PI / 360.0 ); + ymin = -ymax; + + xmin = ymin * aspect; + xmax = ymax * aspect; + + glFrustum( xmin, xmax, ymin, ymax, zNear, zFar ); +} + + +/* +============= +R_SetupGL +============= +*/ +void R_SetupGL (void) +{ + float screenaspect; + extern int glwidth, glheight; + int x, x2, y2, y, w, h; + + // + // set up viewpoint + // + glMatrixMode(GL_PROJECTION); + glLoadIdentity (); + x = r_refdef.vrect.x * glwidth/vid.width; + x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/vid.width; + y = (vid.height-r_refdef.vrect.y) * glheight/vid.height; + y2 = (vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/vid.height; + + // fudge around because of frac screen scale + if (x > 0) + x--; + if (x2 < glwidth) + x2++; + if (y2 < 0) + y2--; + if (y < glheight) + y++; + + w = x2 - x; + h = y - y2; + + if (envmap) + { + x = y2 = 0; + w = h = 256; + } + + glViewport (glx + x, gly + y2, w, h); + screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height; +// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI; +// yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect; +// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI; +// MYgluPerspective (yfov, screenaspect, 4, 4096); + MYgluPerspective (r_refdef.fov_y, screenaspect, 4, 4096); + + if (mirror) + { + if (mirror_plane->normal[2]) + glScalef (1, -1, 1); + else + glScalef (-1, 1, 1); + glCullFace(GL_BACK); + } + else + glCullFace(GL_FRONT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity (); + + glRotatef (-90, 1, 0, 0); // put Z going up + glRotatef (90, 0, 0, 1); // put Z going up + glRotatef (-r_refdef.viewangles[2], 1, 0, 0); + glRotatef (-r_refdef.viewangles[0], 0, 1, 0); + glRotatef (-r_refdef.viewangles[1], 0, 0, 1); + glTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]); + + glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix); + + // + // set drawing parms + // + if (gl_cull.value) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); + + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST); +} + +/* +================ +R_RenderScene + +r_refdef must be set before the first call +================ +*/ +void R_RenderScene (void) +{ + R_SetupFrame (); + + R_SetFrustum (); + + R_SetupGL (); + + R_MarkLeaves (); // done here so we know if we're in water + + R_DrawWorld (); // adds static entities to the list + + S_ExtraUpdate (); // don't let sound get messed up if going slow + + R_DrawEntitiesOnList (); + + GL_DisableMultitexture(); + + R_RenderDlights (); + + R_DrawParticles (); + +#ifdef GLTEST + Test_Draw (); +#endif + +} + + +/* +============= +R_Clear +============= +*/ +void R_Clear (void) +{ + if (r_mirroralpha.value != 1.0) + { + if (gl_clear.value) + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + else + glClear (GL_DEPTH_BUFFER_BIT); + gldepthmin = 0; + gldepthmax = 0.5; + glDepthFunc (GL_LEQUAL); + } + else if (gl_ztrick.value) + { + static int trickframe; + + if (gl_clear.value) + glClear (GL_COLOR_BUFFER_BIT); + + trickframe++; + if (trickframe & 1) + { + gldepthmin = 0; + gldepthmax = 0.49999; + glDepthFunc (GL_LEQUAL); + } + else + { + gldepthmin = 1; + gldepthmax = 0.5; + glDepthFunc (GL_GEQUAL); + } + } + else + { + if (gl_clear.value) + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + else + glClear (GL_DEPTH_BUFFER_BIT); + gldepthmin = 0; + gldepthmax = 1; + glDepthFunc (GL_LEQUAL); + } + + glDepthRange (gldepthmin, gldepthmax); +} + +#if 0 //!!! FIXME, Zoid, mirror is disabled for now +/* +============= +R_Mirror +============= +*/ +void R_Mirror (void) +{ + float d; + msurface_t *s; + entity_t *ent; + + if (!mirror) + return; + + memcpy (r_base_world_matrix, r_world_matrix, sizeof(r_base_world_matrix)); + + d = DotProduct (r_refdef.vieworg, mirror_plane->normal) - mirror_plane->dist; + VectorMA (r_refdef.vieworg, -2*d, mirror_plane->normal, r_refdef.vieworg); + + d = DotProduct (vpn, mirror_plane->normal); + VectorMA (vpn, -2*d, mirror_plane->normal, vpn); + + r_refdef.viewangles[0] = -asin (vpn[2])/M_PI*180; + r_refdef.viewangles[1] = atan2 (vpn[1], vpn[0])/M_PI*180; + r_refdef.viewangles[2] = -r_refdef.viewangles[2]; + + ent = &cl_entities[cl.viewentity]; + if (cl_numvisedicts < MAX_VISEDICTS) + { + cl_visedicts[cl_numvisedicts] = ent; + cl_numvisedicts++; + } + + gldepthmin = 0.5; + gldepthmax = 1; + glDepthRange (gldepthmin, gldepthmax); + glDepthFunc (GL_LEQUAL); + + R_RenderScene (); + R_DrawWaterSurfaces (); + + + gldepthmin = 0; + gldepthmax = 0.5; + glDepthRange (gldepthmin, gldepthmax); + glDepthFunc (GL_LEQUAL); + + // blend on top + glEnable (GL_BLEND); + glMatrixMode(GL_PROJECTION); + if (mirror_plane->normal[2]) + glScalef (1,-1,1); + else + glScalef (-1,1,1); + glCullFace(GL_FRONT); + glMatrixMode(GL_MODELVIEW); + + glLoadMatrixf (r_base_world_matrix); + + glColor4f (1,1,1,r_mirroralpha.value); + s = cl.worldmodel->textures[mirrortexturenum]->texturechain; + for ( ; s ; s=s->texturechain) + R_RenderBrushPoly (s); + cl.worldmodel->textures[mirrortexturenum]->texturechain = NULL; + glDisable (GL_BLEND); + glColor4f (1,1,1,1); +} +#endif + +/* +================ +R_RenderView + +r_refdef must be set before the first call +================ +*/ +void R_RenderView (void) +{ + double time1 = 0, time2; + + if (r_norefresh.value) + return; + + if (!r_worldentity.model || !cl.worldmodel) + Sys_Error ("R_RenderView: NULL worldmodel"); + + if (r_speeds.value) + { + glFinish (); + time1 = Sys_DoubleTime (); + c_brush_polys = 0; + c_alias_polys = 0; + } + + mirror = false; + + if (gl_finish.value) + glFinish (); + + R_Clear (); + + // render normal view + R_RenderScene (); + R_DrawViewModel (); + R_DrawWaterSurfaces (); + + // render mirror view +// R_Mirror (); + + R_PolyBlend (); + + if (r_speeds.value) + { +// glFinish (); + time2 = Sys_DoubleTime (); + Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys); + } +} diff --git a/QW/client/gl_rmisc.c b/QW/client/gl_rmisc.c new file mode 100644 index 0000000..e9907dd --- /dev/null +++ b/QW/client/gl_rmisc.c @@ -0,0 +1,473 @@ +/* +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" + +extern void R_InitBubble(); + +/* +================== +R_InitTextures +================== +*/ +void R_InitTextures (void) +{ + int x,y, m; + byte *dest; + +// create a simple checkerboard texture for the default + r_notexture_mip = Hunk_AllocName (sizeof(texture_t) + 16*16+8*8+4*4+2*2, "notexture"); + + r_notexture_mip->width = r_notexture_mip->height = 16; + r_notexture_mip->offsets[0] = sizeof(texture_t); + r_notexture_mip->offsets[1] = r_notexture_mip->offsets[0] + 16*16; + r_notexture_mip->offsets[2] = r_notexture_mip->offsets[1] + 8*8; + r_notexture_mip->offsets[3] = r_notexture_mip->offsets[2] + 4*4; + + for (m=0 ; m<4 ; m++) + { + dest = (byte *)r_notexture_mip + r_notexture_mip->offsets[m]; + for (y=0 ; y< (16>>m) ; y++) + for (x=0 ; x< (16>>m) ; x++) + { + if ( (y< (8>>m) ) ^ (x< (8>>m) ) ) + *dest++ = 0; + else + *dest++ = 0xff; + } + } +} + +byte dottexture[8][8] = +{ + {0,1,1,0,0,0,0,0}, + {1,1,1,1,0,0,0,0}, + {1,1,1,1,0,0,0,0}, + {0,1,1,0,0,0,0,0}, + {0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0}, +}; +void R_InitParticleTexture (void) +{ + int x,y; + byte data[8][8][4]; + + // + // particle texture + // + particletexture = texture_extension_number++; + GL_Bind(particletexture); + + for (x=0 ; x<8 ; x++) + { + for (y=0 ; y<8 ; y++) + { + data[y][x][0] = 255; + data[y][x][1] = 255; + data[y][x][2] = 255; + data[y][x][3] = dottexture[x][y]*255; + } + } + glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +} + +/* +=============== +R_Envmap_f + +Grab six views for environment mapping tests +=============== +*/ +void R_Envmap_f (void) +{ + byte buffer[256*256*4]; + + glDrawBuffer (GL_FRONT); + glReadBuffer (GL_FRONT); + envmap = true; + + r_refdef.vrect.x = 0; + r_refdef.vrect.y = 0; + r_refdef.vrect.width = 256; + r_refdef.vrect.height = 256; + + r_refdef.viewangles[0] = 0; + r_refdef.viewangles[1] = 0; + r_refdef.viewangles[2] = 0; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + COM_WriteFile ("env0.rgb", buffer, sizeof(buffer)); + + r_refdef.viewangles[1] = 90; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + COM_WriteFile ("env1.rgb", buffer, sizeof(buffer)); + + r_refdef.viewangles[1] = 180; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + COM_WriteFile ("env2.rgb", buffer, sizeof(buffer)); + + r_refdef.viewangles[1] = 270; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + COM_WriteFile ("env3.rgb", buffer, sizeof(buffer)); + + r_refdef.viewangles[0] = -90; + r_refdef.viewangles[1] = 0; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + COM_WriteFile ("env4.rgb", buffer, sizeof(buffer)); + + r_refdef.viewangles[0] = 90; + r_refdef.viewangles[1] = 0; + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + R_RenderView (); + glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + COM_WriteFile ("env5.rgb", buffer, sizeof(buffer)); + + envmap = false; + glDrawBuffer (GL_BACK); + glReadBuffer (GL_BACK); + GL_EndRendering (); +} + +/* +=============== +R_Init +=============== +*/ +void R_Init (void) +{ + Cmd_AddCommand ("timerefresh", R_TimeRefresh_f); + Cmd_AddCommand ("envmap", R_Envmap_f); + Cmd_AddCommand ("pointfile", R_ReadPointFile_f); + + Cvar_RegisterVariable (&r_norefresh); + Cvar_RegisterVariable (&r_lightmap); + Cvar_RegisterVariable (&r_fullbright); + Cvar_RegisterVariable (&r_drawentities); + Cvar_RegisterVariable (&r_drawviewmodel); + Cvar_RegisterVariable (&r_shadows); + Cvar_RegisterVariable (&r_mirroralpha); + Cvar_RegisterVariable (&r_wateralpha); + Cvar_RegisterVariable (&r_dynamic); + Cvar_RegisterVariable (&r_novis); + Cvar_RegisterVariable (&r_speeds); + Cvar_RegisterVariable (&r_netgraph); + + Cvar_RegisterVariable (&gl_clear); + Cvar_RegisterVariable (&gl_texsort); + + if (gl_mtexable) + Cvar_SetValue ("gl_texsort", 0.0); + + Cvar_RegisterVariable (&gl_cull); + Cvar_RegisterVariable (&gl_smoothmodels); + Cvar_RegisterVariable (&gl_affinemodels); + Cvar_RegisterVariable (&gl_polyblend); + Cvar_RegisterVariable (&gl_flashblend); + Cvar_RegisterVariable (&gl_playermip); + Cvar_RegisterVariable (&gl_nocolors); + Cvar_RegisterVariable (&gl_finish); + + Cvar_RegisterVariable (&gl_keeptjunctions); + Cvar_RegisterVariable (&gl_reporttjunctions); + + R_InitBubble(); + + R_InitParticles (); + R_InitParticleTexture (); + +#ifdef GLTEST + Test_Init (); +#endif + + netgraphtexture = texture_extension_number; + texture_extension_number++; + + playertextures = texture_extension_number; + texture_extension_number += MAX_CLIENTS; +} + +/* +=============== +R_TranslatePlayerSkin + +Translates a skin texture by the per-player color lookup +=============== +*/ +void R_TranslatePlayerSkin (int playernum) +{ + int top, bottom; + byte translate[256]; + unsigned translate32[256]; + int i, j; + byte *original; + unsigned pixels[512*256], *out; + unsigned scaled_width, scaled_height; + int inwidth, inheight; + int tinwidth, tinheight; + byte *inrow; + unsigned frac, fracstep; + player_info_t *player; + extern byte player_8bit_texels[320*200]; + char s[512]; + + GL_DisableMultitexture(); + + player = &cl.players[playernum]; + if (!player->name[0]) + return; + + strcpy(s, Info_ValueForKey(player->userinfo, "skin")); + COM_StripExtension(s, s); + if (player->skin && !stricmp(s, player->skin->name)) + player->skin = NULL; + + if (player->_topcolor != player->topcolor || + player->_bottomcolor != player->bottomcolor || !player->skin) { + player->_topcolor = player->topcolor; + player->_bottomcolor = player->bottomcolor; + + top = player->topcolor; + bottom = player->bottomcolor; + top = (top < 0) ? 0 : ((top > 13) ? 13 : top); + bottom = (bottom < 0) ? 0 : ((bottom > 13) ? 13 : bottom); + top *= 16; + bottom *= 16; + + for (i=0 ; i<256 ; i++) + translate[i] = i; + + for (i=0 ; i<16 ; i++) + { + if (top < 128) // the artists made some backwards ranges. sigh. + translate[TOP_RANGE+i] = top+i; + else + translate[TOP_RANGE+i] = top+15-i; + + if (bottom < 128) + translate[BOTTOM_RANGE+i] = bottom+i; + else + translate[BOTTOM_RANGE+i] = bottom+15-i; + } + + // + // locate the original skin pixels + // + // real model width + tinwidth = 296; + tinheight = 194; + + if (!player->skin) + Skin_Find(player); + if ((original = Skin_Cache(player->skin)) != NULL) { + //skin data width + inwidth = 320; + inheight = 200; + } else { + original = player_8bit_texels; + inwidth = 296; + inheight = 194; + } + + + // because this happens during gameplay, do it fast + // instead of sending it through gl_upload 8 + GL_Bind(playertextures + playernum); + + #if 0 + s = 320*200; + byte translated[320*200]; + + for (i=0 ; i<s ; i+=4) + { + translated[i] = translate[original[i]]; + translated[i+1] = translate[original[i+1]]; + translated[i+2] = translate[original[i+2]]; + translated[i+3] = translate[original[i+3]]; + } + + + // don't mipmap these, because it takes too long + GL_Upload8 (translated, paliashdr->skinwidth, paliashdr->skinheight, + false, false, true); + #endif + + scaled_width = gl_max_size.value < 512 ? gl_max_size.value : 512; + scaled_height = gl_max_size.value < 256 ? gl_max_size.value : 256; + // allow users to crunch sizes down even more if they want + scaled_width >>= (int)gl_playermip.value; + scaled_height >>= (int)gl_playermip.value; + + if (VID_Is8bit()) { // 8bit texture upload + byte *out2; + + out2 = (byte *)pixels; + memset(pixels, 0, sizeof(pixels)); + fracstep = tinwidth*0x10000/scaled_width; + for (i=0 ; i<scaled_height ; i++, out2 += scaled_width) + { + inrow = original + inwidth*(i*tinheight/scaled_height); + frac = fracstep >> 1; + for (j=0 ; j<scaled_width ; j+=4) + { + out2[j] = translate[inrow[frac>>16]]; + frac += fracstep; + out2[j+1] = translate[inrow[frac>>16]]; + frac += fracstep; + out2[j+2] = translate[inrow[frac>>16]]; + frac += fracstep; + out2[j+3] = translate[inrow[frac>>16]]; + frac += fracstep; + } + } + + GL_Upload8_EXT ((byte *)pixels, scaled_width, scaled_height, false, false); + return; + } + + for (i=0 ; i<256 ; i++) + translate32[i] = d_8to24table[translate[i]]; + + out = pixels; + memset(pixels, 0, sizeof(pixels)); + fracstep = tinwidth*0x10000/scaled_width; + for (i=0 ; i<scaled_height ; i++, out += scaled_width) + { + inrow = original + inwidth*(i*tinheight/scaled_height); + frac = fracstep >> 1; + for (j=0 ; j<scaled_width ; j+=4) + { + out[j] = translate32[inrow[frac>>16]]; + frac += fracstep; + out[j+1] = translate32[inrow[frac>>16]]; + frac += fracstep; + out[j+2] = translate32[inrow[frac>>16]]; + frac += fracstep; + out[j+3] = translate32[inrow[frac>>16]]; + frac += fracstep; + } + } + + glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, + scaled_width, scaled_height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, pixels); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } +} + +/* +=============== +R_NewMap +=============== +*/ +void R_NewMap (void) +{ + int i; + + for (i=0 ; i<256 ; i++) + d_lightstylevalue[i] = 264; // normal light value + + memset (&r_worldentity, 0, sizeof(r_worldentity)); + r_worldentity.model = cl.worldmodel; + +// clear out efrags in case the level hasn't been reloaded +// FIXME: is this one short? + for (i=0 ; i<cl.worldmodel->numleafs ; i++) + cl.worldmodel->leafs[i].efrags = NULL; + + r_viewleaf = NULL; + R_ClearParticles (); + + GL_BuildLightmaps (); + + // identify sky texture + skytexturenum = -1; + mirrortexturenum = -1; + for (i=0 ; i<cl.worldmodel->numtextures ; i++) + { + if (!cl.worldmodel->textures[i]) + continue; + if (!Q_strncmp(cl.worldmodel->textures[i]->name,"sky",3) ) + skytexturenum = i; + if (!Q_strncmp(cl.worldmodel->textures[i]->name,"window02_1",10) ) + mirrortexturenum = i; + cl.worldmodel->textures[i]->texturechain = NULL; + } +#ifdef QUAKE2 + R_LoadSkys (); +#endif +} + + +/* +==================== +R_TimeRefresh_f + +For program optimization +==================== +*/ +void R_TimeRefresh_f (void) +{ + int i; + float start, stop, time; + + glDrawBuffer (GL_FRONT); + glFinish (); + + start = Sys_DoubleTime (); + for (i=0 ; i<128 ; i++) + { + r_refdef.viewangles[1] = i/128.0*360.0; + R_RenderView (); + } + + glFinish (); + stop = Sys_DoubleTime (); + time = stop-start; + Con_Printf ("%f seconds (%f fps)\n", time, 128/time); + + glDrawBuffer (GL_BACK); + GL_EndRendering (); +} + +void D_FlushCaches (void) +{ +} + + diff --git a/QW/client/gl_rsurf.c b/QW/client/gl_rsurf.c new file mode 100644 index 0000000..c75f0d7 --- /dev/null +++ b/QW/client/gl_rsurf.c @@ -0,0 +1,1697 @@ +/* +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_surf.c: surface-related refresh code + +#include "quakedef.h" + +int skytexturenum; + +#ifndef GL_RGBA4 +#define GL_RGBA4 0 +#endif + + +int lightmap_bytes; // 1, 2, or 4 + +int lightmap_textures; + +unsigned blocklights[18*18]; + +#define BLOCK_WIDTH 128 +#define BLOCK_HEIGHT 128 + +#define MAX_LIGHTMAPS 64 +int active_lightmaps; + +typedef struct glRect_s { + unsigned char l,t,w,h; +} glRect_t; + +glpoly_t *lightmap_polys[MAX_LIGHTMAPS]; +qboolean lightmap_modified[MAX_LIGHTMAPS]; +glRect_t lightmap_rectchange[MAX_LIGHTMAPS]; + +int allocated[MAX_LIGHTMAPS][BLOCK_WIDTH]; + +// the lightmap texture data needs to be kept in +// main memory so texsubimage can update properly +byte lightmaps[4*MAX_LIGHTMAPS*BLOCK_WIDTH*BLOCK_HEIGHT]; + +// For gl_texsort 0 +msurface_t *skychain = NULL; +msurface_t *waterchain = NULL; + +void R_RenderDynamicLightmaps (msurface_t *fa); + +/* +=============== +R_AddDynamicLights +=============== +*/ +void R_AddDynamicLights (msurface_t *surf) +{ + int lnum; + int sd, td; + float dist, rad, minlight; + vec3_t impact, local; + int s, t; + int i; + int smax, tmax; + mtexinfo_t *tex; + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + tex = surf->texinfo; + + for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++) + { + if ( !(surf->dlightbits & (1<<lnum) ) ) + continue; // not lit by this light + + rad = cl_dlights[lnum].radius; + dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) - + surf->plane->dist; + rad -= fabs(dist); + minlight = cl_dlights[lnum].minlight; + if (rad < minlight) + continue; + minlight = rad - minlight; + + for (i=0 ; i<3 ; i++) + { + impact[i] = cl_dlights[lnum].origin[i] - + surf->plane->normal[i]*dist; + } + + local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; + local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; + + local[0] -= surf->texturemins[0]; + local[1] -= surf->texturemins[1]; + + for (t = 0 ; t<tmax ; t++) + { + td = local[1] - t*16; + if (td < 0) + td = -td; + for (s=0 ; s<smax ; s++) + { + sd = local[0] - s*16; + if (sd < 0) + sd = -sd; + if (sd > td) + dist = sd + (td>>1); + else + dist = td + (sd>>1); + if (dist < minlight) + blocklights[t*smax + s] += (rad - dist)*256; + } + } + } +} + + +/* +=============== +R_BuildLightMap + +Combine and scale multiple lightmaps into the 8.8 format in blocklights +=============== +*/ +void R_BuildLightMap (msurface_t *surf, byte *dest, int stride) +{ + int smax, tmax; + int t; + int i, j, size; + byte *lightmap; + unsigned scale; + int maps; + unsigned *bl; + + surf->cached_dlight = (surf->dlightframe == r_framecount); + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + size = smax*tmax; + lightmap = surf->samples; + +// set to full bright if no light data + if (/* r_fullbright.value || */ !cl.worldmodel->lightdata) + { + for (i=0 ; i<size ; i++) + blocklights[i] = 255*256; + goto store; + } + +// clear to no light + for (i=0 ; i<size ; i++) + blocklights[i] = 0; + +// add all the lightmaps + if (lightmap) + for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + for (i=0 ; i<size ; i++) + blocklights[i] += lightmap[i] * scale; + lightmap += size; // skip to next lightmap + } + +// add all the dynamic lights + if (surf->dlightframe == r_framecount) + R_AddDynamicLights (surf); + +// bound, invert, and shift +store: + switch (gl_lightmap_format) + { + case GL_RGBA: + stride -= (smax<<2); + bl = blocklights; + for (i=0 ; i<tmax ; i++, dest += stride) + { + for (j=0 ; j<smax ; j++) + { + t = *bl++; + t >>= 7; + if (t > 255) + t = 255; + dest[3] = 255-t; + dest += 4; + } + } + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + bl = blocklights; + for (i=0 ; i<tmax ; i++, dest += stride) + { + for (j=0 ; j<smax ; j++) + { + t = *bl++; + t >>= 7; + if (t > 255) + t = 255; + dest[j] = 255-t; + } + } + break; + default: + Sys_Error ("Bad lightmap format"); + } +} + + +/* +=============== +R_TextureAnimation + +Returns the proper texture for a given time and base texture +=============== +*/ +texture_t *R_TextureAnimation (texture_t *base) +{ + int reletive; + int count; + + if (currententity->frame) + { + if (base->alternate_anims) + base = base->alternate_anims; + } + + if (!base->anim_total) + return base; + + reletive = (int)(cl.time*10) % base->anim_total; + + count = 0; + while (base->anim_min > reletive || base->anim_max <= reletive) + { + base = base->anim_next; + if (!base) + Sys_Error ("R_TextureAnimation: broken cycle"); + if (++count > 100) + Sys_Error ("R_TextureAnimation: infinite cycle"); + } + + return base; +} + + +/* +============================================================= + + BRUSH MODELS + +============================================================= +*/ + + +extern int solidskytexture; +extern int alphaskytexture; +extern float speedscale; // for top sky and bottom sky + +void DrawGLWaterPoly (glpoly_t *p); +void DrawGLWaterPolyLightmap (glpoly_t *p); + +#ifdef _WIN32 +lpMTexFUNC qglMTexCoord2fSGIS = NULL; +lpSelTexFUNC qglSelectTextureSGIS = NULL; +#endif + +qboolean mtexenabled = false; + +void GL_SelectTexture (GLenum target); + +void GL_DisableMultitexture(void) +{ + if (mtexenabled) { + glDisable(GL_TEXTURE_2D); + GL_SelectTexture(TEXTURE0_SGIS); + mtexenabled = false; + } +} + +void GL_EnableMultitexture(void) +{ + if (gl_mtexable) { + GL_SelectTexture(TEXTURE1_SGIS); + glEnable(GL_TEXTURE_2D); + mtexenabled = true; + } +} + +#ifndef _WIN32 +/* +================ +R_DrawSequentialPoly + +Systems that have fast state and texture changes can +just do everything as it passes with no need to sort +================ +*/ +void R_DrawSequentialPoly (msurface_t *s) +{ + glpoly_t *p; + float *v; + int i; + texture_t *t; + + // + // normal lightmaped poly + // +// if ((!(s->flags & (SURF_DRAWSKY|SURF_DRAWTURB))) +// && ((r_viewleaf->contents!=CONTENTS_EMPTY && (s->flags & SURF_UNDERWATER)) || +// (r_viewleaf->contents==CONTENTS_EMPTY && !(s->flags & SURF_UNDERWATER)))) + if (0) + { + p = s->polys; + + t = R_TextureAnimation (s->texinfo->texture); + GL_Bind (t->gl_texturenum); + glBegin (GL_POLYGON); + v = p->verts[0]; + for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[3], v[4]); + glVertex3fv (v); + } + glEnd (); + + GL_Bind (lightmap_textures + s->lightmaptexturenum); + glEnable (GL_BLEND); + glBegin (GL_POLYGON); + v = p->verts[0]; + for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + + glDisable (GL_BLEND); + + return; + } + + // + // subdivided water surface warp + // + if (s->flags & SURF_DRAWTURB) + { + GL_Bind (s->texinfo->texture->gl_texturenum); + EmitWaterPolys (s); + return; + } + + // + // subdivided sky warp + // + if (s->flags & SURF_DRAWSKY) + { + GL_Bind (solidskytexture); + speedscale = realtime*8; + speedscale -= (int)speedscale; + + EmitSkyPolys (s); + + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GL_Bind (alphaskytexture); + speedscale = realtime*16; + speedscale -= (int)speedscale; + EmitSkyPolys (s); + if (gl_lightmap_format == GL_LUMINANCE) + glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR); + + glDisable (GL_BLEND); + } + + // + // underwater warped with lightmap + // + p = s->polys; + + t = R_TextureAnimation (s->texinfo->texture); + GL_Bind (t->gl_texturenum); + DrawGLWaterPoly (p); + + GL_Bind (lightmap_textures + s->lightmaptexturenum); + glEnable (GL_BLEND); + DrawGLWaterPolyLightmap (p); + glDisable (GL_BLEND); +} +#else +/* +================ +R_DrawSequentialPoly + +Systems that have fast state and texture changes can +just do everything as it passes with no need to sort +================ +*/ +void R_DrawSequentialPoly (msurface_t *s) +{ + glpoly_t *p; + float *v; + int i; + texture_t *t; + vec3_t nv, dir; + float ss, ss2, length; + float s1, t1; + glRect_t *theRect; + + // + // normal lightmaped poly + // + + if (! (s->flags & (SURF_DRAWSKY|SURF_DRAWTURB|SURF_UNDERWATER) ) ) + { + R_RenderDynamicLightmaps (s); + if (gl_mtexable) { + p = s->polys; + + t = R_TextureAnimation (s->texinfo->texture); + // Binds world to texture env 0 + GL_SelectTexture(TEXTURE0_SGIS); + GL_Bind (t->gl_texturenum); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + // Binds lightmap to texenv 1 + GL_EnableMultitexture(); // Same as SelectTexture (TEXTURE1) + GL_Bind (lightmap_textures + s->lightmaptexturenum); + i = s->lightmaptexturenum; + if (lightmap_modified[i]) + { + lightmap_modified[i] = false; + theRect = &lightmap_rectchange[i]; + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, + BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE, + lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes); + theRect->l = BLOCK_WIDTH; + theRect->t = BLOCK_HEIGHT; + theRect->h = 0; + theRect->w = 0; + } + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); + glBegin(GL_POLYGON); + v = p->verts[0]; + for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) + { + qglMTexCoord2fSGIS (TEXTURE0_SGIS, v[3], v[4]); + qglMTexCoord2fSGIS (TEXTURE1_SGIS, v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + return; + } else { + p = s->polys; + + t = R_TextureAnimation (s->texinfo->texture); + GL_Bind (t->gl_texturenum); + glBegin (GL_POLYGON); + v = p->verts[0]; + for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[3], v[4]); + glVertex3fv (v); + } + glEnd (); + + GL_Bind (lightmap_textures + s->lightmaptexturenum); + glEnable (GL_BLEND); + glBegin (GL_POLYGON); + v = p->verts[0]; + for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + + glDisable (GL_BLEND); + } + + return; + } + + // + // subdivided water surface warp + // + + if (s->flags & SURF_DRAWTURB) + { + GL_DisableMultitexture(); + GL_Bind (s->texinfo->texture->gl_texturenum); + EmitWaterPolys (s); + return; + } + + // + // subdivided sky warp + // + if (s->flags & SURF_DRAWSKY) + { + GL_DisableMultitexture(); + GL_Bind (solidskytexture); + speedscale = realtime*8; + speedscale -= (int)speedscale & ~127; + + EmitSkyPolys (s); + + glEnable (GL_BLEND); + GL_Bind (alphaskytexture); + speedscale = realtime*16; + speedscale -= (int)speedscale & ~127; + EmitSkyPolys (s); + + glDisable (GL_BLEND); + return; + } + + // + // underwater warped with lightmap + // + R_RenderDynamicLightmaps (s); + if (gl_mtexable) { + p = s->polys; + + t = R_TextureAnimation (s->texinfo->texture); + GL_SelectTexture(TEXTURE0_SGIS); + GL_Bind (t->gl_texturenum); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + GL_EnableMultitexture(); + GL_Bind (lightmap_textures + s->lightmaptexturenum); + i = s->lightmaptexturenum; + if (lightmap_modified[i]) + { + lightmap_modified[i] = false; + theRect = &lightmap_rectchange[i]; + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, + BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE, + lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes); + theRect->l = BLOCK_WIDTH; + theRect->t = BLOCK_HEIGHT; + theRect->h = 0; + theRect->w = 0; + } + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); + glBegin (GL_TRIANGLE_FAN); + v = p->verts[0]; + for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) + { + qglMTexCoord2fSGIS (TEXTURE0_SGIS, v[3], v[4]); + qglMTexCoord2fSGIS (TEXTURE1_SGIS, v[5], v[6]); + + nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime); + nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime); + nv[2] = v[2]; + + glVertex3fv (nv); + } + glEnd (); + + } else { + p = s->polys; + + t = R_TextureAnimation (s->texinfo->texture); + GL_Bind (t->gl_texturenum); + DrawGLWaterPoly (p); + + GL_Bind (lightmap_textures + s->lightmaptexturenum); + glEnable (GL_BLEND); + DrawGLWaterPolyLightmap (p); + glDisable (GL_BLEND); + } +} +#endif + + +/* +================ +DrawGLWaterPoly + +Warp the vertex coordinates +================ +*/ +void DrawGLWaterPoly (glpoly_t *p) +{ + int i; + float *v; + vec3_t nv; + + GL_DisableMultitexture(); + + glBegin (GL_TRIANGLE_FAN); + v = p->verts[0]; + for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[3], v[4]); + + nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime); + nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime); + nv[2] = v[2]; + + glVertex3fv (nv); + } + glEnd (); +} + +void DrawGLWaterPolyLightmap (glpoly_t *p) +{ + int i; + float *v; + vec3_t nv; + + GL_DisableMultitexture(); + + glBegin (GL_TRIANGLE_FAN); + v = p->verts[0]; + for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[5], v[6]); + + nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime); + nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime); + nv[2] = v[2]; + + glVertex3fv (nv); + } + glEnd (); +} + +/* +================ +DrawGLPoly +================ +*/ +void DrawGLPoly (glpoly_t *p) +{ + int i; + float *v; + + glBegin (GL_POLYGON); + v = p->verts[0]; + for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[3], v[4]); + glVertex3fv (v); + } + glEnd (); +} + + +/* +================ +R_BlendLightmaps +================ +*/ +void R_BlendLightmaps (void) +{ + int i, j; + glpoly_t *p; + float *v; + glRect_t *theRect; + +#if 0 + if (r_fullbright.value) + return; +#endif + if (!gl_texsort.value) + return; + + glDepthMask (0); // don't bother writing Z + + if (gl_lightmap_format == GL_LUMINANCE) + glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR); + else if (gl_lightmap_format == GL_INTENSITY) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor4f (0,0,0,1); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + if (!r_lightmap.value) + { + glEnable (GL_BLEND); + } + + for (i=0 ; i<MAX_LIGHTMAPS ; i++) + { + p = lightmap_polys[i]; + if (!p) + continue; + GL_Bind(lightmap_textures+i); + if (lightmap_modified[i]) + { + lightmap_modified[i] = false; + theRect = &lightmap_rectchange[i]; +// theRect->l = 0; +// theRect->t = 0; +// theRect->w = BLOCK_WIDTH; +// theRect->h = BLOCK_HEIGHT; +// glTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes +// , BLOCK_WIDTH, BLOCK_HEIGHT, 0, +// gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps+i*BLOCK_WIDTH*BLOCK_HEIGHT*lightmap_bytes); +// glTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes +// , BLOCK_WIDTH, theRect->h, 0, +// gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps+(i*BLOCK_HEIGHT+theRect->t)*BLOCK_WIDTH*lightmap_bytes); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, + BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE, + lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes); + theRect->l = BLOCK_WIDTH; + theRect->t = BLOCK_HEIGHT; + theRect->h = 0; + theRect->w = 0; + } + for ( ; p ; p=p->chain) + { +// if (p->flags & SURF_UNDERWATER) +// DrawGLWaterPolyLightmap (p); + if (((r_viewleaf->contents==CONTENTS_EMPTY && (p->flags & SURF_UNDERWATER)) || + (r_viewleaf->contents!=CONTENTS_EMPTY && !(p->flags & SURF_UNDERWATER))) + && !(p->flags & SURF_DONTWARP)) + DrawGLWaterPolyLightmap (p); + else + { + glBegin (GL_POLYGON); + v = p->verts[0]; + for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE) + { + glTexCoord2f (v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + } + } + } + + glDisable (GL_BLEND); + if (gl_lightmap_format == GL_LUMINANCE) + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + else if (gl_lightmap_format == GL_INTENSITY) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glColor4f (1,1,1,1); + } + + glDepthMask (1); // back to normal Z buffering +} + +/* +================ +R_RenderBrushPoly +================ +*/ +void R_RenderBrushPoly (msurface_t *fa) +{ + texture_t *t; + byte *base; + int maps; + glRect_t *theRect; + int smax, tmax; + + c_brush_polys++; + + if (fa->flags & SURF_DRAWSKY) + { // warp texture, no lightmaps + EmitBothSkyLayers (fa); + return; + } + + t = R_TextureAnimation (fa->texinfo->texture); + GL_Bind (t->gl_texturenum); + + if (fa->flags & SURF_DRAWTURB) + { // warp texture, no lightmaps + EmitWaterPolys (fa); + return; + } + + if (((r_viewleaf->contents==CONTENTS_EMPTY && (fa->flags & SURF_UNDERWATER)) || + (r_viewleaf->contents!=CONTENTS_EMPTY && !(fa->flags & SURF_UNDERWATER))) + && !(fa->flags & SURF_DONTWARP)) + DrawGLWaterPoly (fa->polys); + else + DrawGLPoly (fa->polys); + + // add the poly to the proper lightmap chain + + fa->polys->chain = lightmap_polys[fa->lightmaptexturenum]; + lightmap_polys[fa->lightmaptexturenum] = fa->polys; + + // check for lightmap modification + for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; + maps++) + if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]) + goto dynamic; + + if (fa->dlightframe == r_framecount // dynamic this frame + || fa->cached_dlight) // dynamic previously + { +dynamic: + if (r_dynamic.value) + { + lightmap_modified[fa->lightmaptexturenum] = true; + theRect = &lightmap_rectchange[fa->lightmaptexturenum]; + if (fa->light_t < theRect->t) { + if (theRect->h) + theRect->h += theRect->t - fa->light_t; + theRect->t = fa->light_t; + } + if (fa->light_s < theRect->l) { + if (theRect->w) + theRect->w += theRect->l - fa->light_s; + theRect->l = fa->light_s; + } + smax = (fa->extents[0]>>4)+1; + tmax = (fa->extents[1]>>4)+1; + if ((theRect->w + theRect->l) < (fa->light_s + smax)) + theRect->w = (fa->light_s-theRect->l)+smax; + if ((theRect->h + theRect->t) < (fa->light_t + tmax)) + theRect->h = (fa->light_t-theRect->t)+tmax; + base = lightmaps + fa->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT; + base += fa->light_t * BLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; + R_BuildLightMap (fa, base, BLOCK_WIDTH*lightmap_bytes); + } + } +} + +/* +================ +R_RenderDynamicLightmaps +Multitexture +================ +*/ +void R_RenderDynamicLightmaps (msurface_t *fa) +{ + byte *base; + int maps; + glRect_t *theRect; + int smax, tmax; + + c_brush_polys++; + + if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) ) + return; + + fa->polys->chain = lightmap_polys[fa->lightmaptexturenum]; + lightmap_polys[fa->lightmaptexturenum] = fa->polys; + + // check for lightmap modification + for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; + maps++) + if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]) + goto dynamic; + + if (fa->dlightframe == r_framecount // dynamic this frame + || fa->cached_dlight) // dynamic previously + { +dynamic: + if (r_dynamic.value) + { + lightmap_modified[fa->lightmaptexturenum] = true; + theRect = &lightmap_rectchange[fa->lightmaptexturenum]; + if (fa->light_t < theRect->t) { + if (theRect->h) + theRect->h += theRect->t - fa->light_t; + theRect->t = fa->light_t; + } + if (fa->light_s < theRect->l) { + if (theRect->w) + theRect->w += theRect->l - fa->light_s; + theRect->l = fa->light_s; + } + smax = (fa->extents[0]>>4)+1; + tmax = (fa->extents[1]>>4)+1; + if ((theRect->w + theRect->l) < (fa->light_s + smax)) + theRect->w = (fa->light_s-theRect->l)+smax; + if ((theRect->h + theRect->t) < (fa->light_t + tmax)) + theRect->h = (fa->light_t-theRect->t)+tmax; + base = lightmaps + fa->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT; + base += fa->light_t * BLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; + R_BuildLightMap (fa, base, BLOCK_WIDTH*lightmap_bytes); + } + } +} + +/* +================ +R_MirrorChain +================ +*/ +void R_MirrorChain (msurface_t *s) +{ + if (mirror) + return; + mirror = true; + mirror_plane = s->plane; +} + + +#if 0 +/* +================ +R_DrawWaterSurfaces +================ +*/ +void R_DrawWaterSurfaces (void) +{ + int i; + msurface_t *s; + texture_t *t; + + if (r_wateralpha.value == 1.0) + return; + + // + // go back to the world matrix + // + glLoadMatrixf (r_world_matrix); + + glEnable (GL_BLEND); + glColor4f (1,1,1,r_wateralpha.value); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + for (i=0 ; i<cl.worldmodel->numtextures ; i++) + { + t = cl.worldmodel->textures[i]; + if (!t) + continue; + s = t->texturechain; + if (!s) + continue; + if ( !(s->flags & SURF_DRAWTURB) ) + continue; + + // set modulate mode explicitly + GL_Bind (t->gl_texturenum); + + for ( ; s ; s=s->texturechain) + R_RenderBrushPoly (s); + + t->texturechain = NULL; + } + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glColor4f (1,1,1,1); + glDisable (GL_BLEND); +} +#else +/* +================ +R_DrawWaterSurfaces +================ +*/ +void R_DrawWaterSurfaces (void) +{ + int i; + msurface_t *s; + texture_t *t; + + if (r_wateralpha.value == 1.0 && gl_texsort.value) + return; + + // + // go back to the world matrix + // + + glLoadMatrixf (r_world_matrix); + + if (r_wateralpha.value < 1.0) { + glEnable (GL_BLEND); + glColor4f (1,1,1,r_wateralpha.value); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + + if (!gl_texsort.value) { + if (!waterchain) + return; + + for ( s = waterchain ; s ; s=s->texturechain) { + GL_Bind (s->texinfo->texture->gl_texturenum); + EmitWaterPolys (s); + } + + waterchain = NULL; + } else { + + for (i=0 ; i<cl.worldmodel->numtextures ; i++) + { + t = cl.worldmodel->textures[i]; + if (!t) + continue; + s = t->texturechain; + if (!s) + continue; + if ( !(s->flags & SURF_DRAWTURB ) ) + continue; + + // set modulate mode explicitly + + GL_Bind (t->gl_texturenum); + + for ( ; s ; s=s->texturechain) + EmitWaterPolys (s); + + t->texturechain = NULL; + } + + } + + if (r_wateralpha.value < 1.0) { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glColor4f (1,1,1,1); + glDisable (GL_BLEND); + } + +} + +#endif + +/* +================ +DrawTextureChains +================ +*/ +void DrawTextureChains (void) +{ + int i; + msurface_t *s; + texture_t *t; + + if (!gl_texsort.value) { + GL_DisableMultitexture(); + + if (skychain) { + R_DrawSkyChain(skychain); + skychain = NULL; + } + + return; + } + + for (i=0 ; i<cl.worldmodel->numtextures ; i++) + { + t = cl.worldmodel->textures[i]; + if (!t) + continue; + s = t->texturechain; + if (!s) + continue; + if (i == skytexturenum) + R_DrawSkyChain (s); + else if (i == mirrortexturenum && r_mirroralpha.value != 1.0) + { + R_MirrorChain (s); + continue; + } + else + { + if ((s->flags & SURF_DRAWTURB) && r_wateralpha.value != 1.0) + continue; // draw translucent water later + for ( ; s ; s=s->texturechain) + R_RenderBrushPoly (s); + } + + t->texturechain = NULL; + } +} + +/* +================= +R_DrawBrushModel +================= +*/ +void R_DrawBrushModel (entity_t *e) +{ + int i; + int k; + vec3_t mins, maxs; + msurface_t *psurf; + float dot; + mplane_t *pplane; + model_t *clmodel; + qboolean rotated; + + currententity = e; + currenttexture = -1; + + clmodel = e->model; + + if (e->angles[0] || e->angles[1] || e->angles[2]) + { + rotated = true; + for (i=0 ; i<3 ; i++) + { + mins[i] = e->origin[i] - clmodel->radius; + maxs[i] = e->origin[i] + clmodel->radius; + } + } + else + { + rotated = false; + VectorAdd (e->origin, clmodel->mins, mins); + VectorAdd (e->origin, clmodel->maxs, maxs); + } + + if (R_CullBox (mins, maxs)) + return; + + glColor3f (1,1,1); + memset (lightmap_polys, 0, sizeof(lightmap_polys)); + + VectorSubtract (r_refdef.vieworg, e->origin, modelorg); + if (rotated) + { + vec3_t temp; + vec3_t forward, right, up; + + VectorCopy (modelorg, temp); + AngleVectors (e->angles, forward, right, up); + modelorg[0] = DotProduct (temp, forward); + modelorg[1] = -DotProduct (temp, right); + modelorg[2] = DotProduct (temp, up); + } + + psurf = &clmodel->surfaces[clmodel->firstmodelsurface]; + +// calculate dynamic lighting for bmodel if it's not an +// instanced model + if (clmodel->firstmodelsurface != 0 && !gl_flashblend.value) + { + for (k=0 ; k<MAX_DLIGHTS ; k++) + { + if ((cl_dlights[k].die < cl.time) || + (!cl_dlights[k].radius)) + continue; + + R_MarkLights (&cl_dlights[k], 1<<k, + clmodel->nodes + clmodel->hulls[0].firstclipnode); + } + } + + glPushMatrix (); +e->angles[0] = -e->angles[0]; // stupid quake bug + R_RotateForEntity (e); +e->angles[0] = -e->angles[0]; // stupid quake bug + + // + // draw texture + // + for (i=0 ; i<clmodel->nummodelsurfaces ; 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))) + { + if (gl_texsort.value) + R_RenderBrushPoly (psurf); + else + R_DrawSequentialPoly (psurf); + } + } + + R_BlendLightmaps (); + + glPopMatrix (); +} + +/* +============================================================= + + WORLD MODEL + +============================================================= +*/ + +/* +================ +R_RecursiveWorldNode +================ +*/ +void R_RecursiveWorldNode (mnode_t *node) +{ + int c, side; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + double dot; + + if (node->contents == CONTENTS_SOLID) + return; // solid + + if (node->visframe != r_visframecount) + return; + if (R_CullBox (node->minmaxs, node->minmaxs+3)) + return; + +// 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); + + return; + } + +// 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 + R_RecursiveWorldNode (node->children[side]); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + if (dot < 0 -BACKFACE_EPSILON) + side = SURF_PLANEBACK; + else if (dot > BACKFACE_EPSILON) + side = 0; + { + for ( ; c ; c--, surf++) + { + if (surf->visframe != r_framecount) + continue; + + // don't backface underwater surfaces, because they warp +// if ( !(surf->flags & SURF_UNDERWATER) && ( (dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) ) +// continue; // wrong side + if ( !(((r_viewleaf->contents==CONTENTS_EMPTY && (surf->flags & SURF_UNDERWATER)) || + (r_viewleaf->contents!=CONTENTS_EMPTY && !(surf->flags & SURF_UNDERWATER))) + && !(surf->flags & SURF_DONTWARP)) && ( (dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) ) + continue; // wrong side + + // if sorting by texture, just store it out + if (gl_texsort.value) + { + if (!mirror + || surf->texinfo->texture != cl.worldmodel->textures[mirrortexturenum]) + { + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + } else if (surf->flags & SURF_DRAWSKY) { + surf->texturechain = skychain; + skychain = surf; + } else if (surf->flags & SURF_DRAWTURB) { + surf->texturechain = waterchain; + waterchain = surf; + } else + R_DrawSequentialPoly (surf); + + } + } + + } + +// recurse down the back side + R_RecursiveWorldNode (node->children[!side]); +} + + + +/* +============= +R_DrawWorld +============= +*/ +void R_DrawWorld (void) +{ + entity_t ent; + + memset (&ent, 0, sizeof(ent)); + ent.model = cl.worldmodel; + + VectorCopy (r_refdef.vieworg, modelorg); + + currententity = &ent; + currenttexture = -1; + + glColor3f (1,1,1); + memset (lightmap_polys, 0, sizeof(lightmap_polys)); +#ifdef QUAKE2 + R_ClearSkyBox (); +#endif + + R_RecursiveWorldNode (cl.worldmodel->nodes); + + DrawTextureChains (); + + R_BlendLightmaps (); + +#ifdef QUAKE2 + R_DrawSkyBox (); +#endif +} + + +/* +=============== +R_MarkLeaves +=============== +*/ +void R_MarkLeaves (void) +{ + byte *vis; + mnode_t *node; + int i; + byte solid[4096]; + + if (r_oldviewleaf == r_viewleaf && !r_novis.value) + return; + + if (mirror) + return; + + r_visframecount++; + r_oldviewleaf = r_viewleaf; + + if (r_novis.value) + { + vis = solid; + memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3); + } + else + vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel); + + for (i=0 ; i<cl.worldmodel->numleafs ; i++) + { + if (vis[i>>3] & (1<<(i&7))) + { + node = (mnode_t *)&cl.worldmodel->leafs[i+1]; + do + { + if (node->visframe == r_visframecount) + break; + node->visframe = r_visframecount; + node = node->parent; + } while (node); + } + } +} + + + +/* +============================================================================= + + LIGHTMAP ALLOCATION + +============================================================================= +*/ + +// returns a texture number and the position inside it +int AllocBlock (int w, int h, int *x, int *y) +{ + int i, j; + int best, best2; + int texnum; + + for (texnum=0 ; texnum<MAX_LIGHTMAPS ; texnum++) + { + best = BLOCK_HEIGHT; + + for (i=0 ; i<BLOCK_WIDTH-w ; i++) + { + best2 = 0; + + for (j=0 ; j<w ; j++) + { + if (allocated[texnum][i+j] >= best) + break; + if (allocated[texnum][i+j] > best2) + best2 = allocated[texnum][i+j]; + } + if (j == w) + { // this is a valid spot + *x = i; + *y = best = best2; + } + } + + if (best + h > BLOCK_HEIGHT) + continue; + + for (i=0 ; i<w ; i++) + allocated[texnum][*x + i] = best + h; + + return texnum; + } + + Sys_Error ("AllocBlock: full"); + return 0; +} + + +mvertex_t *r_pcurrentvertbase; +model_t *currentmodel; + +int nColinElim; + +/* +================ +BuildSurfaceDisplayList +================ +*/ +void BuildSurfaceDisplayList (msurface_t *fa) +{ + int i, lindex, lnumverts; + medge_t *pedges, *r_pedge; + int vertpage; + float *vec; + float s, t; + glpoly_t *poly; + +// reconstruct the polygon + pedges = currentmodel->edges; + lnumverts = fa->numedges; + vertpage = 0; + + // + // draw texture + // + poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float)); + poly->next = fa->polys; + poly->flags = fa->flags; + fa->polys = poly; + poly->numverts = lnumverts; + + for (i=0 ; i<lnumverts ; i++) + { + lindex = currentmodel->surfedges[fa->firstedge + i]; + + if (lindex > 0) + { + r_pedge = &pedges[lindex]; + vec = r_pcurrentvertbase[r_pedge->v[0]].position; + } + else + { + r_pedge = &pedges[-lindex]; + vec = r_pcurrentvertbase[r_pedge->v[1]].position; + } + s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; + s /= fa->texinfo->texture->width; + + t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; + t /= fa->texinfo->texture->height; + + VectorCopy (vec, poly->verts[i]); + poly->verts[i][3] = s; + poly->verts[i][4] = t; + + // + // lightmap texture coordinates + // + s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; + s -= fa->texturemins[0]; + s += fa->light_s*16; + s += 8; + s /= BLOCK_WIDTH*16; //fa->texinfo->texture->width; + + t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; + t -= fa->texturemins[1]; + t += fa->light_t*16; + t += 8; + t /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height; + + poly->verts[i][5] = s; + poly->verts[i][6] = t; + } + + // + // remove co-linear points - Ed + // + if (!gl_keeptjunctions.value && !(fa->flags & SURF_UNDERWATER) ) + { + for (i = 0 ; i < lnumverts ; ++i) + { + vec3_t v1, v2; + float *prev, *this, *next; + + prev = poly->verts[(i + lnumverts - 1) % lnumverts]; + this = poly->verts[i]; + next = poly->verts[(i + 1) % lnumverts]; + + VectorSubtract( this, prev, v1 ); + VectorNormalize( v1 ); + VectorSubtract( next, prev, v2 ); + VectorNormalize( v2 ); + + // skip co-linear points + #define COLINEAR_EPSILON 0.001 + if ((fabs( v1[0] - v2[0] ) <= COLINEAR_EPSILON) && + (fabs( v1[1] - v2[1] ) <= COLINEAR_EPSILON) && + (fabs( v1[2] - v2[2] ) <= COLINEAR_EPSILON)) + { + int j; + for (j = i + 1; j < lnumverts; ++j) + { + int k; + for (k = 0; k < VERTEXSIZE; ++k) + poly->verts[j - 1][k] = poly->verts[j][k]; + } + --lnumverts; + ++nColinElim; + // retry next vertex next time, which is now current vertex + --i; + } + } + } + poly->numverts = lnumverts; + +} + +/* +======================== +GL_CreateSurfaceLightmap +======================== +*/ +void GL_CreateSurfaceLightmap (msurface_t *surf) +{ + int smax, tmax; + byte *base; + + if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) + return; + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + + surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t); + base = lightmaps + surf->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT; + base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes; + R_BuildLightMap (surf, base, BLOCK_WIDTH*lightmap_bytes); +} + + +/* +================== +GL_BuildLightmaps + +Builds the lightmap texture +with all the surfaces from all brush models +================== +*/ +void GL_BuildLightmaps (void) +{ + int i, j; + model_t *m; + + memset (allocated, 0, sizeof(allocated)); + + r_framecount = 1; // no dlightcache + + if (!lightmap_textures) + { + lightmap_textures = texture_extension_number; + texture_extension_number += MAX_LIGHTMAPS; + } + + gl_lightmap_format = GL_LUMINANCE; + if (COM_CheckParm ("-lm_1")) + gl_lightmap_format = GL_LUMINANCE; + if (COM_CheckParm ("-lm_a")) + gl_lightmap_format = GL_ALPHA; + if (COM_CheckParm ("-lm_i")) + gl_lightmap_format = GL_INTENSITY; + if (COM_CheckParm ("-lm_2")) + gl_lightmap_format = GL_RGBA4; + if (COM_CheckParm ("-lm_4")) + gl_lightmap_format = GL_RGBA; + + switch (gl_lightmap_format) + { + case GL_RGBA: + lightmap_bytes = 4; + break; + case GL_RGBA4: + lightmap_bytes = 2; + break; + case GL_LUMINANCE: + case GL_INTENSITY: + case GL_ALPHA: + lightmap_bytes = 1; + break; + } + + for (j=1 ; j<MAX_MODELS ; j++) + { + m = cl.model_precache[j]; + if (!m) + break; + if (m->name[0] == '*') + continue; + r_pcurrentvertbase = m->vertexes; + currentmodel = m; + for (i=0 ; i<m->numsurfaces ; i++) + { + GL_CreateSurfaceLightmap (m->surfaces + i); + if ( m->surfaces[i].flags & SURF_DRAWTURB ) + continue; +#ifndef QUAKE2 + if ( m->surfaces[i].flags & SURF_DRAWSKY ) + continue; +#endif + BuildSurfaceDisplayList (m->surfaces + i); + } + } + + if (!gl_texsort.value) + GL_SelectTexture(TEXTURE1_SGIS); + + // + // upload all lightmaps that were filled + // + for (i=0 ; i<MAX_LIGHTMAPS ; i++) + { + if (!allocated[i][0]) + break; // no more used + lightmap_modified[i] = false; + lightmap_rectchange[i].l = BLOCK_WIDTH; + lightmap_rectchange[i].t = BLOCK_HEIGHT; + lightmap_rectchange[i].w = 0; + lightmap_rectchange[i].h = 0; + GL_Bind(lightmap_textures + i); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes + , BLOCK_WIDTH, BLOCK_HEIGHT, 0, + gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps+i*BLOCK_WIDTH*BLOCK_HEIGHT*lightmap_bytes); + } + + if (!gl_texsort.value) + GL_SelectTexture(TEXTURE0_SGIS); + +} + diff --git a/QW/client/gl_screen.c b/QW/client/gl_screen.c new file mode 100644 index 0000000..fd62cba --- /dev/null +++ b/QW/client/gl_screen.c @@ -0,0 +1,1188 @@ +/* +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 <time.h> + +/* + +background clear +rendering +turtle/net/ram icons +sbar +centerprint / slow centerprint +notify lines +intermission / finale overlay +loading plaque +console +menu + +required background clears +required update regions + + +syncronous draw mode or async +One off screen buffer, with updates either copied or xblited +Need to double buffer? + + +async draw will require the refresh area to be cleared, because it will be +xblited, but sync draw can just ignore it. + +sync +draw + +CenterPrint () +SlowPrint () +Screen_Update (); +Con_Printf (); + +net +turn off messages option + +the refresh is allways rendered, unless the console is full screen + + +console is: + notify lines + half + full + + +*/ + + +int glx, gly, glwidth, glheight; + +// only the refresh window will be updated unless these variables are flagged +int scr_copytop; +int scr_copyeverything; + +float scr_con_current; +float scr_conlines; // lines of console to display + +float oldscreensize, oldfov; +cvar_t scr_viewsize = {"viewsize","100", true}; +cvar_t scr_fov = {"fov","90"}; // 10 - 170 +cvar_t scr_conspeed = {"scr_conspeed","300"}; +cvar_t scr_centertime = {"scr_centertime","2"}; +cvar_t scr_showram = {"showram","1"}; +cvar_t scr_showturtle = {"showturtle","0"}; +cvar_t scr_showpause = {"showpause","1"}; +cvar_t scr_printspeed = {"scr_printspeed","8"}; +cvar_t scr_allowsnap = {"scr_allowsnap", "1"}; +cvar_t gl_triplebuffer = {"gl_triplebuffer", "1", true }; +extern cvar_t crosshair; + +qboolean scr_initialized; // ready to draw + +qpic_t *scr_ram; +qpic_t *scr_net; +qpic_t *scr_turtle; + +int scr_fullupdate; + +int clearconsole; +int clearnotify; + +int sb_lines; + +viddef_t vid; // global video state + +vrect_t scr_vrect; + +qboolean scr_disabled_for_loading; +qboolean scr_drawloading; +float scr_disabled_time; + +qboolean block_drawing; + +void SCR_ScreenShot_f (void); +void SCR_RSShot_f (void); + +/* +=============================================================================== + +CENTER PRINTING + +=============================================================================== +*/ + +char scr_centerstring[1024]; +float scr_centertime_start; // for slow victory printing +float scr_centertime_off; +int scr_center_lines; +int scr_erase_lines; +int scr_erase_center; + +/* +============== +SCR_CenterPrint + +Called for important messages that should stay in the center of the screen +for a few moments +============== +*/ +void SCR_CenterPrint (char *str) +{ + strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1); + scr_centertime_off = scr_centertime.value; + scr_centertime_start = cl.time; + +// count the number of lines for centering + scr_center_lines = 1; + while (*str) + { + if (*str == '\n') + scr_center_lines++; + str++; + } +} + + +void SCR_DrawCenterString (void) +{ + char *start; + int l; + int j; + int x, y; + int remaining; + +// the finale prints the characters one at a time + if (cl.intermission) + remaining = scr_printspeed.value * (cl.time - scr_centertime_start); + else + remaining = 9999; + + scr_erase_center = 0; + start = scr_centerstring; + + if (scr_center_lines <= 4) + y = vid.height*0.35; + else + y = 48; + + do + { + // scan the width of the line + for (l=0 ; l<40 ; l++) + if (start[l] == '\n' || !start[l]) + break; + x = (vid.width - l*8)/2; + for (j=0 ; j<l ; j++, x+=8) + { + Draw_Character (x, y, start[j]); + if (!remaining--) + return; + } + + y += 8; + + while (*start && *start != '\n') + start++; + + if (!*start) + break; + start++; // skip the \n + } while (1); +} + +void SCR_CheckDrawCenterString (void) +{ + scr_copytop = 1; + if (scr_center_lines > scr_erase_lines) + scr_erase_lines = scr_center_lines; + + scr_centertime_off -= host_frametime; + + if (scr_centertime_off <= 0 && !cl.intermission) + return; + if (key_dest != key_game) + return; + + SCR_DrawCenterString (); +} + +//============================================================================= + +/* +==================== +CalcFov +==================== +*/ +float CalcFov (float fov_x, float width, float height) +{ + float a; + float x; + + if (fov_x < 1 || fov_x > 179) + Sys_Error ("Bad fov: %f", fov_x); + + x = width/tan(fov_x/360*M_PI); + + a = atan (height/x); + + a = a*360/M_PI; + + return a; +} + +/* +================= +SCR_CalcRefdef + +Must be called whenever vid changes +Internal use only +================= +*/ +static void SCR_CalcRefdef (void) +{ + float size; + int h; + qboolean full = false; + + + scr_fullupdate = 0; // force a background redraw + vid.recalc_refdef = 0; + +// force the status bar to redraw + Sbar_Changed (); + +//======================================== + +// bound viewsize + if (scr_viewsize.value < 30) + Cvar_Set ("viewsize","30"); + if (scr_viewsize.value > 120) + Cvar_Set ("viewsize","120"); + +// bound field of view + if (scr_fov.value < 10) + Cvar_Set ("fov","10"); + if (scr_fov.value > 170) + Cvar_Set ("fov","170"); + +// intermission is always full screen + if (cl.intermission) + size = 120; + else + size = scr_viewsize.value; + + if (size >= 120) + sb_lines = 0; // no status bar at all + else if (size >= 110) + sb_lines = 24; // no inventory + else + sb_lines = 24+16+8; + + if (scr_viewsize.value >= 100.0) { + full = true; + size = 100.0; + } else + size = scr_viewsize.value; + if (cl.intermission) + { + full = true; + size = 100.0; + sb_lines = 0; + } + size /= 100.0; + + if (!cl_sbar.value && full) + h = vid.height; + else + h = vid.height - sb_lines; + + r_refdef.vrect.width = vid.width * size; + if (r_refdef.vrect.width < 96) + { + size = 96.0 / r_refdef.vrect.width; + r_refdef.vrect.width = 96; // min for icons + } + + r_refdef.vrect.height = vid.height * size; + if (cl_sbar.value || !full) { + if (r_refdef.vrect.height > vid.height - sb_lines) + r_refdef.vrect.height = vid.height - sb_lines; + } else if (r_refdef.vrect.height > vid.height) + r_refdef.vrect.height = vid.height; + r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2; + if (full) + r_refdef.vrect.y = 0; + else + r_refdef.vrect.y = (h - r_refdef.vrect.height)/2; + + r_refdef.fov_x = scr_fov.value; + r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); + + scr_vrect = r_refdef.vrect; +} + + +/* +================= +SCR_SizeUp_f + +Keybinding command +================= +*/ +void SCR_SizeUp_f (void) +{ + Cvar_SetValue ("viewsize",scr_viewsize.value+10); + vid.recalc_refdef = 1; +} + + +/* +================= +SCR_SizeDown_f + +Keybinding command +================= +*/ +void SCR_SizeDown_f (void) +{ + Cvar_SetValue ("viewsize",scr_viewsize.value-10); + vid.recalc_refdef = 1; +} + +//============================================================================ + +/* +================== +SCR_Init +================== +*/ +void SCR_Init (void) +{ + Cvar_RegisterVariable (&scr_fov); + Cvar_RegisterVariable (&scr_viewsize); + Cvar_RegisterVariable (&scr_conspeed); + Cvar_RegisterVariable (&scr_showram); + Cvar_RegisterVariable (&scr_showturtle); + Cvar_RegisterVariable (&scr_showpause); + Cvar_RegisterVariable (&scr_centertime); + Cvar_RegisterVariable (&scr_printspeed); + Cvar_RegisterVariable (&scr_allowsnap); + Cvar_RegisterVariable (&gl_triplebuffer); + +// +// register our commands +// + Cmd_AddCommand ("screenshot",SCR_ScreenShot_f); + Cmd_AddCommand ("snap",SCR_RSShot_f); + Cmd_AddCommand ("sizeup",SCR_SizeUp_f); + Cmd_AddCommand ("sizedown",SCR_SizeDown_f); + + scr_ram = Draw_PicFromWad ("ram"); + scr_net = Draw_PicFromWad ("net"); + scr_turtle = Draw_PicFromWad ("turtle"); + + scr_initialized = true; +} + + + +/* +============== +SCR_DrawRam +============== +*/ +void SCR_DrawRam (void) +{ + if (!scr_showram.value) + return; + + if (!r_cache_thrash) + return; + + Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram); +} + +/* +============== +SCR_DrawTurtle +============== +*/ +void SCR_DrawTurtle (void) +{ + static int count; + + if (!scr_showturtle.value) + return; + + if (host_frametime < 0.1) + { + count = 0; + return; + } + + count++; + if (count < 3) + return; + + Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle); +} + +/* +============== +SCR_DrawNet +============== +*/ +void SCR_DrawNet (void) +{ + if (cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged < UPDATE_BACKUP-1) + return; + if (cls.demoplayback) + return; + + Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net); +} + +void SCR_DrawFPS (void) +{ + extern cvar_t show_fps; + static double lastframetime; + double t; + extern int fps_count; + static lastfps; + int x, y; + char st[80]; + + if (!show_fps.value) + return; + + t = Sys_DoubleTime(); + if ((t - lastframetime) >= 1.0) { + lastfps = fps_count; + fps_count = 0; + lastframetime = t; + } + + sprintf(st, "%3d FPS", lastfps); + x = vid.width - strlen(st) * 8 - 8; + y = vid.height - sb_lines - 8; +// Draw_TileClear(x, y, strlen(st) * 8, 8); + Draw_String(x, y, st); +} + + +/* +============== +DrawPause +============== +*/ +void SCR_DrawPause (void) +{ + qpic_t *pic; + + if (!scr_showpause.value) // turn off for screenshots + return; + + if (!cl.paused) + return; + + pic = Draw_CachePic ("gfx/pause.lmp"); + Draw_Pic ( (vid.width - pic->width)/2, + (vid.height - 48 - pic->height)/2, pic); +} + + + +/* +============== +SCR_DrawLoading +============== +*/ +void SCR_DrawLoading (void) +{ + qpic_t *pic; + + if (!scr_drawloading) + return; + + pic = Draw_CachePic ("gfx/loading.lmp"); + Draw_Pic ( (vid.width - pic->width)/2, + (vid.height - 48 - pic->height)/2, pic); +} + + + +//============================================================================= + + +/* +================== +SCR_SetUpToDrawConsole +================== +*/ +void SCR_SetUpToDrawConsole (void) +{ + Con_CheckResize (); + + if (scr_drawloading) + return; // never a console with loading plaque + +// decide on the height of the console + if (cls.state != ca_active) + { + scr_conlines = vid.height; // full screen + scr_con_current = scr_conlines; + } + else if (key_dest == key_console) + scr_conlines = vid.height/2; // half screen + else + scr_conlines = 0; // none visible + + if (scr_conlines < scr_con_current) + { + scr_con_current -= scr_conspeed.value*host_frametime; + if (scr_conlines > scr_con_current) + scr_con_current = scr_conlines; + + } + else if (scr_conlines > scr_con_current) + { + scr_con_current += scr_conspeed.value*host_frametime; + if (scr_conlines < scr_con_current) + scr_con_current = scr_conlines; + } + + if (clearconsole++ < vid.numpages) + { + Sbar_Changed (); + } + else if (clearnotify++ < vid.numpages) + { + } + else + con_notifylines = 0; +} + +/* +================== +SCR_DrawConsole +================== +*/ +void SCR_DrawConsole (void) +{ + if (scr_con_current) + { + scr_copyeverything = 1; + Con_DrawConsole (scr_con_current); + clearconsole = 0; + } + else + { + if (key_dest == key_game || key_dest == key_message) + Con_DrawNotify (); // only draw notify in game + } +} + + +/* +============================================================================== + + SCREEN SHOTS + +============================================================================== +*/ + +typedef struct _TargaHeader { + unsigned char id_length, colormap_type, image_type; + unsigned short colormap_index, colormap_length; + unsigned char colormap_size; + unsigned short x_origin, y_origin, width, height; + unsigned char pixel_size, attributes; +} TargaHeader; + + +/* +================== +SCR_ScreenShot_f +================== +*/ +void SCR_ScreenShot_f (void) +{ + byte *buffer; + char pcxname[80]; + char checkname[MAX_OSPATH]; + int i, c, temp; +// +// find a file name to save it to +// + strcpy(pcxname,"quake00.tga"); + + for (i=0 ; i<=99 ; i++) + { + pcxname[5] = i/10 + '0'; + pcxname[6] = i%10 + '0'; + sprintf (checkname, "%s/%s", com_gamedir, pcxname); + if (Sys_FileTime(checkname) == -1) + break; // file doesn't exist + } + if (i==100) + { + Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX file\n"); + return; + } + + + buffer = malloc(glwidth*glheight*3 + 18); + memset (buffer, 0, 18); + buffer[2] = 2; // uncompressed type + buffer[12] = glwidth&255; + buffer[13] = glwidth>>8; + buffer[14] = glheight&255; + buffer[15] = glheight>>8; + buffer[16] = 24; // pixel size + + glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 ); + + // swap rgb to bgr + c = 18+glwidth*glheight*3; + for (i=18 ; i<c ; i+=3) + { + temp = buffer[i]; + buffer[i] = buffer[i+2]; + buffer[i+2] = temp; + } + COM_WriteFile (pcxname, buffer, glwidth*glheight*3 + 18 ); + + free (buffer); + Con_Printf ("Wrote %s\n", pcxname); +} + +/* +============== +WritePCXfile +============== +*/ +void WritePCXfile (char *filename, byte *data, int width, int height, + int rowbytes, byte *palette, qboolean upload) +{ + int i, j, length; + pcx_t *pcx; + byte *pack; + + pcx = Hunk_TempAlloc (width*height*2+1000); + if (pcx == NULL) + { + Con_Printf("SCR_ScreenShot_f: not enough memory\n"); + return; + } + + pcx->manufacturer = 0x0a; // PCX id + pcx->version = 5; // 256 color + pcx->encoding = 1; // uncompressed + pcx->bits_per_pixel = 8; // 256 color + pcx->xmin = 0; + pcx->ymin = 0; + pcx->xmax = LittleShort((short)(width-1)); + pcx->ymax = LittleShort((short)(height-1)); + pcx->hres = LittleShort((short)width); + pcx->vres = LittleShort((short)height); + Q_memset (pcx->palette,0,sizeof(pcx->palette)); + pcx->color_planes = 1; // chunky image + pcx->bytes_per_line = LittleShort((short)width); + pcx->palette_type = LittleShort(2); // not a grey scale + Q_memset (pcx->filler,0,sizeof(pcx->filler)); + +// pack the image + pack = &pcx->data; + + data += rowbytes * (height - 1); + + for (i=0 ; i<height ; i++) + { + for (j=0 ; j<width ; j++) + { + if ( (*data & 0xc0) != 0xc0) + *pack++ = *data++; + else + { + *pack++ = 0xc1; + *pack++ = *data++; + } + } + + data += rowbytes - width; + data -= rowbytes * 2; + } + +// write the palette + *pack++ = 0x0c; // palette ID byte + for (i=0 ; i<768 ; i++) + *pack++ = *palette++; + +// write output file + length = pack - (byte *)pcx; + + if (upload) + CL_StartUpload((void *)pcx, length); + else + COM_WriteFile (filename, pcx, length); +} + + + +/* +Find closest color in the palette for named color +*/ +int MipColor(int r, int g, int b) +{ + int i; + float dist; + int best; + float bestdist; + int r1, g1, b1; + static int lr = -1, lg = -1, lb = -1; + static int lastbest; + + if (r == lr && g == lg && b == lb) + return lastbest; + + bestdist = 256*256*3; + + for (i = 0; i < 256; i++) { + r1 = host_basepal[i*3] - r; + g1 = host_basepal[i*3+1] - g; + b1 = host_basepal[i*3+2] - b; + dist = r1*r1 + g1*g1 + b1*b1; + if (dist < bestdist) { + bestdist = dist; + best = i; + } + } + lr = r; lg = g; lb = b; + lastbest = best; + return best; +} + +// from gl_draw.c +byte *draw_chars; // 8*8 graphic characters + +void SCR_DrawCharToSnap (int num, byte *dest, int width) +{ + int row, col; + byte *source; + int drawline; + int x; + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + drawline = 8; + + while (drawline--) + { + for (x=0 ; x<8 ; x++) + if (source[x]) + dest[x] = source[x]; + else + dest[x] = 98; + source += 128; + dest -= width; + } + +} + +void SCR_DrawStringToSnap (const char *s, byte *buf, int x, int y, int width) +{ + byte *dest; + const unsigned char *p; + + dest = buf + ((y * width) + x); + + p = (const unsigned char *)s; + while (*p) { + SCR_DrawCharToSnap(*p++, dest, width); + dest += 8; + } +} + + +/* +================== +SCR_RSShot_f +================== +*/ +void SCR_RSShot_f (void) +{ + int i, x, y; + unsigned char *src, *dest; + char pcxname[80]; + char checkname[MAX_OSPATH]; + unsigned char *newbuf, *srcbuf; + int srcrowbytes; + int w, h; + int dx, dy, dex, dey, nx; + int r, b, g; + int count; + float fracw, frach; + char st[80]; + time_t now; + + if (CL_IsUploading()) + return; // already one pending + + if (cls.state < ca_onserver) + return; // gotta be connected + + Con_Printf("Remote screen shot requested.\n"); + +#if 0 +// +// find a file name to save it to +// + strcpy(pcxname,"mquake00.pcx"); + + for (i=0 ; i<=99 ; i++) + { + pcxname[6] = i/10 + '0'; + pcxname[7] = i%10 + '0'; + sprintf (checkname, "%s/%s", com_gamedir, pcxname); + if (Sys_FileTime(checkname) == -1) + break; // file doesn't exist + } + if (i==100) + { + Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX"); + return; + } +#endif + +// +// save the pcx file +// + newbuf = malloc(glheight * glwidth * 3); + + glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, newbuf ); + + w = (vid.width < RSSHOT_WIDTH) ? glwidth : RSSHOT_WIDTH; + h = (vid.height < RSSHOT_HEIGHT) ? glheight : RSSHOT_HEIGHT; + + fracw = (float)glwidth / (float)w; + frach = (float)glheight / (float)h; + + for (y = 0; y < h; y++) { + dest = newbuf + (w*3 * y); + + for (x = 0; x < w; x++) { + r = g = b = 0; + + dx = x * fracw; + dex = (x + 1) * fracw; + if (dex == dx) dex++; // at least one + dy = y * frach; + dey = (y + 1) * frach; + if (dey == dy) dey++; // at least one + + count = 0; + for (/* */; dy < dey; dy++) { + src = newbuf + (glwidth * 3 * dy) + dx * 3; + for (nx = dx; nx < dex; nx++) { + r += *src++; + g += *src++; + b += *src++; + count++; + } + } + r /= count; + g /= count; + b /= count; + *dest++ = r; + *dest++ = b; + *dest++ = g; + } + } + + // convert to eight bit + for (y = 0; y < h; y++) { + src = newbuf + (w * 3 * y); + dest = newbuf + (w * y); + + for (x = 0; x < w; x++) { + *dest++ = MipColor(src[0], src[1], src[2]); + src += 3; + } + } + + time(&now); + strcpy(st, ctime(&now)); + st[strlen(st) - 1] = 0; + SCR_DrawStringToSnap (st, newbuf, w - strlen(st)*8, h - 1, w); + + strncpy(st, cls.servername, sizeof(st)); + st[sizeof(st) - 1] = 0; + SCR_DrawStringToSnap (st, newbuf, w - strlen(st)*8, h - 11, w); + + strncpy(st, name.string, sizeof(st)); + st[sizeof(st) - 1] = 0; + SCR_DrawStringToSnap (st, newbuf, w - strlen(st)*8, h - 21, w); + + WritePCXfile (pcxname, newbuf, w, h, w, host_basepal, true); + + free(newbuf); + + Con_Printf ("Wrote %s\n", pcxname); +} + + + + +//============================================================================= + + +//============================================================================= + +char *scr_notifystring; +qboolean scr_drawdialog; + +void SCR_DrawNotifyString (void) +{ + char *start; + int l; + int j; + int x, y; + + start = scr_notifystring; + + y = vid.height*0.35; + + do + { + // scan the width of the line + for (l=0 ; l<40 ; l++) + if (start[l] == '\n' || !start[l]) + break; + x = (vid.width - l*8)/2; + for (j=0 ; j<l ; j++, x+=8) + Draw_Character (x, y, start[j]); + + y += 8; + + while (*start && *start != '\n') + start++; + + if (!*start) + break; + start++; // skip the \n + } while (1); +} + +/* +================== +SCR_ModalMessage + +Displays a text string in the center of the screen and waits for a Y or N +keypress. +================== +*/ +int SCR_ModalMessage (char *text) +{ + scr_notifystring = text; + +// draw a fresh screen + scr_fullupdate = 0; + scr_drawdialog = true; + SCR_UpdateScreen (); + scr_drawdialog = false; + + S_ClearBuffer (); // so dma doesn't loop current sound + + do + { + key_count = -1; // wait for a key down and up + Sys_SendKeyEvents (); + } while (key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE); + + scr_fullupdate = 0; + SCR_UpdateScreen (); + + return key_lastpress == 'y'; +} + + +//============================================================================= + +/* +=============== +SCR_BringDownConsole + +Brings the console down and fades the palettes back to normal +================ +*/ +void SCR_BringDownConsole (void) +{ + int i; + + scr_centertime_off = 0; + + for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++) + SCR_UpdateScreen (); + + cl.cshifts[0].percent = 0; // no area contents palette on next frame + VID_SetPalette (host_basepal); +} + +void SCR_TileClear (void) +{ + if (r_refdef.vrect.x > 0) { + // left + Draw_TileClear (0, 0, r_refdef.vrect.x, vid.height - sb_lines); + // right + Draw_TileClear (r_refdef.vrect.x + r_refdef.vrect.width, 0, + vid.width - r_refdef.vrect.x + r_refdef.vrect.width, + vid.height - sb_lines); + } + if (r_refdef.vrect.y > 0) { + // top + Draw_TileClear (r_refdef.vrect.x, 0, + r_refdef.vrect.x + r_refdef.vrect.width, + r_refdef.vrect.y); + // bottom + Draw_TileClear (r_refdef.vrect.x, + r_refdef.vrect.y + r_refdef.vrect.height, + r_refdef.vrect.width, + vid.height - sb_lines - + (r_refdef.vrect.height + r_refdef.vrect.y)); + } +} + +float oldsbar = 0; + +/* +================== +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! +================== +*/ +void SCR_UpdateScreen (void) +{ + if (block_drawing) + return; + + vid.numpages = 2 + gl_triplebuffer.value; + + scr_copytop = 0; + scr_copyeverything = 0; + + if (scr_disabled_for_loading) + { + if (realtime - scr_disabled_time > 60) + { + scr_disabled_for_loading = false; + Con_Printf ("load failed.\n"); + } + else + return; + } + + if (!scr_initialized || !con_initialized) + return; // not initialized yet + + + if (oldsbar != cl_sbar.value) { + oldsbar = cl_sbar.value; + vid.recalc_refdef = true; + } + + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + + // + // determine size of refresh window + // + if (oldfov != scr_fov.value) + { + oldfov = scr_fov.value; + vid.recalc_refdef = true; + } + + if (vid.recalc_refdef) + SCR_CalcRefdef (); + +// +// do 3D refresh drawing, and then update the screen +// + SCR_SetUpToDrawConsole (); + + V_RenderView (); + + GL_Set2D (); + + // + // draw any areas not covered by the refresh + // + SCR_TileClear (); + + if (r_netgraph.value) + R_NetGraph (); + + if (scr_drawdialog) + { + Sbar_Draw (); + Draw_FadeScreen (); + SCR_DrawNotifyString (); + scr_copyeverything = true; + } + else if (scr_drawloading) + { + SCR_DrawLoading (); + Sbar_Draw (); + } + else if (cl.intermission == 1 && key_dest == key_game) + { + Sbar_IntermissionOverlay (); + } + else if (cl.intermission == 2 && key_dest == key_game) + { + Sbar_FinaleOverlay (); + SCR_CheckDrawCenterString (); + } + else + { + if (crosshair.value) + Draw_Crosshair(); + + SCR_DrawRam (); + SCR_DrawNet (); + SCR_DrawFPS (); + SCR_DrawTurtle (); + SCR_DrawPause (); + SCR_CheckDrawCenterString (); + Sbar_Draw (); + SCR_DrawConsole (); + M_Draw (); + } + + V_UpdatePalette (); + + GL_EndRendering (); +} diff --git a/QW/client/gl_test.c b/QW/client/gl_test.c new file mode 100644 index 0000000..a3b1027 --- /dev/null +++ b/QW/client/gl_test.c @@ -0,0 +1,182 @@ +/* +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. + +*/ + +#include "quakedef.h" + +#ifdef GLTEST + +typedef struct +{ + plane_t *plane; + vec3_t origin; + vec3_t normal; + vec3_t up; + vec3_t right; + vec3_t reflect; + float length; +} puff_t; + +#define MAX_PUFFS 64 + +puff_t puffs[MAX_PUFFS]; + + +void Test_Init (void) +{ +} + + + +plane_t junk; +plane_t *HitPlane (vec3_t start, vec3_t end) +{ + trace_t trace; + +// fill in a default trace + memset (&trace, 0, sizeof(trace_t)); + trace.fraction = 1; + trace.allsolid = true; + VectorCopy (end, trace.endpos); + + SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace); + + junk = trace.plane; + return &junk; +} + +void Test_Spawn (vec3_t origin) +{ + int i; + puff_t *p; + vec3_t temp; + vec3_t normal; + vec3_t incoming; + plane_t *plane; + float d; + + for (i=0,p=puffs ; i<MAX_PUFFS ; i++,p++) + { + if (p->length <= 0) + break; + } + if (i == MAX_PUFFS) + return; + + VectorSubtract (r_refdef.vieworg, origin, incoming); + VectorSubtract (origin, incoming, temp); + plane = HitPlane (r_refdef.vieworg, temp); + + VectorNormalize (incoming); + d = DotProduct (incoming, plane->normal); + VectorSubtract (vec3_origin, incoming, p->reflect); + VectorMA (p->reflect, d*2, plane->normal, p->reflect); + + VectorCopy (origin, p->origin); + VectorCopy (plane->normal, p->normal); + + CrossProduct (incoming, p->normal, p->up); + + CrossProduct (p->up, p->normal, p->right); + + p->length = 8; +} + +void DrawPuff (puff_t *p) +{ + vec3_t pts[2][3]; + int i, j; + float s, d; + + for (i=0 ; i<2 ; i++) + { + if (i == 1) + { + s = 6; + d = p->length; + } + else + { + s = 2; + d = 0; + } + + for (j=0 ; j<3 ; j++) + { + pts[i][0][j] = p->origin[j] + p->up[j]*s + p->reflect[j]*d; + pts[i][1][j] = p->origin[j] + p->right[j]*s + p->reflect[j]*d; + pts[i][2][j] = p->origin[j] + -p->right[j]*s + p->reflect[j]*d; + } + } + + glColor3f (1, 0, 0); + +#if 0 + glBegin (GL_LINES); + glVertex3fv (p->origin); + glVertex3f (p->origin[0] + p->length*p->reflect[0], + p->origin[1] + p->length*p->reflect[1], + p->origin[2] + p->length*p->reflect[2]); + + glVertex3fv (pts[0][0]); + glVertex3fv (pts[1][0]); + + glVertex3fv (pts[0][1]); + glVertex3fv (pts[1][1]); + + glVertex3fv (pts[0][2]); + glVertex3fv (pts[1][2]); + + glEnd (); +#endif + + glBegin (GL_QUADS); + for (i=0 ; i<3 ; i++) + { + j = (i+1)%3; + glVertex3fv (pts[0][j]); + glVertex3fv (pts[1][j]); + glVertex3fv (pts[1][i]); + glVertex3fv (pts[0][i]); + } + glEnd (); + + glBegin (GL_TRIANGLES); + glVertex3fv (pts[1][0]); + glVertex3fv (pts[1][1]); + glVertex3fv (pts[1][2]); + glEnd (); + + p->length -= host_frametime*2; +} + + +void Test_Draw (void) +{ + int i; + puff_t *p; + + for (i=0, p=puffs ; i<MAX_PUFFS ; i++,p++) + { + if (p->length > 0) + DrawPuff (p); + } +} + +#endif diff --git a/QW/client/gl_vidlinux.c b/QW/client/gl_vidlinux.c new file mode 100644 index 0000000..b3f38fe --- /dev/null +++ b/QW/client/gl_vidlinux.c @@ -0,0 +1,816 @@ +/* +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. + +*/ +#include <termios.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/vt.h> +#include <stdarg.h> +#include <stdio.h> +#include <signal.h> + +#include <asm/io.h> + +#include "vga.h" +#include "vgakeyboard.h" +#include "vgamouse.h" + +#include "quakedef.h" +#include "GL/fxmesa.h" + +#define WARP_WIDTH 320 +#define WARP_HEIGHT 200 + +static fxMesaContext fc = NULL; +#define stringify(m) { #m, m } + +unsigned short d_8to16table[256]; +unsigned d_8to24table[256]; +unsigned char d_15to8table[65536]; + +int num_shades=32; + +struct +{ + char *name; + int num; +} mice[] = +{ + stringify(MOUSE_MICROSOFT), + stringify(MOUSE_MOUSESYSTEMS), + stringify(MOUSE_MMSERIES), + stringify(MOUSE_LOGITECH), + stringify(MOUSE_BUSMOUSE), + stringify(MOUSE_PS2), +}; + +static unsigned char scantokey[128]; + +int num_mice = sizeof (mice) / sizeof(mice[0]); + +int d_con_indirect = 0; + +int svgalib_inited=0; +int UseMouse = 1; +int UseKeyboard = 1; + +int mouserate = MOUSE_DEFAULTSAMPLERATE; + +cvar_t _windowed_mouse = {"_windowed_mouse","0", true}; + +cvar_t vid_mode = {"vid_mode","5",false}; +cvar_t vid_redrawfull = {"vid_redrawfull","0",false}; +cvar_t vid_waitforrefresh = {"vid_waitforrefresh","0",true}; + +char *framebuffer_ptr; + +cvar_t mouse_button_commands[3] = +{ + {"mouse1","+attack"}, + {"mouse2","+strafe"}, + {"mouse3","+forward"}, +}; + +int mouse_buttons; +int mouse_buttonstate; +int mouse_oldbuttonstate; +float mouse_x, mouse_y; +float old_mouse_x, old_mouse_y; +int mx, my; + +cvar_t m_filter = {"m_filter","1"}; + +int scr_width, scr_height; + +/*-----------------------------------------------------------------------*/ + +//int texture_mode = GL_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_LINEAR; +int texture_mode = GL_LINEAR; +//int texture_mode = GL_LINEAR_MIPMAP_NEAREST; +//int texture_mode = GL_LINEAR_MIPMAP_LINEAR; + +int texture_extension_number = 1; + +float gldepthmin, gldepthmax; + +cvar_t gl_ztrick = {"gl_ztrick","1"}; + +const char *gl_vendor; +const char *gl_renderer; +const char *gl_version; +const char *gl_extensions; + +qboolean is8bit = false; +qboolean isPermedia = false; +qboolean gl_mtexable = false; + +/*-----------------------------------------------------------------------*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +} + +void D_EndDirectRect (int x, int y, int width, int height) +{ +} + +int matchmouse(int mouse, char *name) +{ + int i; + for (i=0 ; i<num_mice ; i++) + if (!strcmp(mice[i].name, name)) + return i; + return mouse; +} + +#if 0 + +void vtswitch(int newconsole) +{ + + int fd; + struct vt_stat x; + +// switch consoles and wait until reactivated + fd = open("/dev/console", O_RDONLY); + ioctl(fd, VT_GETSTATE, &x); + ioctl(fd, VT_ACTIVATE, newconsole); + ioctl(fd, VT_WAITACTIVE, x.v_active); + close(fd); + +} + +#endif + +void keyhandler(int scancode, int state) +{ + + int sc; + + sc = scancode & 0x7f; + + Key_Event(scantokey[sc], state == KEY_EVENTPRESS); + +} + +void VID_Shutdown(void) +{ + if (!fc) + return; + + fxMesaDestroyContext(fc); + + if (UseKeyboard) + keyboard_close(); +} + +void signal_handler(int sig) +{ + printf("Received signal %d, exiting...\n", sig); + Sys_Quit(); + exit(0); +} + +void InitSig(void) +{ + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + signal(SIGQUIT, signal_handler); + signal(SIGILL, signal_handler); + signal(SIGTRAP, signal_handler); + signal(SIGIOT, signal_handler); + signal(SIGBUS, signal_handler); + signal(SIGFPE, signal_handler); + signal(SIGSEGV, signal_handler); + signal(SIGTERM, signal_handler); +} + +void VID_ShiftPalette(unsigned char *p) +{ +// VID_SetPalette(p); +} + +void VID_SetPalette (unsigned char *palette) +{ + byte *pal; + unsigned r,g,b; + unsigned v; + int r1,g1,b1; + int k; + unsigned short i; + unsigned *table; + FILE *f; + char s[255]; + float dist, bestdist; + static qboolean palflag = false; + +// +// 8 8 8 encoding +// + Con_Printf("Converting 8to24\n"); + + pal = palette; + table = d_8to24table; + for (i=0 ; i<256 ; i++) + { + r = pal[0]; + g = pal[1]; + b = pal[2]; + pal += 3; + +// v = (255<<24) + (r<<16) + (g<<8) + (b<<0); +// v = (255<<0) + (r<<8) + (g<<16) + (b<<24); + v = (255<<24) + (r<<0) + (g<<8) + (b<<16); + *table++ = v; + } + d_8to24table[255] &= 0xffffff; // 255 is transparent + + // JACK: 3D distance calcs - k is last closest, l is the distance. + // FIXME: Precalculate this and cache to disk. + if (palflag) + return; + palflag = true; + + COM_FOpenFile("glquake/15to8.pal", &f); + if (f) { + fread(d_15to8table, 1<<15, 1, f); + fclose(f); + } else { + for (i=0; i < (1<<15); i++) { + /* Maps + 000000000000000 + 000000000011111 = Red = 0x1F + 000001111100000 = Blue = 0x03E0 + 111110000000000 = Grn = 0x7C00 + */ + r = ((i & 0x1F) << 3)+4; + g = ((i & 0x03E0) >> 2)+4; + b = ((i & 0x7C00) >> 7)+4; + pal = (unsigned char *)d_8to24table; + for (v=0,k=0,bestdist=10000.0; v<256; v++,pal+=4) { + r1 = (int)r - (int)pal[0]; + g1 = (int)g - (int)pal[1]; + b1 = (int)b - (int)pal[2]; + dist = sqrt(((r1*r1)+(g1*g1)+(b1*b1))); + if (dist < bestdist) { + k=v; + bestdist = dist; + } + } + d_15to8table[i]=k; + } + sprintf(s, "%s/glquake", com_gamedir); + Sys_mkdir (s); + sprintf(s, "%s/glquake/15to8.pal", com_gamedir); + if ((f = fopen(s, "wb")) != NULL) { + fwrite(d_15to8table, 1<<15, 1, f); + fclose(f); + } + } +} + +/* +=============== +GL_Init +=============== +*/ +void GL_Init (void) +{ + gl_vendor = glGetString (GL_VENDOR); + Con_Printf ("GL_VENDOR: %s\n", gl_vendor); + gl_renderer = glGetString (GL_RENDERER); + Con_Printf ("GL_RENDERER: %s\n", gl_renderer); + + gl_version = glGetString (GL_VERSION); + Con_Printf ("GL_VERSION: %s\n", gl_version); + gl_extensions = glGetString (GL_EXTENSIONS); + Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); + +// Con_Printf ("%s %s\n", gl_renderer, gl_version); + + glClearColor (1,0,0,0); + glCullFace(GL_FRONT); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.666); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glShadeModel (GL_FLAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +} + +/* +================= +GL_BeginRendering + +================= +*/ +void GL_BeginRendering (int *x, int *y, int *width, int *height) +{ + extern cvar_t gl_clear; + + *x = *y = 0; + *width = scr_width; + *height = scr_height; + +// if (!wglMakeCurrent( maindc, baseRC )) +// Sys_Error ("wglMakeCurrent failed"); + +// glViewport (*x, *y, *width, *height); +} + + +void GL_EndRendering (void) +{ + glFlush(); + fxMesaSwapBuffers(); +} + +void Init_KBD(void) +{ + int i; + + if (COM_CheckParm("-nokbd")) UseKeyboard = 0; + + if (UseKeyboard) + { + for (i=0 ; i<128 ; i++) + scantokey[i] = ' '; + + scantokey[42] = K_SHIFT; + scantokey[54] = K_SHIFT; + scantokey[72] = K_UPARROW; + scantokey[103] = K_UPARROW; + scantokey[80] = K_DOWNARROW; + scantokey[108] = K_DOWNARROW; + scantokey[75] = K_LEFTARROW; + scantokey[105] = K_LEFTARROW; + scantokey[77] = K_RIGHTARROW; + scantokey[106] = K_RIGHTARROW; + scantokey[29] = K_CTRL; + scantokey[97] = K_CTRL; + scantokey[56] = K_ALT; + scantokey[100] = K_ALT; +// scantokey[58] = JK_CAPS; +// scantokey[69] = JK_NUM_LOCK; + scantokey[71] = K_HOME; + scantokey[73] = K_PGUP; + scantokey[79] = K_END; + scantokey[81] = K_PGDN; + scantokey[82] = K_INS; + scantokey[83] = K_DEL; + scantokey[1 ] = K_ESCAPE; + scantokey[28] = K_ENTER; + scantokey[15] = K_TAB; + scantokey[14] = K_BACKSPACE; + scantokey[119] = K_PAUSE; + scantokey[57] = ' '; + + scantokey[102] = K_HOME; + scantokey[104] = K_PGUP; + scantokey[107] = K_END; + scantokey[109] = K_PGDN; + scantokey[110] = K_INS; + scantokey[111] = K_DEL; + + scantokey[2] = '1'; + scantokey[3] = '2'; + scantokey[4] = '3'; + scantokey[5] = '4'; + scantokey[6] = '5'; + scantokey[7] = '6'; + scantokey[8] = '7'; + scantokey[9] = '8'; + scantokey[10] = '9'; + scantokey[11] = '0'; + scantokey[12] = '-'; + scantokey[13] = '='; + scantokey[41] = '`'; + scantokey[26] = '['; + scantokey[27] = ']'; + scantokey[39] = ';'; + scantokey[40] = '\''; + scantokey[51] = ','; + scantokey[52] = '.'; + scantokey[53] = '/'; + scantokey[43] = '\\'; + + scantokey[59] = K_F1; + scantokey[60] = K_F2; + scantokey[61] = K_F3; + scantokey[62] = K_F4; + scantokey[63] = K_F5; + scantokey[64] = K_F6; + scantokey[65] = K_F7; + scantokey[66] = K_F8; + scantokey[67] = K_F9; + scantokey[68] = K_F10; + scantokey[87] = K_F11; + scantokey[88] = K_F12; + scantokey[30] = 'a'; + scantokey[48] = 'b'; + scantokey[46] = 'c'; + scantokey[32] = 'd'; + scantokey[18] = 'e'; + scantokey[33] = 'f'; + scantokey[34] = 'g'; + scantokey[35] = 'h'; + scantokey[23] = 'i'; + scantokey[36] = 'j'; + scantokey[37] = 'k'; + scantokey[38] = 'l'; + scantokey[50] = 'm'; + scantokey[49] = 'n'; + scantokey[24] = 'o'; + scantokey[25] = 'p'; + scantokey[16] = 'q'; + scantokey[19] = 'r'; + scantokey[31] = 's'; + scantokey[20] = 't'; + scantokey[22] = 'u'; + scantokey[47] = 'v'; + scantokey[17] = 'w'; + scantokey[45] = 'x'; + scantokey[21] = 'y'; + scantokey[44] = 'z'; + + scantokey[78] = '+'; + scantokey[74] = '-'; + + if (keyboard_init()) + Sys_Error("keyboard_init() failed"); + keyboard_seteventhandler(keyhandler); + } +} + +#define NUM_RESOLUTIONS 3 + +static resolutions[NUM_RESOLUTIONS][3]={ + { 512, 384, GR_RESOLUTION_512x384 }, + { 640, 400, GR_RESOLUTION_640x400 }, + { 640, 480, GR_RESOLUTION_640x480 } +}; + +int findres(int *width, int *height) +{ + int i; + + for(i=0;i<NUM_RESOLUTIONS;i++) + if((*width<=resolutions[i][0]) && (*height<=resolutions[i][1])) { + *width = resolutions[i][0]; + *height = resolutions[i][1]; + return resolutions[i][2]; + } + + *width = 640; + *height = 480; + return GR_RESOLUTION_640x480; +} + +qboolean VID_Is8bit(void) +{ + return is8bit; +} + +#ifdef GL_EXT_SHARED +void VID_Init8bitPalette() +{ + // Check for 8bit Extensions and initialize them. + int i; + char thePalette[256*3]; + char *oldPalette, *newPalette; + + if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") == NULL) + return; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldPalette = (char *) d_8to24table; //d_8to24table3dfx; + newPalette = thePalette; + for (i=0;i<256;i++) { + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + oldPalette++; + } + glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette); + is8bit = true; +} + +#else +extern void gl3DfxSetPaletteEXT(GLuint *pal); + +void VID_Init8bitPalette(void) +{ + // Check for 8bit Extensions and initialize them. + int i; + GLubyte table[256][4]; + char *oldpal; + + if (strstr(gl_extensions, "3DFX_set_global_palette") == NULL) + return; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldpal = (char *) d_8to24table; //d_8to24table3dfx; + for (i=0;i<256;i++) { + table[i][2] = *oldpal++; + table[i][1] = *oldpal++; + table[i][0] = *oldpal++; + table[i][3] = 255; + oldpal++; + } + gl3DfxSetPaletteEXT((GLuint *)table); + is8bit = true; +} +#endif + +void VID_Init(unsigned char *palette) +{ + int i; + GLint attribs[32]; + char gldir[MAX_OSPATH]; + int width = 640, height = 480; + + S_Init(); + + Init_KBD(); + + Cvar_RegisterVariable (&vid_mode); + Cvar_RegisterVariable (&vid_redrawfull); + Cvar_RegisterVariable (&vid_waitforrefresh); + Cvar_RegisterVariable (&gl_ztrick); + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + +// interpret command-line params + +// set vid parameters + attribs[0] = FXMESA_DOUBLEBUFFER; + attribs[1] = FXMESA_ALPHA_SIZE; + attribs[2] = 1; + attribs[3] = FXMESA_DEPTH_SIZE; + attribs[4] = 1; + attribs[5] = FXMESA_NONE; + + if ((i = COM_CheckParm("-width")) != 0) + width = atoi(com_argv[i+1]); + if ((i = COM_CheckParm("-height")) != 0) + height = atoi(com_argv[i+1]); + + if ((i = COM_CheckParm("-conwidth")) != 0) + vid.conwidth = Q_atoi(com_argv[i+1]); + else + vid.conwidth = 640; + + vid.conwidth &= 0xfff8; // make it a multiple of eight + + if (vid.conwidth < 320) + vid.conwidth = 320; + + // pick a conheight that matches with correct aspect + vid.conheight = vid.conwidth*3 / 4; + + if ((i = COM_CheckParm("-conheight")) != 0) + vid.conheight = Q_atoi(com_argv[i+1]); + if (vid.conheight < 200) + vid.conheight = 200; + + fc = fxMesaCreateContext(0, findres(&width, &height), GR_REFRESH_75Hz, + attribs); + if (!fc) + Sys_Error("Unable to create 3DFX context.\n"); + + scr_width = width; + scr_height = height; + + fxMesaMakeCurrent(fc); + + if (vid.conheight > height) + vid.conheight = height; + if (vid.conwidth > width) + vid.conwidth = width; + vid.width = vid.conwidth; + vid.height = vid.conheight; + + vid.aspect = ((float)vid.height / (float)vid.width) * + (320.0 / 240.0); + vid.numpages = 2; + + InitSig(); // trap evil signals + + GL_Init(); + + sprintf (gldir, "%s/glquake", com_gamedir); + Sys_mkdir (gldir); + + VID_SetPalette(palette); + + // Check for 3DFX Extensions and initialize them. + VID_Init8bitPalette(); + + Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height); + + vid.recalc_refdef = 1; // force a surface cache flush +} + +void Sys_SendKeyEvents(void) +{ + if (UseKeyboard) + while (keyboard_update()); +} + +void Force_CenterView_f (void) +{ + cl.viewangles[PITCH] = 0; +} + + +void mousehandler(int buttonstate, int dx, int dy) +{ + mouse_buttonstate = buttonstate; + mx += dx; + my += dy; +} + +void IN_Init(void) +{ + + int mtype; + char *mousedev; + int mouserate; + + if (UseMouse) + { + + Cvar_RegisterVariable (&mouse_button_commands[0]); + Cvar_RegisterVariable (&mouse_button_commands[1]); + Cvar_RegisterVariable (&mouse_button_commands[2]); + Cmd_AddCommand ("force_centerview", Force_CenterView_f); + + mouse_buttons = 3; + + mtype = vga_getmousetype(); + + mousedev = "/dev/mouse"; + if (getenv("MOUSEDEV")) mousedev = getenv("MOUSEDEV"); + if (COM_CheckParm("-mdev")) + mousedev = com_argv[COM_CheckParm("-mdev")+1]; + + mouserate = 1200; + if (getenv("MOUSERATE")) mouserate = atoi(getenv("MOUSERATE")); + if (COM_CheckParm("-mrate")) + mouserate = atoi(com_argv[COM_CheckParm("-mrate")+1]); + + if (mouse_init(mousedev, mtype, mouserate)) + { + Con_Printf("No mouse found\n"); + UseMouse = 0; + } + else + mouse_seteventhandler(mousehandler); + + } + +} + +void IN_Shutdown(void) +{ + if (UseMouse) + mouse_close(); +} + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ + if (UseMouse) + { + // poll mouse values + while (mouse_update()) + ; + + // perform button actions + if ((mouse_buttonstate & MOUSE_LEFTBUTTON) && + !(mouse_oldbuttonstate & MOUSE_LEFTBUTTON)) + Key_Event (K_MOUSE1, true); + else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) && + (mouse_oldbuttonstate & MOUSE_LEFTBUTTON)) + Key_Event (K_MOUSE1, false); + + if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) && + !(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON)) + Key_Event (K_MOUSE2, true); + else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) && + (mouse_oldbuttonstate & MOUSE_RIGHTBUTTON)) + Key_Event (K_MOUSE2, false); + + if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) && + !(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON)) + Key_Event (K_MOUSE3, true); + else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) && + (mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON)) + Key_Event (K_MOUSE3, false); + + mouse_oldbuttonstate = mouse_buttonstate; + } +} + +/* +=========== +IN_Move +=========== +*/ +void IN_MouseMove (usercmd_t *cmd) +{ + if (!UseMouse) + return; + + // poll mouse values + while (mouse_update()) + ; + + if (m_filter.value) + { + mouse_x = (mx + old_mouse_x) * 0.5; + mouse_y = (my + old_mouse_y) * 0.5; + } + else + { + mouse_x = mx; + mouse_y = my; + } + old_mouse_x = mx; + old_mouse_y = my; + mx = my = 0; // clear for next update + + mouse_x *= sensitivity.value; + mouse_y *= sensitivity.value; + +// add mouse X/Y movement to cmd + if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) + cmd->sidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + cl.viewangles[PITCH] += m_pitch.value * mouse_y; + if (cl.viewangles[PITCH] > 80) + cl.viewangles[PITCH] = 80; + if (cl.viewangles[PITCH] < -70) + cl.viewangles[PITCH] = -70; + } + else + { + if ((in_strafe.state & 1) && noclip_anglehack) + cmd->upmove -= m_forward.value * mouse_y; + else + cmd->forwardmove -= m_forward.value * mouse_y; + } +} + +void IN_Move (usercmd_t *cmd) +{ + IN_MouseMove(cmd); +} + +void VID_UnlockBuffer() {} +void VID_LockBuffer() {} + diff --git a/QW/client/gl_vidlinux_svga.c b/QW/client/gl_vidlinux_svga.c new file mode 100644 index 0000000..697ef02 --- /dev/null +++ b/QW/client/gl_vidlinux_svga.c @@ -0,0 +1,855 @@ +/* +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. + +*/ +#include <termios.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/vt.h> +#include <stdarg.h> +#include <stdio.h> +#include <signal.h> + +#include <asm/io.h> + +/*#include "vga.h" */ +#include "vgakeyboard.h" +#include "vgamouse.h" + +#include "quakedef.h" +#include "GL/fxmesa.h" + +#define WARP_WIDTH 320 +#define WARP_HEIGHT 200 + +static fxMesaContext fc = NULL; +#define stringify(m) { #m, m } + +unsigned short d_8to16table[256]; +unsigned d_8to24table[256]; +unsigned char d_15to8table[65536]; + +int num_shades=32; + +struct +{ + char *name; + int num; +} mice[] = +{ + stringify(MOUSE_MICROSOFT), + stringify(MOUSE_MOUSESYSTEMS), + stringify(MOUSE_MMSERIES), + stringify(MOUSE_LOGITECH), + stringify(MOUSE_BUSMOUSE), + stringify(MOUSE_PS2), +}; + +static unsigned char scantokey[128]; + +int num_mice = sizeof (mice) / sizeof(mice[0]); + +int d_con_indirect = 0; + +int svgalib_inited=0; +int UseMouse = 1; +int UseKeyboard = 1; + +int mouserate = MOUSE_DEFAULTSAMPLERATE; + +cvar_t vid_mode = {"vid_mode","5",false}; +cvar_t vid_redrawfull = {"vid_redrawfull","0",false}; +cvar_t vid_waitforrefresh = {"vid_waitforrefresh","0",true}; + +char *framebuffer_ptr; + +cvar_t mouse_button_commands[3] = +{ + {"mouse1","+attack"}, + {"mouse2","+strafe"}, + {"mouse3","+forward"}, +}; + +int mouse_buttons; +int mouse_buttonstate; +int mouse_oldbuttonstate; +float mouse_x, mouse_y; +float old_mouse_x, old_mouse_y; +int mx, my; + +cvar_t _windowed_mouse = {"_windowed_mouse", "1", true}; +cvar_t m_filter = {"m_filter","0"}; + +int scr_width, scr_height; + +/*-----------------------------------------------------------------------*/ + +//int texture_mode = GL_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_LINEAR; +int texture_mode = GL_LINEAR; +//int texture_mode = GL_LINEAR_MIPMAP_NEAREST; +//int texture_mode = GL_LINEAR_MIPMAP_LINEAR; + +int texture_extension_number = 1; + +float gldepthmin, gldepthmax; + +cvar_t gl_ztrick = {"gl_ztrick","1"}; + +const char *gl_vendor; +const char *gl_renderer; +const char *gl_version; +const char *gl_extensions; + +qboolean is8bit = false; +qboolean isPermedia = false; +qboolean gl_mtexable = false; + +/*-----------------------------------------------------------------------*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +} + +void D_EndDirectRect (int x, int y, int width, int height) +{ +} + +/* +================= +VID_Gamma_f + +Keybinding command +================= +*/ +void VID_Gamma_f (void) +{ + float gamma, f, inf; + unsigned char palette[768]; + int i; + + if (Cmd_Argc () == 2) + { + gamma = Q_atof (Cmd_Argv(1)); + + for (i=0 ; i<768 ; i++) + { + f = pow ( (host_basepal[i]+1)/256.0 , gamma ); + inf = f*255 + 0.5; + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + palette[i] = inf; + } + + VID_SetPalette (palette); + + vid.recalc_refdef = 1; // force a surface cache flush + } +} + +int matchmouse(int mouse, char *name) +{ + int i; + for (i=0 ; i<num_mice ; i++) + if (!strcmp(mice[i].name, name)) + return i; + return mouse; +} + +#if 0 + +void vtswitch(int newconsole) +{ + + int fd; + struct vt_stat x; + +// switch consoles and wait until reactivated + fd = open("/dev/console", O_RDONLY); + ioctl(fd, VT_GETSTATE, &x); + ioctl(fd, VT_ACTIVATE, newconsole); + ioctl(fd, VT_WAITACTIVE, x.v_active); + close(fd); + +} + +#endif + +void keyhandler(int scancode, int state) +{ + + int sc; + + sc = scancode & 0x7f; +// Con_Printf("scancode=%x (%d%s)\n", scancode, sc, scancode&0x80?"+128":""); + Key_Event(scantokey[sc], state == KEY_EVENTPRESS); + +} + +void VID_Shutdown(void) +{ + if (!fc) + return; + + fxMesaDestroyContext(fc); + + if (UseKeyboard) + keyboard_close(); +} + +void signal_handler(int sig) +{ + printf("Received signal %d, exiting...\n", sig); + VID_Shutdown(); + exit(0); +} + +void InitSig(void) +{ + signal(SIGHUP, signal_handler); + signal(SIGQUIT, signal_handler); + signal(SIGILL, signal_handler); + signal(SIGTRAP, signal_handler); + signal(SIGIOT, signal_handler); + signal(SIGBUS, signal_handler); + signal(SIGFPE, signal_handler); + signal(SIGSEGV, signal_handler); + signal(SIGTERM, signal_handler); +} + +void VID_ShiftPalette(unsigned char *p) +{ + VID_SetPalette(p); +} + +void VID_SetPalette (unsigned char *palette) +{ + byte *pal; + unsigned short r,g,b; + int v; + int r1,g1,b1; + int k; + unsigned short i; + unsigned *table; + FILE *f; + char s[255]; + float dist, bestdist; + static qboolean palflag = false; + +// +// 8 8 8 encoding +// + pal = palette; + table = d_8to24table; + for (i=0 ; i<256 ; i++) + { + r = pal[0]; + g = pal[1]; + b = pal[2]; + pal += 3; + +// v = (255<<24) + (r<<16) + (g<<8) + (b<<0); +// v = (255<<0) + (r<<8) + (g<<16) + (b<<24); + v = (255<<24) + (r<<0) + (g<<8) + (b<<16); + *table++ = v; + } + d_8to24table[255] &= 0xffffff; // 255 is transparent + + // JACK: 3D distance calcs - k is last closest, l is the distance. + // FIXME: Precalculate this and cache to disk. + if (palflag) + return; + palflag = true; + + COM_FOpenFile("glquake/15to8.pal", &f); + if (f) { + fread(d_15to8table, 1<<15, 1, f); + fclose(f); + } else { + for (i=0; i < (1<<15); i++) { + /* Maps + 000000000000000 + 000000000011111 = Red = 0x1F + 000001111100000 = Blue = 0x03E0 + 111110000000000 = Grn = 0x7C00 + */ + r = ((i & 0x1F) << 3)+4; + g = ((i & 0x03E0) >> 2)+4; + b = ((i & 0x7C00) >> 7)+4; + pal = (unsigned char *)d_8to24table; + for (v=0,k=0,bestdist=10000.0; v<256; v++,pal+=4) { + r1 = (int)r - (int)pal[0]; + g1 = (int)g - (int)pal[1]; + b1 = (int)b - (int)pal[2]; + dist = sqrt(((r1*r1)+(g1*g1)+(b1*b1))); + if (dist < bestdist) { + k=v; + bestdist = dist; + } + } + d_15to8table[i]=k; + } + sprintf(s, "%s/glquake", com_gamedir); + Sys_mkdir (s); + sprintf(s, "%s/glquake/15to8.pal", com_gamedir); + if ((f = fopen(s, "wb")) != NULL) { + fwrite(d_15to8table, 1<<15, 1, f); + fclose(f); + } + } +} + +/* +=============== +GL_Init +=============== +*/ +void GL_Init (void) +{ + gl_vendor = glGetString (GL_VENDOR); + Con_Printf ("GL_VENDOR: %s\n", gl_vendor); + gl_renderer = glGetString (GL_RENDERER); + Con_Printf ("GL_RENDERER: %s\n", gl_renderer); + + gl_version = glGetString (GL_VERSION); + Con_Printf ("GL_VERSION: %s\n", gl_version); + gl_extensions = glGetString (GL_EXTENSIONS); + Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); + +// Con_Printf ("%s %s\n", gl_renderer, gl_version); + + glClearColor (1,0,0,0); + glCullFace(GL_FRONT); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.666); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glShadeModel (GL_FLAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +} + +/* +================= +GL_BeginRendering + +================= +*/ +void GL_BeginRendering (int *x, int *y, int *width, int *height) +{ + extern cvar_t gl_clear; + + *x = *y = 0; + *width = scr_width; + *height = scr_height; + +// if (!wglMakeCurrent( maindc, baseRC )) +// Sys_Error ("wglMakeCurrent failed"); + +// glViewport (*x, *y, *width, *height); +} + + +void GL_EndRendering (void) +{ + glFlush(); + fxMesaSwapBuffers(); +} + +void Init_KBD(void) +{ + int i; + + if (COM_CheckParm("-nokbd")) UseKeyboard = 0; + + if (UseKeyboard) + { + for (i=0 ; i<128 ; i++) + scantokey[i] = ' '; + + scantokey[ 1] = K_ESCAPE; + scantokey[ 2] = '1'; + scantokey[ 3] = '2'; + scantokey[ 4] = '3'; + scantokey[ 5] = '4'; + scantokey[ 6] = '5'; + scantokey[ 7] = '6'; + scantokey[ 8] = '7'; + scantokey[ 9] = '8'; + scantokey[ 10] = '9'; + scantokey[ 11] = '0'; + scantokey[ 12] = '-'; + scantokey[ 13] = '='; + scantokey[ 14] = K_BACKSPACE; + scantokey[ 15] = K_TAB; + scantokey[ 16] = 'q'; + scantokey[ 17] = 'w'; + scantokey[ 18] = 'e'; + scantokey[ 19] = 'r'; + scantokey[ 20] = 't'; + scantokey[ 21] = 'y'; + scantokey[ 22] = 'u'; + scantokey[ 23] = 'i'; + scantokey[ 24] = 'o'; + scantokey[ 25] = 'p'; + scantokey[ 26] = '['; + scantokey[ 27] = ']'; + scantokey[ 28] = K_ENTER; + scantokey[ 29] = K_CTRL; //left + scantokey[ 30] = 'a'; + scantokey[ 31] = 's'; + scantokey[ 32] = 'd'; + scantokey[ 33] = 'f'; + scantokey[ 34] = 'g'; + scantokey[ 35] = 'h'; + scantokey[ 36] = 'j'; + scantokey[ 37] = 'k'; + scantokey[ 38] = 'l'; + scantokey[ 39] = ';'; + scantokey[ 40] = '\''; + scantokey[ 41] = '`'; + scantokey[ 42] = K_SHIFT; //left + scantokey[ 43] = '\\'; + scantokey[ 44] = 'z'; + scantokey[ 45] = 'x'; + scantokey[ 46] = 'c'; + scantokey[ 47] = 'v'; + scantokey[ 48] = 'b'; + scantokey[ 49] = 'n'; + scantokey[ 50] = 'm'; + scantokey[ 51] = ','; + scantokey[ 52] = '.'; + scantokey[ 53] = '/'; + scantokey[ 54] = K_SHIFT; //right + scantokey[ 55] = '*'; //keypad + scantokey[ 56] = K_ALT; //left + scantokey[ 57] = ' '; + // 58 caps lock + scantokey[ 59] = K_F1; + scantokey[ 60] = K_F2; + scantokey[ 61] = K_F3; + scantokey[ 62] = K_F4; + scantokey[ 63] = K_F5; + scantokey[ 64] = K_F6; + scantokey[ 65] = K_F7; + scantokey[ 66] = K_F8; + scantokey[ 67] = K_F9; + scantokey[ 68] = K_F10; + // 69 numlock + // 70 scrollock + scantokey[ 71] = K_HOME; + scantokey[ 72] = K_UPARROW; + scantokey[ 73] = K_PGUP; + scantokey[ 74] = '-'; + scantokey[ 75] = K_LEFTARROW; + scantokey[ 76] = '5'; + scantokey[ 77] = K_RIGHTARROW; + scantokey[ 79] = K_END; + scantokey[ 78] = '+'; + scantokey[ 80] = K_DOWNARROW; + scantokey[ 81] = K_PGDN; + scantokey[ 82] = K_INS; + scantokey[ 83] = K_DEL; + // 84 to 86 not used + scantokey[ 87] = K_F11; + scantokey[ 88] = K_F12; + // 89 to 95 not used + scantokey[ 96] = K_ENTER; //keypad enter + scantokey[ 97] = K_CTRL; //right + scantokey[ 98] = '/'; + scantokey[ 99] = K_F12; // print screen, bind to screenshot by default + scantokey[100] = K_ALT; // right + + + scantokey[101] = K_PAUSE; // break + scantokey[102] = K_HOME; + scantokey[103] = K_UPARROW; + scantokey[104] = K_PGUP; + scantokey[105] = K_LEFTARROW; + scantokey[106] = K_RIGHTARROW; + scantokey[107] = K_END; + scantokey[108] = K_DOWNARROW; + scantokey[109] = K_PGDN; + scantokey[110] = K_INS; + scantokey[111] = K_DEL; + + scantokey[119] = K_PAUSE; + + if (keyboard_init()) + Sys_Error("keyboard_init() failed"); + keyboard_seteventhandler(keyhandler); + } +} + +#define NUM_RESOLUTIONS 3 + +static resolutions[NUM_RESOLUTIONS][3]={ + { 512, 384, GR_RESOLUTION_512x384 }, + { 640, 400, GR_RESOLUTION_640x400 }, + { 640, 480, GR_RESOLUTION_640x480 } +}; + +int findres(int *width, int *height) +{ + int i; + + for(i=0;i<NUM_RESOLUTIONS;i++) + if((*width<=resolutions[i][0]) && (*height<=resolutions[i][1])) { + *width = resolutions[i][0]; + *height = resolutions[i][1]; + return resolutions[i][2]; + } + + *width = 640; + *height = 480; + return GR_RESOLUTION_640x480; +} + +qboolean VID_Is8bit(void) +{ + return is8bit; +} + +#ifdef GL_EXT_SHARED +void VID_Init8bitPalette() +{ + // Check for 8bit Extensions and initialize them. + int i; + char thePalette[256*3]; + char *oldPalette, *newPalette; + + if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") == NULL) + return; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldPalette = (char *) d_8to24table; //d_8to24table3dfx; + newPalette = thePalette; + for (i=0;i<256;i++) { + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + oldPalette++; + } + glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette); + is8bit = true; +} + +#else +extern void gl3DfxSetPaletteEXT(GLuint *pal); + +void VID_Init8bitPalette(void) +{ + // Check for 8bit Extensions and initialize them. + int i; + GLubyte table[256][4]; + char *oldpal; + + if (strstr(gl_extensions, "3DFX_set_global_palette") == NULL) + return; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldpal = (char *) d_8to24table; //d_8to24table3dfx; + for (i=0;i<256;i++) { + table[i][2] = *oldpal++; + table[i][1] = *oldpal++; + table[i][0] = *oldpal++; + table[i][3] = 255; + oldpal++; + } + gl3DfxSetPaletteEXT((GLuint *)table); + is8bit = true; +} +#endif + +void VID_Init(unsigned char *palette) +{ + int i; + GLint attribs[32]; + char gldir[MAX_OSPATH]; + int width = 640, height = 480; + + S_Init(); + + Init_KBD(); + + Cvar_RegisterVariable (&vid_mode); + Cvar_RegisterVariable (&vid_redrawfull); + Cvar_RegisterVariable (&vid_waitforrefresh); + Cvar_RegisterVariable (&gl_ztrick); + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + +// interpret command-line params + +// set vid parameters + attribs[0] = FXMESA_DOUBLEBUFFER; + attribs[1] = FXMESA_ALPHA_SIZE; + attribs[2] = 1; + attribs[3] = FXMESA_DEPTH_SIZE; + attribs[4] = 1; + attribs[5] = FXMESA_NONE; + + if ((i = COM_CheckParm("-width")) != 0) + width = atoi(com_argv[i+1]); + if ((i = COM_CheckParm("-height")) != 0) + height = atoi(com_argv[i+1]); + + if ((i = COM_CheckParm("-conwidth")) != 0) + vid.conwidth = Q_atoi(com_argv[i+1]); + else + vid.conwidth = 640; + + vid.conwidth &= 0xfff8; // make it a multiple of eight + + if (vid.conwidth < 320) + vid.conwidth = 320; + + // pick a conheight that matches with correct aspect + vid.conheight = vid.conwidth*3 / 4; + + if ((i = COM_CheckParm("-conheight")) != 0) + vid.conheight = Q_atoi(com_argv[i+1]); + if (vid.conheight < 200) + vid.conheight = 200; + + fc = fxMesaCreateContext(0, findres(&width, &height), GR_REFRESH_75Hz, + attribs); + if (!fc) + Sys_Error("Unable to create 3DFX context.\n"); + + scr_width = width; + scr_height = height; + + fxMesaMakeCurrent(fc); + + if (vid.conheight > height) + vid.conheight = height; + if (vid.conwidth > width) + vid.conwidth = width; + vid.width = vid.conwidth; + vid.height = vid.conheight; + + vid.aspect = ((float)vid.height / (float)vid.width) * + (320.0 / 240.0); + vid.numpages = 2; + + InitSig(); // trap evil signals + + GL_Init(); + + sprintf (gldir, "%s/glquake", com_gamedir); + Sys_mkdir (gldir); + + VID_SetPalette(palette); + + // Check for 3DFX Extensions and initialize them. + VID_Init8bitPalette(); + + Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height); + + vid.recalc_refdef = 1; // force a surface cache flush +} + +void Sys_SendKeyEvents(void) +{ + if (UseKeyboard) + while (keyboard_update()); +} + +void Force_CenterView_f (void) +{ + cl.viewangles[PITCH] = 0; +} + + +void mousehandler(int buttonstate, int dx, int dy) +{ + mouse_buttonstate = buttonstate; + mx += dx; + my += dy; +} + +void IN_Init(void) +{ + + int mtype; + char *mousedev; + int mouserate; + + if (UseMouse) + { + + Cvar_RegisterVariable (&mouse_button_commands[0]); + Cvar_RegisterVariable (&mouse_button_commands[1]); + Cvar_RegisterVariable (&mouse_button_commands[2]); + Cmd_AddCommand ("force_centerview", Force_CenterView_f); + + mouse_buttons = 3; + + mtype = vga_getmousetype(); + + mousedev = "/dev/mouse"; + if (getenv("MOUSEDEV")) mousedev = getenv("MOUSEDEV"); + if (COM_CheckParm("-mdev")) + mousedev = com_argv[COM_CheckParm("-mdev")+1]; + + mouserate = 1200; + if (getenv("MOUSERATE")) mouserate = atoi(getenv("MOUSERATE")); + if (COM_CheckParm("-mrate")) + mouserate = atoi(com_argv[COM_CheckParm("-mrate")+1]); + + if (mouse_init(mousedev, mtype, mouserate)) + { + Con_Printf("No mouse found\n"); + UseMouse = 0; + } + else + mouse_seteventhandler(mousehandler); + + } + +} + +void IN_Shutdown(void) +{ + if (UseMouse) + mouse_close(); +} + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ + if (UseMouse) + { + // poll mouse values + while (mouse_update()) + ; + + // perform button actions + if ((mouse_buttonstate & MOUSE_LEFTBUTTON) && + !(mouse_oldbuttonstate & MOUSE_LEFTBUTTON)) + Key_Event (K_MOUSE1, true); + else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) && + (mouse_oldbuttonstate & MOUSE_LEFTBUTTON)) + Key_Event (K_MOUSE1, false); + + if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) && + !(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON)) + Key_Event (K_MOUSE2, true); + else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) && + (mouse_oldbuttonstate & MOUSE_RIGHTBUTTON)) + Key_Event (K_MOUSE2, false); + + if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) && + !(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON)) + Key_Event (K_MOUSE3, true); + else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) && + (mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON)) + Key_Event (K_MOUSE3, false); + + mouse_oldbuttonstate = mouse_buttonstate; + } +} + +/* +=========== +IN_Move +=========== +*/ +void IN_MouseMove (usercmd_t *cmd) +{ + if (!UseMouse) + return; + + // poll mouse values + while (mouse_update()) + ; + + if (m_filter.value) + { + mouse_x = (mx + old_mouse_x) * 0.5; + mouse_y = (my + old_mouse_y) * 0.5; + } + else + { + mouse_x = mx; + mouse_y = my; + } + old_mouse_x = mx; + old_mouse_y = my; + mx = my = 0; // clear for next update + + mouse_x *= sensitivity.value; + mouse_y *= sensitivity.value; + +// add mouse X/Y movement to cmd + if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) + cmd->sidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + cl.viewangles[PITCH] += m_pitch.value * mouse_y; + if (cl.viewangles[PITCH] > 80) + cl.viewangles[PITCH] = 80; + if (cl.viewangles[PITCH] < -70) + cl.viewangles[PITCH] = -70; + } + else + { + if ((in_strafe.state & 1) && noclip_anglehack) + cmd->upmove -= m_forward.value * mouse_y; + else + cmd->forwardmove -= m_forward.value * mouse_y; + } +} + +void IN_Move (usercmd_t *cmd) +{ + IN_MouseMove(cmd); +} + + +void VID_LockBuffer (void) {} +void VID_UnlockBuffer (void) {} + diff --git a/QW/client/gl_vidlinux_x11.c b/QW/client/gl_vidlinux_x11.c new file mode 100644 index 0000000..f885381 --- /dev/null +++ b/QW/client/gl_vidlinux_x11.c @@ -0,0 +1,870 @@ +/* +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. + +*/ +#include <termios.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/vt.h> +#include <stdarg.h> +#include <stdio.h> +#include <signal.h> +#include <asm/io.h> + +//#include <X11/cursorfont.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <X11/keysym.h> + +#include "GL/gl.h" +#include "GL/glx.h" + +#include "quakedef.h" + +#define WARP_WIDTH 320 +#define WARP_HEIGHT 200 + +static Display *dpy = NULL; +static Window win; +static GLXContext ctx = NULL; + +unsigned short d_8to16table[256]; +unsigned int d_8to24table[256]; +unsigned char d_15to8table[65536]; + +static qboolean usedga = false; + +#define stringify(m) { #m, m } + +cvar_t vid_mode = {"vid_mode","0",false}; + +cvar_t mouse_button_commands[3] = +{ + {"mouse1","+attack"}, + {"mouse2","+strafe"}, + {"mouse3","+forward"}, +}; + +static int mouse_buttons=3; +static int mouse_buttonstate; +static int mouse_oldbuttonstate; +static float mouse_x, mouse_y; +static float p_mouse_x, p_mouse_y; +static float old_mouse_x, old_mouse_y; + +cvar_t _windowed_mouse = {"_windowed_mouse", "1", true}; +cvar_t m_filter = {"m_filter","0"}; +static float old_windowed_mouse; + +static int scr_width, scr_height; + +#define KEY_MASK (KeyPressMask | KeyReleaseMask) +#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \ + PointerMotionMask | ButtonMotionMask) + +/*-----------------------------------------------------------------------*/ + +//int texture_mode = GL_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_LINEAR; +int texture_mode = GL_LINEAR; +//int texture_mode = GL_LINEAR_MIPMAP_NEAREST; +//int texture_mode = GL_LINEAR_MIPMAP_LINEAR; + +int texture_extension_number = 1; + +float gldepthmin, gldepthmax; + +cvar_t gl_ztrick = {"gl_ztrick","1"}; + +const char *gl_vendor; +const char *gl_renderer; +const char *gl_version; +const char *gl_extensions; + +qboolean is8bit = false; +qboolean isPermedia = false; +qboolean gl_mtexable = false; + +/*-----------------------------------------------------------------------*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +} + +void D_EndDirectRect (int x, int y, int width, int height) +{ +} + +/* +================= +VID_Gamma_f + +Keybinding command +================= +*/ +void VID_Gamma_f (void) +{ + float gamma, f, inf; + unsigned char palette[768]; + int i; + + if (Cmd_Argc () == 2) + { + gamma = Q_atof (Cmd_Argv(1)); + + for (i=0 ; i<768 ; i++) + { + f = pow ( (host_basepal[i]+1)/256.0 , gamma ); + inf = f*255 + 0.5; + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + palette[i] = inf; + } + + VID_SetPalette (palette); + + vid.recalc_refdef = 1; // force a surface cache flush + } +} + +void VID_Shutdown(void) +{ + if (!ctx) + return; + + XUngrabPointer(dpy,CurrentTime); + XUngrabKeyboard(dpy,CurrentTime); + + glXDestroyContext(dpy,ctx); + +#ifdef USE_DGA + if (usedga) + XF86DGADirectVideo(dpy,DefaultScreen(dpy),0); +#endif +} + +int XLateKey(XKeyEvent *ev) +{ + + int key; + char buf[64]; + KeySym keysym; + + key = 0; + + XLookupString(ev, buf, sizeof buf, &keysym, 0); + + switch(keysym) + { + case XK_KP_Page_Up: + case XK_Page_Up: key = K_PGUP; break; + + case XK_KP_Page_Down: + case XK_Page_Down: key = K_PGDN; break; + + case XK_KP_Home: + case XK_Home: key = K_HOME; break; + + case XK_KP_End: + case XK_End: key = K_END; break; + + case XK_KP_Left: + case XK_Left: key = K_LEFTARROW; break; + + case XK_KP_Right: + case XK_Right: key = K_RIGHTARROW; break; + + case XK_KP_Down: + case XK_Down: key = K_DOWNARROW; break; + + case XK_KP_Up: + case XK_Up: key = K_UPARROW; break; + + case XK_Escape: key = K_ESCAPE; break; + + case XK_KP_Enter: + case XK_Return: key = K_ENTER; break; + + case XK_Tab: key = K_TAB; break; + + case XK_F1: key = K_F1; break; + + case XK_F2: key = K_F2; break; + + case XK_F3: key = K_F3; break; + + case XK_F4: key = K_F4; break; + + case XK_F5: key = K_F5; break; + + case XK_F6: key = K_F6; break; + + case XK_F7: key = K_F7; break; + + case XK_F8: key = K_F8; break; + + case XK_F9: key = K_F9; break; + + case XK_F10: key = K_F10; break; + + case XK_F11: key = K_F11; break; + + case XK_F12: key = K_F12; break; + + case XK_BackSpace: key = K_BACKSPACE; break; + + case XK_KP_Delete: + case XK_Delete: key = K_DEL; break; + + case XK_Pause: key = K_PAUSE; break; + + case XK_Shift_L: + case XK_Shift_R: key = K_SHIFT; break; + + case XK_Execute: + case XK_Control_L: + case XK_Control_R: key = K_CTRL; break; + + case XK_Alt_L: + case XK_Meta_L: + case XK_Alt_R: + case XK_Meta_R: key = K_ALT; break; + + case XK_KP_Begin: key = K_AUX30; break; + + case XK_Insert: + case XK_KP_Insert: key = K_INS; break; + + case XK_KP_Multiply: key = '*'; break; + case XK_KP_Add: key = '+'; break; + case XK_KP_Subtract: key = '-'; break; + case XK_KP_Divide: key = '/'; break; + +#if 0 + case 0x021: key = '1';break;/* [!] */ + case 0x040: key = '2';break;/* [@] */ + case 0x023: key = '3';break;/* [#] */ + case 0x024: key = '4';break;/* [$] */ + case 0x025: key = '5';break;/* [%] */ + case 0x05e: key = '6';break;/* [^] */ + case 0x026: key = '7';break;/* [&] */ + case 0x02a: key = '8';break;/* [*] */ + case 0x028: key = '9';;break;/* [(] */ + case 0x029: key = '0';break;/* [)] */ + case 0x05f: key = '-';break;/* [_] */ + case 0x02b: key = '=';break;/* [+] */ + case 0x07c: key = '\'';break;/* [|] */ + case 0x07d: key = '[';break;/* [}] */ + case 0x07b: key = ']';break;/* [{] */ + case 0x022: key = '\'';break;/* ["] */ + case 0x03a: key = ';';break;/* [:] */ + case 0x03f: key = '/';break;/* [?] */ + case 0x03e: key = '.';break;/* [>] */ + case 0x03c: key = ',';break;/* [<] */ +#endif + + default: + key = *(unsigned char*)buf; + if (key >= 'A' && key <= 'Z') + key = key - 'A' + 'a'; +// fprintf(stdout, "case 0x0%x: key = ___;break;/* [%c] */\n", keysym); + break; + } + + return key; +} + +struct +{ + int key; + int down; +} keyq[64]; +int keyq_head=0; +int keyq_tail=0; + +int config_notify=0; +int config_notify_width; +int config_notify_height; + +qboolean Keyboard_Update(void) +{ + XEvent x_event; + + if(!XCheckMaskEvent(dpy,KEY_MASK,&x_event)) + return false; + + switch(x_event.type) { + case KeyPress: + keyq[keyq_head].key = XLateKey(&x_event.xkey); + keyq[keyq_head].down = true; + keyq_head = (keyq_head + 1) & 63; + break; + case KeyRelease: + keyq[keyq_head].key = XLateKey(&x_event.xkey); + keyq[keyq_head].down = false; + keyq_head = (keyq_head + 1) & 63; + break; + } + + return true; +} + +qboolean Mouse_Update(void) +{ + XEvent x_event; + int b; + + if(!XCheckMaskEvent(dpy,MOUSE_MASK,&x_event)) + return false; + + switch(x_event.type) { + case MotionNotify: + if (usedga) { + mouse_x += x_event.xmotion.x_root; + mouse_y += x_event.xmotion.y_root; + } else if (_windowed_mouse.value) { + mouse_x += (float) ((int)x_event.xmotion.x - (int)(scr_width/2)); + mouse_y += (float) ((int)x_event.xmotion.y - (int)(scr_height/2)); + + /* move the mouse to the window center again */ + XSelectInput(dpy,win, (KEY_MASK | MOUSE_MASK) & ~PointerMotionMask); + XWarpPointer(dpy,None,win,0,0,0,0, (scr_width/2),(scr_height/2)); + XSelectInput(dpy,win, KEY_MASK | MOUSE_MASK); + } else { + mouse_x = (float) (x_event.xmotion.x-p_mouse_x); + mouse_y = (float) (x_event.xmotion.y-p_mouse_y); + p_mouse_x=x_event.xmotion.x; + p_mouse_y=x_event.xmotion.y; + } + break; + + case ButtonPress: + b=-1; + if (x_event.xbutton.button == 1) + b = 0; + else if (x_event.xbutton.button == 2) + b = 2; + else if (x_event.xbutton.button == 3) + b = 1; + if (b>=0) + mouse_buttonstate |= 1<<b; + break; + + case ButtonRelease: + b=-1; + if (x_event.xbutton.button == 1) + b = 0; + else if (x_event.xbutton.button == 2) + b = 2; + else if (x_event.xbutton.button == 3) + b = 1; + if (b>=0) + mouse_buttonstate &= ~(1<<b); + break; + } + + if (old_windowed_mouse != _windowed_mouse.value) { + old_windowed_mouse = _windowed_mouse.value; + + if (!_windowed_mouse.value) { + /* ungrab the pointer */ + Con_Printf("Releasing mouse.\n"); + + XUngrabPointer(dpy,CurrentTime); + XUngrabKeyboard(dpy,CurrentTime); + } else { + /* grab the pointer */ + Con_Printf("Grabbing mouse.\n"); + + XGrabPointer(dpy,win,False,MOUSE_MASK,GrabModeAsync, + GrabModeAsync,win,None,CurrentTime); + XWarpPointer(dpy,None,win, 0,0,0,0, scr_width/2, scr_height/2); + XGrabKeyboard(dpy,win, + False, + GrabModeAsync,GrabModeAsync, + CurrentTime); + + //XSync(dpy,True); + } + } + return true; +} + +void signal_handler(int sig) +{ + printf("Received signal %d, exiting...\n", sig); + VID_Shutdown(); + exit(0); +} + +void InitSig(void) +{ + signal(SIGHUP, signal_handler); + signal(SIGQUIT, signal_handler); + signal(SIGILL, signal_handler); + signal(SIGTRAP, signal_handler); + signal(SIGIOT, signal_handler); + signal(SIGBUS, signal_handler); + signal(SIGFPE, signal_handler); + signal(SIGSEGV, signal_handler); + signal(SIGTERM, signal_handler); +} + +void VID_ShiftPalette(unsigned char *p) +{ + VID_SetPalette(p); +} + +void VID_SetPalette (unsigned char *palette) +{ + byte *pal; + unsigned short r,g,b; + int v; + int r1,g1,b1; + int k; + unsigned short i; + unsigned *table; + FILE *f; + char s[255]; + float dist, bestdist; + static qboolean palflag = false; + +// +// 8 8 8 encoding +// + pal = palette; + table = d_8to24table; + for (i=0 ; i<256 ; i++) + { + r = pal[0]; + g = pal[1]; + b = pal[2]; + pal += 3; + +// v = (255<<24) + (r<<16) + (g<<8) + (b<<0); +// v = (255<<0) + (r<<8) + (g<<16) + (b<<24); + v = (255<<24) + (r<<0) + (g<<8) + (b<<16); + *table++ = v; + } + d_8to24table[255] &= 0xffffff; // 255 is transparent + + // JACK: 3D distance calcs - k is last closest, l is the distance. + // FIXME: Precalculate this and cache to disk. + if (palflag) + return; + palflag = true; + + COM_FOpenFile("glquake/15to8.pal", &f); + if (f) { + fread(d_15to8table, 1<<15, 1, f); + fclose(f); + } else { + for (i=0; i < (1<<15); i++) { + /* Maps + 000000000000000 + 000000000011111 = Red = 0x1F + 000001111100000 = Blue = 0x03E0 + 111110000000000 = Grn = 0x7C00 + */ + r = ((i & 0x1F) << 3)+4; + g = ((i & 0x03E0) >> 2)+4; + b = ((i & 0x7C00) >> 7)+4; + pal = (unsigned char *)d_8to24table; + for (v=0,k=0,bestdist=10000.0; v<256; v++,pal+=4) { + r1 = (int)r - (int)pal[0]; + g1 = (int)g - (int)pal[1]; + b1 = (int)b - (int)pal[2]; + dist = sqrt(((r1*r1)+(g1*g1)+(b1*b1))); + if (dist < bestdist) { + k=v; + bestdist = dist; + } + } + d_15to8table[i]=k; + } + sprintf(s, "%s/glquake", com_gamedir); + Sys_mkdir (s); + sprintf(s, "%s/glquake/15to8.pal", com_gamedir); + if ((f = fopen(s, "wb")) != NULL) { + fwrite(d_15to8table, 1<<15, 1, f); + fclose(f); + } + } +} + +/* +=============== +GL_Init +=============== +*/ +void GL_Init (void) +{ + gl_vendor = glGetString (GL_VENDOR); + Con_Printf ("GL_VENDOR: %s\n", gl_vendor); + gl_renderer = glGetString (GL_RENDERER); + Con_Printf ("GL_RENDERER: %s\n", gl_renderer); + + gl_version = glGetString (GL_VERSION); + Con_Printf ("GL_VERSION: %s\n", gl_version); + gl_extensions = glGetString (GL_EXTENSIONS); + Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); + +// Con_Printf ("%s %s\n", gl_renderer, gl_version); + + glClearColor (1,0,0,0); + glCullFace(GL_FRONT); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.666); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glShadeModel (GL_FLAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +} + +/* +================= +GL_BeginRendering + +================= +*/ +void GL_BeginRendering (int *x, int *y, int *width, int *height) +{ + extern cvar_t gl_clear; + + *x = *y = 0; + *width = scr_width; + *height = scr_height; + +// if (!wglMakeCurrent( maindc, baseRC )) +// Sys_Error ("wglMakeCurrent failed"); + +// glViewport (*x, *y, *width, *height); +} + + +void GL_EndRendering (void) +{ + glFlush(); + glXSwapBuffers(dpy,win); +} + +qboolean VID_Is8bit(void) +{ + return is8bit; +} + +#ifdef GL_EXT_SHARED +void VID_Init8bitPalette() +{ + // Check for 8bit Extensions and initialize them. + int i; + char thePalette[256*3]; + char *oldPalette, *newPalette; + + if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") == NULL) + return; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldPalette = (char *) d_8to24table; //d_8to24table3dfx; + newPalette = thePalette; + for (i=0;i<256;i++) { + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + oldPalette++; + } + glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette); + is8bit = true; +} + +#else +extern void gl3DfxSetPaletteEXT(GLuint *pal); + +void VID_Init8bitPalette(void) +{ + // Check for 8bit Extensions and initialize them. + int i; + GLubyte table[256][4]; + char *oldpal; + + if (strstr(gl_extensions, "3DFX_set_global_palette") == NULL) + return; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldpal = (char *) d_8to24table; //d_8to24table3dfx; + for (i=0;i<256;i++) { + table[i][2] = *oldpal++; + table[i][1] = *oldpal++; + table[i][0] = *oldpal++; + table[i][3] = 255; + oldpal++; + } + gl3DfxSetPaletteEXT((GLuint *)table); + is8bit = true; +} +#endif + +void VID_Init(unsigned char *palette) +{ + int i; + char gldir[MAX_OSPATH]; + int width = 640, height = 480; + int attrib[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + GLX_DEPTH_SIZE, 1, + None }; + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + XVisualInfo *visinfo; + + S_Init(); + + Cvar_RegisterVariable (&vid_mode); + Cvar_RegisterVariable (&gl_ztrick); + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + +// interpret command-line params + +// set vid parameters + + if ((i = COM_CheckParm("-width")) != 0) + width = atoi(com_argv[i+1]); + if ((i = COM_CheckParm("-height")) != 0) + height = atoi(com_argv[i+1]); + + if ((i = COM_CheckParm("-conwidth")) != 0) + vid.conwidth = Q_atoi(com_argv[i+1]); + else + vid.conwidth = 640; + + vid.conwidth &= 0xfff8; // make it a multiple of eight + + if (vid.conwidth < 320) + vid.conwidth = 320; + + // pick a conheight that matches with correct aspect + vid.conheight = vid.conwidth*3 / 4; + + if ((i = COM_CheckParm("-conheight")) != 0) + vid.conheight = Q_atoi(com_argv[i+1]); + if (vid.conheight < 200) + vid.conheight = 200; + + if (!(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "Error couldn't open the X display\n"); + exit(1); + } + + scrnum = DefaultScreen(dpy); + root = RootWindow(dpy, scrnum); + + visinfo=glXChooseVisual(dpy,scrnum,attrib); + if (!visinfo) { + fprintf(stderr, "Error couldn't get an RGB, Double-buffered, Depth visual\n"); + exit(1); + } + + /* window attributes */ + attr.background_pixel=0; + attr.border_pixel=0; + attr.colormap=XCreateColormap(dpy,root,visinfo->visual,AllocNone); + attr.event_mask=KEY_MASK|MOUSE_MASK|VisibilityChangeMask; + mask=CWBackPixel|CWBorderPixel|CWColormap|CWEventMask; + + win=XCreateWindow(dpy,root,0,0,width,height, + 0,visinfo->depth,InputOutput, + visinfo->visual,mask,&attr); + XMapWindow(dpy,win); + + XMoveWindow(dpy,win,0,0); + + XFlush(dpy); + + if (COM_CheckParm("-window")) + putenv("MESA_GLX_FX=window"); + else + putenv("MESA_GLX_FX=fullscreen"); + + ctx = glXCreateContext(dpy,visinfo,NULL,True); + + if (!ctx) { + fprintf(stderr, "Unable to create glX context.\n"); + exit(1); + } + + glXMakeCurrent(dpy,win,ctx); + + scr_width = width; + scr_height = height; + + if (vid.conheight > height) + vid.conheight = height; + if (vid.conwidth > width) + vid.conwidth = width; + vid.width = vid.conwidth; + vid.height = vid.conheight; + + vid.aspect = ((float)vid.height / (float)vid.width) * + (320.0 / 240.0); + vid.numpages = 2; + + InitSig(); // trap evil signals + + GL_Init(); + + sprintf (gldir, "%s/glquake", com_gamedir); + Sys_mkdir (gldir); + + VID_SetPalette(palette); + + // Check for 3DFX Extensions and initialize them. + VID_Init8bitPalette(); + + Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height); + + vid.recalc_refdef = 1; // force a surface cache flush +} + +void Sys_SendKeyEvents(void) +{ + if (dpy) + { + while (Keyboard_Update()) + ; + + while (keyq_head != keyq_tail) + { + Key_Event(keyq[keyq_tail].key, keyq[keyq_tail].down); + keyq_tail = (keyq_tail + 1) & 63; + } + } +} + +void Force_CenterView_f (void) +{ + cl.viewangles[PITCH] = 0; +} + + +void IN_Init(void) +{ + Cvar_RegisterVariable (&_windowed_mouse); + Cvar_RegisterVariable (&m_filter); + Cvar_RegisterVariable (&mouse_button_commands[0]); + Cvar_RegisterVariable (&mouse_button_commands[1]); + Cvar_RegisterVariable (&mouse_button_commands[2]); + Cmd_AddCommand ("force_centerview", Force_CenterView_f); +} + +void IN_Shutdown(void) +{ +} + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ + int i; + + for (i=0 ; i<mouse_buttons ; i++) { + if ( (mouse_buttonstate & (1<<i)) && !(mouse_oldbuttonstate & (1<<i)) ) + Key_Event (K_MOUSE1 + i, true); + + if ( !(mouse_buttonstate & (1<<i)) && (mouse_oldbuttonstate & (1<<i)) ) + Key_Event (K_MOUSE1 + i, false); + } + + mouse_oldbuttonstate = mouse_buttonstate; +} + +/* +=========== +IN_Move +=========== +*/ +void IN_Move (usercmd_t *cmd) +{ + while (Mouse_Update()) + ; + + if (m_filter.value) { + mouse_x = (mouse_x + old_mouse_x) * 0.5; + mouse_y = (mouse_y + old_mouse_y) * 0.5; + } + + old_mouse_x = mouse_x; + old_mouse_y = mouse_y; + + mouse_x *= sensitivity.value; + mouse_y *= sensitivity.value; + + if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) + cmd->sidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) { + cl.viewangles[PITCH] += m_pitch.value * mouse_y; + if (cl.viewangles[PITCH] > 80) + cl.viewangles[PITCH] = 80; + if (cl.viewangles[PITCH] < -70) + cl.viewangles[PITCH] = -70; + } else { + if ((in_strafe.state & 1) && noclip_anglehack) + cmd->upmove -= m_forward.value * mouse_y; + else + cmd->forwardmove -= m_forward.value * mouse_y; + } + mouse_x = mouse_y = 0.0; +} + + +void VID_LockBuffer (void) {} +void VID_UnlockBuffer (void) {} + diff --git a/QW/client/gl_vidlinuxglx.c b/QW/client/gl_vidlinuxglx.c new file mode 100644 index 0000000..96da029 --- /dev/null +++ b/QW/client/gl_vidlinuxglx.c @@ -0,0 +1,789 @@ +/* +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. + +*/ +#include <termios.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/vt.h> +#include <stdarg.h> +#include <stdio.h> +#include <signal.h> + +#include "quakedef.h" + +#include <GL/glx.h> + +#include <X11/keysym.h> +#include <X11/cursorfont.h> + +#ifdef USE_DGA +#include <X11/extensions/xf86dga.h> +#endif + + +#define WARP_WIDTH 320 +#define WARP_HEIGHT 200 + +static Display *dpy = NULL; +static Window win; +static GLXContext ctx = NULL; + +static float old_windowed_mouse = 0; + +#define KEY_MASK (KeyPressMask | KeyReleaseMask) +#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \ + PointerMotionMask) + +#define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask) + +unsigned short d_8to16table[256]; +unsigned d_8to24table[256]; +unsigned char d_15to8table[65536]; + +cvar_t _windowed_mouse = {"_windowed_mouse","0", true}; +cvar_t vid_mode = {"vid_mode","0",false}; + +static float mouse_x, mouse_y; +static float old_mouse_x, old_mouse_y; + +cvar_t m_filter = {"m_filter", "0"}; + +static int scr_width, scr_height; + +/*-----------------------------------------------------------------------*/ + +//int texture_mode = GL_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_LINEAR; +int texture_mode = GL_LINEAR; +//int texture_mode = GL_LINEAR_MIPMAP_NEAREST; +//int texture_mode = GL_LINEAR_MIPMAP_LINEAR; + +int texture_extension_number = 1; + +float gldepthmin, gldepthmax; + +cvar_t gl_ztrick = {"gl_ztrick","1"}; + +const char *gl_vendor; +const char *gl_renderer; +const char *gl_version; +const char *gl_extensions; + +qboolean is8bit = false; +qboolean isPermedia = false; +qboolean gl_mtexable = false; + +/*-----------------------------------------------------------------------*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +} + +void D_EndDirectRect (int x, int y, int width, int height) +{ +} + +static int XLateKey(XKeyEvent *ev) +{ + + int key; + char buf[64]; + KeySym keysym; + + key = 0; + + XLookupString(ev, buf, sizeof buf, &keysym, 0); + + switch(keysym) + { + case XK_KP_Page_Up: + case XK_Page_Up: key = K_PGUP; break; + + case XK_KP_Page_Down: + case XK_Page_Down: key = K_PGDN; break; + + case XK_KP_Home: + case XK_Home: key = K_HOME; break; + + case XK_KP_End: + case XK_End: key = K_END; break; + + case XK_KP_Left: + case XK_Left: key = K_LEFTARROW; break; + + case XK_KP_Right: + case XK_Right: key = K_RIGHTARROW; break; + + case XK_KP_Down: + case XK_Down: key = K_DOWNARROW; break; + + case XK_KP_Up: + case XK_Up: key = K_UPARROW; break; + + case XK_Escape: key = K_ESCAPE; break; + + case XK_KP_Enter: + case XK_Return: key = K_ENTER; break; + + case XK_Tab: key = K_TAB; break; + + case XK_F1: key = K_F1; break; + + case XK_F2: key = K_F2; break; + + case XK_F3: key = K_F3; break; + + case XK_F4: key = K_F4; break; + + case XK_F5: key = K_F5; break; + + case XK_F6: key = K_F6; break; + + case XK_F7: key = K_F7; break; + + case XK_F8: key = K_F8; break; + + case XK_F9: key = K_F9; break; + + case XK_F10: key = K_F10; break; + + case XK_F11: key = K_F11; break; + + case XK_F12: key = K_F12; break; + + case XK_BackSpace: key = K_BACKSPACE; break; + + case XK_KP_Delete: + case XK_Delete: key = K_DEL; break; + + case XK_Pause: key = K_PAUSE; break; + + case XK_Shift_L: + case XK_Shift_R: key = K_SHIFT; break; + + case XK_Execute: + case XK_Control_L: + case XK_Control_R: key = K_CTRL; break; + + case XK_Alt_L: + case XK_Meta_L: + case XK_Alt_R: + case XK_Meta_R: key = K_ALT; break; + + case XK_KP_Begin: key = '5'; break; + + case XK_KP_Insert: + case XK_Insert:key = K_INS; break; + + case XK_KP_Multiply: key = '*'; break; + case XK_KP_Add: key = '+'; break; + case XK_KP_Subtract: key = '-'; break; + case XK_KP_Divide: key = '/'; break; + +#if 0 + case 0x021: key = '1';break;/* [!] */ + case 0x040: key = '2';break;/* [@] */ + case 0x023: key = '3';break;/* [#] */ + case 0x024: key = '4';break;/* [$] */ + case 0x025: key = '5';break;/* [%] */ + case 0x05e: key = '6';break;/* [^] */ + case 0x026: key = '7';break;/* [&] */ + case 0x02a: key = '8';break;/* [*] */ + case 0x028: key = '9';;break;/* [(] */ + case 0x029: key = '0';break;/* [)] */ + case 0x05f: key = '-';break;/* [_] */ + case 0x02b: key = '=';break;/* [+] */ + case 0x07c: key = '\'';break;/* [|] */ + case 0x07d: key = '[';break;/* [}] */ + case 0x07b: key = ']';break;/* [{] */ + case 0x022: key = '\'';break;/* ["] */ + case 0x03a: key = ';';break;/* [:] */ + case 0x03f: key = '/';break;/* [?] */ + case 0x03e: key = '.';break;/* [>] */ + case 0x03c: key = ',';break;/* [<] */ +#endif + + default: + key = *(unsigned char*)buf; + if (key >= 'A' && key <= 'Z') + key = key - 'A' + 'a'; + break; + } + + return key; +} + +static void install_grabs(void) +{ + XGrabPointer(dpy, win, + True, + 0, + GrabModeAsync, GrabModeAsync, + win, + None, + CurrentTime); + +#ifdef USE_DGA + XF86DGADirectVideo(dpy, DefaultScreen(dpy), XF86DGADirectMouse); + dgamouse = 1; +#else + XWarpPointer(dpy, None, win, + 0, 0, 0, 0, + vid.width / 2, vid.height / 2); +#endif + + XGrabKeyboard(dpy, win, + False, + GrabModeAsync, GrabModeAsync, + CurrentTime); + +// XSync(dpy, True); +} + +static void uninstall_grabs(void) +{ +#ifdef USE_DGA + XF86DGADirectVideo(dpy, DefaultScreen(dpy), 0); + dgamouse = 0; +#endif + + XUngrabPointer(dpy, CurrentTime); + XUngrabKeyboard(dpy, CurrentTime); + +// XSync(dpy, True); +} + +static void GetEvent(void) +{ + XEvent event; + int b; + + if (!dpy) + return; + + XNextEvent(dpy, &event); + + switch (event.type) { + case KeyPress: + case KeyRelease: + Key_Event(XLateKey(&event.xkey), event.type == KeyPress); + break; + + case MotionNotify: +#ifdef USE_DGA + if (dgamouse && _windowed_mouse.value) { + mouse_x = event.xmotion.x_root; + mouse_y = event.xmotion.y_root; + } else +#endif + { + if (_windowed_mouse.value) { + mouse_x = (float) ((int)event.xmotion.x - (int)(vid.width/2)); + mouse_y = (float) ((int)event.xmotion.y - (int)(vid.height/2)); + + /* move the mouse to the window center again */ + XSelectInput(dpy, win, X_MASK & ~PointerMotionMask); + XWarpPointer(dpy, None, win, 0, 0, 0, 0, + (vid.width/2), (vid.height/2)); + XSelectInput(dpy, win, X_MASK); + } + } + break; + + case ButtonPress: + b=-1; + if (event.xbutton.button == 1) + b = 0; + else if (event.xbutton.button == 2) + b = 2; + else if (event.xbutton.button == 3) + b = 1; + if (b>=0) + Key_Event(K_MOUSE1 + b, true); + break; + + case ButtonRelease: + b=-1; + if (event.xbutton.button == 1) + b = 0; + else if (event.xbutton.button == 2) + b = 2; + else if (event.xbutton.button == 3) + b = 1; + if (b>=0) + Key_Event(K_MOUSE1 + b, false); + break; + } + + if (old_windowed_mouse != _windowed_mouse.value) { + old_windowed_mouse = _windowed_mouse.value; + + if (!_windowed_mouse.value) { + /* ungrab the pointer */ + uninstall_grabs(); + } else { + /* grab the pointer */ + install_grabs(); + } + } +} + + +void VID_Shutdown(void) +{ + if (!ctx) + return; + + glXDestroyContext(dpy, ctx); +} + +void signal_handler(int sig) +{ + printf("Received signal %d, exiting...\n", sig); + Sys_Quit(); + exit(0); +} + +void InitSig(void) +{ + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + signal(SIGQUIT, signal_handler); + signal(SIGILL, signal_handler); + signal(SIGTRAP, signal_handler); + signal(SIGIOT, signal_handler); + signal(SIGBUS, signal_handler); + signal(SIGFPE, signal_handler); + signal(SIGSEGV, signal_handler); + signal(SIGTERM, signal_handler); +} + +void VID_ShiftPalette(unsigned char *p) +{ +// VID_SetPalette(p); +} + +void VID_SetPalette (unsigned char *palette) +{ + byte *pal; + unsigned r,g,b; + unsigned v; + int r1,g1,b1; + int k; + unsigned short i; + unsigned *table; + FILE *f; + char s[255]; + float dist, bestdist; + static qboolean palflag = false; + +// +// 8 8 8 encoding +// + Con_Printf("Converting 8to24\n"); + + pal = palette; + table = d_8to24table; + for (i=0 ; i<256 ; i++) + { + r = pal[0]; + g = pal[1]; + b = pal[2]; + pal += 3; + +// v = (255<<24) + (r<<16) + (g<<8) + (b<<0); +// v = (255<<0) + (r<<8) + (g<<16) + (b<<24); + v = (255<<24) + (r<<0) + (g<<8) + (b<<16); + *table++ = v; + } + d_8to24table[255] &= 0xffffff; // 255 is transparent + + // JACK: 3D distance calcs - k is last closest, l is the distance. + // FIXME: Precalculate this and cache to disk. + if (palflag) + return; + palflag = true; + + COM_FOpenFile("glquake/15to8.pal", &f); + if (f) { + fread(d_15to8table, 1<<15, 1, f); + fclose(f); + } else { + for (i=0; i < (1<<15); i++) { + /* Maps + 000000000000000 + 000000000011111 = Red = 0x1F + 000001111100000 = Blue = 0x03E0 + 111110000000000 = Grn = 0x7C00 + */ + r = ((i & 0x1F) << 3)+4; + g = ((i & 0x03E0) >> 2)+4; + b = ((i & 0x7C00) >> 7)+4; + pal = (unsigned char *)d_8to24table; + for (v=0,k=0,bestdist=10000.0; v<256; v++,pal+=4) { + r1 = (int)r - (int)pal[0]; + g1 = (int)g - (int)pal[1]; + b1 = (int)b - (int)pal[2]; + dist = sqrt(((r1*r1)+(g1*g1)+(b1*b1))); + if (dist < bestdist) { + k=v; + bestdist = dist; + } + } + d_15to8table[i]=k; + } + sprintf(s, "%s/glquake", com_gamedir); + Sys_mkdir (s); + sprintf(s, "%s/glquake/15to8.pal", com_gamedir); + if ((f = fopen(s, "wb")) != NULL) { + fwrite(d_15to8table, 1<<15, 1, f); + fclose(f); + } + } +} + +/* +=============== +GL_Init +=============== +*/ +void GL_Init (void) +{ + gl_vendor = glGetString (GL_VENDOR); + Con_Printf ("GL_VENDOR: %s\n", gl_vendor); + gl_renderer = glGetString (GL_RENDERER); + Con_Printf ("GL_RENDERER: %s\n", gl_renderer); + + gl_version = glGetString (GL_VERSION); + Con_Printf ("GL_VERSION: %s\n", gl_version); + gl_extensions = glGetString (GL_EXTENSIONS); + Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); + +// Con_Printf ("%s %s\n", gl_renderer, gl_version); + + glClearColor (1,0,0,0); + glCullFace(GL_FRONT); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.666); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glShadeModel (GL_FLAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +} + +/* +================= +GL_BeginRendering + +================= +*/ +void GL_BeginRendering (int *x, int *y, int *width, int *height) +{ + extern cvar_t gl_clear; + + *x = *y = 0; + *width = scr_width; + *height = scr_height; + +// if (!wglMakeCurrent( maindc, baseRC )) +// Sys_Error ("wglMakeCurrent failed"); + +// glViewport (*x, *y, *width, *height); +} + + +void GL_EndRendering (void) +{ + glFlush(); + glXSwapBuffers(dpy, win); +} + +qboolean VID_Is8bit(void) +{ + return is8bit; +} + +#ifdef GL_EXT_SHARED +void VID_Init8bitPalette() +{ + // Check for 8bit Extensions and initialize them. + int i; + char thePalette[256*3]; + char *oldPalette, *newPalette; + + if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") == NULL) + return; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldPalette = (char *) d_8to24table; //d_8to24table3dfx; + newPalette = thePalette; + for (i=0;i<256;i++) { + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + oldPalette++; + } + glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette); + is8bit = true; +} + +#else +extern void gl3DfxSetPaletteEXT(GLuint *pal); + +void VID_Init8bitPalette(void) +{ + // Check for 8bit Extensions and initialize them. + int i; + GLubyte table[256][4]; + char *oldpal; + + if (strstr(gl_extensions, "3DFX_set_global_palette") == NULL) + return; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldpal = (char *) d_8to24table; //d_8to24table3dfx; + for (i=0;i<256;i++) { + table[i][2] = *oldpal++; + table[i][1] = *oldpal++; + table[i][0] = *oldpal++; + table[i][3] = 255; + oldpal++; + } + gl3DfxSetPaletteEXT((GLuint *)table); + is8bit = true; +} +#endif + +void VID_Init(unsigned char *palette) +{ + int i; + int attrib[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + GLX_DEPTH_SIZE, 1, + None + }; + char gldir[MAX_OSPATH]; + int width = 640, height = 480; + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + XVisualInfo *visinfo; + + S_Init(); + + Cvar_RegisterVariable (&vid_mode); + Cvar_RegisterVariable (&gl_ztrick); + Cvar_RegisterVariable (&_windowed_mouse); + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + +// interpret command-line params + +// set vid parameters + if ((i = COM_CheckParm("-width")) != 0) + width = atoi(com_argv[i+1]); + if ((i = COM_CheckParm("-height")) != 0) + height = atoi(com_argv[i+1]); + + if ((i = COM_CheckParm("-conwidth")) != 0) + vid.conwidth = Q_atoi(com_argv[i+1]); + else + vid.conwidth = 640; + + vid.conwidth &= 0xfff8; // make it a multiple of eight + + if (vid.conwidth < 320) + vid.conwidth = 320; + + // pick a conheight that matches with correct aspect + vid.conheight = vid.conwidth*3 / 4; + + if ((i = COM_CheckParm("-conheight")) != 0) + vid.conheight = Q_atoi(com_argv[i+1]); + if (vid.conheight < 200) + vid.conheight = 200; + + if (!(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "Error couldn't open the X display\n"); + exit(1); + } + + scrnum = DefaultScreen(dpy); + root = RootWindow(dpy, scrnum); + + visinfo = glXChooseVisual(dpy, scrnum, attrib); + if (!visinfo) { + fprintf(stderr, "qkHack: Error couldn't get an RGB, Double-buffered, Depth visual\n"); + exit(1); + } + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); + attr.event_mask = X_MASK; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow(dpy, root, 0, 0, width, height, + 0, visinfo->depth, InputOutput, + visinfo->visual, mask, &attr); + XMapWindow(dpy, win); + + XMoveWindow(dpy, win, 0, 0); + + XFlush(dpy); + + ctx = glXCreateContext(dpy, visinfo, NULL, True); + + glXMakeCurrent(dpy, win, ctx); + + scr_width = width; + scr_height = height; + + if (vid.conheight > height) + vid.conheight = height; + if (vid.conwidth > width) + vid.conwidth = width; + vid.width = vid.conwidth; + vid.height = vid.conheight; + + vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); + vid.numpages = 2; + + InitSig(); // trap evil signals + + GL_Init(); + + sprintf (gldir, "%s/glquake", com_gamedir); + Sys_mkdir (gldir); + + VID_SetPalette(palette); + + // Check for 3DFX Extensions and initialize them. + VID_Init8bitPalette(); + + Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height); + + vid.recalc_refdef = 1; // force a surface cache flush +} + +void Sys_SendKeyEvents(void) +{ + if (dpy) { + while (XPending(dpy)) + GetEvent(); + } +} + +void Force_CenterView_f (void) +{ + cl.viewangles[PITCH] = 0; +} + +void IN_Init(void) +{ +} + +void IN_Shutdown(void) +{ +} + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ +} + +/* +=========== +IN_Move +=========== +*/ +void IN_MouseMove (usercmd_t *cmd) +{ + if (m_filter.value) + { + mouse_x = (mouse_x + old_mouse_x) * 0.5; + mouse_y = (mouse_y + old_mouse_y) * 0.5; + } + old_mouse_x = mouse_x; + old_mouse_y = mouse_y; + + mouse_x *= sensitivity.value; + mouse_y *= sensitivity.value; + +// add mouse X/Y movement to cmd + if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) + cmd->sidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + cl.viewangles[PITCH] += m_pitch.value * mouse_y; + if (cl.viewangles[PITCH] > 80) + cl.viewangles[PITCH] = 80; + if (cl.viewangles[PITCH] < -70) + cl.viewangles[PITCH] = -70; + } + else + { + if ((in_strafe.state & 1) && noclip_anglehack) + cmd->upmove -= m_forward.value * mouse_y; + else + cmd->forwardmove -= m_forward.value * mouse_y; + } + mouse_x = mouse_y = 0.0; +} + +void IN_Move (usercmd_t *cmd) +{ + IN_MouseMove(cmd); +} + + +void VID_UnlockBuffer() {} +void VID_LockBuffer() {} + diff --git a/QW/client/gl_vidnt.c b/QW/client/gl_vidnt.c new file mode 100644 index 0000000..932a68d --- /dev/null +++ b/QW/client/gl_vidnt.c @@ -0,0 +1,1949 @@ +/* +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. + +*/ +// gl_vidnt.c -- NT GL vid component + +#include "quakedef.h" +#include "winquake.h" +#include "resource.h" +#include <commctrl.h> + +#define MAX_MODE_LIST 30 +#define VID_ROW_SIZE 3 +#define WARP_WIDTH 320 +#define WARP_HEIGHT 200 +#define MAXWIDTH 10000 +#define MAXHEIGHT 10000 +#define BASEWIDTH 320 +#define BASEHEIGHT 200 + +#define MODE_WINDOWED 0 +#define NO_MODE (MODE_WINDOWED - 1) +#define MODE_FULLSCREEN_DEFAULT (MODE_WINDOWED + 1) + +typedef struct { + modestate_t type; + int width; + int height; + int modenum; + int dib; + int fullscreen; + int bpp; + int halfscreen; + char modedesc[17]; +} vmode_t; + +typedef struct { + int width; + int height; +} lmode_t; + +lmode_t lowresmodes[] = { + {320, 200}, + {320, 240}, + {400, 300}, + {512, 384}, +}; + +const char *gl_vendor; +const char *gl_renderer; +const char *gl_version; +const char *gl_extensions; + +qboolean DDActive; +qboolean scr_skipupdate; + +static vmode_t modelist[MAX_MODE_LIST]; +static int nummodes; +static vmode_t *pcurrentmode; +static vmode_t badmode; + +static DEVMODE gdevmode; +static qboolean vid_initialized = false; +static qboolean windowed, leavecurrentmode; +static qboolean vid_canalttab = false; +static qboolean vid_wassuspended = false; +static int windowed_mouse; +extern qboolean mouseactive; // from in_win.c +static HICON hIcon; + +int DIBWidth, DIBHeight; +RECT WindowRect; +DWORD WindowStyle, ExWindowStyle; + +HWND mainwindow, dibwindow; + +int vid_modenum = NO_MODE; +int vid_realmode; +int vid_default = MODE_WINDOWED; +static int windowed_default; +unsigned char vid_curpal[256*3]; +static qboolean fullsbardraw = false; + +static float vid_gamma = 1.0; + +HGLRC baseRC; +HDC maindc; + +glvert_t glv; + +cvar_t gl_ztrick = {"gl_ztrick","1"}; + +HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow); + +viddef_t vid; // global video state + +unsigned short d_8to16table[256]; +unsigned d_8to24table[256]; +unsigned char d_15to8table[65536]; + +float gldepthmin, gldepthmax; + +modestate_t modestate = MS_UNINIT; + +void VID_MenuDraw (void); +void VID_MenuKey (int key); + +LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void AppActivate(BOOL fActive, BOOL minimize); +char *VID_GetModeDescription (int mode); +void ClearAllStates (void); +void VID_UpdateWindowStatus (void); +void GL_Init (void); + +PROC glArrayElementEXT; +PROC glColorPointerEXT; +PROC glTexCoordPointerEXT; +PROC glVertexPointerEXT; + +typedef void (APIENTRY *lp3DFXFUNC) (int, int, int, int, int, const void*); +lp3DFXFUNC glColorTableEXT; +qboolean is8bit = false; +qboolean isPermedia = false; +qboolean gl_mtexable = false; + +//==================================== + +cvar_t vid_mode = {"vid_mode","0", false}; +// Note that 0 is MODE_WINDOWED +cvar_t _vid_default_mode = {"_vid_default_mode","0", true}; +// Note that 3 is MODE_FULLSCREEN_DEFAULT +cvar_t _vid_default_mode_win = {"_vid_default_mode_win","3", true}; +cvar_t vid_wait = {"vid_wait","0"}; +cvar_t vid_nopageflip = {"vid_nopageflip","0", true}; +cvar_t _vid_wait_override = {"_vid_wait_override", "0", true}; +cvar_t vid_config_x = {"vid_config_x","800", true}; +cvar_t vid_config_y = {"vid_config_y","600", true}; +cvar_t vid_stretch_by_2 = {"vid_stretch_by_2","1", true}; +cvar_t _windowed_mouse = {"_windowed_mouse","1", true}; + +int window_center_x, window_center_y, window_x, window_y, window_width, window_height; +RECT window_rect; + +// direct draw software compatability stuff + +void VID_HandlePause (qboolean pause) +{ +} + +void VID_ForceLockState (int lk) +{ +} + +void VID_LockBuffer (void) +{ +} + +void VID_UnlockBuffer (void) +{ +} + +int VID_ForceUnlockedAndReturnState (void) +{ + return 0; +} + +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +} + +void D_EndDirectRect (int x, int y, int width, int height) +{ +} + + +void CenterWindow(HWND hWndCenter, int width, int height, BOOL lefttopjustify) +{ + RECT rect; + int CenterX, CenterY; + + CenterX = (GetSystemMetrics(SM_CXSCREEN) - width) / 2; + CenterY = (GetSystemMetrics(SM_CYSCREEN) - height) / 2; + if (CenterX > CenterY*2) + CenterX >>= 1; // dual screens + CenterX = (CenterX < 0) ? 0: CenterX; + CenterY = (CenterY < 0) ? 0: CenterY; + SetWindowPos (hWndCenter, NULL, CenterX, CenterY, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); +} + +qboolean VID_SetWindowedMode (int modenum) +{ + HDC hdc; + int lastmodestate, width, height; + RECT rect; + + lastmodestate = modestate; + + WindowRect.top = WindowRect.left = 0; + + WindowRect.right = modelist[modenum].width; + WindowRect.bottom = modelist[modenum].height; + + DIBWidth = modelist[modenum].width; + DIBHeight = modelist[modenum].height; + + WindowStyle = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | + WS_MINIMIZEBOX; + ExWindowStyle = 0; + + rect = WindowRect; + AdjustWindowRectEx(&rect, WindowStyle, FALSE, 0); + + width = rect.right - rect.left; + height = rect.bottom - rect.top; + + // Create the DIB window + dibwindow = CreateWindowEx ( + ExWindowStyle, + "WinQuake", + "GLQuake", + WindowStyle, + rect.left, rect.top, + width, + height, + NULL, + NULL, + global_hInstance, + NULL); + + if (!dibwindow) + Sys_Error ("Couldn't create DIB window"); + + // Center and show the DIB window + CenterWindow(dibwindow, WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, false); + + ShowWindow (dibwindow, SW_SHOWDEFAULT); + UpdateWindow (dibwindow); + + modestate = MS_WINDOWED; + +// because we have set the background brush for the window to NULL +// (to avoid flickering when re-sizing the window on the desktop), +// we clear the window to black when created, otherwise it will be +// empty while Quake starts up. + hdc = GetDC(dibwindow); + PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS); + ReleaseDC(dibwindow, hdc); + + if (vid.conheight > modelist[modenum].height) + vid.conheight = modelist[modenum].height; + if (vid.conwidth > modelist[modenum].width) + vid.conwidth = modelist[modenum].width; + vid.width = vid.conwidth; + vid.height = vid.conheight; + + vid.numpages = 2; + + mainwindow = dibwindow; + + SendMessage (mainwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon); + SendMessage (mainwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon); + + return true; +} + + +qboolean VID_SetFullDIBMode (int modenum) +{ + HDC hdc; + int lastmodestate, width, height; + RECT rect; + + if (!leavecurrentmode) + { + gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + gdevmode.dmBitsPerPel = modelist[modenum].bpp; + gdevmode.dmPelsWidth = modelist[modenum].width << + modelist[modenum].halfscreen; + gdevmode.dmPelsHeight = modelist[modenum].height; + gdevmode.dmSize = sizeof (gdevmode); + + if (ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) + Sys_Error ("Couldn't set fullscreen DIB mode"); + } + + lastmodestate = modestate; + modestate = MS_FULLDIB; + + WindowRect.top = WindowRect.left = 0; + + WindowRect.right = modelist[modenum].width; + WindowRect.bottom = modelist[modenum].height; + + DIBWidth = modelist[modenum].width; + DIBHeight = modelist[modenum].height; + + WindowStyle = WS_POPUP; + ExWindowStyle = 0; + + rect = WindowRect; + AdjustWindowRectEx(&rect, WindowStyle, FALSE, 0); + + width = rect.right - rect.left; + height = rect.bottom - rect.top; + + // Create the DIB window + dibwindow = CreateWindowEx ( + ExWindowStyle, + "WinQuake", + "GLQuake", + WindowStyle, + rect.left, rect.top, + width, + height, + NULL, + NULL, + global_hInstance, + NULL); + + if (!dibwindow) + Sys_Error ("Couldn't create DIB window"); + + ShowWindow (dibwindow, SW_SHOWDEFAULT); + UpdateWindow (dibwindow); + + // Because we have set the background brush for the window to NULL + // (to avoid flickering when re-sizing the window on the desktop), we + // clear the window to black when created, otherwise it will be + // empty while Quake starts up. + hdc = GetDC(dibwindow); + PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS); + ReleaseDC(dibwindow, hdc); + + if (vid.conheight > modelist[modenum].height) + vid.conheight = modelist[modenum].height; + if (vid.conwidth > modelist[modenum].width) + vid.conwidth = modelist[modenum].width; + vid.width = vid.conwidth; + vid.height = vid.conheight; + + vid.numpages = 2; + +// needed because we're not getting WM_MOVE messages fullscreen on NT + window_x = 0; + window_y = 0; + + mainwindow = dibwindow; + + SendMessage (mainwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon); + SendMessage (mainwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon); + + return true; +} + + +int VID_SetMode (int modenum, unsigned char *palette) +{ + int original_mode, temp; + qboolean stat; + MSG msg; + HDC hdc; + + if ((windowed && (modenum != 0)) || + (!windowed && (modenum < 1)) || + (!windowed && (modenum >= nummodes))) + { + Sys_Error ("Bad video mode\n"); + } + +// so Con_Printfs don't mess us up by forcing vid and snd updates + temp = scr_disabled_for_loading; + scr_disabled_for_loading = true; + + CDAudio_Pause (); + + if (vid_modenum == NO_MODE) + original_mode = windowed_default; + else + original_mode = vid_modenum; + + // Set either the fullscreen or windowed mode + if (modelist[modenum].type == MS_WINDOWED) + { + if (_windowed_mouse.value && key_dest == key_game) + { + stat = VID_SetWindowedMode(modenum); + IN_ActivateMouse (); + IN_HideMouse (); + } + else + { + IN_DeactivateMouse (); + IN_ShowMouse (); + stat = VID_SetWindowedMode(modenum); + } + } + else if (modelist[modenum].type == MS_FULLDIB) + { + stat = VID_SetFullDIBMode(modenum); + IN_ActivateMouse (); + IN_HideMouse (); + } + else + { + Sys_Error ("VID_SetMode: Bad mode type in modelist"); + } + + window_width = DIBWidth; + window_height = DIBHeight; + VID_UpdateWindowStatus (); + + CDAudio_Resume (); + scr_disabled_for_loading = temp; + + if (!stat) + { + Sys_Error ("Couldn't set video mode"); + } + +// now we try to make sure we get the focus on the mode switch, because +// sometimes in some systems we don't. We grab the foreground, then +// finish setting up, pump all our messages, and sleep for a little while +// to let messages finish bouncing around the system, then we put +// ourselves at the top of the z order, then grab the foreground again, +// Who knows if it helps, but it probably doesn't hurt + SetForegroundWindow (mainwindow); + VID_SetPalette (palette); + vid_modenum = modenum; + Cvar_SetValue ("vid_mode", (float)vid_modenum); + + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + + Sleep (100); + + SetWindowPos (mainwindow, HWND_TOP, 0, 0, 0, 0, + SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | + SWP_NOCOPYBITS); + + SetForegroundWindow (mainwindow); + +// fix the leftover Alt from any Alt-Tab or the like that switched us away + ClearAllStates (); + + if (!msg_suppress_1) + Con_SafePrintf ("Video mode %s initialized.\n", VID_GetModeDescription (vid_modenum)); + + VID_SetPalette (palette); + + vid.recalc_refdef = 1; + + return true; +} + + +/* +================ +VID_UpdateWindowStatus +================ +*/ +void VID_UpdateWindowStatus (void) +{ + + window_rect.left = window_x; + window_rect.top = window_y; + window_rect.right = window_x + window_width; + window_rect.bottom = window_y + window_height; + window_center_x = (window_rect.left + window_rect.right) / 2; + window_center_y = (window_rect.top + window_rect.bottom) / 2; + + IN_UpdateClipCursor (); +} + + +//==================================== + +BINDTEXFUNCPTR bindTexFunc; + +#define TEXTURE_EXT_STRING "GL_EXT_texture_object" + + +void CheckTextureExtensions (void) +{ + char *tmp; + qboolean texture_ext; + HINSTANCE hInstGL; + + texture_ext = FALSE; + /* check for texture extension */ + tmp = (unsigned char *)glGetString(GL_EXTENSIONS); + while (*tmp) + { + if (strncmp((const char*)tmp, TEXTURE_EXT_STRING, strlen(TEXTURE_EXT_STRING)) == 0) + texture_ext = TRUE; + tmp++; + } + + if (!texture_ext || COM_CheckParm ("-gl11") ) + { + hInstGL = LoadLibrary("opengl32.dll"); + + if (hInstGL == NULL) + Sys_Error ("Couldn't load opengl32.dll\n"); + + bindTexFunc = (void *)GetProcAddress(hInstGL,"glBindTexture"); + + if (!bindTexFunc) + Sys_Error ("No texture objects!"); + return; + } + +/* load library and get procedure adresses for texture extension API */ + if ((bindTexFunc = (BINDTEXFUNCPTR) + wglGetProcAddress((LPCSTR) "glBindTextureEXT")) == NULL) + { + Sys_Error ("GetProcAddress for BindTextureEXT failed"); + return; + } +} + +void CheckArrayExtensions (void) +{ + char *tmp; + + /* check for texture extension */ + tmp = (unsigned char *)glGetString(GL_EXTENSIONS); + while (*tmp) + { + if (strncmp((const char*)tmp, "GL_EXT_vertex_array", strlen("GL_EXT_vertex_array")) == 0) + { + if ( +((glArrayElementEXT = wglGetProcAddress("glArrayElementEXT")) == NULL) || +((glColorPointerEXT = wglGetProcAddress("glColorPointerEXT")) == NULL) || +((glTexCoordPointerEXT = wglGetProcAddress("glTexCoordPointerEXT")) == NULL) || +((glVertexPointerEXT = wglGetProcAddress("glVertexPointerEXT")) == NULL) ) + { + Sys_Error ("GetProcAddress for vertex extension failed"); + return; + } + return; + } + tmp++; + } + + Sys_Error ("Vertex array extension not present"); +} + +//int texture_mode = GL_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_LINEAR; +int texture_mode = GL_LINEAR; +//int texture_mode = GL_LINEAR_MIPMAP_NEAREST; +//int texture_mode = GL_LINEAR_MIPMAP_LINEAR; + +int texture_extension_number = 1; + +#ifdef _WIN32 +void CheckMultiTextureExtensions(void) +{ + if (strstr(gl_extensions, "GL_SGIS_multitexture ") && !COM_CheckParm("-nomtex")) { + Con_Printf("Multitexture extensions found.\n"); + qglMTexCoord2fSGIS = (void *) wglGetProcAddress("glMTexCoord2fSGIS"); + qglSelectTextureSGIS = (void *) wglGetProcAddress("glSelectTextureSGIS"); + gl_mtexable = true; + } +} +#else +void CheckMultiTextureExtensions(void) +{ + gl_mtexable = true; +} +#endif + +/* +=============== +GL_Init +=============== +*/ +void GL_Init (void) +{ + gl_vendor = glGetString (GL_VENDOR); + Con_Printf ("GL_VENDOR: %s\n", gl_vendor); + gl_renderer = glGetString (GL_RENDERER); + Con_Printf ("GL_RENDERER: %s\n", gl_renderer); + + gl_version = glGetString (GL_VERSION); + Con_Printf ("GL_VERSION: %s\n", gl_version); + gl_extensions = glGetString (GL_EXTENSIONS); + Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); + +// Con_Printf ("%s %s\n", gl_renderer, gl_version); + + if (strnicmp(gl_renderer,"PowerVR",7)==0) + fullsbardraw = true; + + if (strnicmp(gl_renderer,"Permedia",8)==0) + isPermedia = true; + + CheckTextureExtensions (); + CheckMultiTextureExtensions (); + + glClearColor (1,0,0,0); + glCullFace(GL_FRONT); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.666); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glShadeModel (GL_FLAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + +#if 0 + CheckArrayExtensions (); + + glEnable (GL_VERTEX_ARRAY_EXT); + glEnable (GL_TEXTURE_COORD_ARRAY_EXT); + glVertexPointerEXT (3, GL_FLOAT, 0, 0, &glv.x); + glTexCoordPointerEXT (2, GL_FLOAT, 0, 0, &glv.s); + glColorPointerEXT (3, GL_FLOAT, 0, 0, &glv.r); +#endif +} + +/* +================= +GL_BeginRendering + +================= +*/ +void GL_BeginRendering (int *x, int *y, int *width, int *height) +{ + extern cvar_t gl_clear; + + *x = *y = 0; + *width = WindowRect.right - WindowRect.left; + *height = WindowRect.bottom - WindowRect.top; + +// if (!wglMakeCurrent( maindc, baseRC )) +// Sys_Error ("wglMakeCurrent failed"); + +// glViewport (*x, *y, *width, *height); +} + + +void GL_EndRendering (void) +{ + if (!scr_skipupdate || block_drawing) + SwapBuffers(maindc); + +// handle the mouse state when windowed if that's changed + if (modestate == MS_WINDOWED) + { + if (!_windowed_mouse.value) { + if (windowed_mouse) { + IN_DeactivateMouse (); + IN_ShowMouse (); + windowed_mouse = false; + } + } else { + windowed_mouse = true; + if (key_dest == key_game && !mouseactive && ActiveApp) { + IN_ActivateMouse (); + IN_HideMouse (); + } else if (mouseactive && key_dest != key_game) { + IN_DeactivateMouse (); + IN_ShowMouse (); + } + } + } + if (fullsbardraw) + Sbar_Changed(); +} + +void VID_SetPalette (unsigned char *palette) +{ + byte *pal; + unsigned r,g,b; + unsigned v; + int r1,g1,b1; + int j,k,l,m; + unsigned short i; + unsigned *table; + FILE *f; + char s[255]; + HWND hDlg, hProgress; + float gamma; + +// +// 8 8 8 encoding +// + pal = palette; + table = d_8to24table; + for (i=0 ; i<256 ; i++) + { + r = pal[0]; + g = pal[1]; + b = pal[2]; + pal += 3; + +// v = (255<<24) + (r<<16) + (g<<8) + (b<<0); +// v = (255<<0) + (r<<8) + (g<<16) + (b<<24); + v = (255<<24) + (r<<0) + (g<<8) + (b<<16); + *table++ = v; + } + d_8to24table[255] &= 0xffffff; // 255 is transparent + + // JACK: 3D distance calcs - k is last closest, l is the distance. + // FIXME: Precalculate this and cache to disk. + for (i=0; i < (1<<15); i++) { + /* Maps + 000000000000000 + 000000000011111 = Red = 0x1F + 000001111100000 = Blue = 0x03E0 + 111110000000000 = Grn = 0x7C00 + */ + r = ((i & 0x1F) << 3)+4; + g = ((i & 0x03E0) >> 2)+4; + b = ((i & 0x7C00) >> 7)+4; + pal = (unsigned char *)d_8to24table; + for (v=0,k=0,l=10000*10000; v<256; v++,pal+=4) { + r1 = r-pal[0]; + g1 = g-pal[1]; + b1 = b-pal[2]; + j = (r1*r1)+(g1*g1)+(b1*b1); + if (j<l) { + k=v; + l=j; + } + } + d_15to8table[i]=k; + } +} + +BOOL gammaworks; + +void VID_ShiftPalette (unsigned char *palette) +{ + extern byte ramps[3][256]; + +// VID_SetPalette (palette); + +// gammaworks = SetDeviceGammaRamp (maindc, ramps); +} + + +void VID_SetDefaultMode (void) +{ + IN_DeactivateMouse (); +} + + +void VID_Shutdown (void) +{ + HGLRC hRC; + HDC hDC; + + if (vid_initialized) + { + vid_canalttab = false; + hRC = wglGetCurrentContext(); + hDC = wglGetCurrentDC(); + + wglMakeCurrent(NULL, NULL); + + if (hRC) + wglDeleteContext(hRC); + + if (hDC && dibwindow) + ReleaseDC(dibwindow, hDC); + + if (modestate == MS_FULLDIB) + ChangeDisplaySettings (NULL, 0); + + if (maindc && dibwindow) + ReleaseDC (dibwindow, maindc); + + AppActivate(false, false); + } +} + + +//========================================================================== + + +BOOL bSetupPixelFormat(HDC hDC) +{ + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW // support window + | PFD_SUPPORT_OPENGL // support OpenGL + | PFD_DOUBLEBUFFER , // double buffered + PFD_TYPE_RGBA, // RGBA type + 24, // 24-bit color depth + 0, 0, 0, 0, 0, 0, // color bits ignored + 0, // no alpha buffer + 0, // shift bit ignored + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + 32, // 32-bit z-buffer + 0, // no stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; + int pixelformat; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ) + { + MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE) + { + MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + + + +byte scantokey[128] = + { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0 , 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '/', K_SHIFT,'*', + K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE , 0 , K_HOME, + K_UPARROW,K_PGUP,'-',K_LEFTARROW,'5',K_RIGHTARROW,'+',K_END, //4 + K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11, + K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5 + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6 + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7 + }; + +byte shiftscantokey[128] = + { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0 , 27, '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', K_BACKSPACE, 9, // 0 + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', + 'O', 'P', '{', '}', 13 , K_CTRL,'A', 'S', // 1 + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', + '"' , '~', K_SHIFT,'|', 'Z', 'X', 'C', 'V', // 2 + 'B', 'N', 'M', '<', '>', '?', K_SHIFT,'*', + K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE , 0 , K_HOME, + K_UPARROW,K_PGUP,'_',K_LEFTARROW,'%',K_RIGHTARROW,'+',K_END, //4 + K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11, + K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5 + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6 + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7 + }; + + +/* +======= +MapKey + +Map from windows to quake keynums +======= +*/ +int MapKey (int key) +{ + key = (key>>16)&255; + if (key > 127) + return 0; + if (scantokey[key] == 0) + Con_DPrintf("key 0x%02x has no translation\n", key); + return scantokey[key]; +} + +/* +=================================================================== + +MAIN WINDOW + +=================================================================== +*/ + +/* +================ +ClearAllStates +================ +*/ +void ClearAllStates (void) +{ + int i; + +// send an up event for each key, to make sure the server clears them all + for (i=0 ; i<256 ; i++) + { + Key_Event (i, false); + } + + Key_ClearStates (); + IN_ClearStates (); +} + +void AppActivate(BOOL fActive, BOOL minimize) +/**************************************************************************** +* +* Function: AppActivate +* Parameters: fActive - True if app is activating +* +* Description: If the application is activating, then swap the system +* into SYSPAL_NOSTATIC mode so that our palettes will display +* correctly. +* +****************************************************************************/ +{ + MSG msg; + HDC hdc; + int i, t; + static BOOL sound_active; + + ActiveApp = fActive; + Minimized = minimize; + +// enable/disable sound on focus gain/loss + if (!ActiveApp && sound_active) + { + S_BlockSound (); + sound_active = false; + } + else if (ActiveApp && !sound_active) + { + S_UnblockSound (); + sound_active = true; + } + + if (fActive) + { + if (modestate == MS_FULLDIB) + { + IN_ActivateMouse (); + IN_HideMouse (); + if (vid_canalttab && vid_wassuspended) { + vid_wassuspended = false; + ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN); + ShowWindow(mainwindow, SW_SHOWNORMAL); + } + } + else if ((modestate == MS_WINDOWED) && _windowed_mouse.value && key_dest == key_game) + { + IN_ActivateMouse (); + IN_HideMouse (); + } + } + + if (!fActive) + { + if (modestate == MS_FULLDIB) + { + IN_DeactivateMouse (); + IN_ShowMouse (); + if (vid_canalttab) { + ChangeDisplaySettings (NULL, 0); + vid_wassuspended = true; + } + } + else if ((modestate == MS_WINDOWED) && _windowed_mouse.value) + { + IN_DeactivateMouse (); + IN_ShowMouse (); + } + } +} + + +/* main window procedure */ +LONG WINAPI MainWndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + LONG lRet = 1; + int fwKeys, xPos, yPos, fActive, fMinimized, temp; + extern unsigned int uiWheelMessage; + + if ( uMsg == uiWheelMessage ) + uMsg = WM_MOUSEWHEEL; + + switch (uMsg) + { + case WM_KILLFOCUS: + if (modestate == MS_FULLDIB) + ShowWindow(mainwindow, SW_SHOWMINNOACTIVE); + break; + + case WM_CREATE: + break; + + case WM_MOVE: + window_x = (int) LOWORD(lParam); + window_y = (int) HIWORD(lParam); + VID_UpdateWindowStatus (); + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + Key_Event (MapKey(lParam), true); + break; + + case WM_KEYUP: + case WM_SYSKEYUP: + Key_Event (MapKey(lParam), false); + break; + + case WM_SYSCHAR: + // keep Alt-Space from happening + break; + + // this is complicated because Win32 seems to pack multiple mouse events into + // one update sometimes, so we always check all states and look for events + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_MOUSEMOVE: + temp = 0; + + if (wParam & MK_LBUTTON) + temp |= 1; + + if (wParam & MK_RBUTTON) + temp |= 2; + + if (wParam & MK_MBUTTON) + temp |= 4; + + IN_MouseEvent (temp); + + break; + + // JACK: This is the mouse wheel with the Intellimouse + // Its delta is either positive or neg, and we generate the proper + // Event. + case WM_MOUSEWHEEL: + if ((short) HIWORD(wParam) > 0) { + Key_Event(K_MWHEELUP, true); + Key_Event(K_MWHEELUP, false); + } else { + Key_Event(K_MWHEELDOWN, true); + Key_Event(K_MWHEELDOWN, false); + } + break; + + case WM_SIZE: + break; + + case WM_CLOSE: + if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit", + MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) + { + Sys_Quit (); + } + + break; + + case WM_ACTIVATE: + fActive = LOWORD(wParam); + fMinimized = (BOOL) HIWORD(wParam); + AppActivate(!(fActive == WA_INACTIVE), fMinimized); + + // fix the leftover Alt from any Alt-Tab or the like that switched us away + ClearAllStates (); + + break; + + case WM_DESTROY: + { + if (dibwindow) + DestroyWindow (dibwindow); + + PostQuitMessage (0); + } + break; + + case MM_MCINOTIFY: + lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); + break; + + default: + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } + + /* return 1 if handled message, 0 if not */ + return lRet; +} + + +/* +================= +VID_NumModes +================= +*/ +int VID_NumModes (void) +{ + return nummodes; +} + + +/* +================= +VID_GetModePtr +================= +*/ +vmode_t *VID_GetModePtr (int modenum) +{ + + if ((modenum >= 0) && (modenum < nummodes)) + return &modelist[modenum]; + else + return &badmode; +} + + +/* +================= +VID_GetModeDescription +================= +*/ +char *VID_GetModeDescription (int mode) +{ + char *pinfo; + vmode_t *pv; + static char temp[100]; + + if ((mode < 0) || (mode >= nummodes)) + return NULL; + + if (!leavecurrentmode) + { + pv = VID_GetModePtr (mode); + pinfo = pv->modedesc; + } + else + { + sprintf (temp, "Desktop resolution (%dx%d)", + modelist[MODE_FULLSCREEN_DEFAULT].width, + modelist[MODE_FULLSCREEN_DEFAULT].height); + pinfo = temp; + } + + return pinfo; +} + + +// KJB: Added this to return the mode driver name in description for console + +char *VID_GetExtModeDescription (int mode) +{ + static char pinfo[40]; + vmode_t *pv; + + if ((mode < 0) || (mode >= nummodes)) + return NULL; + + pv = VID_GetModePtr (mode); + if (modelist[mode].type == MS_FULLDIB) + { + if (!leavecurrentmode) + { + sprintf(pinfo,"%s fullscreen", pv->modedesc); + } + else + { + sprintf (pinfo, "Desktop resolution (%dx%d)", + modelist[MODE_FULLSCREEN_DEFAULT].width, + modelist[MODE_FULLSCREEN_DEFAULT].height); + } + } + else + { + if (modestate == MS_WINDOWED) + sprintf(pinfo, "%s windowed", pv->modedesc); + else + sprintf(pinfo, "windowed"); + } + + return pinfo; +} + + +/* +================= +VID_DescribeCurrentMode_f +================= +*/ +void VID_DescribeCurrentMode_f (void) +{ + Con_Printf ("%s\n", VID_GetExtModeDescription (vid_modenum)); +} + + +/* +================= +VID_NumModes_f +================= +*/ +void VID_NumModes_f (void) +{ + + if (nummodes == 1) + Con_Printf ("%d video mode is available\n", nummodes); + else + Con_Printf ("%d video modes are available\n", nummodes); +} + + +/* +================= +VID_DescribeMode_f +================= +*/ +void VID_DescribeMode_f (void) +{ + int t, modenum; + + modenum = Q_atoi (Cmd_Argv(1)); + + t = leavecurrentmode; + leavecurrentmode = 0; + + Con_Printf ("%s\n", VID_GetExtModeDescription (modenum)); + + leavecurrentmode = t; +} + + +/* +================= +VID_DescribeModes_f +================= +*/ +void VID_DescribeModes_f (void) +{ + int i, lnummodes, t; + char *pinfo; + vmode_t *pv; + + lnummodes = VID_NumModes (); + + t = leavecurrentmode; + leavecurrentmode = 0; + + for (i=1 ; i<lnummodes ; i++) + { + pv = VID_GetModePtr (i); + pinfo = VID_GetExtModeDescription (i); + Con_Printf ("%2d: %s\n", i, pinfo); + } + + leavecurrentmode = t; +} + + +void VID_InitDIB (HINSTANCE hInstance) +{ + WNDCLASS wc; + HDC hdc; + int i; + + /* Register the frame class */ + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = 0; + wc.lpszClassName = "WinQuake"; + + if (!RegisterClass (&wc) ) + Sys_Error ("Couldn't register window class"); + + modelist[0].type = MS_WINDOWED; + + if (COM_CheckParm("-width")) + modelist[0].width = Q_atoi(com_argv[COM_CheckParm("-width")+1]); + else + modelist[0].width = 640; + + if (modelist[0].width < 320) + modelist[0].width = 320; + + if (COM_CheckParm("-height")) + modelist[0].height= Q_atoi(com_argv[COM_CheckParm("-height")+1]); + else + modelist[0].height = modelist[0].width * 240/320; + + if (modelist[0].height < 240) + modelist[0].height = 240; + + sprintf (modelist[0].modedesc, "%dx%d", + modelist[0].width, modelist[0].height); + + modelist[0].modenum = MODE_WINDOWED; + modelist[0].dib = 1; + modelist[0].fullscreen = 0; + modelist[0].halfscreen = 0; + modelist[0].bpp = 0; + + nummodes = 1; +} + + +/* +================= +VID_InitFullDIB +================= +*/ +void VID_InitFullDIB (HINSTANCE hInstance) +{ + DEVMODE devmode; + int i, modenum, cmodes, originalnummodes, existingmode, numlowresmodes; + int j, bpp, done; + BOOL stat; + +// enumerate >8 bpp modes + originalnummodes = nummodes; + modenum = 0; + + do + { + stat = EnumDisplaySettings (NULL, modenum, &devmode); + + if ((devmode.dmBitsPerPel >= 15) && + (devmode.dmPelsWidth <= MAXWIDTH) && + (devmode.dmPelsHeight <= MAXHEIGHT) && + (nummodes < MAX_MODE_LIST)) + { + devmode.dmFields = DM_BITSPERPEL | + DM_PELSWIDTH | + DM_PELSHEIGHT; + + if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) == + DISP_CHANGE_SUCCESSFUL) + { + modelist[nummodes].type = MS_FULLDIB; + modelist[nummodes].width = devmode.dmPelsWidth; + modelist[nummodes].height = devmode.dmPelsHeight; + modelist[nummodes].modenum = 0; + modelist[nummodes].halfscreen = 0; + modelist[nummodes].dib = 1; + modelist[nummodes].fullscreen = 1; + modelist[nummodes].bpp = devmode.dmBitsPerPel; + sprintf (modelist[nummodes].modedesc, "%dx%dx%d", + devmode.dmPelsWidth, devmode.dmPelsHeight, + devmode.dmBitsPerPel); + + // if the width is more than twice the height, reduce it by half because this + // is probably a dual-screen monitor + if (!COM_CheckParm("-noadjustaspect")) + { + if (modelist[nummodes].width > (modelist[nummodes].height << 1)) + { + modelist[nummodes].width >>= 1; + modelist[nummodes].halfscreen = 1; + sprintf (modelist[nummodes].modedesc, "%dx%dx%d", + modelist[nummodes].width, + modelist[nummodes].height, + modelist[nummodes].bpp); + } + } + + for (i=originalnummodes, existingmode = 0 ; i<nummodes ; i++) + { + if ((modelist[nummodes].width == modelist[i].width) && + (modelist[nummodes].height == modelist[i].height) && + (modelist[nummodes].bpp == modelist[i].bpp)) + { + existingmode = 1; + break; + } + } + + if (!existingmode) + { + nummodes++; + } + } + } + + modenum++; + } while (stat); + +// see if there are any low-res modes that aren't being reported + numlowresmodes = sizeof(lowresmodes) / sizeof(lowresmodes[0]); + bpp = 16; + done = 0; + + do + { + for (j=0 ; (j<numlowresmodes) && (nummodes < MAX_MODE_LIST) ; j++) + { + devmode.dmBitsPerPel = bpp; + devmode.dmPelsWidth = lowresmodes[j].width; + devmode.dmPelsHeight = lowresmodes[j].height; + devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + + if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) == + DISP_CHANGE_SUCCESSFUL) + { + modelist[nummodes].type = MS_FULLDIB; + modelist[nummodes].width = devmode.dmPelsWidth; + modelist[nummodes].height = devmode.dmPelsHeight; + modelist[nummodes].modenum = 0; + modelist[nummodes].halfscreen = 0; + modelist[nummodes].dib = 1; + modelist[nummodes].fullscreen = 1; + modelist[nummodes].bpp = devmode.dmBitsPerPel; + sprintf (modelist[nummodes].modedesc, "%dx%dx%d", + devmode.dmPelsWidth, devmode.dmPelsHeight, + devmode.dmBitsPerPel); + + for (i=originalnummodes, existingmode = 0 ; i<nummodes ; i++) + { + if ((modelist[nummodes].width == modelist[i].width) && + (modelist[nummodes].height == modelist[i].height) && + (modelist[nummodes].bpp == modelist[i].bpp)) + { + existingmode = 1; + break; + } + } + + if (!existingmode) + { + nummodes++; + } + } + } + switch (bpp) + { + case 16: + bpp = 32; + break; + + case 32: + bpp = 24; + break; + + case 24: + done = 1; + break; + } + } while (!done); + + if (nummodes == originalnummodes) + Con_SafePrintf ("No fullscreen DIB modes found\n"); +} + +qboolean VID_Is8bit() { + return is8bit; +} + +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB + +void VID_Init8bitPalette() +{ + // Check for 8bit Extensions and initialize them. + int i; + char thePalette[256*3]; + char *oldPalette, *newPalette; + + glColorTableEXT = (void *)wglGetProcAddress("glColorTableEXT"); + if (!glColorTableEXT || strstr(gl_extensions, "GL_EXT_shared_texture_palette") || + COM_CheckParm("-no8bit")) + return; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldPalette = (char *) d_8to24table; //d_8to24table3dfx; + newPalette = thePalette; + for (i=0;i<256;i++) { + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + oldPalette++; + } + glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, + (void *) thePalette); + is8bit = TRUE; +} + +static void Check_Gamma (unsigned char *pal) +{ + float f, inf; + unsigned char palette[768]; + int i; + + if ((i = COM_CheckParm("-gamma")) == 0) { + if ((gl_renderer && strstr(gl_renderer, "Voodoo")) || + (gl_vendor && strstr(gl_vendor, "3Dfx"))) + vid_gamma = 1; + else + vid_gamma = 0.7; // default to 0.7 on non-3dfx hardware + } else + vid_gamma = Q_atof(com_argv[i+1]); + + for (i=0 ; i<768 ; i++) + { + f = pow ( (pal[i]+1)/256.0 , vid_gamma ); + inf = f*255 + 0.5; + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + palette[i] = inf; + } + + memcpy (pal, palette, sizeof(palette)); +} + +/* +=================== +VID_Init +=================== +*/ +void VID_Init (unsigned char *palette) +{ + int i, existingmode; + int basenummodes, width, height, bpp, findbpp, done; + byte *ptmp; + char gldir[MAX_OSPATH]; + HDC hdc; + DEVMODE devmode; + + memset(&devmode, 0, sizeof(devmode)); + + Cvar_RegisterVariable (&vid_mode); + Cvar_RegisterVariable (&vid_wait); + Cvar_RegisterVariable (&vid_nopageflip); + Cvar_RegisterVariable (&_vid_wait_override); + Cvar_RegisterVariable (&_vid_default_mode); + Cvar_RegisterVariable (&_vid_default_mode_win); + Cvar_RegisterVariable (&vid_config_x); + Cvar_RegisterVariable (&vid_config_y); + Cvar_RegisterVariable (&vid_stretch_by_2); + Cvar_RegisterVariable (&_windowed_mouse); + Cvar_RegisterVariable (&gl_ztrick); + + Cmd_AddCommand ("vid_nummodes", VID_NumModes_f); + Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f); + Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f); + Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f); + + hIcon = LoadIcon (global_hInstance, MAKEINTRESOURCE (IDI_ICON2)); + + InitCommonControls(); + + VID_InitDIB (global_hInstance); + basenummodes = nummodes = 1; + + VID_InitFullDIB (global_hInstance); + + if (COM_CheckParm("-window")) + { + hdc = GetDC (NULL); + + if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) + { + Sys_Error ("Can't run in non-RGB mode"); + } + + ReleaseDC (NULL, hdc); + + windowed = true; + + vid_default = MODE_WINDOWED; + } + else + { + if (nummodes == 1) + Sys_Error ("No RGB fullscreen modes available"); + + windowed = false; + + if (COM_CheckParm("-mode")) + { + vid_default = Q_atoi(com_argv[COM_CheckParm("-mode")+1]); + } + else + { + if (COM_CheckParm("-current")) + { + modelist[MODE_FULLSCREEN_DEFAULT].width = + GetSystemMetrics (SM_CXSCREEN); + modelist[MODE_FULLSCREEN_DEFAULT].height = + GetSystemMetrics (SM_CYSCREEN); + vid_default = MODE_FULLSCREEN_DEFAULT; + leavecurrentmode = 1; + } + else + { + if (COM_CheckParm("-width")) + { + width = Q_atoi(com_argv[COM_CheckParm("-width")+1]); + } + else + { + width = 640; + } + + if (COM_CheckParm("-bpp")) + { + bpp = Q_atoi(com_argv[COM_CheckParm("-bpp")+1]); + findbpp = 0; + } + else + { + bpp = 15; + findbpp = 1; + } + + if (COM_CheckParm("-height")) + height = Q_atoi(com_argv[COM_CheckParm("-height")+1]); + + // if they want to force it, add the specified mode to the list + if (COM_CheckParm("-force") && (nummodes < MAX_MODE_LIST)) + { + modelist[nummodes].type = MS_FULLDIB; + modelist[nummodes].width = width; + modelist[nummodes].height = height; + modelist[nummodes].modenum = 0; + modelist[nummodes].halfscreen = 0; + modelist[nummodes].dib = 1; + modelist[nummodes].fullscreen = 1; + modelist[nummodes].bpp = bpp; + sprintf (modelist[nummodes].modedesc, "%dx%dx%d", + devmode.dmPelsWidth, devmode.dmPelsHeight, + devmode.dmBitsPerPel); + + for (i=nummodes, existingmode = 0 ; i<nummodes ; i++) + { + if ((modelist[nummodes].width == modelist[i].width) && + (modelist[nummodes].height == modelist[i].height) && + (modelist[nummodes].bpp == modelist[i].bpp)) + { + existingmode = 1; + break; + } + } + + if (!existingmode) + { + nummodes++; + } + } + + done = 0; + + do + { + if (COM_CheckParm("-height")) + { + height = Q_atoi(com_argv[COM_CheckParm("-height")+1]); + + for (i=1, vid_default=0 ; i<nummodes ; i++) + { + if ((modelist[i].width == width) && + (modelist[i].height == height) && + (modelist[i].bpp == bpp)) + { + vid_default = i; + done = 1; + break; + } + } + } + else + { + for (i=1, vid_default=0 ; i<nummodes ; i++) + { + if ((modelist[i].width == width) && (modelist[i].bpp == bpp)) + { + vid_default = i; + done = 1; + break; + } + } + } + + if (!done) + { + if (findbpp) + { + switch (bpp) + { + case 15: + bpp = 16; + break; + case 16: + bpp = 32; + break; + case 32: + bpp = 24; + break; + case 24: + done = 1; + break; + } + } + else + { + done = 1; + } + } + } while (!done); + + if (!vid_default) + { + Sys_Error ("Specified video mode not available"); + } + } + } + } + + vid_initialized = true; + + if ((i = COM_CheckParm("-conwidth")) != 0) + vid.conwidth = Q_atoi(com_argv[i+1]); + else + vid.conwidth = 640; + + vid.conwidth &= 0xfff8; // make it a multiple of eight + + if (vid.conwidth < 320) + vid.conwidth = 320; + + // pick a conheight that matches with correct aspect + vid.conheight = vid.conwidth*3 / 4; + + if ((i = COM_CheckParm("-conheight")) != 0) + vid.conheight = Q_atoi(com_argv[i+1]); + if (vid.conheight < 200) + vid.conheight = 200; + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + + DestroyWindow (hwnd_dialog); + + Check_Gamma(palette); + VID_SetPalette (palette); + + VID_SetMode (vid_default, palette); + + maindc = GetDC(mainwindow); + bSetupPixelFormat(maindc); + + baseRC = wglCreateContext( maindc ); + if (!baseRC) + Sys_Error ("Could not initialize GL (wglCreateContext failed).\n\nMake sure you in are 65535 color mode, and try running -window."); + if (!wglMakeCurrent( maindc, baseRC )) + Sys_Error ("wglMakeCurrent failed"); + + GL_Init (); + + sprintf (gldir, "%s/glquake", com_gamedir); + Sys_mkdir (gldir); + + vid_realmode = vid_modenum; + + // Check for 3DFX Extensions and initialize them. + VID_Init8bitPalette(); + + vid_menudrawfn = VID_MenuDraw; + vid_menukeyfn = VID_MenuKey; + + strcpy (badmode.modedesc, "Bad mode"); + vid_canalttab = true; + + if (COM_CheckParm("-fullsbar")) + fullsbardraw = true; +} + + +//======================================================== +// Video menu stuff +//======================================================== + +extern void M_Menu_Options_f (void); +extern void M_Print (int cx, int cy, char *str); +extern void M_PrintWhite (int cx, int cy, char *str); +extern void M_DrawCharacter (int cx, int line, int num); +extern void M_DrawTransPic (int x, int y, qpic_t *pic); +extern void M_DrawPic (int x, int y, qpic_t *pic); + +static int vid_line, vid_wmodes; + +typedef struct +{ + int modenum; + char *desc; + int iscur; +} modedesc_t; + +#define MAX_COLUMN_SIZE 9 +#define MODE_AREA_HEIGHT (MAX_COLUMN_SIZE + 2) +#define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) + +static modedesc_t modedescs[MAX_MODEDESCS]; + +/* +================ +VID_MenuDraw +================ +*/ +void VID_MenuDraw (void) +{ + qpic_t *p; + char *ptr; + int lnummodes, i, j, k, column, row, dup, dupmode; + char temp[100]; + vmode_t *pv; + + p = Draw_CachePic ("gfx/vidmodes.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + vid_wmodes = 0; + lnummodes = VID_NumModes (); + + for (i=1 ; (i<lnummodes) && (vid_wmodes < MAX_MODEDESCS) ; i++) + { + ptr = VID_GetModeDescription (i); + pv = VID_GetModePtr (i); + + k = vid_wmodes; + + modedescs[k].modenum = i; + modedescs[k].desc = ptr; + modedescs[k].iscur = 0; + + if (i == vid_modenum) + modedescs[k].iscur = 1; + + vid_wmodes++; + + } + + if (vid_wmodes > 0) + { + M_Print (2*8, 36+0*8, "Fullscreen Modes (WIDTHxHEIGHTxBPP)"); + + column = 8; + row = 36+2*8; + + for (i=0 ; i<vid_wmodes ; i++) + { + if (modedescs[i].iscur) + M_PrintWhite (column, row, modedescs[i].desc); + else + M_Print (column, row, modedescs[i].desc); + + column += 13*8; + + if ((i % VID_ROW_SIZE) == (VID_ROW_SIZE - 1)) + { + column = 8; + row += 8; + } + } + } + + M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*2, + "Video modes must be set from the"); + M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*3, + "command line with -width <width>"); + M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*4, + "and -bpp <bits-per-pixel>"); + M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*6, + "Select windowed mode with -window"); +} + + +/* +================ +VID_MenuKey +================ +*/ +void VID_MenuKey (int key) +{ + switch (key) + { + case K_ESCAPE: + S_LocalSound ("misc/menu1.wav"); + M_Menu_Options_f (); + break; + + default: + break; + } +} diff --git a/QW/client/gl_warp.c b/QW/client/gl_warp.c new file mode 100644 index 0000000..a7ac7f9 --- /dev/null +++ b/QW/client/gl_warp.c @@ -0,0 +1,1087 @@ +/* +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. + +*/ +// gl_warp.c -- sky and water polygons + +#include "quakedef.h" + +extern model_t *loadmodel; + +int skytexturenum; + +int solidskytexture; +int alphaskytexture; +float speedscale; // for top sky and bottom sky + +msurface_t *warpface; + +extern cvar_t gl_subdivide_size; + +void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs) +{ + int i, j; + float *v; + + mins[0] = mins[1] = mins[2] = 9999; + maxs[0] = maxs[1] = maxs[2] = -9999; + v = verts; + for (i=0 ; i<numverts ; i++) + for (j=0 ; j<3 ; j++, v++) + { + if (*v < mins[j]) + mins[j] = *v; + if (*v > maxs[j]) + maxs[j] = *v; + } +} + +void SubdividePolygon (int numverts, float *verts) +{ + int i, j, k; + vec3_t mins, maxs; + float m; + float *v; + vec3_t front[64], back[64]; + int f, b; + float dist[64]; + float frac; + glpoly_t *poly; + float s, t; + + if (numverts > 60) + Sys_Error ("numverts = %i", numverts); + + BoundPoly (numverts, verts, mins, maxs); + + for (i=0 ; i<3 ; i++) + { + m = (mins[i] + maxs[i]) * 0.5; + m = gl_subdivide_size.value * floor (m/gl_subdivide_size.value + 0.5); + if (maxs[i] - m < 8) + continue; + if (m - mins[i] < 8) + continue; + + // cut it + v = verts + i; + for (j=0 ; j<numverts ; j++, v+= 3) + dist[j] = *v - m; + + // wrap cases + dist[j] = dist[0]; + v-=i; + VectorCopy (verts, v); + + f = b = 0; + v = verts; + for (j=0 ; j<numverts ; j++, v+= 3) + { + if (dist[j] >= 0) + { + VectorCopy (v, front[f]); + f++; + } + if (dist[j] <= 0) + { + VectorCopy (v, back[b]); + b++; + } + if (dist[j] == 0 || dist[j+1] == 0) + continue; + if ( (dist[j] > 0) != (dist[j+1] > 0) ) + { + // clip point + frac = dist[j] / (dist[j] - dist[j+1]); + for (k=0 ; k<3 ; k++) + front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]); + f++; + b++; + } + } + + SubdividePolygon (f, front[0]); + SubdividePolygon (b, back[0]); + return; + } + + poly = Hunk_Alloc (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float)); + poly->next = warpface->polys; + warpface->polys = poly; + poly->numverts = numverts; + for (i=0 ; i<numverts ; i++, verts+= 3) + { + VectorCopy (verts, poly->verts[i]); + s = DotProduct (verts, warpface->texinfo->vecs[0]); + t = DotProduct (verts, warpface->texinfo->vecs[1]); + poly->verts[i][3] = s; + poly->verts[i][4] = t; + } +} + +/* +================ +GL_SubdivideSurface + +Breaks a polygon up along axial 64 unit +boundaries so that turbulent and sky warps +can be done reasonably. +================ +*/ +void GL_SubdivideSurface (msurface_t *fa) +{ + vec3_t verts[64]; + int numverts; + int i; + int lindex; + float *vec; + + warpface = fa; + + // + // convert edges back to a normal polygon + // + numverts = 0; + for (i=0 ; i<fa->numedges ; i++) + { + lindex = loadmodel->surfedges[fa->firstedge + i]; + + if (lindex > 0) + vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position; + else + vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position; + VectorCopy (vec, verts[numverts]); + numverts++; + } + + SubdividePolygon (numverts, verts[0]); +} + +//========================================================= + + + +// speed up sin calculations - Ed +float turbsin[] = +{ + #include "gl_warp_sin.h" +}; +#define TURBSCALE (256.0 / (2 * M_PI)) + +/* +============= +EmitWaterPolys + +Does a water warp on the pre-fragmented glpoly_t chain +============= +*/ +void EmitWaterPolys (msurface_t *fa) +{ + glpoly_t *p; + float *v; + int i; + float s, t, os, ot; + + + for (p=fa->polys ; p ; p=p->next) + { + glBegin (GL_POLYGON); + for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE) + { + os = v[3]; + ot = v[4]; + + s = os + turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255]; + s *= (1.0/64); + + t = ot + turbsin[(int)((os*0.125+realtime) * TURBSCALE) & 255]; + t *= (1.0/64); + + glTexCoord2f (s, t); + glVertex3fv (v); + } + glEnd (); + } +} + + + + +/* +============= +EmitSkyPolys +============= +*/ +void EmitSkyPolys (msurface_t *fa) +{ + glpoly_t *p; + float *v; + int i; + float s, t; + vec3_t dir; + float length; + + for (p=fa->polys ; p ; p=p->next) + { + glBegin (GL_POLYGON); + for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE) + { + VectorSubtract (v, r_origin, dir); + dir[2] *= 3; // flatten the sphere + + length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]; + length = sqrt (length); + length = 6*63/length; + + dir[0] *= length; + dir[1] *= length; + + s = (speedscale + dir[0]) * (1.0/128); + t = (speedscale + dir[1]) * (1.0/128); + + glTexCoord2f (s, t); + glVertex3fv (v); + } + glEnd (); + } +} + +/* +=============== +EmitBothSkyLayers + +Does a sky warp on the pre-fragmented glpoly_t chain +This will be called for brushmodels, the world +will have them chained together. +=============== +*/ +void EmitBothSkyLayers (msurface_t *fa) +{ + GL_DisableMultitexture(); + + GL_Bind (solidskytexture); + speedscale = realtime*8; + speedscale -= (int)speedscale & ~127 ; + + EmitSkyPolys (fa); + + glEnable (GL_BLEND); + GL_Bind (alphaskytexture); + speedscale = realtime*16; + speedscale -= (int)speedscale & ~127 ; + + EmitSkyPolys (fa); + + glDisable (GL_BLEND); +} + +#ifndef QUAKE2 +/* +================= +R_DrawSkyChain +================= +*/ +void R_DrawSkyChain (msurface_t *s) +{ + msurface_t *fa; + + GL_DisableMultitexture(); + + // used when gl_texsort is on + GL_Bind(solidskytexture); + speedscale = realtime*8; + speedscale -= (int)speedscale & ~127 ; + + for (fa=s ; fa ; fa=fa->texturechain) + EmitSkyPolys (fa); + + glEnable (GL_BLEND); + GL_Bind (alphaskytexture); + speedscale = realtime*16; + speedscale -= (int)speedscale & ~127 ; + + for (fa=s ; fa ; fa=fa->texturechain) + EmitSkyPolys (fa); + + glDisable (GL_BLEND); +} + +#endif + +/* +================================================================= + + Quake 2 environment sky + +================================================================= +*/ + +#ifdef QUAKE2 + + +#define SKY_TEX 2000 + +/* +================================================================= + + PCX Loading + +================================================================= +*/ + +typedef struct +{ + char manufacturer; + char version; + char encoding; + char bits_per_pixel; + unsigned short xmin,ymin,xmax,ymax; + unsigned short hres,vres; + unsigned char palette[48]; + char reserved; + char color_planes; + unsigned short bytes_per_line; + unsigned short palette_type; + char filler[58]; + unsigned data; // unbounded +} pcx_t; + +byte *pcx_rgb; + +/* +============ +LoadPCX +============ +*/ +void LoadPCX (FILE *f) +{ + pcx_t *pcx, pcxbuf; + byte palette[768]; + byte *pix; + int x, y; + int dataByte, runLength; + int count; + +// +// parse the PCX file +// + fread (&pcxbuf, 1, sizeof(pcxbuf), f); + + pcx = &pcxbuf; + + if (pcx->manufacturer != 0x0a + || pcx->version != 5 + || pcx->encoding != 1 + || pcx->bits_per_pixel != 8 + || pcx->xmax >= 320 + || pcx->ymax >= 256) + { + Con_Printf ("Bad pcx file\n"); + return; + } + + // seek to palette + fseek (f, -768, SEEK_END); + fread (palette, 1, 768, f); + + fseek (f, sizeof(pcxbuf) - 4, SEEK_SET); + + count = (pcx->xmax+1) * (pcx->ymax+1); + pcx_rgb = malloc( count * 4); + + for (y=0 ; y<=pcx->ymax ; y++) + { + pix = pcx_rgb + 4*y*(pcx->xmax+1); + for (x=0 ; x<=pcx->ymax ; ) + { + dataByte = fgetc(f); + + if((dataByte & 0xC0) == 0xC0) + { + runLength = dataByte & 0x3F; + dataByte = fgetc(f); + } + else + runLength = 1; + + while(runLength-- > 0) + { + pix[0] = palette[dataByte*3]; + pix[1] = palette[dataByte*3+1]; + pix[2] = palette[dataByte*3+2]; + pix[3] = 255; + pix += 4; + x++; + } + } + } +} + +/* +========================================================= + +TARGA LOADING + +========================================================= +*/ + +typedef struct _TargaHeader { + unsigned char id_length, colormap_type, image_type; + unsigned short colormap_index, colormap_length; + unsigned char colormap_size; + unsigned short x_origin, y_origin, width, height; + unsigned char pixel_size, attributes; +} TargaHeader; + + +TargaHeader targa_header; +byte *targa_rgba; + +int fgetLittleShort (FILE *f) +{ + byte b1, b2; + + b1 = fgetc(f); + b2 = fgetc(f); + + return (short)(b1 + b2*256); +} + +int fgetLittleLong (FILE *f) +{ + byte b1, b2, b3, b4; + + b1 = fgetc(f); + b2 = fgetc(f); + b3 = fgetc(f); + b4 = fgetc(f); + + return b1 + (b2<<8) + (b3<<16) + (b4<<24); +} + + +/* +============= +LoadTGA +============= +*/ +void LoadTGA (FILE *fin) +{ + int columns, rows, numPixels; + byte *pixbuf; + int row, column; + + targa_header.id_length = fgetc(fin); + targa_header.colormap_type = fgetc(fin); + targa_header.image_type = fgetc(fin); + + targa_header.colormap_index = fgetLittleShort(fin); + targa_header.colormap_length = fgetLittleShort(fin); + targa_header.colormap_size = fgetc(fin); + targa_header.x_origin = fgetLittleShort(fin); + targa_header.y_origin = fgetLittleShort(fin); + targa_header.width = fgetLittleShort(fin); + targa_header.height = fgetLittleShort(fin); + targa_header.pixel_size = fgetc(fin); + targa_header.attributes = fgetc(fin); + + if (targa_header.image_type!=2 + && targa_header.image_type!=10) + Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n"); + + if (targa_header.colormap_type !=0 + || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24)) + Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n"); + + columns = targa_header.width; + rows = targa_header.height; + numPixels = columns * rows; + + targa_rgba = malloc (numPixels*4); + + if (targa_header.id_length != 0) + fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment + + if (targa_header.image_type==2) { // Uncompressed, RGB images + for(row=rows-1; row>=0; row--) { + pixbuf = targa_rgba + row*columns*4; + for(column=0; column<columns; column++) { + unsigned char red,green,blue,alphabyte; + switch (targa_header.pixel_size) { + case 24: + + blue = getc(fin); + green = getc(fin); + red = getc(fin); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + case 32: + blue = getc(fin); + green = getc(fin); + red = getc(fin); + alphabyte = getc(fin); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = alphabyte; + break; + } + } + } + } + else if (targa_header.image_type==10) { // Runlength encoded RGB images + unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j; + for(row=rows-1; row>=0; row--) { + pixbuf = targa_rgba + row*columns*4; + for(column=0; column<columns; ) { + packetHeader=getc(fin); + packetSize = 1 + (packetHeader & 0x7f); + if (packetHeader & 0x80) { // run-length packet + switch (targa_header.pixel_size) { + case 24: + blue = getc(fin); + green = getc(fin); + red = getc(fin); + alphabyte = 255; + break; + case 32: + blue = getc(fin); + green = getc(fin); + red = getc(fin); + alphabyte = getc(fin); + break; + } + + for(j=0;j<packetSize;j++) { + *pixbuf++=red; + *pixbuf++=green; + *pixbuf++=blue; + *pixbuf++=alphabyte; + column++; + if (column==columns) { // run spans across rows + column=0; + if (row>0) + row--; + else + goto breakOut; + pixbuf = targa_rgba + row*columns*4; + } + } + } + else { // non run-length packet + for(j=0;j<packetSize;j++) { + switch (targa_header.pixel_size) { + case 24: + blue = getc(fin); + green = getc(fin); + red = getc(fin); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + case 32: + blue = getc(fin); + green = getc(fin); + red = getc(fin); + alphabyte = getc(fin); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = alphabyte; + break; + } + column++; + if (column==columns) { // pixel packet run spans across rows + column=0; + if (row>0) + row--; + else + goto breakOut; + pixbuf = targa_rgba + row*columns*4; + } + } + } + } + breakOut:; + } + } + + fclose(fin); +} + +/* +================== +R_LoadSkys +================== +*/ +char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; +void R_LoadSkys (void) +{ + int i; + FILE *f; + char name[64]; + + for (i=0 ; i<6 ; i++) + { + GL_Bind (SKY_TEX + i); + sprintf (name, "gfx/env/bkgtst%s.tga", suf[i]); + COM_FOpenFile (name, &f); + if (!f) + { + Con_Printf ("Couldn't load %s\n", name); + continue; + } + LoadTGA (f); +// LoadPCX (f); + + glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba); +// glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pcx_rgb); + + free (targa_rgba); +// free (pcx_rgb); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } +} + + +vec3_t skyclip[6] = { + {1,1,0}, + {1,-1,0}, + {0,-1,1}, + {0,1,1}, + {1,0,1}, + {-1,0,1} +}; +int c_sky; + +// 1 = s, 2 = t, 3 = 2048 +int st_to_vec[6][3] = +{ + {3,-1,2}, + {-3,1,2}, + + {1,3,2}, + {-1,-3,2}, + + {-2,-1,3}, // 0 degrees yaw, look straight up + {2,-1,-3} // look straight down + +// {-1,2,3}, +// {1,2,-3} +}; + +// s = [0]/[2], t = [1]/[2] +int vec_to_st[6][3] = +{ + {-2,3,1}, + {2,3,-1}, + + {1,3,2}, + {-1,3,-2}, + + {-2,-1,3}, + {-2,1,-3} + +// {-1,2,3}, +// {1,2,-3} +}; + +float skymins[2][6], skymaxs[2][6]; + +void DrawSkyPolygon (int nump, vec3_t vecs) +{ + int i,j; + vec3_t v, av; + float s, t, dv; + int axis; + float *vp; + + c_sky++; +#if 0 +glBegin (GL_POLYGON); +for (i=0 ; i<nump ; i++, vecs+=3) +{ + VectorAdd(vecs, r_origin, v); + glVertex3fv (v); +} +glEnd(); +return; +#endif + // decide which face it maps to + VectorCopy (vec3_origin, v); + for (i=0, vp=vecs ; i<nump ; i++, vp+=3) + { + VectorAdd (vp, v, v); + } + av[0] = fabs(v[0]); + av[1] = fabs(v[1]); + av[2] = fabs(v[2]); + if (av[0] > av[1] && av[0] > av[2]) + { + if (v[0] < 0) + axis = 1; + else + axis = 0; + } + else if (av[1] > av[2] && av[1] > av[0]) + { + if (v[1] < 0) + axis = 3; + else + axis = 2; + } + else + { + if (v[2] < 0) + axis = 5; + else + axis = 4; + } + + // project new texture coords + for (i=0 ; i<nump ; i++, vecs+=3) + { + j = vec_to_st[axis][2]; + if (j > 0) + dv = vecs[j - 1]; + else + dv = -vecs[-j - 1]; + + j = vec_to_st[axis][0]; + if (j < 0) + s = -vecs[-j -1] / dv; + else + s = vecs[j-1] / dv; + j = vec_to_st[axis][1]; + if (j < 0) + t = -vecs[-j -1] / dv; + else + t = vecs[j-1] / dv; + + if (s < skymins[0][axis]) + skymins[0][axis] = s; + if (t < skymins[1][axis]) + skymins[1][axis] = t; + if (s > skymaxs[0][axis]) + skymaxs[0][axis] = s; + if (t > skymaxs[1][axis]) + skymaxs[1][axis] = t; + } +} + +#define MAX_CLIP_VERTS 64 +void ClipSkyPolygon (int nump, vec3_t vecs, int stage) +{ + float *norm; + float *v; + qboolean front, back; + float d, e; + float dists[MAX_CLIP_VERTS]; + int sides[MAX_CLIP_VERTS]; + vec3_t newv[2][MAX_CLIP_VERTS]; + int newc[2]; + int i, j; + + if (nump > MAX_CLIP_VERTS-2) + Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS"); + if (stage == 6) + { // fully clipped, so draw it + DrawSkyPolygon (nump, vecs); + return; + } + + front = back = false; + norm = skyclip[stage]; + for (i=0, v = vecs ; i<nump ; i++, v+=3) + { + d = DotProduct (v, norm); + if (d > ON_EPSILON) + { + front = true; + sides[i] = SIDE_FRONT; + } + else if (d < ON_EPSILON) + { + back = true; + sides[i] = SIDE_BACK; + } + else + sides[i] = SIDE_ON; + dists[i] = d; + } + + if (!front || !back) + { // not clipped + ClipSkyPolygon (nump, vecs, stage+1); + return; + } + + // clip it + sides[i] = sides[0]; + dists[i] = dists[0]; + VectorCopy (vecs, (vecs+(i*3)) ); + newc[0] = newc[1] = 0; + + for (i=0, v = vecs ; i<nump ; i++, v+=3) + { + switch (sides[i]) + { + case SIDE_FRONT: + VectorCopy (v, newv[0][newc[0]]); + newc[0]++; + break; + case SIDE_BACK: + VectorCopy (v, newv[1][newc[1]]); + newc[1]++; + break; + case SIDE_ON: + VectorCopy (v, newv[0][newc[0]]); + newc[0]++; + VectorCopy (v, newv[1][newc[1]]); + newc[1]++; + break; + } + + if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) + continue; + + d = dists[i] / (dists[i] - dists[i+1]); + for (j=0 ; j<3 ; j++) + { + e = v[j] + d*(v[j+3] - v[j]); + newv[0][newc[0]][j] = e; + newv[1][newc[1]][j] = e; + } + newc[0]++; + newc[1]++; + } + + // continue + ClipSkyPolygon (newc[0], newv[0][0], stage+1); + ClipSkyPolygon (newc[1], newv[1][0], stage+1); +} + +/* +================= +R_DrawSkyChain +================= +*/ +void R_DrawSkyChain (msurface_t *s) +{ + msurface_t *fa; + + int i; + vec3_t verts[MAX_CLIP_VERTS]; + glpoly_t *p; + + c_sky = 0; + GL_Bind(solidskytexture); + + // calculate vertex values for sky box + + for (fa=s ; fa ; fa=fa->texturechain) + { + for (p=fa->polys ; p ; p=p->next) + { + for (i=0 ; i<p->numverts ; i++) + { + VectorSubtract (p->verts[i], r_origin, verts[i]); + } + ClipSkyPolygon (p->numverts, verts[0], 0); + } + } +} + + +/* +============== +R_ClearSkyBox +============== +*/ +void R_ClearSkyBox (void) +{ + int i; + + for (i=0 ; i<6 ; i++) + { + skymins[0][i] = skymins[1][i] = 9999; + skymaxs[0][i] = skymaxs[1][i] = -9999; + } +} + + +void MakeSkyVec (float s, float t, int axis) +{ + vec3_t v, b; + int j, k; + + b[0] = s*2048; + b[1] = t*2048; + b[2] = 2048; + + for (j=0 ; j<3 ; j++) + { + k = st_to_vec[axis][j]; + if (k < 0) + v[j] = -b[-k - 1]; + else + v[j] = b[k - 1]; + v[j] += r_origin[j]; + } + + // avoid bilerp seam + s = (s+1)*0.5; + t = (t+1)*0.5; + + if (s < 1.0/512) + s = 1.0/512; + else if (s > 511.0/512) + s = 511.0/512; + if (t < 1.0/512) + t = 1.0/512; + else if (t > 511.0/512) + t = 511.0/512; + + t = 1.0 - t; + glTexCoord2f (s, t); + glVertex3fv (v); +} + +/* +============== +R_DrawSkyBox +============== +*/ +int skytexorder[6] = {0,2,1,3,4,5}; +void R_DrawSkyBox (void) +{ + int i, j, k; + vec3_t v; + float s, t; + +#if 0 +glEnable (GL_BLEND); +glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +glColor4f (1,1,1,0.5); +glDisable (GL_DEPTH_TEST); +#endif + for (i=0 ; i<6 ; i++) + { + if (skymins[0][i] >= skymaxs[0][i] + || skymins[1][i] >= skymaxs[1][i]) + continue; + + GL_Bind (SKY_TEX+skytexorder[i]); +#if 0 +skymins[0][i] = -1; +skymins[1][i] = -1; +skymaxs[0][i] = 1; +skymaxs[1][i] = 1; +#endif + glBegin (GL_QUADS); + MakeSkyVec (skymins[0][i], skymins[1][i], i); + MakeSkyVec (skymins[0][i], skymaxs[1][i], i); + MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i); + MakeSkyVec (skymaxs[0][i], skymins[1][i], i); + glEnd (); + } +#if 0 +glDisable (GL_BLEND); +glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +glColor4f (1,1,1,0.5); +glEnable (GL_DEPTH_TEST); +#endif +} + + +#endif + +//=============================================================== + +/* +============= +R_InitSky + +A sky texture is 256*128, with the right side being a masked overlay +============== +*/ +void R_InitSky (texture_t *mt) +{ + int i, j, p; + byte *src; + unsigned trans[128*128]; + unsigned transpix; + int r, g, b; + unsigned *rgba; + extern int skytexturenum; + + src = (byte *)mt + mt->offsets[0]; + + // make an average value for the back to avoid + // a fringe on the top level + + r = g = b = 0; + for (i=0 ; i<128 ; i++) + for (j=0 ; j<128 ; j++) + { + p = src[i*256 + j + 128]; + rgba = &d_8to24table[p]; + trans[(i*128) + j] = *rgba; + r += ((byte *)rgba)[0]; + g += ((byte *)rgba)[1]; + b += ((byte *)rgba)[2]; + } + + ((byte *)&transpix)[0] = r/(128*128); + ((byte *)&transpix)[1] = g/(128*128); + ((byte *)&transpix)[2] = b/(128*128); + ((byte *)&transpix)[3] = 0; + + + if (!solidskytexture) + solidskytexture = texture_extension_number++; + GL_Bind (solidskytexture ); + glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + + for (i=0 ; i<128 ; i++) + for (j=0 ; j<128 ; j++) + { + p = src[i*256 + j]; + if (p == 0) + trans[(i*128) + j] = transpix; + else + trans[(i*128) + j] = d_8to24table[p]; + } + + if (!alphaskytexture) + alphaskytexture = texture_extension_number++; + GL_Bind(alphaskytexture); + glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +} + diff --git a/QW/client/gl_warp_sin.h b/QW/client/gl_warp_sin.h new file mode 100644 index 0000000..22976a7 --- /dev/null +++ b/QW/client/gl_warp_sin.h @@ -0,0 +1,51 @@ +/* +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. + +*/ + 0, 0.19633, 0.392541, 0.588517, 0.784137, 0.979285, 1.17384, 1.3677, + 1.56072, 1.75281, 1.94384, 2.1337, 2.32228, 2.50945, 2.69512, 2.87916, + 3.06147, 3.24193, 3.42044, 3.59689, 3.77117, 3.94319, 4.11282, 4.27998, + 4.44456, 4.60647, 4.76559, 4.92185, 5.07515, 5.22538, 5.37247, 5.51632, + 5.65685, 5.79398, 5.92761, 6.05767, 6.18408, 6.30677, 6.42566, 6.54068, + 6.65176, 6.75883, 6.86183, 6.9607, 7.05537, 7.14579, 7.23191, 7.31368, + 7.39104, 7.46394, 7.53235, 7.59623, 7.65552, 7.71021, 7.76025, 7.80562, + 7.84628, 7.88222, 7.91341, 7.93984, 7.96148, 7.97832, 7.99036, 7.99759, + 8, 7.99759, 7.99036, 7.97832, 7.96148, 7.93984, 7.91341, 7.88222, + 7.84628, 7.80562, 7.76025, 7.71021, 7.65552, 7.59623, 7.53235, 7.46394, + 7.39104, 7.31368, 7.23191, 7.14579, 7.05537, 6.9607, 6.86183, 6.75883, + 6.65176, 6.54068, 6.42566, 6.30677, 6.18408, 6.05767, 5.92761, 5.79398, + 5.65685, 5.51632, 5.37247, 5.22538, 5.07515, 4.92185, 4.76559, 4.60647, + 4.44456, 4.27998, 4.11282, 3.94319, 3.77117, 3.59689, 3.42044, 3.24193, + 3.06147, 2.87916, 2.69512, 2.50945, 2.32228, 2.1337, 1.94384, 1.75281, + 1.56072, 1.3677, 1.17384, 0.979285, 0.784137, 0.588517, 0.392541, 0.19633, + 9.79717e-16, -0.19633, -0.392541, -0.588517, -0.784137, -0.979285, -1.17384, -1.3677, + -1.56072, -1.75281, -1.94384, -2.1337, -2.32228, -2.50945, -2.69512, -2.87916, + -3.06147, -3.24193, -3.42044, -3.59689, -3.77117, -3.94319, -4.11282, -4.27998, + -4.44456, -4.60647, -4.76559, -4.92185, -5.07515, -5.22538, -5.37247, -5.51632, + -5.65685, -5.79398, -5.92761, -6.05767, -6.18408, -6.30677, -6.42566, -6.54068, + -6.65176, -6.75883, -6.86183, -6.9607, -7.05537, -7.14579, -7.23191, -7.31368, + -7.39104, -7.46394, -7.53235, -7.59623, -7.65552, -7.71021, -7.76025, -7.80562, + -7.84628, -7.88222, -7.91341, -7.93984, -7.96148, -7.97832, -7.99036, -7.99759, + -8, -7.99759, -7.99036, -7.97832, -7.96148, -7.93984, -7.91341, -7.88222, + -7.84628, -7.80562, -7.76025, -7.71021, -7.65552, -7.59623, -7.53235, -7.46394, + -7.39104, -7.31368, -7.23191, -7.14579, -7.05537, -6.9607, -6.86183, -6.75883, + -6.65176, -6.54068, -6.42566, -6.30677, -6.18408, -6.05767, -5.92761, -5.79398, + -5.65685, -5.51632, -5.37247, -5.22538, -5.07515, -4.92185, -4.76559, -4.60647, + -4.44456, -4.27998, -4.11282, -3.94319, -3.77117, -3.59689, -3.42044, -3.24193, + -3.06147, -2.87916, -2.69512, -2.50945, -2.32228, -2.1337, -1.94384, -1.75281, + -1.56072, -1.3677, -1.17384, -0.979285, -0.784137, -0.588517, -0.392541, -0.19633, diff --git a/QW/client/glquake.h b/QW/client/glquake.h new file mode 100644 index 0000000..c7d60ef --- /dev/null +++ b/QW/client/glquake.h @@ -0,0 +1,302 @@ +/* +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. + +*/ +// disable data conversion warnings + +#pragma warning(disable : 4244) // MIPS +#pragma warning(disable : 4136) // X86 +#pragma warning(disable : 4051) // ALPHA + +#ifdef _WIN32 +#include <windows.h> +#endif + +#include <GL/gl.h> +#include <GL/glu.h> + +void GL_BeginRendering (int *x, int *y, int *width, int *height); +void GL_EndRendering (void); + + +// Function prototypes for the Texture Object Extension routines +typedef GLboolean (APIENTRY *ARETEXRESFUNCPTR)(GLsizei, const GLuint *, + const GLboolean *); +typedef void (APIENTRY *BINDTEXFUNCPTR)(GLenum, GLuint); +typedef void (APIENTRY *DELTEXFUNCPTR)(GLsizei, const GLuint *); +typedef void (APIENTRY *GENTEXFUNCPTR)(GLsizei, GLuint *); +typedef GLboolean (APIENTRY *ISTEXFUNCPTR)(GLuint); +typedef void (APIENTRY *PRIORTEXFUNCPTR)(GLsizei, const GLuint *, + const GLclampf *); +typedef void (APIENTRY *TEXSUBIMAGEPTR)(int, int, int, int, int, int, int, int, void *); + +extern BINDTEXFUNCPTR bindTexFunc; +extern DELTEXFUNCPTR delTexFunc; +extern TEXSUBIMAGEPTR TexSubImage2DFunc; + +extern int texture_extension_number; +extern int texture_mode; + +extern float gldepthmin, gldepthmax; + +void GL_Upload32 (unsigned *data, int width, int height, qboolean mipmap, qboolean alpha); +void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha); +void GL_Upload8_EXT (byte *data, int width, int height, qboolean mipmap, qboolean alpha); +int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha); +int GL_FindTexture (char *identifier); + +typedef struct +{ + float x, y, z; + float s, t; + float r, g, b; +} glvert_t; + +extern glvert_t glv; + +extern int glx, gly, glwidth, glheight; + +#ifdef _WIN32 +extern PROC glArrayElementEXT; +extern PROC glColorPointerEXT; +extern PROC glTexturePointerEXT; +extern PROC glVertexPointerEXT; +#endif + +// r_local.h -- private refresh defs + +#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0) + // normalizing factor so player model works out to about + // 1 pixel per triangle +#define MAX_LBM_HEIGHT 480 + +#define TILE_SIZE 128 // size of textures generated by R_GenTiledSurf + +#define SKYSHIFT 7 +#define SKYSIZE (1 << SKYSHIFT) +#define SKYMASK (SKYSIZE - 1) + +#define BACKFACE_EPSILON 0.01 + + +void R_TimeRefresh_f (void); +void R_ReadPointFile_f (void); +texture_t *R_TextureAnimation (texture_t *base); + +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 + byte data[4]; // width*height elements +} surfcache_t; + + +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; + + +typedef enum { + pt_static, pt_grav, pt_slowgrav, pt_fire, pt_explode, pt_explode2, pt_blob, pt_blob2 +} ptype_t; + +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +typedef struct particle_s +{ +// driver-usable fields + vec3_t org; + float color; +// drivers never touch the following fields + struct particle_s *next; + vec3_t vel; + float ramp; + float die; + ptype_t type; +} particle_t; + + +//==================================================== + + +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? +extern int r_framecount; +extern mplane_t frustum[4]; +extern int c_brush_polys, c_alias_polys; + + +// +// view origin +// +extern vec3_t vup; +extern vec3_t vpn; +extern vec3_t vright; +extern vec3_t r_origin; + +// +// screen size info +// +extern refdef_t r_refdef; +extern mleaf_t *r_viewleaf, *r_oldviewleaf; +extern texture_t *r_notexture_mip; +extern int d_lightstylevalue[256]; // 8.8 fraction of base light value + +extern qboolean envmap; +extern int currenttexture; +extern int cnttextures[2]; +extern int particletexture; +extern int netgraphtexture; // netgraph texture +extern int playertextures; + +extern int skytexturenum; // index in cl.loadmodel, not gl texture object + +extern cvar_t r_norefresh; +extern cvar_t r_drawentities; +extern cvar_t r_drawworld; +extern cvar_t r_drawviewmodel; +extern cvar_t r_speeds; +extern cvar_t r_waterwarp; +extern cvar_t r_fullbright; +extern cvar_t r_lightmap; +extern cvar_t r_shadows; +extern cvar_t r_mirroralpha; +extern cvar_t r_wateralpha; +extern cvar_t r_dynamic; +extern cvar_t r_novis; +extern cvar_t r_netgraph; + +extern cvar_t gl_clear; +extern cvar_t gl_cull; +extern cvar_t gl_poly; +extern cvar_t gl_texsort; +extern cvar_t gl_smoothmodels; +extern cvar_t gl_affinemodels; +extern cvar_t gl_polyblend; +extern cvar_t gl_keeptjunctions; +extern cvar_t gl_reporttjunctions; +extern cvar_t gl_flashblend; +extern cvar_t gl_nocolors; +extern cvar_t gl_finish; + +extern int gl_lightmap_format; +extern int gl_solid_format; +extern int gl_alpha_format; + +extern cvar_t gl_max_size; +extern cvar_t gl_playermip; + +extern int mirrortexturenum; // quake texturenum, not gltexturenum +extern qboolean mirror; +extern mplane_t *mirror_plane; + +extern float r_world_matrix[16]; + +extern const char *gl_vendor; +extern const char *gl_renderer; +extern const char *gl_version; +extern const char *gl_extensions; + +void R_TranslatePlayerSkin (int playernum); +void GL_Bind (int texnum); + +// Multitexture +#define TEXTURE0_SGIS 0x835E +#define TEXTURE1_SGIS 0x835F + +#ifdef _WIN32 +typedef void (APIENTRY *lpMTexFUNC) (GLenum, GLfloat, GLfloat); +typedef void (APIENTRY *lpSelTexFUNC) (GLenum); +extern lpMTexFUNC qglMTexCoord2fSGIS; +extern lpSelTexFUNC qglSelectTextureSGIS; +#endif + +extern qboolean gl_mtexable; + +void GL_DisableMultitexture(void); +void GL_EnableMultitexture(void); + +// +// gl_warp.c +// +void GL_SubdivideSurface (msurface_t *fa); +void EmitBothSkyLayers (msurface_t *fa); +void EmitWaterPolys (msurface_t *fa); +void EmitSkyPolys (msurface_t *fa); +void R_DrawSkyChain (msurface_t *s); + +// +// gl_draw.c +// +int GL_LoadPicTexture (qpic_t *pic); +void GL_Set2D (void); + +// +// gl_rmain.c +// +qboolean R_CullBox (vec3_t mins, vec3_t maxs); +void R_RotateForEntity (entity_t *e); + +// +// gl_rlight.c +// +void R_MarkLights (dlight_t *light, int bit, mnode_t *node); +void R_AnimateLight (void); +void R_RenderDlights (void); +int R_LightPoint (vec3_t p); + +// +// gl_refrag.c +// +void R_StoreEfrags (efrag_t **ppefrag); + +// +// gl_mesh.c +// +void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr); + +// +// gl_rsurf.c +// +void R_DrawBrushModel (entity_t *e); +void R_DrawWorld (void); +void GL_BuildLightmaps (void); + +// +// gl_ngraph.c +// +void R_NetGraph (void); + diff --git a/QW/client/glquake2.h b/QW/client/glquake2.h new file mode 100644 index 0000000..6aeed05 --- /dev/null +++ b/QW/client/glquake2.h @@ -0,0 +1,190 @@ +// disable data conversion warnings + +#pragma warning(disable : 4244) // MIPS +#pragma warning(disable : 4136) // X86 +#pragma warning(disable : 4051) // ALPHA + +#include <windows.h> + +#include <gl\gl.h> +#include <gl\glu.h> + +void GL_BeginRendering (int *x, int *y, int *width, int *height); +void GL_EndRendering (void); + + +// Function prototypes for the Texture Object Extension routines +typedef GLboolean (APIENTRY *ARETEXRESFUNCPTR)(GLsizei, const GLuint *, + const GLboolean *); +typedef void (APIENTRY *BINDTEXFUNCPTR)(GLenum, GLuint); +typedef void (APIENTRY *DELTEXFUNCPTR)(GLsizei, const GLuint *); +typedef void (APIENTRY *GENTEXFUNCPTR)(GLsizei, GLuint *); +typedef GLboolean (APIENTRY *ISTEXFUNCPTR)(GLuint); +typedef void (APIENTRY *PRIORTEXFUNCPTR)(GLsizei, const GLuint *, + const GLclampf *); +typedef void (APIENTRY *TEXSUBIMAGEPTR)(int, int, int, int, int, int, int, int, void *); + +extern BINDTEXFUNCPTR bindTexFunc; +extern DELTEXFUNCPTR delTexFunc; +extern TEXSUBIMAGEPTR TexSubImage2DFunc; + +extern int texture_extension_number; +extern int texture_mode; + +extern float gldepthmin, gldepthmax; + +void GL_Upload32 (unsigned *data, int width, int height, qboolean mipmap, qboolean alpha, qboolean modulate); +void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha, qboolean modulate); +int GL_LoadTexture (char *identifier, int width, int height, byte *data, int mipmap, int alpha, int modulate); +int GL_FindTexture (char *identifier); + +typedef struct +{ + float x, y, z; + float s, t; + float r, g, b; +} glvert_t; + +extern glvert_t glv; + +extern int glx, gly, glwidth, glheight; + +extern PROC glArrayElementEXT; +extern PROC glColorPointerEXT; +extern PROC glTexturePointerEXT; +extern PROC glVertexPointerEXT; + + +// r_local.h -- private refresh defs + +#define MAXALIASVERTS 2000 // TODO: tune this + +#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0) + // normalizing factor so player model works out to about + // 1 pixel per triangle +#define MAX_LBM_HEIGHT 480 + +#define TILE_SIZE 128 // size of textures generated by R_GenTiledSurf + +#define SKYSHIFT 7 +#define SKYSIZE (1 << SKYSHIFT) +#define SKYMASK (SKYSIZE - 1) + +#define BACKFACE_EPSILON 0.01 + + +void R_TimeRefresh_f (void); +void R_ReadPointFile_f (void); +texture_t *R_TextureAnimation (texture_t *base); + +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 + byte data[4]; // width*height elements +} surfcache_t; + + +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; + + +typedef enum { + pt_static, pt_grav, pt_slowgrav, pt_fire, pt_explode, pt_explode2, pt_blob, pt_blob2 +} ptype_t; + +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +typedef struct particle_s +{ +// driver-usable fields + vec3_t org; + float color; +// drivers never touch the following fields + struct particle_s *next; + vec3_t vel; + float ramp; + float die; + ptype_t type; +} particle_t; + + +//==================================================== + + +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? +extern int r_framecount; +extern mplane_t frustum[4]; +extern int c_brush_polys, c_alias_polys; + + +// +// view origin +// +extern vec3_t vup; +extern vec3_t vpn; +extern vec3_t vright; +extern vec3_t r_origin; + +// +// screen size info +// +extern refdef_t r_refdef; +extern mleaf_t *r_viewleaf, *r_oldviewleaf; +extern texture_t *r_notexture_mip; +extern int d_lightstylevalue[256]; // 8.8 fraction of base light value + +extern qboolean envmap; +extern int currenttexture; +extern int particletexture; +extern int playertextures; + +extern int skytexturenum; // index in cl.loadmodel, not gl texture object + +extern cvar_t r_drawentities; +extern cvar_t r_drawworld; +extern cvar_t r_drawviewmodel; +extern cvar_t r_speeds; +extern cvar_t r_waterwarp; +extern cvar_t r_fullbright; +extern cvar_t r_lightmap; +extern cvar_t r_shadows; +extern cvar_t r_dynamic; + +extern cvar_t gl_clear; +extern cvar_t gl_cull; +extern cvar_t gl_poly; +extern cvar_t gl_texsort; +extern cvar_t gl_smoothmodels; +extern cvar_t gl_affinemodels; +extern cvar_t gl_fogblend; +extern cvar_t gl_polyblend; +extern cvar_t gl_keeptjunctions; +extern cvar_t gl_reporttjunctions; + +extern int gl_lightmap_format; +extern int gl_solid_format; +extern int gl_alpha_format; + +void R_TranslatePlayerSkin (int playernum); +void GL_Bind (int texnum); diff --git a/QW/client/in_null.c b/QW/client/in_null.c new file mode 100644 index 0000000..33b09b7 --- /dev/null +++ b/QW/client/in_null.c @@ -0,0 +1,29 @@ +// in_null.c -- for systems without a mouse + +#include "quakedef.h" + +void IN_Init (void) +{ +} + +void IN_Shutdown (void) +{ +} + +void IN_Commands (void) +{ +} + +void IN_Move (usercmd_t *cmd) +{ +} + +/* +=========== +IN_ModeChanged +=========== +*/ +void IN_ModeChanged (void) +{ +} + diff --git a/QW/client/in_win.c b/QW/client/in_win.c new file mode 100644 index 0000000..ca7d0a1 --- /dev/null +++ b/QW/client/in_win.c @@ -0,0 +1,1232 @@ +/* +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. + +*/ +// in_win.c -- windows 95 mouse and joystick code +// 02/21/97 JCB Added extended DirectInput code to support external controllers. + +#include <dinput.h> +#include "quakedef.h" +#include "winquake.h" +//#include "dosisms.h" + +#define DINPUT_BUFFERSIZE 16 +#define iDirectInputCreate(a,b,c,d) pDirectInputCreate(a,b,c,d) + +HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, + LPDIRECTINPUT * lplpDirectInput, LPUNKNOWN punkOuter); + +// mouse variables +cvar_t m_filter = {"m_filter","0"}; + +int mouse_buttons; +int mouse_oldbuttonstate; +POINT current_pos; +int mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum; + +static qboolean restore_spi; +static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; +qboolean mouseinitialized; +static qboolean mouseparmsvalid, mouseactivatetoggle; +static qboolean mouseshowtoggle = 1; +static qboolean dinput_acquired; +static unsigned int mstate_di; +unsigned int uiWheelMessage; + +qboolean mouseactive; + +// joystick defines and variables +// where should defines be moved? +#define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick +#define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball +#define JOY_MAX_AXES 6 // X, Y, Z, R, U, V +#define JOY_AXIS_X 0 +#define JOY_AXIS_Y 1 +#define JOY_AXIS_Z 2 +#define JOY_AXIS_R 3 +#define JOY_AXIS_U 4 +#define JOY_AXIS_V 5 + +enum _ControlList +{ + AxisNada = 0, AxisForward, AxisLook, AxisSide, AxisTurn +}; + +DWORD dwAxisFlags[JOY_MAX_AXES] = +{ + JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, JOY_RETURNR, JOY_RETURNU, JOY_RETURNV +}; + +DWORD dwAxisMap[JOY_MAX_AXES]; +DWORD dwControlMap[JOY_MAX_AXES]; +PDWORD pdwRawValue[JOY_MAX_AXES]; + +// none of these cvars are saved over a session +// this means that advanced controller configuration needs to be executed +// each time. this avoids any problems with getting back to a default usage +// or when changing from one controller to another. this way at least something +// works. +cvar_t in_joystick = {"joystick","0", true}; +cvar_t joy_name = {"joyname", "joystick"}; +cvar_t joy_advanced = {"joyadvanced", "0"}; +cvar_t joy_advaxisx = {"joyadvaxisx", "0"}; +cvar_t joy_advaxisy = {"joyadvaxisy", "0"}; +cvar_t joy_advaxisz = {"joyadvaxisz", "0"}; +cvar_t joy_advaxisr = {"joyadvaxisr", "0"}; +cvar_t joy_advaxisu = {"joyadvaxisu", "0"}; +cvar_t joy_advaxisv = {"joyadvaxisv", "0"}; +cvar_t joy_forwardthreshold = {"joyforwardthreshold", "0.15"}; +cvar_t joy_sidethreshold = {"joysidethreshold", "0.15"}; +cvar_t joy_pitchthreshold = {"joypitchthreshold", "0.15"}; +cvar_t joy_yawthreshold = {"joyyawthreshold", "0.15"}; +cvar_t joy_forwardsensitivity = {"joyforwardsensitivity", "-1.0"}; +cvar_t joy_sidesensitivity = {"joysidesensitivity", "-1.0"}; +cvar_t joy_pitchsensitivity = {"joypitchsensitivity", "1.0"}; +cvar_t joy_yawsensitivity = {"joyyawsensitivity", "-1.0"}; +cvar_t joy_wwhack1 = {"joywwhack1", "0.0"}; +cvar_t joy_wwhack2 = {"joywwhack2", "0.0"}; + +qboolean joy_avail, joy_advancedinit, joy_haspov; +DWORD joy_oldbuttonstate, joy_oldpovstate; + +int joy_id; +DWORD joy_flags; +DWORD joy_numbuttons; + +static LPDIRECTINPUT g_pdi; +static LPDIRECTINPUTDEVICE g_pMouse; + +static JOYINFOEX ji; + +static HINSTANCE hInstDI; + +static qboolean dinput; + +typedef struct MYDATA { + LONG lX; // X axis goes here + LONG lY; // Y axis goes here + LONG lZ; // Z axis goes here + BYTE bButtonA; // One button goes here + BYTE bButtonB; // Another button goes here + BYTE bButtonC; // Another button goes here + BYTE bButtonD; // Another button goes here +} MYDATA; + +static DIOBJECTDATAFORMAT rgodf[] = { + { &GUID_XAxis, FIELD_OFFSET(MYDATA, lX), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, + { &GUID_YAxis, FIELD_OFFSET(MYDATA, lY), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, + { &GUID_ZAxis, FIELD_OFFSET(MYDATA, lZ), 0x80000000 | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, + { 0, FIELD_OFFSET(MYDATA, bButtonA), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, + { 0, FIELD_OFFSET(MYDATA, bButtonB), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, + { 0, FIELD_OFFSET(MYDATA, bButtonC), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, + { 0, FIELD_OFFSET(MYDATA, bButtonD), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, +}; + +#define NUM_OBJECTS (sizeof(rgodf) / sizeof(rgodf[0])) + +static DIDATAFORMAT df = { + sizeof(DIDATAFORMAT), // this structure + sizeof(DIOBJECTDATAFORMAT), // size of object data format + DIDF_RELAXIS, // absolute axis coordinates + sizeof(MYDATA), // device data size + NUM_OBJECTS, // number of objects + rgodf, // and here they are +}; + +// forward-referenced functions +void IN_StartupJoystick (void); +void Joy_AdvancedUpdate_f (void); +void IN_JoyMove (usercmd_t *cmd); + + +/* +=========== +Force_CenterView_f +=========== +*/ +void Force_CenterView_f (void) +{ + cl.viewangles[PITCH] = 0; +} + + +/* +=========== +IN_UpdateClipCursor +=========== +*/ +void IN_UpdateClipCursor (void) +{ + + if (mouseinitialized && mouseactive && !dinput) + { + ClipCursor (&window_rect); + } +} + + +/* +=========== +IN_ShowMouse +=========== +*/ +void IN_ShowMouse (void) +{ + + if (!mouseshowtoggle) + { + ShowCursor (TRUE); + mouseshowtoggle = 1; + } +} + + +/* +=========== +IN_HideMouse +=========== +*/ +void IN_HideMouse (void) +{ + + if (mouseshowtoggle) + { + ShowCursor (FALSE); + mouseshowtoggle = 0; + } +} + + +/* +=========== +IN_ActivateMouse +=========== +*/ +void IN_ActivateMouse (void) +{ + + mouseactivatetoggle = true; + + if (mouseinitialized) + { + if (dinput) + { + if (g_pMouse) + { + if (!dinput_acquired) + { + IDirectInputDevice_Acquire(g_pMouse); + dinput_acquired = true; + } + } + else + { + return; + } + } + else + { + if (mouseparmsvalid) + restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); + + SetCursorPos (window_center_x, window_center_y); + SetCapture (mainwindow); + ClipCursor (&window_rect); + } + + mouseactive = true; + } +} + + +/* +=========== +IN_SetQuakeMouseState +=========== +*/ +void IN_SetQuakeMouseState (void) +{ + if (mouseactivatetoggle) + IN_ActivateMouse (); +} + + +/* +=========== +IN_DeactivateMouse +=========== +*/ +void IN_DeactivateMouse (void) +{ + + mouseactivatetoggle = false; + + if (mouseinitialized) + { + if (dinput) + { + if (g_pMouse) + { + if (dinput_acquired) + { + IDirectInputDevice_Unacquire(g_pMouse); + dinput_acquired = false; + } + } + } + else + { + if (restore_spi) + SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); + + ClipCursor (NULL); + ReleaseCapture (); + } + + mouseactive = false; + } +} + + +/* +=========== +IN_RestoreOriginalMouseState +=========== +*/ +void IN_RestoreOriginalMouseState (void) +{ + if (mouseactivatetoggle) + { + IN_DeactivateMouse (); + mouseactivatetoggle = true; + } + +// try to redraw the cursor so it gets reinitialized, because sometimes it +// has garbage after the mode switch + ShowCursor (TRUE); + ShowCursor (FALSE); +} + + +/* +=========== +IN_InitDInput +=========== +*/ +qboolean IN_InitDInput (void) +{ + HRESULT hr; + DIPROPDWORD dipdw = { + { + sizeof(DIPROPDWORD), // diph.dwSize + sizeof(DIPROPHEADER), // diph.dwHeaderSize + 0, // diph.dwObj + DIPH_DEVICE, // diph.dwHow + }, + DINPUT_BUFFERSIZE, // dwData + }; + + if (!hInstDI) + { + hInstDI = LoadLibrary("dinput.dll"); + + if (hInstDI == NULL) + { + Con_SafePrintf ("Couldn't load dinput.dll\n"); + return false; + } + } + + if (!pDirectInputCreate) + { + pDirectInputCreate = (void *)GetProcAddress(hInstDI,"DirectInputCreateA"); + + if (!pDirectInputCreate) + { + Con_SafePrintf ("Couldn't get DI proc addr\n"); + return false; + } + } + +// register with DirectInput and get an IDirectInput to play with. + hr = iDirectInputCreate(global_hInstance, DIRECTINPUT_VERSION, &g_pdi, NULL); + + if (FAILED(hr)) + { + return false; + } + +// obtain an interface to the system mouse device. + hr = IDirectInput_CreateDevice(g_pdi, &GUID_SysMouse, &g_pMouse, NULL); + + if (FAILED(hr)) + { + Con_SafePrintf ("Couldn't open DI mouse device\n"); + return false; + } + +// set the data format to "mouse format". + hr = IDirectInputDevice_SetDataFormat(g_pMouse, &df); + + if (FAILED(hr)) + { + Con_SafePrintf ("Couldn't set DI mouse format\n"); + return false; + } + +// set the cooperativity level. + hr = IDirectInputDevice_SetCooperativeLevel(g_pMouse, mainwindow, + DISCL_EXCLUSIVE | DISCL_FOREGROUND); + + if (FAILED(hr)) + { + Con_SafePrintf ("Couldn't set DI coop level\n"); + return false; + } + + +// set the buffer size to DINPUT_BUFFERSIZE elements. +// the buffer size is a DWORD property associated with the device + hr = IDirectInputDevice_SetProperty(g_pMouse, DIPROP_BUFFERSIZE, &dipdw.diph); + + if (FAILED(hr)) + { + Con_SafePrintf ("Couldn't set DI buffersize\n"); + return false; + } + + return true; +} + + +/* +=========== +IN_StartupMouse +=========== +*/ +void IN_StartupMouse (void) +{ + HDC hdc; + + if ( COM_CheckParm ("-nomouse") ) + return; + + mouseinitialized = true; + + if (COM_CheckParm ("-dinput")) + { + dinput = IN_InitDInput (); + + if (dinput) + { + Con_SafePrintf ("DirectInput initialized\n"); + } + else + { + Con_SafePrintf ("DirectInput not initialized\n"); + } + } + + if (!dinput) + { + mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); + + if (mouseparmsvalid) + { + if ( COM_CheckParm ("-noforcemspd") ) + newmouseparms[2] = originalmouseparms[2]; + + if ( COM_CheckParm ("-noforcemaccel") ) + { + newmouseparms[0] = originalmouseparms[0]; + newmouseparms[1] = originalmouseparms[1]; + } + + if ( COM_CheckParm ("-noforcemparms") ) + { + newmouseparms[0] = originalmouseparms[0]; + newmouseparms[1] = originalmouseparms[1]; + newmouseparms[2] = originalmouseparms[2]; + } + } + } + + mouse_buttons = 3; + +// if a fullscreen video mode was set before the mouse was initialized, +// set the mouse state appropriately + if (mouseactivatetoggle) + IN_ActivateMouse (); +} + + +/* +=========== +IN_Init +=========== +*/ +void IN_Init (void) +{ + // mouse variables + Cvar_RegisterVariable (&m_filter); + + // joystick variables + Cvar_RegisterVariable (&in_joystick); + Cvar_RegisterVariable (&joy_name); + Cvar_RegisterVariable (&joy_advanced); + Cvar_RegisterVariable (&joy_advaxisx); + Cvar_RegisterVariable (&joy_advaxisy); + Cvar_RegisterVariable (&joy_advaxisz); + Cvar_RegisterVariable (&joy_advaxisr); + Cvar_RegisterVariable (&joy_advaxisu); + Cvar_RegisterVariable (&joy_advaxisv); + Cvar_RegisterVariable (&joy_forwardthreshold); + Cvar_RegisterVariable (&joy_sidethreshold); + Cvar_RegisterVariable (&joy_pitchthreshold); + Cvar_RegisterVariable (&joy_yawthreshold); + Cvar_RegisterVariable (&joy_forwardsensitivity); + Cvar_RegisterVariable (&joy_sidesensitivity); + Cvar_RegisterVariable (&joy_pitchsensitivity); + Cvar_RegisterVariable (&joy_yawsensitivity); + Cvar_RegisterVariable (&joy_wwhack1); + Cvar_RegisterVariable (&joy_wwhack2); + + Cmd_AddCommand ("force_centerview", Force_CenterView_f); + Cmd_AddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f); + + uiWheelMessage = RegisterWindowMessage ( "MSWHEEL_ROLLMSG" ); + + IN_StartupMouse (); + IN_StartupJoystick (); +} + +/* +=========== +IN_Shutdown +=========== +*/ +void IN_Shutdown (void) +{ + + IN_DeactivateMouse (); + IN_ShowMouse (); + + if (g_pMouse) + { + IDirectInputDevice_Release(g_pMouse); + g_pMouse = NULL; + } + + if (g_pdi) + { + IDirectInput_Release(g_pdi); + g_pdi = NULL; + } +} + + +/* +=========== +IN_MouseEvent +=========== +*/ +void IN_MouseEvent (int mstate) +{ + int i; + + if (mouseactive && !dinput) + { + // perform button actions + for (i=0 ; i<mouse_buttons ; i++) + { + if ( (mstate & (1<<i)) && + !(mouse_oldbuttonstate & (1<<i)) ) + { + Key_Event (K_MOUSE1 + i, true); + } + + if ( !(mstate & (1<<i)) && + (mouse_oldbuttonstate & (1<<i)) ) + { + Key_Event (K_MOUSE1 + i, false); + } + } + + mouse_oldbuttonstate = mstate; + } +} + + +/* +=========== +IN_MouseMove +=========== +*/ +void IN_MouseMove (usercmd_t *cmd) +{ + int mx, my; + HDC hdc; + int i; + DIDEVICEOBJECTDATA od; + DWORD dwElements; + HRESULT hr; + + if (!mouseactive) + return; + + if (dinput) + { + mx = 0; + my = 0; + + for (;;) + { + dwElements = 1; + + hr = IDirectInputDevice_GetDeviceData(g_pMouse, + sizeof(DIDEVICEOBJECTDATA), &od, &dwElements, 0); + + if ((hr == DIERR_INPUTLOST) || (hr == DIERR_NOTACQUIRED)) + { + dinput_acquired = true; + IDirectInputDevice_Acquire(g_pMouse); + break; + } + + /* Unable to read data or no data available */ + if (FAILED(hr) || dwElements == 0) + { + break; + } + + /* Look at the element to see what happened */ + + switch (od.dwOfs) + { + case DIMOFS_X: + mx += od.dwData; + break; + + case DIMOFS_Y: + my += od.dwData; + break; + + case DIMOFS_BUTTON0: + if (od.dwData & 0x80) + mstate_di |= 1; + else + mstate_di &= ~1; + break; + + case DIMOFS_BUTTON1: + if (od.dwData & 0x80) + mstate_di |= (1<<1); + else + mstate_di &= ~(1<<1); + break; + + case DIMOFS_BUTTON2: + if (od.dwData & 0x80) + mstate_di |= (1<<2); + else + mstate_di &= ~(1<<2); + break; + } + } + + // perform button actions + for (i=0 ; i<mouse_buttons ; i++) + { + if ( (mstate_di & (1<<i)) && + !(mouse_oldbuttonstate & (1<<i)) ) + { + Key_Event (K_MOUSE1 + i, true); + } + + if ( !(mstate_di & (1<<i)) && + (mouse_oldbuttonstate & (1<<i)) ) + { + Key_Event (K_MOUSE1 + i, false); + } + } + + mouse_oldbuttonstate = mstate_di; + } + else + { + GetCursorPos (¤t_pos); + mx = current_pos.x - window_center_x + mx_accum; + my = current_pos.y - window_center_y + my_accum; + mx_accum = 0; + my_accum = 0; + } + + if (m_filter.value) + { + mouse_x = (mx + old_mouse_x) * 0.5; + mouse_y = (my + old_mouse_y) * 0.5; + } + else + { + mouse_x = mx; + mouse_y = my; + } + + old_mouse_x = mx; + old_mouse_y = my; + + mouse_x *= sensitivity.value; + mouse_y *= sensitivity.value; + +// add mouse X/Y movement to cmd + if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) + cmd->sidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + cl.viewangles[PITCH] += m_pitch.value * mouse_y; + if (cl.viewangles[PITCH] > 80) + cl.viewangles[PITCH] = 80; + if (cl.viewangles[PITCH] < -70) + cl.viewangles[PITCH] = -70; + } + else + { + if ((in_strafe.state & 1) && noclip_anglehack) + cmd->upmove -= m_forward.value * mouse_y; + else + cmd->forwardmove -= m_forward.value * mouse_y; + } + +// if the mouse has moved, force it to the center, so there's room to move + if (mx || my) + { + SetCursorPos (window_center_x, window_center_y); + } +} + + +/* +=========== +IN_Move +=========== +*/ +void IN_Move (usercmd_t *cmd) +{ + + if (ActiveApp && !Minimized) + { + IN_MouseMove (cmd); + IN_JoyMove (cmd); + } +} + + +/* +=========== +IN_Accumulate +=========== +*/ +void IN_Accumulate (void) +{ + int mx, my; + HDC hdc; + + if (mouseactive) + { + GetCursorPos (¤t_pos); + + mx_accum += current_pos.x - window_center_x; + my_accum += current_pos.y - window_center_y; + + // force the mouse to the center, so there's room to move + SetCursorPos (window_center_x, window_center_y); + } +} + + +/* +=================== +IN_ClearStates +=================== +*/ +void IN_ClearStates (void) +{ + + if (mouseactive) + { + mx_accum = 0; + my_accum = 0; + mouse_oldbuttonstate = 0; + } +} + + +/* +=============== +IN_StartupJoystick +=============== +*/ +void IN_StartupJoystick (void) +{ + int i, numdevs; + JOYCAPS jc; + MMRESULT mmr; + + // assume no joystick + joy_avail = false; + + // abort startup if user requests no joystick + if ( COM_CheckParm ("-nojoy") ) + return; + + // verify joystick driver is present + if ((numdevs = joyGetNumDevs ()) == 0) + { + Con_Printf ("\njoystick not found -- driver not present\n\n"); + return; + } + + // cycle through the joystick ids for the first valid one + for (joy_id=0 ; joy_id<numdevs ; joy_id++) + { + memset (&ji, 0, sizeof(ji)); + ji.dwSize = sizeof(ji); + ji.dwFlags = JOY_RETURNCENTERED; + + if ((mmr = joyGetPosEx (joy_id, &ji)) == JOYERR_NOERROR) + break; + } + + // abort startup if we didn't find a valid joystick + if (mmr != JOYERR_NOERROR) + { + Con_Printf ("\njoystick not found -- no valid joysticks (%x)\n\n", mmr); + return; + } + + // get the capabilities of the selected joystick + // abort startup if command fails + memset (&jc, 0, sizeof(jc)); + if ((mmr = joyGetDevCaps (joy_id, &jc, sizeof(jc))) != JOYERR_NOERROR) + { + Con_Printf ("\njoystick not found -- invalid joystick capabilities (%x)\n\n", mmr); + return; + } + + // save the joystick's number of buttons and POV status + joy_numbuttons = jc.wNumButtons; + joy_haspov = jc.wCaps & JOYCAPS_HASPOV; + + // old button and POV states default to no buttons pressed + joy_oldbuttonstate = joy_oldpovstate = 0; + + // mark the joystick as available and advanced initialization not completed + // this is needed as cvars are not available during initialization + + joy_avail = true; + joy_advancedinit = false; + + Con_Printf ("\njoystick detected\n\n"); +} + + +/* +=========== +RawValuePointer +=========== +*/ +PDWORD RawValuePointer (int axis) +{ + switch (axis) + { + case JOY_AXIS_X: + return &ji.dwXpos; + case JOY_AXIS_Y: + return &ji.dwYpos; + case JOY_AXIS_Z: + return &ji.dwZpos; + case JOY_AXIS_R: + return &ji.dwRpos; + case JOY_AXIS_U: + return &ji.dwUpos; + case JOY_AXIS_V: + return &ji.dwVpos; + } +} + + +/* +=========== +Joy_AdvancedUpdate_f +=========== +*/ +void Joy_AdvancedUpdate_f (void) +{ + + // called once by IN_ReadJoystick and by user whenever an update is needed + // cvars are now available + int i; + DWORD dwTemp; + + // initialize all the maps + for (i = 0; i < JOY_MAX_AXES; i++) + { + dwAxisMap[i] = AxisNada; + dwControlMap[i] = JOY_ABSOLUTE_AXIS; + pdwRawValue[i] = RawValuePointer(i); + } + + if( joy_advanced.value == 0.0) + { + // default joystick initialization + // 2 axes only with joystick control + dwAxisMap[JOY_AXIS_X] = AxisTurn; + // dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS; + dwAxisMap[JOY_AXIS_Y] = AxisForward; + // dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS; + } + else + { + if (Q_strcmp (joy_name.string, "joystick") != 0) + { + // notify user of advanced controller + Con_Printf ("\n%s configured\n\n", joy_name.string); + } + + // advanced initialization here + // data supplied by user via joy_axisn cvars + dwTemp = (DWORD) joy_advaxisx.value; + dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisy.value; + dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisz.value; + dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisr.value; + dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisu.value; + dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisv.value; + dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; + } + + // compute the axes to collect from DirectInput + joy_flags = JOY_RETURNCENTERED | JOY_RETURNBUTTONS | JOY_RETURNPOV; + for (i = 0; i < JOY_MAX_AXES; i++) + { + if (dwAxisMap[i] != AxisNada) + { + joy_flags |= dwAxisFlags[i]; + } + } +} + + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ + int i, key_index; + DWORD buttonstate, povstate; + + if (!joy_avail) + { + return; + } + + + // loop through the joystick buttons + // key a joystick event or auxillary event for higher number buttons for each state change + buttonstate = ji.dwButtons; + for (i=0 ; i < joy_numbuttons ; i++) + { + if ( (buttonstate & (1<<i)) && !(joy_oldbuttonstate & (1<<i)) ) + { + key_index = (i < 4) ? K_JOY1 : K_AUX1; + Key_Event (key_index + i, true); + } + + if ( !(buttonstate & (1<<i)) && (joy_oldbuttonstate & (1<<i)) ) + { + key_index = (i < 4) ? K_JOY1 : K_AUX1; + Key_Event (key_index + i, false); + } + } + joy_oldbuttonstate = buttonstate; + + if (joy_haspov) + { + // convert POV information into 4 bits of state information + // this avoids any potential problems related to moving from one + // direction to another without going through the center position + povstate = 0; + if(ji.dwPOV != JOY_POVCENTERED) + { + if (ji.dwPOV == JOY_POVFORWARD) + povstate |= 0x01; + if (ji.dwPOV == JOY_POVRIGHT) + povstate |= 0x02; + if (ji.dwPOV == JOY_POVBACKWARD) + povstate |= 0x04; + if (ji.dwPOV == JOY_POVLEFT) + povstate |= 0x08; + } + // determine which bits have changed and key an auxillary event for each change + for (i=0 ; i < 4 ; i++) + { + if ( (povstate & (1<<i)) && !(joy_oldpovstate & (1<<i)) ) + { + Key_Event (K_AUX29 + i, true); + } + + if ( !(povstate & (1<<i)) && (joy_oldpovstate & (1<<i)) ) + { + Key_Event (K_AUX29 + i, false); + } + } + joy_oldpovstate = povstate; + } +} + + +/* +=============== +IN_ReadJoystick +=============== +*/ +qboolean IN_ReadJoystick (void) +{ + + memset (&ji, 0, sizeof(ji)); + ji.dwSize = sizeof(ji); + ji.dwFlags = joy_flags; + + if (joyGetPosEx (joy_id, &ji) == JOYERR_NOERROR) + { + // this is a hack -- there is a bug in the Logitech WingMan Warrior DirectInput Driver + // rather than having 32768 be the zero point, they have the zero point at 32668 + // go figure -- anyway, now we get the full resolution out of the device + if (joy_wwhack1.value != 0.0) + { + ji.dwUpos += 100; + } + return true; + } + else + { + // read error occurred + // turning off the joystick seems too harsh for 1 read error,\ + // but what should be done? + // Con_Printf ("IN_ReadJoystick: no response\n"); + // joy_avail = false; + return false; + } +} + + +/* +=========== +IN_JoyMove +=========== +*/ +void IN_JoyMove (usercmd_t *cmd) +{ + float speed, aspeed; + float fAxisValue, fTemp; + int i; + + // complete initialization if first time in + // this is needed as cvars are not available at initialization time + if( joy_advancedinit != true ) + { + Joy_AdvancedUpdate_f(); + joy_advancedinit = true; + } + + // verify joystick is available and that the user wants to use it + if (!joy_avail || !in_joystick.value) + { + return; + } + + // collect the joystick data, if possible + if (IN_ReadJoystick () != true) + { + return; + } + + if (in_speed.state & 1) + speed = cl_movespeedkey.value; + else + speed = 1; + aspeed = speed * host_frametime; + + // loop through the axes + for (i = 0; i < JOY_MAX_AXES; i++) + { + // get the floating point zero-centered, potentially-inverted data for the current axis + fAxisValue = (float) *pdwRawValue[i]; + // move centerpoint to zero + fAxisValue -= 32768.0; + + if (joy_wwhack2.value != 0.0) + { + if (dwAxisMap[i] == AxisTurn) + { + // this is a special formula for the Logitech WingMan Warrior + // y=ax^b; where a = 300 and b = 1.3 + // also x values are in increments of 800 (so this is factored out) + // then bounds check result to level out excessively high spin rates + fTemp = 300.0 * pow(abs(fAxisValue) / 800.0, 1.3); + if (fTemp > 14000.0) + fTemp = 14000.0; + // restore direction information + fAxisValue = (fAxisValue > 0.0) ? fTemp : -fTemp; + } + } + + // convert range from -32768..32767 to -1..1 + fAxisValue /= 32768.0; + + switch (dwAxisMap[i]) + { + case AxisForward: + if ((joy_advanced.value == 0.0) && (in_mlook.state & 1)) + { + // user wants forward control to become look control + if (fabs(fAxisValue) > joy_pitchthreshold.value) + { + // if mouse invert is on, invert the joystick pitch value + // only absolute control support here (joy_advanced is false) + if (m_pitch.value < 0.0) + { + cl.viewangles[PITCH] -= (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value; + } + else + { + cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value; + } + V_StopPitchDrift(); + } + else + { + // no pitch movement + // disable pitch return-to-center unless requested by user + // *** this code can be removed when the lookspring bug is fixed + // *** the bug always has the lookspring feature on + if(lookspring.value == 0.0) + V_StopPitchDrift(); + } + } + else + { + // user wants forward control to be forward control + if (fabs(fAxisValue) > joy_forwardthreshold.value) + { + cmd->forwardmove += (fAxisValue * joy_forwardsensitivity.value) * speed * cl_forwardspeed.value; + } + } + break; + + case AxisSide: + if (fabs(fAxisValue) > joy_sidethreshold.value) + { + cmd->sidemove += (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value; + } + break; + + case AxisTurn: + if ((in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1))) + { + // user wants turn control to become side control + if (fabs(fAxisValue) > joy_sidethreshold.value) + { + cmd->sidemove -= (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value; + } + } + else + { + // user wants turn control to be turn control + if (fabs(fAxisValue) > joy_yawthreshold.value) + { + if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) + { + cl.viewangles[YAW] += (fAxisValue * joy_yawsensitivity.value) * aspeed * cl_yawspeed.value; + } + else + { + cl.viewangles[YAW] += (fAxisValue * joy_yawsensitivity.value) * speed * 180.0; + } + + } + } + break; + + case AxisLook: + if (in_mlook.state & 1) + { + if (fabs(fAxisValue) > joy_pitchthreshold.value) + { + // pitch movement detected and pitch movement desired by user + if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) + { + cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value; + } + else + { + cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity.value) * speed * 180.0; + } + V_StopPitchDrift(); + } + else + { + // no pitch movement + // disable pitch return-to-center unless requested by user + // *** this code can be removed when the lookspring bug is fixed + // *** the bug always has the lookspring feature on + if(lookspring.value == 0.0) + V_StopPitchDrift(); + } + } + break; + + default: + break; + } + } + + // bounds check pitch + if (cl.viewangles[PITCH] > 80.0) + cl.viewangles[PITCH] = 80.0; + if (cl.viewangles[PITCH] < -70.0) + cl.viewangles[PITCH] = -70.0; +} diff --git a/QW/client/input.h b/QW/client/input.h new file mode 100644 index 0000000..4a5a129 --- /dev/null +++ b/QW/client/input.h @@ -0,0 +1,34 @@ +/* +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. + +*/ +// input.h -- external (non-keyboard) input devices + +void IN_Init (void); + +void IN_Shutdown (void); + +void IN_Commands (void); +// oportunity for devices to stick commands on the script buffer + +void IN_Move (usercmd_t *cmd); +// add additional movement on top of the keyboard move cmd + +void IN_ModeChanged (void); +// called whenever screen dimensions change + diff --git a/QW/client/keys.c b/QW/client/keys.c new file mode 100644 index 0000000..572a7cc --- /dev/null +++ b/QW/client/keys.c @@ -0,0 +1,839 @@ +/* +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. + +*/ +#include "quakedef.h" +#ifdef _WINDOWS +#include <windows.h> +#endif +/* + +key up events are sent even if in console mode + +*/ + + +#define MAXCMDLINE 256 +char key_lines[32][MAXCMDLINE]; +int key_linepos; +int shift_down=false; +int key_lastpress; + +int edit_line=0; +int history_line=0; + +keydest_t key_dest; + +int key_count; // incremented every key event + +char *keybindings[256]; +qboolean consolekeys[256]; // if true, can't be rebound while in console +qboolean menubound[256]; // if true, can't be rebound while in menu +int keyshift[256]; // key to map to if shift held down in console +int key_repeats[256]; // if > 1, it is autorepeating +qboolean keydown[256]; + +typedef struct +{ + char *name; + int keynum; +} keyname_t; + +keyname_t keynames[] = +{ + {"TAB", K_TAB}, + {"ENTER", K_ENTER}, + {"ESCAPE", K_ESCAPE}, + {"SPACE", K_SPACE}, + {"BACKSPACE", K_BACKSPACE}, + {"UPARROW", K_UPARROW}, + {"DOWNARROW", K_DOWNARROW}, + {"LEFTARROW", K_LEFTARROW}, + {"RIGHTARROW", K_RIGHTARROW}, + + {"ALT", K_ALT}, + {"CTRL", K_CTRL}, + {"SHIFT", K_SHIFT}, + + {"F1", K_F1}, + {"F2", K_F2}, + {"F3", K_F3}, + {"F4", K_F4}, + {"F5", K_F5}, + {"F6", K_F6}, + {"F7", K_F7}, + {"F8", K_F8}, + {"F9", K_F9}, + {"F10", K_F10}, + {"F11", K_F11}, + {"F12", K_F12}, + + {"INS", K_INS}, + {"DEL", K_DEL}, + {"PGDN", K_PGDN}, + {"PGUP", K_PGUP}, + {"HOME", K_HOME}, + {"END", K_END}, + + {"MOUSE1", K_MOUSE1}, + {"MOUSE2", K_MOUSE2}, + {"MOUSE3", K_MOUSE3}, + + {"JOY1", K_JOY1}, + {"JOY2", K_JOY2}, + {"JOY3", K_JOY3}, + {"JOY4", K_JOY4}, + + {"AUX1", K_AUX1}, + {"AUX2", K_AUX2}, + {"AUX3", K_AUX3}, + {"AUX4", K_AUX4}, + {"AUX5", K_AUX5}, + {"AUX6", K_AUX6}, + {"AUX7", K_AUX7}, + {"AUX8", K_AUX8}, + {"AUX9", K_AUX9}, + {"AUX10", K_AUX10}, + {"AUX11", K_AUX11}, + {"AUX12", K_AUX12}, + {"AUX13", K_AUX13}, + {"AUX14", K_AUX14}, + {"AUX15", K_AUX15}, + {"AUX16", K_AUX16}, + {"AUX17", K_AUX17}, + {"AUX18", K_AUX18}, + {"AUX19", K_AUX19}, + {"AUX20", K_AUX20}, + {"AUX21", K_AUX21}, + {"AUX22", K_AUX22}, + {"AUX23", K_AUX23}, + {"AUX24", K_AUX24}, + {"AUX25", K_AUX25}, + {"AUX26", K_AUX26}, + {"AUX27", K_AUX27}, + {"AUX28", K_AUX28}, + {"AUX29", K_AUX29}, + {"AUX30", K_AUX30}, + {"AUX31", K_AUX31}, + {"AUX32", K_AUX32}, + + {"PAUSE", K_PAUSE}, + + {"MWHEELUP", K_MWHEELUP}, + {"MWHEELDOWN", K_MWHEELDOWN}, + + {"SEMICOLON", ';'}, // because a raw semicolon seperates commands + + {NULL,0} +}; + +/* +============================================================================== + + LINE TYPING INTO THE CONSOLE + +============================================================================== +*/ + +qboolean CheckForCommand (void) +{ + char command[128]; + char *cmd, *s; + int i; + + s = key_lines[edit_line]+1; + + for (i=0 ; i<127 ; i++) + if (s[i] <= ' ') + break; + else + command[i] = s[i]; + command[i] = 0; + + cmd = Cmd_CompleteCommand (command); + if (!cmd || strcmp (cmd, command)) + cmd = Cvar_CompleteVariable (command); + if (!cmd || strcmp (cmd, command) ) + return false; // just a chat message + return true; +} + +void CompleteCommand (void) +{ + char *cmd, *s; + + s = key_lines[edit_line]+1; + if (*s == '\\' || *s == '/') + s++; + + cmd = Cmd_CompleteCommand (s); + if (!cmd) + cmd = Cvar_CompleteVariable (s); + if (cmd) + { + key_lines[edit_line][1] = '/'; + Q_strcpy (key_lines[edit_line]+2, cmd); + key_linepos = Q_strlen(cmd)+2; + key_lines[edit_line][key_linepos] = ' '; + key_linepos++; + key_lines[edit_line][key_linepos] = 0; + return; + } +} + +/* +==================== +Key_Console + +Interactive line editing and console scrollback +==================== +*/ +void Key_Console (int key) +{ +#ifdef _WIN32 + char *cmd, *s; + int i; + HANDLE th; + char *clipText, *textCopied; +#endif + + if (key == K_ENTER) + { // backslash text are commands, else chat + if (key_lines[edit_line][1] == '\\' || key_lines[edit_line][1] == '/') + Cbuf_AddText (key_lines[edit_line]+2); // skip the > + else if (CheckForCommand()) + Cbuf_AddText (key_lines[edit_line]+1); // valid command + else + { // convert to a chat message + if (cls.state >= ca_connected) + Cbuf_AddText ("say "); + Cbuf_AddText (key_lines[edit_line]+1); // skip the > + } + + Cbuf_AddText ("\n"); + Con_Printf ("%s\n",key_lines[edit_line]); + edit_line = (edit_line + 1) & 31; + history_line = edit_line; + key_lines[edit_line][0] = ']'; + key_linepos = 1; + if (cls.state == ca_disconnected) + SCR_UpdateScreen (); // force an update, because the command + // may take some time + return; + } + + if (key == K_TAB) + { // command completion + CompleteCommand (); + return; + } + + if (key == K_BACKSPACE || key == K_LEFTARROW) + { + if (key_linepos > 1) + key_linepos--; + return; + } + + if (key == K_UPARROW) + { + do + { + history_line = (history_line - 1) & 31; + } while (history_line != edit_line + && !key_lines[history_line][1]); + if (history_line == edit_line) + history_line = (edit_line+1)&31; + Q_strcpy(key_lines[edit_line], key_lines[history_line]); + key_linepos = Q_strlen(key_lines[edit_line]); + return; + } + + if (key == K_DOWNARROW) + { + if (history_line == edit_line) return; + do + { + history_line = (history_line + 1) & 31; + } + while (history_line != edit_line + && !key_lines[history_line][1]); + if (history_line == edit_line) + { + key_lines[edit_line][0] = ']'; + key_linepos = 1; + } + else + { + Q_strcpy(key_lines[edit_line], key_lines[history_line]); + key_linepos = Q_strlen(key_lines[edit_line]); + } + return; + } + + if (key == K_PGUP || key==K_MWHEELUP) + { + con->display -= 2; + return; + } + + if (key == K_PGDN || key==K_MWHEELDOWN) + { + con->display += 2; + if (con->display > con->current) + con->display = con->current; + return; + } + + if (key == K_HOME) + { + con->display = con->current - con_totallines + 10; + return; + } + + if (key == K_END) + { + con->display = con->current; + return; + } + +#ifdef _WIN32 + if ((key=='V' || key=='v') && GetKeyState(VK_CONTROL)<0) { + if (OpenClipboard(NULL)) { + th = GetClipboardData(CF_TEXT); + if (th) { + clipText = GlobalLock(th); + if (clipText) { + textCopied = malloc(GlobalSize(th)+1); + strcpy(textCopied, clipText); + /* Substitutes a NULL for every token */strtok(textCopied, "\n\r\b"); + i = strlen(textCopied); + if (i+key_linepos>=MAXCMDLINE) + i=MAXCMDLINE-key_linepos; + if (i>0) { + textCopied[i]=0; + strcat(key_lines[edit_line], textCopied); + key_linepos+=i;; + } + free(textCopied); + } + GlobalUnlock(th); + } + CloseClipboard(); + return; + } + } +#endif + + if (key < 32 || key > 127) + return; // non printable + + if (key_linepos < MAXCMDLINE-1) + { + key_lines[edit_line][key_linepos] = key; + key_linepos++; + key_lines[edit_line][key_linepos] = 0; + } + +} + +//============================================================================ + +qboolean chat_team; +char chat_buffer[MAXCMDLINE]; +int chat_bufferlen = 0; + +void Key_Message (int key) +{ + + if (key == K_ENTER) + { + if (chat_team) + Cbuf_AddText ("say_team \""); + else + Cbuf_AddText ("say \""); + Cbuf_AddText(chat_buffer); + Cbuf_AddText("\"\n"); + + key_dest = key_game; + chat_bufferlen = 0; + chat_buffer[0] = 0; + return; + } + + if (key == K_ESCAPE) + { + key_dest = key_game; + chat_bufferlen = 0; + chat_buffer[0] = 0; + return; + } + + if (key < 32 || key > 127) + return; // non printable + + if (key == K_BACKSPACE) + { + if (chat_bufferlen) + { + chat_bufferlen--; + chat_buffer[chat_bufferlen] = 0; + } + return; + } + + if (chat_bufferlen == sizeof(chat_buffer)-1) + return; // all full + + chat_buffer[chat_bufferlen++] = key; + chat_buffer[chat_bufferlen] = 0; +} + +//============================================================================ + + +/* +=================== +Key_StringToKeynum + +Returns a key number to be used to index keybindings[] by looking at +the given string. Single ascii characters return themselves, while +the K_* names are matched up. +=================== +*/ +int Key_StringToKeynum (char *str) +{ + keyname_t *kn; + + if (!str || !str[0]) + return -1; + if (!str[1]) + return str[0]; + + for (kn=keynames ; kn->name ; kn++) + { + if (!Q_strcasecmp(str,kn->name)) + return kn->keynum; + } + return -1; +} + +/* +=================== +Key_KeynumToString + +Returns a string (either a single ascii char, or a K_* name) for the +given keynum. +FIXME: handle quote special (general escape sequence?) +=================== +*/ +char *Key_KeynumToString (int keynum) +{ + keyname_t *kn; + static char tinystr[2]; + + if (keynum == -1) + return "<KEY NOT FOUND>"; + if (keynum > 32 && keynum < 127) + { // printable ascii + tinystr[0] = keynum; + tinystr[1] = 0; + return tinystr; + } + + for (kn=keynames ; kn->name ; kn++) + if (keynum == kn->keynum) + return kn->name; + + return "<UNKNOWN KEYNUM>"; +} + + +/* +=================== +Key_SetBinding +=================== +*/ +void Key_SetBinding (int keynum, char *binding) +{ + char *new; + int l; + + if (keynum == -1) + return; + +// free old bindings + if (keybindings[keynum]) + { + Z_Free (keybindings[keynum]); + keybindings[keynum] = NULL; + } + +// allocate memory for new binding + l = Q_strlen (binding); + new = Z_Malloc (l+1); + Q_strcpy (new, binding); + new[l] = 0; + keybindings[keynum] = new; +} + +/* +=================== +Key_Unbind_f +=================== +*/ +void Key_Unbind_f (void) +{ + int b; + + if (Cmd_Argc() != 2) + { + Con_Printf ("unbind <key> : remove commands from a key\n"); + return; + } + + b = Key_StringToKeynum (Cmd_Argv(1)); + if (b==-1) + { + Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); + return; + } + + Key_SetBinding (b, ""); +} + +void Key_Unbindall_f (void) +{ + int i; + + for (i=0 ; i<256 ; i++) + if (keybindings[i]) + Key_SetBinding (i, ""); +} + + +/* +=================== +Key_Bind_f +=================== +*/ +void Key_Bind_f (void) +{ + int i, c, b; + char cmd[1024]; + + c = Cmd_Argc(); + + if (c != 2 && c != 3) + { + Con_Printf ("bind <key> [command] : attach a command to a key\n"); + return; + } + b = Key_StringToKeynum (Cmd_Argv(1)); + if (b==-1) + { + Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); + return; + } + + if (c == 2) + { + if (keybindings[b]) + Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b] ); + else + Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) ); + return; + } + +// copy the rest of the command line + cmd[0] = 0; // start out with a null string + for (i=2 ; i< c ; i++) + { + strcat (cmd, Cmd_Argv(i)); + if (i != (c-1)) + strcat (cmd, " "); + } + + Key_SetBinding (b, cmd); +} + +/* +============ +Key_WriteBindings + +Writes lines containing "bind key value" +============ +*/ +void Key_WriteBindings (FILE *f) +{ + int i; + + for (i=0 ; i<256 ; i++) + if (keybindings[i]) + fprintf (f, "bind %s \"%s\"\n", Key_KeynumToString(i), keybindings[i]); +} + + +/* +=================== +Key_Init +=================== +*/ +void Key_Init (void) +{ + int i; + + for (i=0 ; i<32 ; i++) + { + key_lines[i][0] = ']'; + key_lines[i][1] = 0; + } + key_linepos = 1; + +// +// init ascii characters in console mode +// + for (i=32 ; i<128 ; i++) + consolekeys[i] = true; + consolekeys[K_ENTER] = true; + consolekeys[K_TAB] = true; + consolekeys[K_LEFTARROW] = true; + consolekeys[K_RIGHTARROW] = true; + consolekeys[K_UPARROW] = true; + consolekeys[K_DOWNARROW] = true; + consolekeys[K_BACKSPACE] = true; + consolekeys[K_HOME] = true; + consolekeys[K_END] = true; + consolekeys[K_PGUP] = true; + consolekeys[K_PGDN] = true; + consolekeys[K_SHIFT] = true; + consolekeys[K_MWHEELUP] = true; + consolekeys[K_MWHEELDOWN] = true; + consolekeys['`'] = false; + consolekeys['~'] = false; + + for (i=0 ; i<256 ; i++) + keyshift[i] = i; + for (i='a' ; i<='z' ; i++) + keyshift[i] = i - 'a' + 'A'; + keyshift['1'] = '!'; + keyshift['2'] = '@'; + keyshift['3'] = '#'; + keyshift['4'] = '$'; + keyshift['5'] = '%'; + keyshift['6'] = '^'; + keyshift['7'] = '&'; + keyshift['8'] = '*'; + keyshift['9'] = '('; + keyshift['0'] = ')'; + keyshift['-'] = '_'; + keyshift['='] = '+'; + keyshift[','] = '<'; + keyshift['.'] = '>'; + keyshift['/'] = '?'; + keyshift[';'] = ':'; + keyshift['\''] = '"'; + keyshift['['] = '{'; + keyshift[']'] = '}'; + keyshift['`'] = '~'; + keyshift['\\'] = '|'; + + menubound[K_ESCAPE] = true; + for (i=0 ; i<12 ; i++) + menubound[K_F1+i] = true; + +// +// register our functions +// + Cmd_AddCommand ("bind",Key_Bind_f); + Cmd_AddCommand ("unbind",Key_Unbind_f); + Cmd_AddCommand ("unbindall",Key_Unbindall_f); + + +} + +/* +=================== +Key_Event + +Called by the system between frames for both key up and key down events +Should NOT be called during an interrupt! +=================== +*/ +void Key_Event (int key, qboolean down) +{ + char *kb; + char cmd[1024]; + +// Con_Printf ("%i : %i\n", key, down); //@@@ + + keydown[key] = down; + + if (!down) + key_repeats[key] = 0; + + key_lastpress = key; + key_count++; + if (key_count <= 0) + { + return; // just catching keys for Con_NotifyBox + } + +// update auto-repeat status + if (down) + { + key_repeats[key]++; + if (key != K_BACKSPACE + && key != K_PAUSE + && key != K_PGUP + && key != K_PGDN + && key_repeats[key] > 1) + return; // ignore most autorepeats + + if (key >= 200 && !keybindings[key]) + Con_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString (key) ); + } + + if (key == K_SHIFT) + shift_down = down; + +// +// handle escape specialy, so the user can never unbind it +// + if (key == K_ESCAPE) + { + if (!down) + return; + switch (key_dest) + { + case key_message: + Key_Message (key); + break; + case key_menu: + M_Keydown (key); + break; + case key_game: + case key_console: + M_ToggleMenu_f (); + break; + default: + Sys_Error ("Bad key_dest"); + } + return; + } + +// +// key up events only generate commands if the game key binding is +// a button command (leading + sign). These will occur even in console mode, +// to keep the character from continuing an action started before a console +// switch. Button commands include the kenum as a parameter, so multiple +// downs can be matched with ups +// + if (!down) + { + kb = keybindings[key]; + if (kb && kb[0] == '+') + { + sprintf (cmd, "-%s %i\n", kb+1, key); + Cbuf_AddText (cmd); + } + if (keyshift[key] != key) + { + kb = keybindings[keyshift[key]]; + if (kb && kb[0] == '+') + { + sprintf (cmd, "-%s %i\n", kb+1, key); + Cbuf_AddText (cmd); + } + } + return; + } + +// +// during demo playback, most keys bring up the main menu +// + if (cls.demoplayback && down && consolekeys[key] && key_dest == key_game) + { + M_ToggleMenu_f (); + return; + } + +// +// if not a consolekey, send to the interpreter no matter what mode is +// + if ( (key_dest == key_menu && menubound[key]) + || (key_dest == key_console && !consolekeys[key]) + || (key_dest == key_game && ( cls.state == ca_active || !consolekeys[key] ) ) ) + { + kb = keybindings[key]; + if (kb) + { + if (kb[0] == '+') + { // button commands add keynum as a parm + sprintf (cmd, "%s %i\n", kb, key); + Cbuf_AddText (cmd); + } + else + { + Cbuf_AddText (kb); + Cbuf_AddText ("\n"); + } + } + return; + } + + if (!down) + return; // other systems only care about key down events + + if (shift_down) + key = keyshift[key]; + + switch (key_dest) + { + case key_message: + Key_Message (key); + break; + case key_menu: + M_Keydown (key); + break; + + case key_game: + case key_console: + Key_Console (key); + break; + default: + Sys_Error ("Bad key_dest"); + } +} + +/* +=================== +Key_ClearStates +=================== +*/ +void Key_ClearStates (void) +{ + int i; + + for (i=0 ; i<256 ; i++) + { + keydown[i] = false; + key_repeats[i] = false; + } +} + diff --git a/QW/client/keys.h b/QW/client/keys.h new file mode 100644 index 0000000..46c80e2 --- /dev/null +++ b/QW/client/keys.h @@ -0,0 +1,137 @@ +/* +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. + +*/ + +// +// these are the key numbers that should be passed to Key_Event +// +#define K_TAB 9 +#define K_ENTER 13 +#define K_ESCAPE 27 +#define K_SPACE 32 + +// normal keys should be passed as lowercased ascii + +#define K_BACKSPACE 127 +#define K_UPARROW 128 +#define K_DOWNARROW 129 +#define K_LEFTARROW 130 +#define K_RIGHTARROW 131 + +#define K_ALT 132 +#define K_CTRL 133 +#define K_SHIFT 134 +#define K_F1 135 +#define K_F2 136 +#define K_F3 137 +#define K_F4 138 +#define K_F5 139 +#define K_F6 140 +#define K_F7 141 +#define K_F8 142 +#define K_F9 143 +#define K_F10 144 +#define K_F11 145 +#define K_F12 146 +#define K_INS 147 +#define K_DEL 148 +#define K_PGDN 149 +#define K_PGUP 150 +#define K_HOME 151 +#define K_END 152 + +#define K_PAUSE 255 + +// +// mouse buttons generate virtual keys +// +#define K_MOUSE1 200 +#define K_MOUSE2 201 +#define K_MOUSE3 202 + +// +// joystick buttons +// +#define K_JOY1 203 +#define K_JOY2 204 +#define K_JOY3 205 +#define K_JOY4 206 + +// +// aux keys are for multi-buttoned joysticks to generate so they can use +// the normal binding process +// +#define K_AUX1 207 +#define K_AUX2 208 +#define K_AUX3 209 +#define K_AUX4 210 +#define K_AUX5 211 +#define K_AUX6 212 +#define K_AUX7 213 +#define K_AUX8 214 +#define K_AUX9 215 +#define K_AUX10 216 +#define K_AUX11 217 +#define K_AUX12 218 +#define K_AUX13 219 +#define K_AUX14 220 +#define K_AUX15 221 +#define K_AUX16 222 +#define K_AUX17 223 +#define K_AUX18 224 +#define K_AUX19 225 +#define K_AUX20 226 +#define K_AUX21 227 +#define K_AUX22 228 +#define K_AUX23 229 +#define K_AUX24 230 +#define K_AUX25 231 +#define K_AUX26 232 +#define K_AUX27 233 +#define K_AUX28 234 +#define K_AUX29 235 +#define K_AUX30 236 +#define K_AUX31 237 +#define K_AUX32 238 + +// JACK: Intellimouse(c) Mouse Wheel Support + +#define K_MWHEELUP 239 +#define K_MWHEELDOWN 240 + + + +typedef enum {key_game, key_console, key_message, key_menu} keydest_t; + +extern keydest_t key_dest; +extern char *keybindings[256]; +extern int key_repeats[256]; +extern int key_count; // incremented every key event +extern int key_lastpress; + +extern char chat_buffer[]; +extern int chat_bufferlen; +extern qboolean chat_team; + +void Key_Event (int key, qboolean down); +void Key_Init (void); +void Key_WriteBindings (FILE *f); +void Key_SetBinding (int keynum, char *binding); +void Key_ClearStates (void); + diff --git a/QW/client/makefile.svgalib b/QW/client/makefile.svgalib new file mode 100644 index 0000000..562590e --- /dev/null +++ b/QW/client/makefile.svgalib @@ -0,0 +1,109 @@ +OBJS= \ + cl_demo.o \ + cl_ents.o \ + cl_input.o \ + cl_main.o \ + cl_parse.o \ + cl_pred.o \ + cl_tent.o \ + cl_cam.o \ + cmd.o \ + common.o \ + console.o \ + crc.o \ + cvar.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_vars.o \ + d_zpoint.o \ + draw.o \ + keys.o \ + mathlib.o \ + md4.o \ + menu.o \ + model.o \ + net_chan.o \ + net_udp.o \ + nonintel.o \ + pmove.o \ + pmovetst.o \ + r_aclip.o \ + r_alias.o \ + r_bsp.o \ + r_draw.o \ + r_edge.o \ + r_efrag.o \ + r_light.o \ + r_main.o \ + r_misc.o \ + r_part.o \ + r_sky.o \ + r_sprite.o \ + r_surf.o \ + r_vars.o \ + sbar.o \ + screen.o \ + skin.o \ + snd_dma.o \ + snd_mem.o \ + snd_mix.o \ + view.o \ + wad.o \ + zone.o \ + cd_linux.o \ + sys_linux.o \ + vid_svgalib.o \ + snd_linux.o + +ASMOBJS= \ + d_copy.o \ + d_draw.o \ + d_draw16.o \ + d_parta.o \ + d_polysa.o \ + d_scana.o \ + d_spr8.o \ + d_varsa.o \ + math.o \ + r_aclipa.o \ + r_aliasa.o \ + r_drawa.o \ + r_edgea.o \ + r_varsa.o \ + snd_mixa.o \ + surf16.o \ + surf8.o \ + sys_dosa.o + +#CFLAGS=-O3 -Wall -fomit-frame-pointer -fno-strength-reduce -funroll-loops +#CFLAGS=-mpentium -O3 -Wall -fomit-frame-pointer -fno-strength-reduce +CFLAGS=-V2.7.2.1 -bi486-linux/ -O6 -Wall -fomit-frame-pointer -fno-strength-reduce +#CFLAGS=-V2.7.2.1 -bi486-linux/ -O2 -g -Wall + +LDFLAGS = + +LIBS = -lm -lvga +TARGET = qwcl + +%.o : %.s + $(CC) $(CFLAGS) -DELF -x assembler-with-cpp -c $< + +#$(TARGET) : $(OBJS) +# $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) + +$(TARGET) : $(ASMOBJS) $(OBJS) + $(CC) $(LDFLAGS) -o $(TARGET) $(ASMOBJS) $(OBJS) $(LIBS) + +clean: + -rm $(OBJS) + +clobber: clean + -rm $(TARGET) diff --git a/QW/client/math.asm b/QW/client/math.asm new file mode 100644 index 0000000..ec57505 --- /dev/null +++ b/QW/client/math.asm @@ -0,0 +1,495 @@ + .386P + .model FLAT + externdef _d_zistepu:dword + externdef _d_pzbuffer:dword + externdef _d_zistepv:dword + externdef _d_zrowbytes:dword + externdef _d_ziorigin:dword + externdef _r_turb_s:dword + externdef _r_turb_t:dword + externdef _r_turb_pdest:dword + externdef _r_turb_spancount:dword + externdef _r_turb_turb:dword + externdef _r_turb_pbase:dword + externdef _r_turb_sstep:dword + externdef _r_turb_tstep:dword + externdef _r_bmodelactive:dword + externdef _d_sdivzstepu:dword + externdef _d_tdivzstepu:dword + externdef _d_sdivzstepv:dword + externdef _d_tdivzstepv:dword + externdef _d_sdivzorigin:dword + externdef _d_tdivzorigin:dword + externdef _sadjust:dword + externdef _tadjust:dword + externdef _bbextents:dword + externdef _bbextentt:dword + externdef _cacheblock:dword + externdef _d_viewbuffer:dword + externdef _cachewidth:dword + externdef _d_pzbuffer:dword + externdef _d_zrowbytes:dword + externdef _d_zwidth:dword + externdef _d_scantable:dword + externdef _r_lightptr:dword + externdef _r_numvblocks:dword + externdef _prowdestbase:dword + externdef _pbasesource:dword + externdef _r_lightwidth:dword + externdef _lightright:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _lightdelta:dword + externdef _lightright:dword + externdef _lightdelta:dword + externdef _sourcetstep:dword + externdef _surfrowbytes:dword + externdef _lightrightstep:dword + externdef _lightdeltastep:dword + externdef _r_sourcemax:dword + externdef _r_stepback:dword + externdef _colormap:dword + externdef _blocksize:dword + externdef _sourcesstep:dword + externdef _lightleft:dword + externdef _blockdivshift:dword + externdef _blockdivmask:dword + externdef _lightleftstep:dword + externdef _r_origin:dword + externdef _r_ppn:dword + externdef _r_pup:dword + externdef _r_pright:dword + externdef _ycenter:dword + externdef _xcenter:dword + externdef _d_vrectbottom_particle:dword + externdef _d_vrectright_particle:dword + externdef _d_vrecty:dword + externdef _d_vrectx:dword + externdef _d_pix_shift:dword + externdef _d_pix_min:dword + externdef _d_pix_max:dword + externdef _d_y_aspect_shift:dword + externdef _screenwidth:dword + externdef _vright:dword + externdef _vup:dword + externdef _vpn:dword + externdef _BOPS_Error:dword + externdef _snd_scaletable:dword + externdef _paintbuffer:dword + externdef _snd_linear_count:dword + externdef _snd_p:dword + externdef _snd_vol:dword + externdef _snd_out:dword + externdef _r_leftclipped:dword + externdef _r_leftenter:dword + externdef _r_rightclipped:dword + externdef _r_rightenter:dword + externdef _modelorg:dword + externdef _xscale:dword + externdef _r_refdef:dword + externdef _yscale:dword + externdef _r_leftexit:dword + externdef _r_rightexit:dword + externdef _r_lastvertvalid:dword + externdef _cacheoffset:dword + externdef _newedges:dword + externdef _removeedges:dword + externdef _r_pedge:dword + externdef _r_framecount:dword + externdef _r_u1:dword + externdef _r_emitted:dword + externdef _edge_p:dword + externdef _surface_p:dword + externdef _surfaces:dword + externdef _r_lzi1:dword + externdef _r_v1:dword + externdef _r_ceilv1:dword + externdef _r_nearzi:dword + externdef _r_nearzionly:dword + externdef _edge_aftertail:dword + externdef _edge_tail:dword + externdef _current_iv:dword + externdef _edge_head_u_shift20:dword + externdef _span_p:dword + externdef _edge_head:dword + externdef _fv:dword + externdef _edge_tail_u_shift20:dword + externdef _r_apverts:dword + externdef _r_anumverts:dword + externdef _aliastransform:dword + externdef _r_avertexnormals:dword + externdef _r_plightvec:dword + externdef _r_ambientlight:dword + externdef _r_shadelight:dword + externdef _aliasxcenter:dword + externdef _aliasycenter:dword + externdef _a_sstepxfrac:dword + externdef _r_affinetridesc:dword + externdef _acolormap:dword + externdef _d_pcolormap:dword + externdef _r_affinetridesc:dword + externdef _d_sfrac:dword + externdef _d_ptex:dword + externdef _d_pedgespanpackage:dword + externdef _d_tfrac:dword + externdef _d_light:dword + externdef _d_zi:dword + externdef _d_pdest:dword + externdef _d_pz:dword + externdef _d_aspancount:dword + externdef _erroradjustup:dword + externdef _errorterm:dword + externdef _d_xdenom:dword + externdef _r_p0:dword + externdef _r_p1:dword + externdef _r_p2:dword + externdef _a_tstepxfrac:dword + externdef _r_sstepx:dword + externdef _r_tstepx:dword + externdef _a_ststepxwhole:dword + externdef _zspantable:dword + externdef _skintable:dword + externdef _r_zistepx:dword + externdef _erroradjustdown:dword + externdef _d_countextrastep:dword + externdef _ubasestep:dword + externdef _a_ststepxwhole:dword + externdef _a_tstepxfrac:dword + externdef _r_lstepx:dword + externdef _a_spans:dword + externdef _erroradjustdown:dword + externdef _d_pdestextrastep:dword + externdef _d_pzextrastep:dword + externdef _d_sfracextrastep:dword + externdef _d_ptexextrastep:dword + externdef _d_countextrastep:dword + externdef _d_tfracextrastep:dword + externdef _d_lightextrastep:dword + externdef _d_ziextrastep:dword + externdef _d_pdestbasestep:dword + externdef _d_pzbasestep:dword + externdef _d_sfracbasestep:dword + externdef _d_ptexbasestep:dword + externdef _ubasestep:dword + externdef _d_tfracbasestep:dword + externdef _d_lightbasestep:dword + externdef _d_zibasestep:dword + externdef _zspantable:dword + externdef _r_lstepy:dword + externdef _r_sstepy:dword + externdef _r_tstepy:dword + externdef _r_zistepy:dword + externdef _D_PolysetSetEdgeTable:dword + externdef _D_RasterizeAliasPolySmooth:dword + externdef float_point5:dword + externdef Float2ToThe31nd:dword + externdef izistep:dword + externdef izi:dword + externdef FloatMinus2ToThe31nd:dword + externdef float_1:dword + externdef float_particle_z_clip:dword + externdef float_minus_1:dword + externdef float_0:dword + externdef fp_16:dword + externdef fp_64k:dword + externdef fp_1m:dword + externdef fp_1m_minus_1:dword + externdef fp_8:dword + externdef entryvec_table:dword + externdef advancetable:dword + externdef sstep:dword + externdef tstep:dword + externdef pspantemp:dword + externdef counttemp:dword + externdef jumptemp:dword + externdef reciprocal_table:dword + externdef DP_Count:dword + externdef DP_u:dword + externdef DP_v:dword + externdef DP_32768:dword + externdef DP_Color:dword + externdef DP_Pix:dword + externdef DP_EntryTable:dword + externdef pbase:dword + externdef s:dword + externdef t:dword + externdef sfracf:dword + externdef tfracf:dword + externdef snext:dword + externdef tnext:dword + externdef spancountminus1:dword + externdef zi16stepu:dword + externdef sdivz16stepu:dword + externdef tdivz16stepu:dword + externdef zi8stepu:dword + externdef sdivz8stepu:dword + externdef tdivz8stepu:dword + externdef reciprocal_table_16:dword + externdef entryvec_table_16:dword + externdef ceil_cw:dword + externdef single_cw:dword + externdef fp_64kx64k:dword + externdef pz:dword + externdef spr8entryvec_table:dword +_DATA SEGMENT + align 4 +Ljmptab dd Lcase0, Lcase1, Lcase2, Lcase3 + dd Lcase4, Lcase5, Lcase6, Lcase7 +_DATA ENDS +_TEXT SEGMENT + public _Invert24To16 +_Invert24To16: + mov ecx,ds:dword ptr[4+esp] + mov edx,0100h + cmp ecx,edx + jle LOutOfRange + sub eax,eax + div ecx + ret +LOutOfRange: + mov eax,0FFFFFFFFh + ret + align 2 + public _TransformVector +_TransformVector: + mov eax,ds:dword ptr[4+esp] + mov edx,ds:dword ptr[8+esp] + fld ds:dword ptr[eax] + fmul ds:dword ptr[_vright] + fld ds:dword ptr[eax] + fmul ds:dword ptr[_vup] + fld ds:dword ptr[eax] + fmul ds:dword ptr[_vpn] + fld ds:dword ptr[4+eax] + fmul ds:dword ptr[_vright+4] + fld ds:dword ptr[4+eax] + fmul ds:dword ptr[_vup+4] + fld ds:dword ptr[4+eax] + fmul ds:dword ptr[_vpn+4] + fxch st(2) + faddp st(5),st(0) + faddp st(3),st(0) + faddp st(1),st(0) + fld ds:dword ptr[8+eax] + fmul ds:dword ptr[_vright+8] + fld ds:dword ptr[8+eax] + fmul ds:dword ptr[_vup+8] + fld ds:dword ptr[8+eax] + fmul ds:dword ptr[_vpn+8] + fxch st(2) + faddp st(5),st(0) + faddp st(3),st(0) + faddp st(1),st(0) + fstp ds:dword ptr[8+edx] + fstp ds:dword ptr[4+edx] + fstp ds:dword ptr[edx] + ret + align 2 + public _BoxOnPlaneSide +_BoxOnPlaneSide: + push ebx + mov edx,ds:dword ptr[4+12+esp] + mov ecx,ds:dword ptr[4+4+esp] + xor eax,eax + mov ebx,ds:dword ptr[4+8+esp] + mov al,ds:byte ptr[17+edx] + cmp al,8 + jge Lerror + fld ds:dword ptr[0+edx] + fld st(0) + jmp dword ptr[Ljmptab+eax*4] +Lcase0: + fmul ds:dword ptr[ebx] + fld ds:dword ptr[0+4+edx] + fxch st(2) + fmul ds:dword ptr[ecx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[4+ebx] + fld ds:dword ptr[0+8+edx] + fxch st(2) + fmul ds:dword ptr[4+ecx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[8+ebx] + fxch st(5) + faddp st(3),st(0) + fmul ds:dword ptr[8+ecx] + fxch st(1) + faddp st(3),st(0) + fxch st(3) + faddp st(2),st(0) + jmp LSetSides +Lcase1: + fmul ds:dword ptr[ecx] + fld ds:dword ptr[0+4+edx] + fxch st(2) + fmul ds:dword ptr[ebx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[4+ebx] + fld ds:dword ptr[0+8+edx] + fxch st(2) + fmul ds:dword ptr[4+ecx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[8+ebx] + fxch st(5) + faddp st(3),st(0) + fmul ds:dword ptr[8+ecx] + fxch st(1) + faddp st(3),st(0) + fxch st(3) + faddp st(2),st(0) + jmp LSetSides +Lcase2: + fmul ds:dword ptr[ebx] + fld ds:dword ptr[0+4+edx] + fxch st(2) + fmul ds:dword ptr[ecx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[4+ecx] + fld ds:dword ptr[0+8+edx] + fxch st(2) + fmul ds:dword ptr[4+ebx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[8+ebx] + fxch st(5) + faddp st(3),st(0) + fmul ds:dword ptr[8+ecx] + fxch st(1) + faddp st(3),st(0) + fxch st(3) + faddp st(2),st(0) + jmp LSetSides +Lcase3: + fmul ds:dword ptr[ecx] + fld ds:dword ptr[0+4+edx] + fxch st(2) + fmul ds:dword ptr[ebx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[4+ecx] + fld ds:dword ptr[0+8+edx] + fxch st(2) + fmul ds:dword ptr[4+ebx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[8+ebx] + fxch st(5) + faddp st(3),st(0) + fmul ds:dword ptr[8+ecx] + fxch st(1) + faddp st(3),st(0) + fxch st(3) + faddp st(2),st(0) + jmp LSetSides +Lcase4: + fmul ds:dword ptr[ebx] + fld ds:dword ptr[0+4+edx] + fxch st(2) + fmul ds:dword ptr[ecx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[4+ebx] + fld ds:dword ptr[0+8+edx] + fxch st(2) + fmul ds:dword ptr[4+ecx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[8+ecx] + fxch st(5) + faddp st(3),st(0) + fmul ds:dword ptr[8+ebx] + fxch st(1) + faddp st(3),st(0) + fxch st(3) + faddp st(2),st(0) + jmp LSetSides +Lcase5: + fmul ds:dword ptr[ecx] + fld ds:dword ptr[0+4+edx] + fxch st(2) + fmul ds:dword ptr[ebx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[4+ebx] + fld ds:dword ptr[0+8+edx] + fxch st(2) + fmul ds:dword ptr[4+ecx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[8+ecx] + fxch st(5) + faddp st(3),st(0) + fmul ds:dword ptr[8+ebx] + fxch st(1) + faddp st(3),st(0) + fxch st(3) + faddp st(2),st(0) + jmp LSetSides +Lcase6: + fmul ds:dword ptr[ebx] + fld ds:dword ptr[0+4+edx] + fxch st(2) + fmul ds:dword ptr[ecx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[4+ecx] + fld ds:dword ptr[0+8+edx] + fxch st(2) + fmul ds:dword ptr[4+ebx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[8+ecx] + fxch st(5) + faddp st(3),st(0) + fmul ds:dword ptr[8+ebx] + fxch st(1) + faddp st(3),st(0) + fxch st(3) + faddp st(2),st(0) + jmp LSetSides +Lcase7: + fmul ds:dword ptr[ecx] + fld ds:dword ptr[0+4+edx] + fxch st(2) + fmul ds:dword ptr[ebx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[4+ecx] + fld ds:dword ptr[0+8+edx] + fxch st(2) + fmul ds:dword ptr[4+ebx] + fxch st(2) + fld st(0) + fmul ds:dword ptr[8+ecx] + fxch st(5) + faddp st(3),st(0) + fmul ds:dword ptr[8+ebx] + fxch st(1) + faddp st(3),st(0) + fxch st(3) + faddp st(2),st(0) +LSetSides: + faddp st(2),st(0) + fcomp ds:dword ptr[12+edx] + xor ecx,ecx + fnstsw ax + fcomp ds:dword ptr[12+edx] + and ah,1 + xor ah,1 + add cl,ah + fnstsw ax + and ah,1 + add ah,ah + add cl,ah + pop ebx + mov eax,ecx + ret +Lerror: + call near ptr _BOPS_Error +_TEXT ENDS + END diff --git a/QW/client/math.s b/QW/client/math.s new file mode 100644 index 0000000..ed82dfd --- /dev/null +++ b/QW/client/math.s @@ -0,0 +1,417 @@ +/* +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. + +*/ +// +// math.s +// x86 assembly-language math routines. + +#include "asm_i386.h" +#include "quakeasm.h" + + +#if id386 + + .data + + .align 4 +Ljmptab: .long Lcase0, Lcase1, Lcase2, Lcase3 + .long Lcase4, Lcase5, Lcase6, Lcase7 + + .text + +// TODO: rounding needed? +// stack parameter offset +#define val 4 + +.globl C(Invert24To16) +C(Invert24To16): + + movl val(%esp),%ecx + movl $0x100,%edx // 0x10000000000 as dividend + cmpl %edx,%ecx + jle LOutOfRange + + subl %eax,%eax + divl %ecx + + ret + +LOutOfRange: + movl $0xFFFFFFFF,%eax + 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 + + +#define EMINS 4+4 +#define EMAXS 4+8 +#define P 4+12 + + .align 2 +.globl C(BoxOnPlaneSide) +C(BoxOnPlaneSide): + pushl %ebx + + movl P(%esp),%edx + movl EMINS(%esp),%ecx + xorl %eax,%eax + movl EMAXS(%esp),%ebx + movb pl_signbits(%edx),%al + cmpb $8,%al + jge Lerror + flds pl_normal(%edx) // p->normal[0] + fld %st(0) // p->normal[0] | p->normal[0] + jmp Ljmptab(,%eax,4) + + +//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +//dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +Lcase0: + fmuls (%ebx) // p->normal[0]*emaxs[0] | p->normal[0] + flds pl_normal+4(%edx) // p->normal[1] | p->normal[0]*emaxs[0] | + // p->normal[0] + fxch %st(2) // p->normal[0] | p->normal[0]*emaxs[0] | + // p->normal[1] + fmuls (%ecx) // p->normal[0]*emins[0] | + // p->normal[0]*emaxs[0] | p->normal[1] + fxch %st(2) // p->normal[1] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fld %st(0) // p->normal[1] | p->normal[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fmuls 4(%ebx) // p->normal[1]*emaxs[1] | p->normal[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + flds pl_normal+8(%edx) // p->normal[2] | p->normal[1]*emaxs[1] | + // p->normal[1] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fxch %st(2) // p->normal[1] | p->normal[1]*emaxs[1] | + // p->normal[2] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fmuls 4(%ecx) // p->normal[1]*emins[1] | + // p->normal[1]*emaxs[1] | + // p->normal[2] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fxch %st(2) // p->normal[2] | p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fld %st(0) // p->normal[2] | p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fmuls 8(%ebx) // p->normal[2]*emaxs[2] | + // p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fxch %st(5) // p->normal[0]*emins[0] | + // p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + faddp %st(0),%st(3) //p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + fmuls 8(%ecx) //p->normal[2]*emins[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + fxch %st(1) //p->normal[1]*emaxs[1] | + // p->normal[2]*emins[2] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + faddp %st(0),%st(3) //p->normal[2]*emins[2] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]| + // p->normal[2]*emaxs[2] + fxch %st(3) //p->normal[2]*emaxs[2] + + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]| + // p->normal[2]*emins[2] + faddp %st(0),%st(2) //p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // dist1 | p->normal[2]*emins[2] + + jmp LSetSides + +//dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +Lcase1: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ebx) // emaxs[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ecx) // emins[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ebx) // emaxs[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ecx) // emins[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +//dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +Lcase2: + fmuls (%ebx) // emaxs[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ecx) // emins[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ebx) // emaxs[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ecx) // emins[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +Lcase3: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ebx) // emaxs[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ecx) // emins[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +//dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +Lcase4: + fmuls (%ebx) // emaxs[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ecx) // emins[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ebx) // emaxs[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ecx) // emins[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +Lcase5: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ebx) // emaxs[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ecx) // emins[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +//dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +Lcase6: + fmuls (%ebx) // emaxs[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ecx) // emins[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +Lcase7: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + +LSetSides: + +// sides = 0; +// if (dist1 >= p->dist) +// sides = 1; +// if (dist2 < p->dist) +// sides |= 2; + + faddp %st(0),%st(2) // dist1 | dist2 + fcomps pl_dist(%edx) + xorl %ecx,%ecx + fnstsw %ax + fcomps pl_dist(%edx) + andb $1,%ah + xorb $1,%ah + addb %ah,%cl + + fnstsw %ax + andb $1,%ah + addb %ah,%ah + addb %ah,%cl + +// return sides; + + popl %ebx + movl %ecx,%eax // return status + + ret + + +Lerror: + call C(BOPS_Error) + +#endif // id386 diff --git a/QW/client/mathlib.c b/QW/client/mathlib.c new file mode 100644 index 0000000..cebdaf5 --- /dev/null +++ b/QW/client/mathlib.c @@ -0,0 +1,583 @@ +/* +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. + +*/ +// mathlib.c -- math primitives + +#include <math.h> +#include "quakedef.h" + +void Sys_Error (char *error, ...); + +vec3_t vec3_origin = {0,0,0}; +int nanmask = 255<<23; + +/*-----------------------------------------------------------------*/ + +#define DEG2RAD( a ) ( a * M_PI ) / 180.0F + +void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ) +{ + float d; + vec3_t n; + float inv_denom; + + inv_denom = 1.0F / DotProduct( normal, normal ); + + d = DotProduct( normal, p ) * inv_denom; + + n[0] = normal[0] * inv_denom; + n[1] = normal[1] * inv_denom; + n[2] = normal[2] * inv_denom; + + dst[0] = p[0] - d * n[0]; + dst[1] = p[1] - d * n[1]; + dst[2] = p[2] - d * n[2]; +} + +/* +** assumes "src" is normalized +*/ +void PerpendicularVector( vec3_t dst, const vec3_t src ) +{ + int pos; + int i; + float minelem = 1.0F; + vec3_t tempvec; + + /* + ** find the smallest magnitude axially aligned vector + */ + for ( pos = 0, i = 0; i < 3; i++ ) + { + if ( fabs( src[i] ) < minelem ) + { + pos = i; + minelem = fabs( src[i] ); + } + } + tempvec[0] = tempvec[1] = tempvec[2] = 0.0F; + tempvec[pos] = 1.0F; + + /* + ** project the point onto the plane defined by src + */ + ProjectPointOnPlane( dst, tempvec, src ); + + /* + ** normalize the result + */ + VectorNormalize( dst ); +} + +#ifdef _WIN32 +#pragma optimize( "", off ) +#endif + + +void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ) +{ + float m[3][3]; + float im[3][3]; + float zrot[3][3]; + float tmpmat[3][3]; + float rot[3][3]; + int i; + vec3_t vr, vup, vf; + + vf[0] = dir[0]; + vf[1] = dir[1]; + vf[2] = dir[2]; + + PerpendicularVector( vr, dir ); + CrossProduct( vr, vf, vup ); + + m[0][0] = vr[0]; + m[1][0] = vr[1]; + m[2][0] = vr[2]; + + m[0][1] = vup[0]; + m[1][1] = vup[1]; + m[2][1] = vup[2]; + + m[0][2] = vf[0]; + m[1][2] = vf[1]; + m[2][2] = vf[2]; + + memcpy( im, m, sizeof( im ) ); + + im[0][1] = m[1][0]; + im[0][2] = m[2][0]; + im[1][0] = m[0][1]; + im[1][2] = m[2][1]; + im[2][0] = m[0][2]; + im[2][1] = m[1][2]; + + memset( zrot, 0, sizeof( zrot ) ); + zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F; + + zrot[0][0] = cos( DEG2RAD( degrees ) ); + zrot[0][1] = sin( DEG2RAD( degrees ) ); + zrot[1][0] = -sin( DEG2RAD( degrees ) ); + zrot[1][1] = cos( DEG2RAD( degrees ) ); + + R_ConcatRotations( m, zrot, tmpmat ); + R_ConcatRotations( tmpmat, im, rot ); + + for ( i = 0; i < 3; i++ ) + { + dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2]; + } +} + +#ifdef _WIN32 +#pragma optimize( "", on ) +#endif + +/*-----------------------------------------------------------------*/ + +float anglemod(float a) +{ +#if 0 + if (a >= 0) + a -= 360*(int)(a/360); + else + a += 360*( 1 + (int)(-a/360) ); +#endif + a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535); + return a; +} + +/* +================== +BOPS_Error + +Split out like this for ASM to call. +================== +*/ +void BOPS_Error (void) +{ + Sys_Error ("BoxOnPlaneSide: Bad signbits"); +} + +#if !id386 + +/* +================== +BoxOnPlaneSide + +Returns 1, 2, or 1 + 2 +================== +*/ +int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, mplane_t *p) +{ + float dist1, dist2; + int sides; + +#if 0 // this is done by the BOX_ON_PLANE_SIDE macro before calling this + // function +// fast axial cases + if (p->type < 3) + { + if (p->dist <= emins[p->type]) + return 1; + if (p->dist >= emaxs[p->type]) + return 2; + return 3; + } +#endif + +// general case + switch (p->signbits) + { + case 0: +dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + break; + case 1: +dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; +dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + break; + case 2: +dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + break; + case 3: +dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; +dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + break; + case 4: +dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + break; + case 5: +dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; +dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + break; + case 6: +dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + break; + case 7: +dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; +dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + break; + default: + dist1 = dist2 = 0; // shut up compiler + BOPS_Error (); + break; + } + +#if 0 + int i; + vec3_t corners[2]; + + for (i=0 ; i<3 ; i++) + { + if (plane->normal[i] < 0) + { + corners[0][i] = emins[i]; + corners[1][i] = emaxs[i]; + } + else + { + corners[1][i] = emins[i]; + corners[0][i] = emaxs[i]; + } + } + dist = DotProduct (plane->normal, corners[0]) - plane->dist; + dist2 = DotProduct (plane->normal, corners[1]) - plane->dist; + sides = 0; + if (dist1 >= 0) + sides = 1; + if (dist2 < 0) + sides |= 2; + +#endif + + sides = 0; + if (dist1 >= p->dist) + sides = 1; + if (dist2 < p->dist) + sides |= 2; + +#ifdef PARANOID +if (sides == 0) + Sys_Error ("BoxOnPlaneSide: sides==0"); +#endif + + return sides; +} + +#endif + + +void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) +{ + float angle; + float sr, sp, sy, cr, cp, cy; + + angle = angles[YAW] * (M_PI*2 / 360); + sy = sin(angle); + cy = cos(angle); + angle = angles[PITCH] * (M_PI*2 / 360); + sp = sin(angle); + cp = cos(angle); + angle = angles[ROLL] * (M_PI*2 / 360); + sr = sin(angle); + cr = cos(angle); + + forward[0] = cp*cy; + forward[1] = cp*sy; + forward[2] = -sp; + right[0] = (-1*sr*sp*cy+-1*cr*-sy); + right[1] = (-1*sr*sp*sy+-1*cr*cy); + right[2] = -1*sr*cp; + up[0] = (cr*sp*cy+-sr*-sy); + up[1] = (cr*sp*sy+-sr*cy); + up[2] = cr*cp; +} + +int VectorCompare (vec3_t v1, vec3_t v2) +{ + int i; + + for (i=0 ; i<3 ; i++) + if (v1[i] != v2[i]) + return 0; + + return 1; +} + +void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc) +{ + vecc[0] = veca[0] + scale*vecb[0]; + vecc[1] = veca[1] + scale*vecb[1]; + vecc[2] = veca[2] + scale*vecb[2]; +} + + +vec_t _DotProduct (vec3_t v1, vec3_t v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out) +{ + out[0] = veca[0]-vecb[0]; + out[1] = veca[1]-vecb[1]; + out[2] = veca[2]-vecb[2]; +} + +void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out) +{ + out[0] = veca[0]+vecb[0]; + out[1] = veca[1]+vecb[1]; + out[2] = veca[2]+vecb[2]; +} + +void _VectorCopy (vec3_t in, vec3_t out) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; +} + +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) +{ + cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} + +double sqrt(double x); + +vec_t Length(vec3_t v) +{ + int i; + float length; + + length = 0; + for (i=0 ; i< 3 ; i++) + length += v[i]*v[i]; + length = sqrt (length); // FIXME + + return length; +} + +float VectorNormalize (vec3_t v) +{ + float length, ilength; + + length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; + length = sqrt (length); // FIXME + + if (length) + { + ilength = 1/length; + v[0] *= ilength; + v[1] *= ilength; + v[2] *= ilength; + } + + return length; + +} + +void VectorInverse (vec3_t v) +{ + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; +} + +void VectorScale (vec3_t in, vec_t scale, vec3_t out) +{ + out[0] = in[0]*scale; + out[1] = in[1]*scale; + out[2] = in[2]*scale; +} + + +int Q_log2(int val) +{ + int answer=0; + while ((val>>=1) != 0) + answer++; + return answer; +} + + +/* +================ +R_ConcatRotations +================ +*/ +void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]) +{ + out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + + in1[0][2] * in2[2][0]; + out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + + in1[0][2] * in2[2][1]; + out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + + in1[0][2] * in2[2][2]; + out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + + in1[1][2] * in2[2][0]; + out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + + in1[1][2] * in2[2][1]; + out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + + in1[1][2] * in2[2][2]; + out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + + in1[2][2] * in2[2][0]; + out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + + in1[2][2] * in2[2][1]; + out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + + in1[2][2] * in2[2][2]; +} + + +/* +================ +R_ConcatTransforms +================ +*/ +void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]) +{ + out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + + in1[0][2] * in2[2][0]; + out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + + in1[0][2] * in2[2][1]; + out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + + in1[0][2] * in2[2][2]; + out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + + in1[0][2] * in2[2][3] + in1[0][3]; + out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + + in1[1][2] * in2[2][0]; + out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + + in1[1][2] * in2[2][1]; + out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + + in1[1][2] * in2[2][2]; + out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + + in1[1][2] * in2[2][3] + in1[1][3]; + out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + + in1[2][2] * in2[2][0]; + out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + + in1[2][2] * in2[2][1]; + out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + + in1[2][2] * in2[2][2]; + out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + + in1[2][2] * in2[2][3] + in1[2][3]; +} + + +/* +=================== +FloorDivMod + +Returns mathematically correct (floor-based) quotient and remainder for +numer and denom, both of which should contain no fractional part. The +quotient must fit in 32 bits. +==================== +*/ + +void FloorDivMod (double numer, double denom, int *quotient, + int *rem) +{ + int q, r; + double x; + +#ifndef PARANOID + if (denom <= 0.0) + Sys_Error ("FloorDivMod: bad denominator %d\n", denom); + +// if ((floor(numer) != numer) || (floor(denom) != denom)) +// Sys_Error ("FloorDivMod: non-integer numer or denom %f %f\n", +// numer, denom); +#endif + + if (numer >= 0.0) + { + + x = floor(numer / denom); + q = (int)x; + r = (int)floor(numer - (x * denom)); + } + else + { + // + // perform operations with positive values, and fix mod to make floor-based + // + x = floor(-numer / denom); + q = -(int)x; + r = (int)floor(-numer - (x * denom)); + if (r != 0) + { + q--; + r = (int)denom - r; + } + } + + *quotient = q; + *rem = r; +} + + +/* +=================== +GreatestCommonDivisor +==================== +*/ +int GreatestCommonDivisor (int i1, int i2) +{ + if (i1 > i2) + { + if (i2 == 0) + return (i1); + return GreatestCommonDivisor (i2, i1 % i2); + } + else + { + if (i1 == 0) + return (i2); + return GreatestCommonDivisor (i1, i2 % i1); + } +} + + +#if !id386 + +// TODO: move to nonintel.c + +/* +=================== +Invert24To16 + +Inverts an 8.24 value to a 16.16 value +==================== +*/ + +fixed16_t Invert24To16(fixed16_t val) +{ + if (val < 256) + return (0xFFFFFFFF); + + return (fixed16_t) + (((double)0x10000 * (double)0x1000000 / (double)val) + 0.5); +} + +#endif diff --git a/QW/client/mathlib.h b/QW/client/mathlib.h new file mode 100644 index 0000000..b1cfdd1 --- /dev/null +++ b/QW/client/mathlib.h @@ -0,0 +1,91 @@ +/* +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. + +*/ +// mathlib.h + +typedef float vec_t; +typedef vec_t vec3_t[3]; +typedef vec_t vec5_t[5]; + +typedef int fixed4_t; +typedef int fixed8_t; +typedef int fixed16_t; + +#ifndef M_PI +#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h +#endif + +struct mplane_s; + +extern vec3_t vec3_origin; +extern int nanmask; + +#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) + +#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2]) +#define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];} +#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];} +#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];} + +void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc); + +vec_t _DotProduct (vec3_t v1, vec3_t v2); +void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out); +void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out); +void _VectorCopy (vec3_t in, vec3_t out); + +int VectorCompare (vec3_t v1, vec3_t v2); +vec_t Length (vec3_t v); +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross); +float VectorNormalize (vec3_t v); // returns vector length +void VectorInverse (vec3_t v); +void VectorScale (vec3_t in, vec_t scale, vec3_t out); +int Q_log2(int val); + +void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]); +void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]); + +void FloorDivMod (double numer, double denom, int *quotient, + int *rem); +fixed16_t Invert24To16(fixed16_t val); +fixed16_t Mul16_30(fixed16_t multiplier, fixed16_t multiplicand); +int GreatestCommonDivisor (int i1, int i2); + +void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); +int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane); +float anglemod(float a); + +void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ); + + +#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \ + (((p)->type < 3)? \ + ( \ + ((p)->dist <= (emins)[(p)->type])? \ + 1 \ + : \ + ( \ + ((p)->dist >= (emaxs)[(p)->type])?\ + 2 \ + : \ + 3 \ + ) \ + ) \ + : \ + BoxOnPlaneSide( (emins), (emaxs), (p))) diff --git a/QW/client/md4.c b/QW/client/md4.c new file mode 100644 index 0000000..7932d4a --- /dev/null +++ b/QW/client/md4.c @@ -0,0 +1,306 @@ +/* +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. + +*/ +/* GLOBAL.H - RSAREF types and constants */ + +#include <string.h> + +/* POINTER defines a generic pointer type */ +typedef unsigned char *POINTER; + +/* UINT2 defines a two byte word */ +typedef unsigned short int UINT2; + +/* UINT4 defines a four byte word */ +#ifdef __alpha__ +typedef unsigned int UINT4; +#else +typedef unsigned long int UINT4; +#endif + + +/* MD4.H - header file for MD4C.C */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. + +All rights reserved. + +License to copy and use this software is granted provided that it is identified as the “RSA Data Security, Inc. MD4 Message-Digest Algorithm” in all material mentioning or referencing this software or this function. +License is also granted to make and use derivative works provided that such works are identified as “derived from the RSA Data Security, Inc. MD4 Message-Digest Algorithm” in all material mentioning or referencing the derived work. +RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided “as is” without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this documentation and/or software. */ + +/* MD4 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD4_CTX; + +void MD4Init (MD4_CTX *); +void MD4Update (MD4_CTX *, unsigned char *, unsigned int); +void MD4Final (unsigned char [16], MD4_CTX *); + + + +/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm */ +/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved. + +License to copy and use this software is granted provided that it is identified as the +RSA Data Security, Inc. MD4 Message-Digest Algorithm + in all material mentioning or referencing this software or this function. +License is also granted to make and use derivative works provided that such works are identified as +derived from the RSA Data Security, Inc. MD4 Message-Digest Algorithm +in all material mentioning or referencing the derived work. +RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided +as is without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this documentation and/or software. */ + +/* Constants for MD4Transform routine. */ +#define S11 3 +#define S12 7 +#define S13 11 +#define S14 19 +#define S21 3 +#define S22 5 +#define S23 9 +#define S24 13 +#define S31 3 +#define S32 9 +#define S33 11 +#define S34 15 + +static void MD4Transform (UINT4 [4], unsigned char [64]); +static void Encode (unsigned char *, UINT4 *, unsigned int); +static void Decode (UINT4 *, unsigned char *, unsigned int); + +static unsigned char PADDING[64] = { +0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G and H are basic MD4 functions. */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* ROTATE_LEFT rotates x left n bits. */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s) {(a) += F ((b), (c), (d)) + (x); (a) = ROTATE_LEFT ((a), (s));} + +#define GG(a, b, c, d, x, s) {(a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; (a) = ROTATE_LEFT ((a), (s));} + +#define HH(a, b, c, d, x, s) {(a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; (a) = ROTATE_LEFT ((a), (s));} + + +/* MD4 initialization. Begins an MD4 operation, writing a new context. */ +void MD4Init (MD4_CTX *context) +{ + context->count[0] = context->count[1] = 0; + +/* Load magic initialization constants.*/ +context->state[0] = 0x67452301; +context->state[1] = 0xefcdab89; +context->state[2] = 0x98badcfe; +context->state[3] = 0x10325476; +} + +/* MD4 block update operation. Continues an MD4 message-digest operation, processing another message block, and updating the context. */ +void MD4Update (MD4_CTX *context, unsigned char *input, unsigned int inputLen) +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3))< ((UINT4)inputLen << 3)) + context->count[1]++; + + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible.*/ + if (inputLen >= partLen) + { + memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); + MD4Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD4Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); +} + + +/* MD4 finalization. Ends an MD4 message-digest operation, writing the the message digest and zeroizing the context. */ +void MD4Final (unsigned char digest[16], MD4_CTX *context) +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64.*/ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD4Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD4Update (context, bits, 8); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information.*/ + memset ((POINTER)context, 0, sizeof (*context)); +} + + +/* MD4 basic transformation. Transforms state based on block. */ +static void MD4Transform (UINT4 state[4], unsigned char block[64]) +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + +/* Round 1 */ +FF (a, b, c, d, x[ 0], S11); /* 1 */ +FF (d, a, b, c, x[ 1], S12); /* 2 */ +FF (c, d, a, b, x[ 2], S13); /* 3 */ +FF (b, c, d, a, x[ 3], S14); /* 4 */ +FF (a, b, c, d, x[ 4], S11); /* 5 */ +FF (d, a, b, c, x[ 5], S12); /* 6 */ +FF (c, d, a, b, x[ 6], S13); /* 7 */ +FF (b, c, d, a, x[ 7], S14); /* 8 */ +FF (a, b, c, d, x[ 8], S11); /* 9 */ +FF (d, a, b, c, x[ 9], S12); /* 10 */ +FF (c, d, a, b, x[10], S13); /* 11 */ +FF (b, c, d, a, x[11], S14); /* 12 */ +FF (a, b, c, d, x[12], S11); /* 13 */ +FF (d, a, b, c, x[13], S12); /* 14 */ +FF (c, d, a, b, x[14], S13); /* 15 */ +FF (b, c, d, a, x[15], S14); /* 16 */ + +/* Round 2 */ +GG (a, b, c, d, x[ 0], S21); /* 17 */ +GG (d, a, b, c, x[ 4], S22); /* 18 */ +GG (c, d, a, b, x[ 8], S23); /* 19 */ +GG (b, c, d, a, x[12], S24); /* 20 */ +GG (a, b, c, d, x[ 1], S21); /* 21 */ +GG (d, a, b, c, x[ 5], S22); /* 22 */ +GG (c, d, a, b, x[ 9], S23); /* 23 */ +GG (b, c, d, a, x[13], S24); /* 24 */ +GG (a, b, c, d, x[ 2], S21); /* 25 */ +GG (d, a, b, c, x[ 6], S22); /* 26 */ +GG (c, d, a, b, x[10], S23); /* 27 */ +GG (b, c, d, a, x[14], S24); /* 28 */ +GG (a, b, c, d, x[ 3], S21); /* 29 */ +GG (d, a, b, c, x[ 7], S22); /* 30 */ +GG (c, d, a, b, x[11], S23); /* 31 */ +GG (b, c, d, a, x[15], S24); /* 32 */ + +/* Round 3 */ +HH (a, b, c, d, x[ 0], S31); /* 33 */ +HH (d, a, b, c, x[ 8], S32); /* 34 */ +HH (c, d, a, b, x[ 4], S33); /* 35 */ +HH (b, c, d, a, x[12], S34); /* 36 */ +HH (a, b, c, d, x[ 2], S31); /* 37 */ +HH (d, a, b, c, x[10], S32); /* 38 */ +HH (c, d, a, b, x[ 6], S33); /* 39 */ +HH (b, c, d, a, x[14], S34); /* 40 */ +HH (a, b, c, d, x[ 1], S31); /* 41 */ +HH (d, a, b, c, x[ 9], S32); /* 42 */ +HH (c, d, a, b, x[ 5], S33); /* 43 */ +HH (b, c, d, a, x[13], S34); /* 44 */ +HH (a, b, c, d, x[ 3], S31); /* 45 */ +HH (d, a, b, c, x[11], S32); /* 46 */ +HH (c, d, a, b, x[ 7], S33); /* 47 */ +HH (b, c, d, a, x[15], S34); /* 48 */ + +state[0] += a; +state[1] += b; +state[2] += c; +state[3] += d; + + /* Zeroize sensitive information.*/ + memset ((POINTER)x, 0, sizeof (x)); +} + + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */ +static void Encode (unsigned char *output, UINT4 *input, unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */ +static void Decode (UINT4 *output, unsigned char *input, unsigned int len) +{ +unsigned int i, j; + +for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); +} + +//=================================================================== + +unsigned Com_BlockChecksum (void *buffer, int length) +{ + int digest[4]; + unsigned val; + MD4_CTX ctx; + + MD4Init (&ctx); + MD4Update (&ctx, (unsigned char *)buffer, length); + MD4Final ( (unsigned char *)digest, &ctx); + + val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3]; + + return val; +} + +void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf) +{ + MD4_CTX ctx; + + MD4Init (&ctx); + MD4Update (&ctx, (unsigned char *)buffer, len); + MD4Final ( outbuf, &ctx); +} diff --git a/QW/client/menu.c b/QW/client/menu.c new file mode 100644 index 0000000..a356a19 --- /dev/null +++ b/QW/client/menu.c @@ -0,0 +1,1326 @@ +/* +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. + +*/ +#include "quakedef.h" +#include "winquake.h" + +void (*vid_menudrawfn)(void); +void (*vid_menukeyfn)(int key); + +enum {m_none, m_main, m_singleplayer, m_load, m_save, m_multiplayer, m_setup, m_net, m_options, m_video, m_keys, m_help, m_quit, m_serialconfig, m_modemconfig, m_lanconfig, m_gameoptions, m_search, m_slist} m_state; + +void M_Menu_Main_f (void); + void M_Menu_SinglePlayer_f (void); + void M_Menu_Load_f (void); + void M_Menu_Save_f (void); + void M_Menu_MultiPlayer_f (void); + void M_Menu_Setup_f (void); + void M_Menu_Net_f (void); + void M_Menu_Options_f (void); + void M_Menu_Keys_f (void); + void M_Menu_Video_f (void); + void M_Menu_Help_f (void); + void M_Menu_Quit_f (void); +void M_Menu_SerialConfig_f (void); + void M_Menu_ModemConfig_f (void); +void M_Menu_LanConfig_f (void); +void M_Menu_GameOptions_f (void); +void M_Menu_Search_f (void); +void M_Menu_ServerList_f (void); + +void M_Main_Draw (void); + void M_SinglePlayer_Draw (void); + void M_Load_Draw (void); + void M_Save_Draw (void); + void M_MultiPlayer_Draw (void); + void M_Setup_Draw (void); + void M_Net_Draw (void); + void M_Options_Draw (void); + void M_Keys_Draw (void); + void M_Video_Draw (void); + void M_Help_Draw (void); + void M_Quit_Draw (void); +void M_SerialConfig_Draw (void); + void M_ModemConfig_Draw (void); +void M_LanConfig_Draw (void); +void M_GameOptions_Draw (void); +void M_Search_Draw (void); +void M_ServerList_Draw (void); + +void M_Main_Key (int key); + void M_SinglePlayer_Key (int key); + void M_Load_Key (int key); + void M_Save_Key (int key); + void M_MultiPlayer_Key (int key); + void M_Setup_Key (int key); + void M_Net_Key (int key); + void M_Options_Key (int key); + void M_Keys_Key (int key); + void M_Video_Key (int key); + void M_Help_Key (int key); + void M_Quit_Key (int key); +void M_SerialConfig_Key (int key); + void M_ModemConfig_Key (int key); +void M_LanConfig_Key (int key); +void M_GameOptions_Key (int key); +void M_Search_Key (int key); +void M_ServerList_Key (int key); + +qboolean m_entersound; // play after drawing a frame, so caching + // won't disrupt the sound +qboolean m_recursiveDraw; + +int m_return_state; +qboolean m_return_onerror; +char m_return_reason [32]; + +#define StartingGame (m_multiplayer_cursor == 1) +#define JoiningGame (m_multiplayer_cursor == 0) +#define SerialConfig (m_net_cursor == 0) +#define DirectConfig (m_net_cursor == 1) +#define IPXConfig (m_net_cursor == 2) +#define TCPIPConfig (m_net_cursor == 3) + +void M_ConfigureNetSubsystem(void); + +//============================================================================= +/* Support Routines */ + +/* +================ +M_DrawCharacter + +Draws one solid graphics character +================ +*/ +void M_DrawCharacter (int cx, int line, int num) +{ + Draw_Character ( cx + ((vid.width - 320)>>1), line, num); +} + +void M_Print (int cx, int cy, char *str) +{ + while (*str) + { + M_DrawCharacter (cx, cy, (*str)+128); + str++; + cx += 8; + } +} + +void M_PrintWhite (int cx, int cy, char *str) +{ + while (*str) + { + M_DrawCharacter (cx, cy, *str); + str++; + cx += 8; + } +} + +void M_DrawTransPic (int x, int y, qpic_t *pic) +{ + Draw_TransPic (x + ((vid.width - 320)>>1), y, pic); +} + +void M_DrawPic (int x, int y, qpic_t *pic) +{ + Draw_Pic (x + ((vid.width - 320)>>1), y, pic); +} + +byte identityTable[256]; +byte translationTable[256]; + +void M_BuildTranslationTable(int top, int bottom) +{ + int j; + byte *dest, *source; + + for (j = 0; j < 256; j++) + identityTable[j] = j; + dest = translationTable; + source = identityTable; + memcpy (dest, source, 256); + + if (top < 128) // the artists made some backwards ranges. sigh. + memcpy (dest + TOP_RANGE, source + top, 16); + else + for (j=0 ; j<16 ; j++) + dest[TOP_RANGE+j] = source[top+15-j]; + + if (bottom < 128) + memcpy (dest + BOTTOM_RANGE, source + bottom, 16); + else + for (j=0 ; j<16 ; j++) + dest[BOTTOM_RANGE+j] = source[bottom+15-j]; +} + + +void M_DrawTransPicTranslate (int x, int y, qpic_t *pic) +{ + Draw_TransPicTranslate (x + ((vid.width - 320)>>1), y, pic, translationTable); +} + + +void M_DrawTextBox (int x, int y, int width, int lines) +{ + qpic_t *p; + int cx, cy; + int n; + + // draw left side + cx = x; + cy = y; + p = Draw_CachePic ("gfx/box_tl.lmp"); + M_DrawTransPic (cx, cy, p); + p = Draw_CachePic ("gfx/box_ml.lmp"); + for (n = 0; n < lines; n++) + { + cy += 8; + M_DrawTransPic (cx, cy, p); + } + p = Draw_CachePic ("gfx/box_bl.lmp"); + M_DrawTransPic (cx, cy+8, p); + + // draw middle + cx += 8; + while (width > 0) + { + cy = y; + p = Draw_CachePic ("gfx/box_tm.lmp"); + M_DrawTransPic (cx, cy, p); + p = Draw_CachePic ("gfx/box_mm.lmp"); + for (n = 0; n < lines; n++) + { + cy += 8; + if (n == 1) + p = Draw_CachePic ("gfx/box_mm2.lmp"); + M_DrawTransPic (cx, cy, p); + } + p = Draw_CachePic ("gfx/box_bm.lmp"); + M_DrawTransPic (cx, cy+8, p); + width -= 2; + cx += 16; + } + + // draw right side + cy = y; + p = Draw_CachePic ("gfx/box_tr.lmp"); + M_DrawTransPic (cx, cy, p); + p = Draw_CachePic ("gfx/box_mr.lmp"); + for (n = 0; n < lines; n++) + { + cy += 8; + M_DrawTransPic (cx, cy, p); + } + p = Draw_CachePic ("gfx/box_br.lmp"); + M_DrawTransPic (cx, cy+8, p); +} + +//============================================================================= + +int m_save_demonum; + +/* +================ +M_ToggleMenu_f +================ +*/ +void M_ToggleMenu_f (void) +{ + m_entersound = true; + + if (key_dest == key_menu) + { + if (m_state != m_main) + { + M_Menu_Main_f (); + return; + } + key_dest = key_game; + m_state = m_none; + return; + } + if (key_dest == key_console) + { + Con_ToggleConsole_f (); + } + else + { + M_Menu_Main_f (); + } +} + + +//============================================================================= +/* MAIN MENU */ + +int m_main_cursor; +#define MAIN_ITEMS 5 + + +void M_Menu_Main_f (void) +{ + if (key_dest != key_menu) + { + m_save_demonum = cls.demonum; + cls.demonum = -1; + } + key_dest = key_menu; + m_state = m_main; + m_entersound = true; +} + + +void M_Main_Draw (void) +{ + int f; + qpic_t *p; + + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/ttl_main.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawTransPic (72, 32, Draw_CachePic ("gfx/mainmenu.lmp") ); + + f = (int)(realtime * 10)%6; + + M_DrawTransPic (54, 32 + m_main_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); +} + + +void M_Main_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + key_dest = key_game; + m_state = m_none; + cls.demonum = m_save_demonum; + if (cls.demonum != -1 && !cls.demoplayback && cls.state == ca_disconnected) + CL_NextDemo (); + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + if (++m_main_cursor >= MAIN_ITEMS) + m_main_cursor = 0; + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + if (--m_main_cursor < 0) + m_main_cursor = MAIN_ITEMS - 1; + break; + + case K_ENTER: + m_entersound = true; + + switch (m_main_cursor) + { + case 0: + M_Menu_SinglePlayer_f (); + break; + + case 1: + M_Menu_MultiPlayer_f (); + break; + + case 2: + M_Menu_Options_f (); + break; + + case 3: + M_Menu_Help_f (); + break; + + case 4: + M_Menu_Quit_f (); + break; + } + } +} + + +//============================================================================= +/* OPTIONS MENU */ + +#define OPTIONS_ITEMS 16 + +#define SLIDER_RANGE 10 + +int options_cursor; + +void M_Menu_Options_f (void) +{ + key_dest = key_menu; + m_state = m_options; + m_entersound = true; +} + + +void M_AdjustSliders (int dir) +{ + S_LocalSound ("misc/menu3.wav"); + + switch (options_cursor) + { + case 3: // screen size + scr_viewsize.value += dir * 10; + if (scr_viewsize.value < 30) + scr_viewsize.value = 30; + if (scr_viewsize.value > 120) + scr_viewsize.value = 120; + Cvar_SetValue ("viewsize", scr_viewsize.value); + break; + case 4: // gamma + v_gamma.value -= dir * 0.05; + if (v_gamma.value < 0.5) + v_gamma.value = 0.5; + if (v_gamma.value > 1) + v_gamma.value = 1; + Cvar_SetValue ("gamma", v_gamma.value); + break; + case 5: // mouse speed + sensitivity.value += dir * 0.5; + if (sensitivity.value < 1) + sensitivity.value = 1; + if (sensitivity.value > 11) + sensitivity.value = 11; + Cvar_SetValue ("sensitivity", sensitivity.value); + break; + case 6: // music volume +#ifdef _WIN32 + bgmvolume.value += dir * 1.0; +#else + bgmvolume.value += dir * 0.1; +#endif + if (bgmvolume.value < 0) + bgmvolume.value = 0; + if (bgmvolume.value > 1) + bgmvolume.value = 1; + Cvar_SetValue ("bgmvolume", bgmvolume.value); + break; + case 7: // sfx volume + volume.value += dir * 0.1; + if (volume.value < 0) + volume.value = 0; + if (volume.value > 1) + volume.value = 1; + Cvar_SetValue ("volume", volume.value); + break; + + case 8: // allways run + if (cl_forwardspeed.value > 200) + { + Cvar_SetValue ("cl_forwardspeed", 200); + Cvar_SetValue ("cl_backspeed", 200); + } + else + { + Cvar_SetValue ("cl_forwardspeed", 400); + Cvar_SetValue ("cl_backspeed", 400); + } + break; + + case 9: // invert mouse + Cvar_SetValue ("m_pitch", -m_pitch.value); + break; + + case 10: // lookspring + Cvar_SetValue ("lookspring", !lookspring.value); + break; + + case 11: // lookstrafe + Cvar_SetValue ("lookstrafe", !lookstrafe.value); + break; + + case 12: + Cvar_SetValue ("cl_sbar", !cl_sbar.value); + break; + + case 13: + Cvar_SetValue ("cl_hudswap", !cl_hudswap.value); + + case 15: // _windowed_mouse + Cvar_SetValue ("_windowed_mouse", !_windowed_mouse.value); + break; + } +} + + +void M_DrawSlider (int x, int y, float range) +{ + int i; + + if (range < 0) + range = 0; + if (range > 1) + range = 1; + M_DrawCharacter (x-8, y, 128); + for (i=0 ; i<SLIDER_RANGE ; i++) + M_DrawCharacter (x + i*8, y, 129); + M_DrawCharacter (x+i*8, y, 130); + M_DrawCharacter (x + (SLIDER_RANGE-1)*8 * range, y, 131); +} + +void M_DrawCheckbox (int x, int y, int on) +{ +#if 0 + if (on) + M_DrawCharacter (x, y, 131); + else + M_DrawCharacter (x, y, 129); +#endif + if (on) + M_Print (x, y, "on"); + else + M_Print (x, y, "off"); +} + +void M_Options_Draw (void) +{ + float r; + qpic_t *p; + + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/p_option.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + M_Print (16, 32, " Customize controls"); + M_Print (16, 40, " Go to console"); + M_Print (16, 48, " Reset to defaults"); + + M_Print (16, 56, " Screen size"); + r = (scr_viewsize.value - 30) / (120 - 30); + M_DrawSlider (220, 56, r); + + M_Print (16, 64, " Brightness"); + r = (1.0 - v_gamma.value) / 0.5; + M_DrawSlider (220, 64, r); + + M_Print (16, 72, " Mouse Speed"); + r = (sensitivity.value - 1)/10; + M_DrawSlider (220, 72, r); + + M_Print (16, 80, " CD Music Volume"); + r = bgmvolume.value; + M_DrawSlider (220, 80, r); + + M_Print (16, 88, " Sound Volume"); + r = volume.value; + M_DrawSlider (220, 88, r); + + M_Print (16, 96, " Always Run"); + M_DrawCheckbox (220, 96, cl_forwardspeed.value > 200); + + M_Print (16, 104, " Invert Mouse"); + M_DrawCheckbox (220, 104, m_pitch.value < 0); + + M_Print (16, 112, " Lookspring"); + M_DrawCheckbox (220, 112, lookspring.value); + + M_Print (16, 120, " Lookstrafe"); + M_DrawCheckbox (220, 120, lookstrafe.value); + + M_Print (16, 128, " Use old status bar"); + M_DrawCheckbox (220, 128, cl_sbar.value); + + M_Print (16, 136, " HUD on left side"); + M_DrawCheckbox (220, 136, cl_hudswap.value); + + if (vid_menudrawfn) + M_Print (16, 144, " Video Options"); + +#ifdef _WIN32 + if (modestate == MS_WINDOWED) + { +#endif + M_Print (16, 152, " Use Mouse"); + M_DrawCheckbox (220, 152, _windowed_mouse.value); +#ifdef _WIN32 + } +#endif + +// cursor + M_DrawCharacter (200, 32 + options_cursor*8, 12+((int)(realtime*4)&1)); +} + + +void M_Options_Key (int k) +{ + switch (k) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_ENTER: + m_entersound = true; + switch (options_cursor) + { + case 0: + M_Menu_Keys_f (); + break; + case 1: + m_state = m_none; + Con_ToggleConsole_f (); + break; + case 2: + Cbuf_AddText ("exec default.cfg\n"); + break; + case 14: + M_Menu_Video_f (); + break; + default: + M_AdjustSliders (1); + break; + } + return; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + options_cursor--; + if (options_cursor < 0) + options_cursor = OPTIONS_ITEMS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + options_cursor++; + if (options_cursor >= OPTIONS_ITEMS) + options_cursor = 0; + break; + + case K_LEFTARROW: + M_AdjustSliders (-1); + break; + + case K_RIGHTARROW: + M_AdjustSliders (1); + break; + } + + if (options_cursor == 14 && vid_menudrawfn == NULL) + { + if (k == K_UPARROW) + options_cursor = 13; + else + options_cursor = 0; + } + + if ((options_cursor == 15) +#ifdef _WIN32 + && (modestate != MS_WINDOWED) +#endif + ) + { + if (k == K_UPARROW) + options_cursor = 14; + else + options_cursor = 0; + } +} + + +//============================================================================= +/* KEYS MENU */ + +char *bindnames[][2] = +{ +{"+attack", "attack"}, +{"impulse 10", "change weapon"}, +{"+jump", "jump / swim up"}, +{"+forward", "walk forward"}, +{"+back", "backpedal"}, +{"+left", "turn left"}, +{"+right", "turn right"}, +{"+speed", "run"}, +{"+moveleft", "step left"}, +{"+moveright", "step right"}, +{"+strafe", "sidestep"}, +{"+lookup", "look up"}, +{"+lookdown", "look down"}, +{"centerview", "center view"}, +{"+mlook", "mouse look"}, +{"+klook", "keyboard look"}, +{"+moveup", "swim up"}, +{"+movedown", "swim down"} +}; + +#define NUMCOMMANDS (sizeof(bindnames)/sizeof(bindnames[0])) + +int keys_cursor; +int bind_grab; + +void M_Menu_Keys_f (void) +{ + key_dest = key_menu; + m_state = m_keys; + m_entersound = true; +} + + +void M_FindKeysForCommand (char *command, int *twokeys) +{ + int count; + int j; + int l; + char *b; + + twokeys[0] = twokeys[1] = -1; + l = strlen(command); + count = 0; + + for (j=0 ; j<256 ; j++) + { + b = keybindings[j]; + if (!b) + continue; + if (!strncmp (b, command, l) ) + { + twokeys[count] = j; + count++; + if (count == 2) + break; + } + } +} + +void M_UnbindCommand (char *command) +{ + int j; + int l; + char *b; + + l = strlen(command); + + for (j=0 ; j<256 ; j++) + { + b = keybindings[j]; + if (!b) + continue; + if (!strncmp (b, command, l) ) + Key_SetBinding (j, ""); + } +} + + +void M_Keys_Draw (void) +{ + int i, l; + int keys[2]; + char *name; + int x, y; + qpic_t *p; + + p = Draw_CachePic ("gfx/ttl_cstm.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + if (bind_grab) + M_Print (12, 32, "Press a key or button for this action"); + else + M_Print (18, 32, "Enter to change, backspace to clear"); + +// search for known bindings + for (i=0 ; i<NUMCOMMANDS ; i++) + { + y = 48 + 8*i; + + M_Print (16, y, bindnames[i][1]); + + l = strlen (bindnames[i][0]); + + M_FindKeysForCommand (bindnames[i][0], keys); + + if (keys[0] == -1) + { + M_Print (140, y, "???"); + } + else + { + name = Key_KeynumToString (keys[0]); + M_Print (140, y, name); + x = strlen(name) * 8; + if (keys[1] != -1) + { + M_Print (140 + x + 8, y, "or"); + M_Print (140 + x + 32, y, Key_KeynumToString (keys[1])); + } + } + } + + if (bind_grab) + M_DrawCharacter (130, 48 + keys_cursor*8, '='); + else + M_DrawCharacter (130, 48 + keys_cursor*8, 12+((int)(realtime*4)&1)); +} + + +void M_Keys_Key (int k) +{ + char cmd[80]; + int keys[2]; + + if (bind_grab) + { // defining a key + S_LocalSound ("misc/menu1.wav"); + if (k == K_ESCAPE) + { + bind_grab = false; + } + else if (k != '`') + { + sprintf (cmd, "bind %s \"%s\"\n", Key_KeynumToString (k), bindnames[keys_cursor][0]); + Cbuf_InsertText (cmd); + } + + bind_grab = false; + return; + } + + switch (k) + { + case K_ESCAPE: + M_Menu_Options_f (); + break; + + case K_LEFTARROW: + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + keys_cursor--; + if (keys_cursor < 0) + keys_cursor = NUMCOMMANDS-1; + break; + + case K_DOWNARROW: + case K_RIGHTARROW: + S_LocalSound ("misc/menu1.wav"); + keys_cursor++; + if (keys_cursor >= NUMCOMMANDS) + keys_cursor = 0; + break; + + case K_ENTER: // go into bind mode + M_FindKeysForCommand (bindnames[keys_cursor][0], keys); + S_LocalSound ("misc/menu2.wav"); + if (keys[1] != -1) + M_UnbindCommand (bindnames[keys_cursor][0]); + bind_grab = true; + break; + + case K_BACKSPACE: // delete bindings + case K_DEL: // delete bindings + S_LocalSound ("misc/menu2.wav"); + M_UnbindCommand (bindnames[keys_cursor][0]); + break; + } +} + +//============================================================================= +/* VIDEO MENU */ + +void M_Menu_Video_f (void) +{ + key_dest = key_menu; + m_state = m_video; + m_entersound = true; +} + + +void M_Video_Draw (void) +{ + (*vid_menudrawfn) (); +} + + +void M_Video_Key (int key) +{ + (*vid_menukeyfn) (key); +} + +//============================================================================= +/* HELP MENU */ + +int help_page; +#define NUM_HELP_PAGES 6 + + +void M_Menu_Help_f (void) +{ + key_dest = key_menu; + m_state = m_help; + m_entersound = true; + help_page = 0; +} + + + +void M_Help_Draw (void) +{ + M_DrawPic (0, 0, Draw_CachePic ( va("gfx/help%i.lmp", help_page)) ); +} + + +void M_Help_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_UPARROW: + case K_RIGHTARROW: + m_entersound = true; + if (++help_page >= NUM_HELP_PAGES) + help_page = 0; + break; + + case K_DOWNARROW: + case K_LEFTARROW: + m_entersound = true; + if (--help_page < 0) + help_page = NUM_HELP_PAGES-1; + break; + } + +} + +//============================================================================= +/* QUIT MENU */ + +int msgNumber; +int m_quit_prevstate; +qboolean wasInMenus; + +char *quitMessage [] = +{ +/* .........1.........2.... */ + " Are you gonna quit ", + " this game just like ", + " everything else? ", + " ", + + " Milord, methinks that ", + " thou art a lowly ", + " quitter. Is this true? ", + " ", + + " Do I need to bust your ", + " face open for trying ", + " to quit? ", + " ", + + " Man, I oughta smack you", + " for trying to quit! ", + " Press Y to get ", + " smacked out. ", + + " Press Y to quit like a ", + " big loser in life. ", + " Press N to stay proud ", + " and successful! ", + + " If you press Y to ", + " quit, I will summon ", + " Satan all over your ", + " hard drive! ", + + " Um, Asmodeus dislikes ", + " his children trying to ", + " quit. Press Y to return", + " to your Tinkertoys. ", + + " If you quit now, I'll ", + " throw a blanket-party ", + " for you next time! ", + " " +}; + +void M_Menu_Quit_f (void) +{ + if (m_state == m_quit) + return; + wasInMenus = (key_dest == key_menu); + key_dest = key_menu; + m_quit_prevstate = m_state; + m_state = m_quit; + m_entersound = true; + msgNumber = rand()&7; +} + + +void M_Quit_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + case 'n': + case 'N': + if (wasInMenus) + { + m_state = m_quit_prevstate; + m_entersound = true; + } + else + { + key_dest = key_game; + m_state = m_none; + } + break; + + case 'Y': + case 'y': + key_dest = key_console; + CL_Disconnect (); + Sys_Quit (); + break; + + default: + break; + } + +} + +void M_Menu_SinglePlayer_f (void) { + m_state = m_singleplayer; +} + +void M_SinglePlayer_Draw (void) { + qpic_t *p; + + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); +// M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/ttl_sgl.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); +// M_DrawTransPic (72, 32, Draw_CachePic ("gfx/sp_menu.lmp") ); + + M_DrawTextBox (60, 10*8, 23, 4); + M_PrintWhite (92, 12*8, "QuakeWorld is for"); + M_PrintWhite (88, 13*8, "Internet play only"); + +} + +void M_SinglePlayer_Key (key) { + if (key == K_ESCAPE || key==K_ENTER) + m_state = m_main; +} + +void M_Menu_MultiPlayer_f (void) { + m_state = m_multiplayer; +} + +void M_MultiPlayer_Draw (void) { + qpic_t *p; + + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); +// M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); +// M_DrawTransPic (72, 32, Draw_CachePic ("gfx/sp_menu.lmp") ); + + M_DrawTextBox (46, 8*8, 27, 9); + M_PrintWhite (72, 10*8, "If you want to find QW "); + M_PrintWhite (72, 11*8, "games, head on over to: "); + M_Print (72, 12*8, " www.quakeworld.net "); + M_PrintWhite (72, 13*8, " or "); + M_Print (72, 14*8, " www.quakespy.com "); + M_PrintWhite (72, 15*8, "For pointers on getting "); + M_PrintWhite (72, 16*8, " started! "); +} + +void M_MultiPlayer_Key (key) { + if (key == K_ESCAPE || key==K_ENTER) + m_state = m_main; +} + +void M_Quit_Draw (void) +{ +#define VSTR(x) #x +#define VSTR2(x) VSTR(x) + char *cmsg[] = { +// 0123456789012345678901234567890123456789 + "0 QuakeWorld", + "1 version " VSTR2(VERSION) " by id Software", + "0Programming", + "1 John Carmack Michael Abrash", + "1 John Cash Christian Antkow", + "0Additional Programming", + "1 Dave 'Zoid' Kirsch", + "1 Jack 'morbid' Mathews", + "0Id Software is not responsible for", + "0providing technical support for", + "0QUAKEWORLD(tm). (c)1996 Id Software,", + "0Inc. All Rights Reserved.", + "0QUAKEWORLD(tm) is a trademark of Id", + "0Software, Inc.", + "1NOTICE: THE COPYRIGHT AND TRADEMARK", + "1NOTICES APPEARING IN YOUR COPY OF", + "1QUAKE(r) ARE NOT MODIFIED BY THE USE", + "1OF QUAKEWORLD(tm) AND REMAIN IN FULL", + "1FORCE.", + "0NIN(r) is a registered trademark", + "0licensed to Nothing Interactive, Inc.", + "0All rights reserved. Press y to exit", + NULL }; + char **p; + int y; + + if (wasInMenus) + { + m_state = m_quit_prevstate; + m_recursiveDraw = true; + M_Draw (); + m_state = m_quit; + } +#if 1 + M_DrawTextBox (0, 0, 38, 23); + y = 12; + for (p = cmsg; *p; p++, y += 8) { + if (**p == '0') + M_PrintWhite (16, y, *p + 1); + else + M_Print (16, y, *p + 1); + } +#else + M_DrawTextBox (56, 76, 24, 4); + M_Print (64, 84, quitMessage[msgNumber*4+0]); + M_Print (64, 92, quitMessage[msgNumber*4+1]); + M_Print (64, 100, quitMessage[msgNumber*4+2]); + M_Print (64, 108, quitMessage[msgNumber*4+3]); +#endif +} + + + +//============================================================================= +/* Menu Subsystem */ + + +void M_Init (void) +{ + Cmd_AddCommand ("togglemenu", M_ToggleMenu_f); + + Cmd_AddCommand ("menu_main", M_Menu_Main_f); + Cmd_AddCommand ("menu_options", M_Menu_Options_f); + Cmd_AddCommand ("menu_keys", M_Menu_Keys_f); + Cmd_AddCommand ("menu_video", M_Menu_Video_f); + Cmd_AddCommand ("help", M_Menu_Help_f); + Cmd_AddCommand ("menu_quit", M_Menu_Quit_f); +} + + +void M_Draw (void) +{ + if (m_state == m_none || key_dest != key_menu) + return; + + if (!m_recursiveDraw) + { + scr_copyeverything = 1; + + if (scr_con_current) + { + Draw_ConsoleBackground (vid.height); + VID_UnlockBuffer (); + S_ExtraUpdate (); + VID_LockBuffer (); + } + else + Draw_FadeScreen (); + + scr_fullupdate = 0; + } + else + { + m_recursiveDraw = false; + } + + switch (m_state) + { + case m_none: + break; + + case m_main: + M_Main_Draw (); + break; + + case m_singleplayer: + M_SinglePlayer_Draw (); + break; + + case m_load: +// M_Load_Draw (); + break; + + case m_save: +// M_Save_Draw (); + break; + + case m_multiplayer: + M_MultiPlayer_Draw (); + break; + + case m_setup: +// M_Setup_Draw (); + break; + + case m_net: +// M_Net_Draw (); + break; + + case m_options: + M_Options_Draw (); + break; + + case m_keys: + M_Keys_Draw (); + break; + + case m_video: + M_Video_Draw (); + break; + + case m_help: + M_Help_Draw (); + break; + + case m_quit: + M_Quit_Draw (); + break; + + case m_serialconfig: +// M_SerialConfig_Draw (); + break; + + case m_modemconfig: +// M_ModemConfig_Draw (); + break; + + case m_lanconfig: +// M_LanConfig_Draw (); + break; + + case m_gameoptions: +// M_GameOptions_Draw (); + break; + + case m_search: +// M_Search_Draw (); + break; + + case m_slist: +// M_ServerList_Draw (); + break; + } + + if (m_entersound) + { + S_LocalSound ("misc/menu2.wav"); + m_entersound = false; + } + + VID_UnlockBuffer (); + S_ExtraUpdate (); + VID_LockBuffer (); +} + + +void M_Keydown (int key) +{ + switch (m_state) + { + case m_none: + return; + + case m_main: + M_Main_Key (key); + return; + + case m_singleplayer: + M_SinglePlayer_Key (key); + return; + + case m_load: +// M_Load_Key (key); + return; + + case m_save: +// M_Save_Key (key); + return; + + case m_multiplayer: + M_MultiPlayer_Key (key); + return; + + case m_setup: +// M_Setup_Key (key); + return; + + case m_net: +// M_Net_Key (key); + return; + + case m_options: + M_Options_Key (key); + return; + + case m_keys: + M_Keys_Key (key); + return; + + case m_video: + M_Video_Key (key); + return; + + case m_help: + M_Help_Key (key); + return; + + case m_quit: + M_Quit_Key (key); + return; + + case m_serialconfig: +// M_SerialConfig_Key (key); + return; + + case m_modemconfig: +// M_ModemConfig_Key (key); + return; + + case m_lanconfig: +// M_LanConfig_Key (key); + return; + + case m_gameoptions: +// M_GameOptions_Key (key); + return; + + case m_search: +// M_Search_Key (key); + break; + + case m_slist: +// M_ServerList_Key (key); + return; + } +} + + diff --git a/QW/client/menu.h b/QW/client/menu.h new file mode 100644 index 0000000..8a30d09 --- /dev/null +++ b/QW/client/menu.h @@ -0,0 +1,41 @@ +/* +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. + +*/ + +// +// the net drivers should just set the apropriate bits in m_activenet, +// instead of having the menu code look through their internal tables +// +#define MNET_IPX 1 +#define MNET_TCP 2 + +extern int m_activenet; + +// +// menus +// +void M_Init (void); +void M_Keydown (int key); +void M_Draw (void); +void M_ToggleMenu_f (void); +qpic_t *M_CachePic (char *path); +void M_DrawTextBox (int x, int y, int width, int lines); +void M_Menu_Quit_f (void); + + diff --git a/QW/client/model.c b/QW/client/model.c new file mode 100644 index 0000000..5ec926c --- /dev/null +++ b/QW/client/model.c @@ -0,0 +1,1891 @@ +/* +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. + +*/ +// models.c -- model loading and caching + +// models are the only shared resource between a client and server running +// on the same machine. + +#include "quakedef.h" +#include "r_local.h" + +model_t *loadmodel; +char loadname[32]; // for hunk tags + +void Mod_LoadSpriteModel (model_t *mod, void *buffer); +void Mod_LoadBrushModel (model_t *mod, void *buffer); +void Mod_LoadAliasModel (model_t *mod, void *buffer); +model_t *Mod_LoadModel (model_t *mod, qboolean crash); + +byte mod_novis[MAX_MAP_LEAFS/8]; + +#define MAX_MOD_KNOWN 256 +model_t mod_known[MAX_MOD_KNOWN]; +int mod_numknown; + +/* +=============== +Mod_Init +=============== +*/ +void Mod_Init (void) +{ + memset (mod_novis, 0xff, sizeof(mod_novis)); +} + +/* +=============== +Mod_Init + +Caches the data if needed +=============== +*/ +void *Mod_Extradata (model_t *mod) +{ + void *r; + + r = Cache_Check (&mod->cache); + if (r) + return r; + + Mod_LoadModel (mod, true); + + if (!mod->cache.data) + Sys_Error ("Mod_Extradata: caching failed"); + return mod->cache.data; +} + +/* +=============== +Mod_PointInLeaf +=============== +*/ +mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) +{ + mnode_t *node; + float d; + mplane_t *plane; + + if (!model || !model->nodes) + Sys_Error ("Mod_PointInLeaf: bad model"); + + node = model->nodes; + while (1) + { + if (node->contents < 0) + return (mleaf_t *)node; + plane = node->plane; + d = DotProduct (p,plane->normal) - plane->dist; + if (d > 0) + node = node->children[0]; + else + node = node->children[1]; + } + + return NULL; // never reached +} + + +/* +=================== +Mod_DecompressVis +=================== +*/ +byte *Mod_DecompressVis (byte *in, model_t *model) +{ + static byte decompressed[MAX_MAP_LEAFS/8]; + int c; + byte *out; + int row; + + row = (model->numleafs+7)>>3; + out = decompressed; + +#if 0 + memcpy (out, in, row); +#else + if (!in) + { // no vis info, so make all visible + while (row) + { + *out++ = 0xff; + row--; + } + return decompressed; + } + + do + { + if (*in) + { + *out++ = *in++; + continue; + } + + c = in[1]; + in += 2; + while (c) + { + *out++ = 0; + c--; + } + } while (out - decompressed < row); +#endif + + return decompressed; +} + +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) +{ + if (leaf == model->leafs) + return mod_novis; + return Mod_DecompressVis (leaf->compressed_vis, model); +} + +/* +=================== +Mod_ClearAll +=================== +*/ +void Mod_ClearAll (void) +{ + int i; + model_t *mod; + + for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) + if (mod->type != mod_alias) + mod->needload = true; +} + +/* +================== +Mod_FindName + +================== +*/ +model_t *Mod_FindName (char *name) +{ + int i; + model_t *mod; + + if (!name[0]) + Sys_Error ("Mod_ForName: NULL name"); + +// +// search the currently loaded models +// + for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) + if (!strcmp (mod->name, name) ) + break; + + if (i == mod_numknown) + { + if (mod_numknown == MAX_MOD_KNOWN) + Sys_Error ("mod_numknown == MAX_MOD_KNOWN"); + strcpy (mod->name, name); + mod->needload = true; + mod_numknown++; + } + + return mod; +} + +/* +================== +Mod_TouchModel + +================== +*/ +void Mod_TouchModel (char *name) +{ + model_t *mod; + + mod = Mod_FindName (name); + + if (!mod->needload) + { + if (mod->type == mod_alias) + Cache_Check (&mod->cache); + } +} + +/* +================== +Mod_LoadModel + +Loads a model into the cache +================== +*/ +model_t *Mod_LoadModel (model_t *mod, qboolean crash) +{ + void *d; + unsigned *buf; + byte stackbuf[1024]; // avoid dirtying the cache heap + + if (!mod->needload) + { + if (mod->type == mod_alias) + { + d = Cache_Check (&mod->cache); + if (d) + return mod; + } + else + return mod; // not cached at all + } + +// +// because the world is so huge, load it one piece at a time +// + if (!crash) + { + + } + +// +// load the file +// + buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf)); + if (!buf) + { + if (crash) + Sys_Error ("Mod_NumForName: %s not found", mod->name); + return NULL; + } + +// +// allocate a new model +// + COM_FileBase (mod->name, loadname); + + loadmodel = mod; + +// +// fill it in +// + +// call the apropriate loader + mod->needload = false; + + switch (LittleLong(*(unsigned *)buf)) + { + case IDPOLYHEADER: + Mod_LoadAliasModel (mod, buf); + break; + + case IDSPRITEHEADER: + Mod_LoadSpriteModel (mod, buf); + break; + + default: + Mod_LoadBrushModel (mod, buf); + break; + } + + return mod; +} + +/* +================== +Mod_ForName + +Loads in a model for the given name +================== +*/ +model_t *Mod_ForName (char *name, qboolean crash) +{ + model_t *mod; + + mod = Mod_FindName (name); + + return Mod_LoadModel (mod, crash); +} + + +/* +=============================================================================== + + BRUSHMODEL LOADING + +=============================================================================== +*/ + +byte *mod_base; + + +/* +================= +Mod_LoadTextures +================= +*/ +void Mod_LoadTextures (lump_t *l) +{ + int i, j, pixels, num, max, altmax; + miptex_t *mt; + texture_t *tx, *tx2; + texture_t *anims[10]; + texture_t *altanims[10]; + dmiptexlump_t *m; + + if (!l->filelen) + { + loadmodel->textures = NULL; + return; + } + m = (dmiptexlump_t *)(mod_base + l->fileofs); + + m->nummiptex = LittleLong (m->nummiptex); + + loadmodel->numtextures = m->nummiptex; + loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); + + for (i=0 ; i<m->nummiptex ; i++) + { + m->dataofs[i] = LittleLong(m->dataofs[i]); + if (m->dataofs[i] == -1) + continue; + mt = (miptex_t *)((byte *)m + m->dataofs[i]); + mt->width = LittleLong (mt->width); + mt->height = LittleLong (mt->height); + for (j=0 ; j<MIPLEVELS ; j++) + mt->offsets[j] = LittleLong (mt->offsets[j]); + + if ( (mt->width & 15) || (mt->height & 15) ) + Sys_Error ("Texture %s is not 16 aligned", mt->name); + pixels = mt->width*mt->height/64*85; + tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); + loadmodel->textures[i] = tx; + + memcpy (tx->name, mt->name, sizeof(tx->name)); + tx->width = mt->width; + tx->height = mt->height; + for (j=0 ; j<MIPLEVELS ; j++) + tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); + // the pixels immediately follow the structures + memcpy ( tx+1, mt+1, pixels); + + if (!Q_strncmp(mt->name,"sky",3)) + R_InitSky (tx); + } + +// +// sequence the animations +// + for (i=0 ; i<m->nummiptex ; i++) + { + tx = loadmodel->textures[i]; + if (!tx || tx->name[0] != '+') + continue; + if (tx->anim_next) + continue; // allready sequenced + + // find the number of frames in the animation + memset (anims, 0, sizeof(anims)); + memset (altanims, 0, sizeof(altanims)); + + max = tx->name[1]; + altmax = 0; + if (max >= 'a' && max <= 'z') + max -= 'a' - 'A'; + if (max >= '0' && max <= '9') + { + max -= '0'; + altmax = 0; + anims[max] = tx; + max++; + } + else if (max >= 'A' && max <= 'J') + { + altmax = max - 'A'; + max = 0; + altanims[altmax] = tx; + altmax++; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + + for (j=i+1 ; j<m->nummiptex ; j++) + { + tx2 = loadmodel->textures[j]; + if (!tx2 || tx2->name[0] != '+') + continue; + if (strcmp (tx2->name+2, tx->name+2)) + continue; + + num = tx2->name[1]; + if (num >= 'a' && num <= 'z') + num -= 'a' - 'A'; + if (num >= '0' && num <= '9') + { + num -= '0'; + anims[num] = tx2; + if (num+1 > max) + max = num + 1; + } + else if (num >= 'A' && num <= 'J') + { + num = num - 'A'; + altanims[num] = tx2; + if (num+1 > altmax) + altmax = num+1; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + } + +#define ANIM_CYCLE 2 + // link them all together + for (j=0 ; j<max ; j++) + { + tx2 = anims[j]; + if (!tx2) + Sys_Error ("Missing frame %i of %s",j, tx->name); + tx2->anim_total = max * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = anims[ (j+1)%max ]; + if (altmax) + tx2->alternate_anims = altanims[0]; + } + for (j=0 ; j<altmax ; j++) + { + tx2 = altanims[j]; + if (!tx2) + Sys_Error ("Missing frame %i of %s",j, tx->name); + tx2->anim_total = altmax * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = altanims[ (j+1)%altmax ]; + if (max) + tx2->alternate_anims = anims[0]; + } + } +} + +/* +================= +Mod_LoadLighting +================= +*/ +void Mod_LoadLighting (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->lightdata = NULL; + return; + } + loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadVisibility +================= +*/ +void Mod_LoadVisibility (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->visdata = NULL; + return; + } + loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadEntities +================= +*/ +void Mod_LoadEntities (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->entities = NULL; + return; + } + loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadVertexes +================= +*/ +void Mod_LoadVertexes (lump_t *l) +{ + dvertex_t *in; + mvertex_t *out; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->vertexes = out; + loadmodel->numvertexes = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + out->position[0] = LittleFloat (in->point[0]); + out->position[1] = LittleFloat (in->point[1]); + out->position[2] = LittleFloat (in->point[2]); + } +} + +/* +================= +Mod_LoadSubmodels +================= +*/ +void Mod_LoadSubmodels (lump_t *l) +{ + dmodel_t *in; + dmodel_t *out; + int i, j, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->submodels = out; + loadmodel->numsubmodels = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + for (j=0 ; j<3 ; j++) + { // spread the mins / maxs by a pixel + out->mins[j] = LittleFloat (in->mins[j]) - 1; + out->maxs[j] = LittleFloat (in->maxs[j]) + 1; + out->origin[j] = LittleFloat (in->origin[j]); + } + for (j=0 ; j<MAX_MAP_HULLS ; j++) + out->headnode[j] = LittleLong (in->headnode[j]); + out->visleafs = LittleLong (in->visleafs); + out->firstface = LittleLong (in->firstface); + out->numfaces = LittleLong (in->numfaces); + } +} + +/* +================= +Mod_LoadEdges +================= +*/ +void Mod_LoadEdges (lump_t *l) +{ + dedge_t *in; + medge_t *out; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); + + loadmodel->edges = out; + loadmodel->numedges = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + out->v[0] = (unsigned short)LittleShort(in->v[0]); + out->v[1] = (unsigned short)LittleShort(in->v[1]); + } +} + +/* +================= +Mod_LoadTexinfo +================= +*/ +void Mod_LoadTexinfo (lump_t *l) +{ + texinfo_t *in; + mtexinfo_t *out; + int i, j, count; + int miptex; + float len1, len2; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->texinfo = out; + loadmodel->numtexinfo = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + for (j=0 ; j<8 ; j++) + out->vecs[0][j] = LittleFloat (in->vecs[0][j]); + len1 = Length (out->vecs[0]); + len2 = Length (out->vecs[1]); + len1 = (len1 + len2)/2; + if (len1 < 0.32) + out->mipadjust = 4; + else if (len1 < 0.49) + out->mipadjust = 3; + else if (len1 < 0.99) + out->mipadjust = 2; + else + out->mipadjust = 1; +#if 0 + if (len1 + len2 < 0.001) + out->mipadjust = 1; // don't crash + else + out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 ); +#endif + + miptex = LittleLong (in->miptex); + out->flags = LittleLong (in->flags); + + if (!loadmodel->textures) + { + out->texture = r_notexture_mip; // checkerboard texture + out->flags = 0; + } + else + { + if (miptex >= loadmodel->numtextures) + Sys_Error ("miptex >= loadmodel->numtextures"); + out->texture = loadmodel->textures[miptex]; + if (!out->texture) + { + out->texture = r_notexture_mip; // texture not found + out->flags = 0; + } + } + } +} + +/* +================ +CalcSurfaceExtents + +Fills in s->texturemins[] and s->extents[] +================ +*/ +void CalcSurfaceExtents (msurface_t *s) +{ + float mins[2], maxs[2], val; + int i,j, e; + mvertex_t *v; + mtexinfo_t *tex; + int bmins[2], bmaxs[2]; + + mins[0] = mins[1] = 999999; + maxs[0] = maxs[1] = -99999; + + tex = s->texinfo; + + for (i=0 ; i<s->numedges ; i++) + { + e = loadmodel->surfedges[s->firstedge+i]; + if (e >= 0) + v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; + else + v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; + + for (j=0 ; j<2 ; j++) + { + val = v->position[0] * tex->vecs[j][0] + + v->position[1] * tex->vecs[j][1] + + v->position[2] * tex->vecs[j][2] + + tex->vecs[j][3]; + if (val < mins[j]) + mins[j] = val; + if (val > maxs[j]) + maxs[j] = val; + } + } + + for (i=0 ; i<2 ; i++) + { + bmins[i] = floor(mins[i]/16); + bmaxs[i] = ceil(maxs[i]/16); + + s->texturemins[i] = bmins[i] * 16; + s->extents[i] = (bmaxs[i] - bmins[i]) * 16; + if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 256) + Sys_Error ("Bad surface extents"); + } +} + + +/* +================= +Mod_LoadFaces +================= +*/ +void Mod_LoadFaces (lump_t *l) +{ + dface_t *in; + msurface_t *out; + int i, count, surfnum; + int planenum, side; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++) + { + out->firstedge = LittleLong(in->firstedge); + out->numedges = LittleShort(in->numedges); + out->flags = 0; + + planenum = LittleShort(in->planenum); + side = LittleShort(in->side); + if (side) + out->flags |= SURF_PLANEBACK; + + out->plane = loadmodel->planes + planenum; + + out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); + + CalcSurfaceExtents (out); + + // lighting info + + for (i=0 ; i<MAXLIGHTMAPS ; i++) + out->styles[i] = in->styles[i]; + i = LittleLong(in->lightofs); + if (i == -1) + out->samples = NULL; + else + out->samples = loadmodel->lightdata + i; + + // set the drawing flags flag + + if (!Q_strncmp(out->texinfo->texture->name,"sky",3)) // sky + { + out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); + continue; + } + + if (!Q_strncmp(out->texinfo->texture->name,"*",1)) // turbulent + { + out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); + for (i=0 ; i<2 ; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + continue; + } + } +} + + +/* +================= +Mod_SetParent +================= +*/ +void Mod_SetParent (mnode_t *node, mnode_t *parent) +{ + node->parent = parent; + if (node->contents < 0) + return; + Mod_SetParent (node->children[0], node); + Mod_SetParent (node->children[1], node); +} + +/* +================= +Mod_LoadNodes +================= +*/ +void Mod_LoadNodes (lump_t *l) +{ + int i, j, count, p; + dnode_t *in; + mnode_t *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->nodes = out; + loadmodel->numnodes = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + for (j=0 ; j<3 ; j++) + { + out->minmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->planenum); + out->plane = loadmodel->planes + p; + + out->firstsurface = LittleShort (in->firstface); + out->numsurfaces = LittleShort (in->numfaces); + + for (j=0 ; j<2 ; j++) + { + p = LittleShort (in->children[j]); + if (p >= 0) + out->children[j] = loadmodel->nodes + p; + else + out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); + } + } + + Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs +} + +/* +================= +Mod_LoadLeafs +================= +*/ +void Mod_LoadLeafs (lump_t *l) +{ + dleaf_t *in; + mleaf_t *out; + int i, j, count, p; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->leafs = out; + loadmodel->numleafs = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + for (j=0 ; j<3 ; j++) + { + out->minmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->contents); + out->contents = p; + + out->firstmarksurface = loadmodel->marksurfaces + + LittleShort(in->firstmarksurface); + out->nummarksurfaces = LittleShort(in->nummarksurfaces); + + p = LittleLong(in->visofs); + if (p == -1) + out->compressed_vis = NULL; + else + out->compressed_vis = loadmodel->visdata + p; + out->efrags = NULL; + + for (j=0 ; j<4 ; j++) + out->ambient_sound_level[j] = in->ambient_level[j]; + } +} + +/* +================= +Mod_LoadClipnodes +================= +*/ +void Mod_LoadClipnodes (lump_t *l) +{ + dclipnode_t *in, *out; + int i, count; + hull_t *hull; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->clipnodes = out; + loadmodel->numclipnodes = count; + + hull = &loadmodel->hulls[1]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -16; + hull->clip_mins[1] = -16; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 16; + hull->clip_maxs[1] = 16; + hull->clip_maxs[2] = 32; + + hull = &loadmodel->hulls[2]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -32; + hull->clip_mins[1] = -32; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 32; + hull->clip_maxs[1] = 32; + hull->clip_maxs[2] = 64; + + for (i=0 ; i<count ; i++, out++, in++) + { + out->planenum = LittleLong(in->planenum); + out->children[0] = LittleShort(in->children[0]); + out->children[1] = LittleShort(in->children[1]); + } +} + +/* +================= +Mod_MakeHull0 + +Deplicate the drawing hull structure as a clipping hull +================= +*/ +void Mod_MakeHull0 (void) +{ + mnode_t *in, *child; + dclipnode_t *out; + int i, j, count; + hull_t *hull; + + hull = &loadmodel->hulls[0]; + + in = loadmodel->nodes; + count = loadmodel->numnodes; + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + + for (i=0 ; i<count ; i++, out++, in++) + { + out->planenum = in->plane - loadmodel->planes; + for (j=0 ; j<2 ; j++) + { + child = in->children[j]; + if (child->contents < 0) + out->children[j] = child->contents; + else + out->children[j] = child - loadmodel->nodes; + } + } +} + +/* +================= +Mod_LoadMarksurfaces +================= +*/ +void Mod_LoadMarksurfaces (lump_t *l) +{ + int i, j, count; + short *in; + msurface_t **out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->marksurfaces = out; + loadmodel->nummarksurfaces = count; + + for ( i=0 ; i<count ; i++) + { + j = LittleShort(in[i]); + if (j >= loadmodel->numsurfaces) + Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); + out[i] = loadmodel->surfaces + j; + } +} + +/* +================= +Mod_LoadSurfedges +================= +*/ +void Mod_LoadSurfedges (lump_t *l) +{ + int i, count; + int *in, *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfedges = out; + loadmodel->numsurfedges = count; + + for ( i=0 ; i<count ; i++) + out[i] = LittleLong (in[i]); +} + +/* +================= +Mod_LoadPlanes +================= +*/ +void Mod_LoadPlanes (lump_t *l) +{ + int i, j; + mplane_t *out; + dplane_t *in; + int count; + int bits; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*2*sizeof(*out), loadname); + + loadmodel->planes = out; + loadmodel->numplanes = count; + + for ( i=0 ; i<count ; i++, in++, out++) + { + bits = 0; + for (j=0 ; j<3 ; j++) + { + out->normal[j] = LittleFloat (in->normal[j]); + if (out->normal[j] < 0) + bits |= 1<<j; + } + + out->dist = LittleFloat (in->dist); + out->type = LittleLong (in->type); + out->signbits = bits; + } +} + +/* +================= +RadiusFromBounds +================= +*/ +float RadiusFromBounds (vec3_t mins, vec3_t maxs) +{ + int i; + vec3_t corner; + + for (i=0 ; i<3 ; i++) + { + corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]); + } + + return Length (corner); +} + +/* +================= +Mod_LoadBrushModel +================= +*/ +void Mod_LoadBrushModel (model_t *mod, void *buffer) +{ + int i, j; + dheader_t *header; + dmodel_t *bm; + + loadmodel->type = mod_brush; + + header = (dheader_t *)buffer; + + i = LittleLong (header->version); + if (i != BSPVERSION) + Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); + +// swap all the lumps + mod_base = (byte *)header; + + for (i=0 ; i<sizeof(dheader_t)/4 ; i++) + ((int *)header)[i] = LittleLong ( ((int *)header)[i]); + + mod->checksum = 0; + mod->checksum2 = 0; + +// checksum all of the map, except for entities + for (i = 0; i < HEADER_LUMPS; i++) { + if (i == LUMP_ENTITIES) + continue; + mod->checksum ^= Com_BlockChecksum(mod_base + header->lumps[i].fileofs, + header->lumps[i].filelen); + + if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES) + continue; + mod->checksum2 ^= Com_BlockChecksum(mod_base + header->lumps[i].fileofs, + header->lumps[i].filelen); + } + +// load into heap + + Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); + Mod_LoadEdges (&header->lumps[LUMP_EDGES]); + Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); + Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); + Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); + Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); + Mod_LoadFaces (&header->lumps[LUMP_FACES]); + Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); + Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); + Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); + Mod_LoadNodes (&header->lumps[LUMP_NODES]); + Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); + Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); + Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); + + Mod_MakeHull0 (); + + mod->numframes = 2; // regular and alternate animation + +// +// set up the submodels (FIXME: this is confusing) +// + for (i=0 ; i<mod->numsubmodels ; i++) + { + bm = &mod->submodels[i]; + + mod->hulls[0].firstclipnode = bm->headnode[0]; + for (j=1 ; j<MAX_MAP_HULLS ; j++) + { + mod->hulls[j].firstclipnode = bm->headnode[j]; + mod->hulls[j].lastclipnode = mod->numclipnodes-1; + } + + mod->firstmodelsurface = bm->firstface; + mod->nummodelsurfaces = bm->numfaces; + mod->radius = RadiusFromBounds (mod->mins, mod->maxs); + + VectorCopy (bm->maxs, mod->maxs); + VectorCopy (bm->mins, mod->mins); + + mod->numleafs = bm->visleafs; + + if (i < mod->numsubmodels-1) + { // duplicate the basic information + char name[10]; + + sprintf (name, "*%i", i+1); + loadmodel = Mod_FindName (name); + *loadmodel = *mod; + strcpy (loadmodel->name, name); + mod = loadmodel; + } + } +} + +/* +============================================================================== + +ALIAS MODELS + +============================================================================== +*/ + +/* +================= +Mod_LoadAliasFrame +================= +*/ +void * Mod_LoadAliasFrame (void * pin, int *pframeindex, int numv, + trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name) +{ + trivertx_t *pframe, *pinframe; + int i, j; + daliasframe_t *pdaliasframe; + + pdaliasframe = (daliasframe_t *)pin; + + strcpy (name, pdaliasframe->name); + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about + // endianness + pbboxmin->v[i] = pdaliasframe->bboxmin.v[i]; + pbboxmax->v[i] = pdaliasframe->bboxmax.v[i]; + } + + pinframe = (trivertx_t *)(pdaliasframe + 1); + pframe = Hunk_AllocName (numv * sizeof(*pframe), loadname); + + *pframeindex = (byte *)pframe - (byte *)pheader; + + for (j=0 ; j<numv ; j++) + { + int k; + + // these are all byte values, so no need to deal with endianness + pframe[j].lightnormalindex = pinframe[j].lightnormalindex; + + for (k=0 ; k<3 ; k++) + { + pframe[j].v[k] = pinframe[j].v[k]; + } + } + + pinframe += numv; + + return (void *)pinframe; +} + + +/* +================= +Mod_LoadAliasGroup +================= +*/ +void * Mod_LoadAliasGroup (void * pin, int *pframeindex, int numv, + trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name) +{ + daliasgroup_t *pingroup; + maliasgroup_t *paliasgroup; + int i, numframes; + daliasinterval_t *pin_intervals; + float *poutintervals; + void *ptemp; + + pingroup = (daliasgroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + paliasgroup = Hunk_AllocName (sizeof (maliasgroup_t) + + (numframes - 1) * sizeof (paliasgroup->frames[0]), loadname); + + paliasgroup->numframes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + pbboxmin->v[i] = pingroup->bboxmin.v[i]; + pbboxmax->v[i] = pingroup->bboxmax.v[i]; + } + + *pframeindex = (byte *)paliasgroup - (byte *)pheader; + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + paliasgroup->intervals = (byte *)poutintervals - (byte *)pheader; + + for (i=0 ; i<numframes ; i++) + { + *poutintervals = LittleFloat (pin_intervals->interval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadAliasGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; i<numframes ; i++) + { + ptemp = Mod_LoadAliasFrame (ptemp, + &paliasgroup->frames[i].frame, + numv, + &paliasgroup->frames[i].bboxmin, + &paliasgroup->frames[i].bboxmax, + pheader, name); + } + + return ptemp; +} + + +/* +================= +Mod_LoadAliasSkin +================= +*/ +void * Mod_LoadAliasSkin (void * pin, int *pskinindex, int skinsize, + aliashdr_t *pheader) +{ + int i; + byte *pskin, *pinskin; + unsigned short *pusskin; + + pskin = Hunk_AllocName (skinsize * r_pixbytes, loadname); + pinskin = (byte *)pin; + *pskinindex = (byte *)pskin - (byte *)pheader; + + if (r_pixbytes == 1) + { + Q_memcpy (pskin, pinskin, skinsize); + } + else if (r_pixbytes == 2) + { + pusskin = (unsigned short *)pskin; + + for (i=0 ; i<skinsize ; i++) + pusskin[i] = d_8to16table[pinskin[i]]; + } + else + { + Sys_Error ("Mod_LoadAliasSkin: driver set invalid r_pixbytes: %d\n", + r_pixbytes); + } + + pinskin += skinsize; + + return ((void *)pinskin); +} + + +/* +================= +Mod_LoadAliasSkinGroup +================= +*/ +void * Mod_LoadAliasSkinGroup (void * pin, int *pskinindex, int skinsize, + aliashdr_t *pheader) +{ + daliasskingroup_t *pinskingroup; + maliasskingroup_t *paliasskingroup; + int i, numskins; + daliasskininterval_t *pinskinintervals; + float *poutskinintervals; + void *ptemp; + + pinskingroup = (daliasskingroup_t *)pin; + + numskins = LittleLong (pinskingroup->numskins); + + paliasskingroup = Hunk_AllocName (sizeof (maliasskingroup_t) + + (numskins - 1) * sizeof (paliasskingroup->skindescs[0]), + loadname); + + paliasskingroup->numskins = numskins; + + *pskinindex = (byte *)paliasskingroup - (byte *)pheader; + + pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); + + poutskinintervals = Hunk_AllocName (numskins * sizeof (float),loadname); + + paliasskingroup->intervals = (byte *)poutskinintervals - (byte *)pheader; + + for (i=0 ; i<numskins ; i++) + { + *poutskinintervals = LittleFloat (pinskinintervals->interval); + if (*poutskinintervals <= 0) + Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0"); + + poutskinintervals++; + pinskinintervals++; + } + + ptemp = (void *)pinskinintervals; + + for (i=0 ; i<numskins ; i++) + { + ptemp = Mod_LoadAliasSkin (ptemp, + &paliasskingroup->skindescs[i].skin, skinsize, pheader); + } + + return ptemp; +} + + +/* +================= +Mod_LoadAliasModel +================= +*/ +void Mod_LoadAliasModel (model_t *mod, void *buffer) +{ + int i; + mdl_t *pmodel, *pinmodel; + stvert_t *pstverts, *pinstverts; + aliashdr_t *pheader; + mtriangle_t *ptri; + dtriangle_t *pintriangles; + int version, numframes, numskins; + int size; + daliasframetype_t *pframetype; + daliasskintype_t *pskintype; + maliasskindesc_t *pskindesc; + int skinsize; + int start, end, total; + + if (!strcmp(loadmodel->name, "progs/player.mdl") || + !strcmp(loadmodel->name, "progs/eyes.mdl")) { + unsigned short crc; + byte *p; + int len; + char st[40]; + + CRC_Init(&crc); + for (len = com_filesize, p = buffer; len; len--, p++) + CRC_ProcessByte(&crc, *p); + + sprintf(st, "%d", (int) crc); + Info_SetValueForKey (cls.userinfo, + !strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name, + st, MAX_INFO_STRING); + + if (cls.state >= ca_connected) { + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + sprintf(st, "setinfo %s %d", + !strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name, + (int)crc); + SZ_Print (&cls.netchan.message, st); + } + } + + start = Hunk_LowMark (); + + pinmodel = (mdl_t *)buffer; + + version = LittleLong (pinmodel->version); + if (version != ALIAS_VERSION) + Sys_Error ("%s has wrong version number (%i should be %i)", + mod->name, version, ALIAS_VERSION); + +// +// allocate space for a working header, plus all the data except the frames, +// skin and group info +// + size = sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) * + sizeof (pheader->frames[0]) + + sizeof (mdl_t) + + LittleLong (pinmodel->numverts) * sizeof (stvert_t) + + LittleLong (pinmodel->numtris) * sizeof (mtriangle_t); + + pheader = Hunk_AllocName (size, loadname); + pmodel = (mdl_t *) ((byte *)&pheader[1] + + (LittleLong (pinmodel->numframes) - 1) * + sizeof (pheader->frames[0])); + +// mod->cache.data = pheader; + mod->flags = LittleLong (pinmodel->flags); + +// +// endian-adjust and copy the data, starting with the alias model header +// + pmodel->boundingradius = LittleFloat (pinmodel->boundingradius); + pmodel->numskins = LittleLong (pinmodel->numskins); + pmodel->skinwidth = LittleLong (pinmodel->skinwidth); + pmodel->skinheight = LittleLong (pinmodel->skinheight); + + if (pmodel->skinheight > MAX_LBM_HEIGHT) + Sys_Error ("model %s has a skin taller than %d", mod->name, + MAX_LBM_HEIGHT); + + pmodel->numverts = LittleLong (pinmodel->numverts); + + if (pmodel->numverts <= 0) + Sys_Error ("model %s has no vertices", mod->name); + + if (pmodel->numverts > MAXALIASVERTS) + Sys_Error ("model %s has too many vertices", mod->name); + + pmodel->numtris = LittleLong (pinmodel->numtris); + + if (pmodel->numtris <= 0) + Sys_Error ("model %s has no triangles", mod->name); + + pmodel->numframes = LittleLong (pinmodel->numframes); + pmodel->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; + mod->synctype = LittleLong (pinmodel->synctype); + mod->numframes = pmodel->numframes; + + for (i=0 ; i<3 ; i++) + { + pmodel->scale[i] = LittleFloat (pinmodel->scale[i]); + pmodel->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); + pmodel->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); + } + + numskins = pmodel->numskins; + numframes = pmodel->numframes; + + if (pmodel->skinwidth & 0x03) + Sys_Error ("Mod_LoadAliasModel: skinwidth not multiple of 4"); + + pheader->model = (byte *)pmodel - (byte *)pheader; + +// +// load the skins +// + skinsize = pmodel->skinheight * pmodel->skinwidth; + + if (numskins < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); + + pskintype = (daliasskintype_t *)&pinmodel[1]; + + pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t), + loadname); + + pheader->skindesc = (byte *)pskindesc - (byte *)pheader; + + for (i=0 ; i<numskins ; i++) + { + aliasskintype_t skintype; + + skintype = LittleLong (pskintype->type); + pskindesc[i].type = skintype; + + if (skintype == ALIAS_SKIN_SINGLE) + { + pskintype = (daliasskintype_t *) + Mod_LoadAliasSkin (pskintype + 1, + &pskindesc[i].skin, + skinsize, pheader); + } + else + { + pskintype = (daliasskintype_t *) + Mod_LoadAliasSkinGroup (pskintype + 1, + &pskindesc[i].skin, + skinsize, pheader); + } + } + +// +// set base s and t vertices +// + pstverts = (stvert_t *)&pmodel[1]; + pinstverts = (stvert_t *)pskintype; + + pheader->stverts = (byte *)pstverts - (byte *)pheader; + + for (i=0 ; i<pmodel->numverts ; i++) + { + pstverts[i].onseam = LittleLong (pinstverts[i].onseam); + // put s and t in 16.16 format + pstverts[i].s = LittleLong (pinstverts[i].s) << 16; + pstverts[i].t = LittleLong (pinstverts[i].t) << 16; + } + +// +// set up the triangles +// + ptri = (mtriangle_t *)&pstverts[pmodel->numverts]; + pintriangles = (dtriangle_t *)&pinstverts[pmodel->numverts]; + + pheader->triangles = (byte *)ptri - (byte *)pheader; + + for (i=0 ; i<pmodel->numtris ; i++) + { + int j; + + ptri[i].facesfront = LittleLong (pintriangles[i].facesfront); + + for (j=0 ; j<3 ; j++) + { + ptri[i].vertindex[j] = + LittleLong (pintriangles[i].vertindex[j]); + } + } + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); + + pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris]; + + for (i=0 ; i<numframes ; i++) + { + aliasframetype_t frametype; + + frametype = LittleLong (pframetype->type); + pheader->frames[i].type = frametype; + + + if (frametype == ALIAS_SINGLE) + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasFrame (pframetype + 1, + &pheader->frames[i].frame, + pmodel->numverts, + &pheader->frames[i].bboxmin, + &pheader->frames[i].bboxmax, + pheader, pheader->frames[i].name); + } + else + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasGroup (pframetype + 1, + &pheader->frames[i].frame, + pmodel->numverts, + &pheader->frames[i].bboxmin, + &pheader->frames[i].bboxmax, + pheader, pheader->frames[i].name); + } + } + + mod->type = mod_alias; + +// FIXME: do this right + mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; + mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; + +// +// move the complete, relocatable alias model to the cache +// + end = Hunk_LowMark (); + total = end - start; + + Cache_Alloc (&mod->cache, total, loadname); + if (!mod->cache.data) + return; + memcpy (mod->cache.data, pheader, total); + + Hunk_FreeToLowMark (start); +} + +//============================================================================= + +/* +================= +Mod_LoadSpriteFrame +================= +*/ +void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe) +{ + dspriteframe_t *pinframe; + mspriteframe_t *pspriteframe; + int i, width, height, size, origin[2]; + unsigned short *ppixout; + byte *ppixin; + + pinframe = (dspriteframe_t *)pin; + + width = LittleLong (pinframe->width); + height = LittleLong (pinframe->height); + size = width * height; + + pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t) + size*r_pixbytes, + loadname); + + Q_memset (pspriteframe, 0, sizeof (mspriteframe_t) + size); + *ppframe = pspriteframe; + + pspriteframe->width = width; + pspriteframe->height = height; + origin[0] = LittleLong (pinframe->origin[0]); + origin[1] = LittleLong (pinframe->origin[1]); + + pspriteframe->up = origin[1]; + pspriteframe->down = origin[1] - height; + pspriteframe->left = origin[0]; + pspriteframe->right = width + origin[0]; + + if (r_pixbytes == 1) + { + Q_memcpy (&pspriteframe->pixels[0], (byte *)(pinframe + 1), size); + } + else if (r_pixbytes == 2) + { + ppixin = (byte *)(pinframe + 1); + ppixout = (unsigned short *)&pspriteframe->pixels[0]; + + for (i=0 ; i<size ; i++) + ppixout[i] = d_8to16table[ppixin[i]]; + } + else + { + Sys_Error ("Mod_LoadSpriteFrame: driver set invalid r_pixbytes: %d\n", + r_pixbytes); + } + + return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size); +} + + +/* +================= +Mod_LoadSpriteGroup +================= +*/ +void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe) +{ + dspritegroup_t *pingroup; + mspritegroup_t *pspritegroup; + int i, numframes; + dspriteinterval_t *pin_intervals; + float *poutintervals; + void *ptemp; + + pingroup = (dspritegroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + + (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); + + pspritegroup->numframes = numframes; + + *ppframe = (mspriteframe_t *)pspritegroup; + + pin_intervals = (dspriteinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + pspritegroup->intervals = poutintervals; + + for (i=0 ; i<numframes ; i++) + { + *poutintervals = LittleFloat (pin_intervals->interval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; i<numframes ; i++) + { + ptemp = Mod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i]); + } + + return ptemp; +} + + +/* +================= +Mod_LoadSpriteModel +================= +*/ +void Mod_LoadSpriteModel (model_t *mod, void *buffer) +{ + int i; + int version; + dsprite_t *pin; + msprite_t *psprite; + int numframes; + int size; + dspriteframetype_t *pframetype; + + pin = (dsprite_t *)buffer; + + version = LittleLong (pin->version); + if (version != SPRITE_VERSION) + Sys_Error ("%s has wrong version number " + "(%i should be %i)", mod->name, version, SPRITE_VERSION); + + numframes = LittleLong (pin->numframes); + + size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); + + psprite = Hunk_AllocName (size, loadname); + + mod->cache.data = psprite; + + psprite->type = LittleLong (pin->type); + psprite->maxwidth = LittleLong (pin->width); + psprite->maxheight = LittleLong (pin->height); + psprite->beamlength = LittleFloat (pin->beamlength); + mod->synctype = LittleLong (pin->synctype); + psprite->numframes = numframes; + + mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; + mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; + mod->mins[2] = -psprite->maxheight/2; + mod->maxs[2] = psprite->maxheight/2; + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); + + mod->numframes = numframes; + + pframetype = (dspriteframetype_t *)(pin + 1); + + for (i=0 ; i<numframes ; i++) + { + spriteframetype_t frametype; + + frametype = LittleLong (pframetype->type); + psprite->frames[i].type = frametype; + + if (frametype == SPR_SINGLE) + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteFrame (pframetype + 1, + &psprite->frames[i].frameptr); + } + else + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteGroup (pframetype + 1, + &psprite->frames[i].frameptr); + } + } + + mod->type = mod_sprite; +} + +//============================================================================= + +/* +================ +Mod_Print +================ +*/ +void Mod_Print (void) +{ + int i; + model_t *mod; + + Con_Printf ("Cached models:\n"); + for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++) + { + Con_Printf ("%8p : %s\n",mod->cache.data, mod->name); + } +} + + diff --git a/QW/client/model.h b/QW/client/model.h new file mode 100644 index 0000000..6487c42 --- /dev/null +++ b/QW/client/model.h @@ -0,0 +1,402 @@ +/* +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. + +*/ + +#ifndef __MODEL__ +#define __MODEL__ + +#include "modelgen.h" +#include "spritegn.h" + +/* + +d*_t structures are on-disk representations +m*_t structures are in-memory + +*/ + +// entity effects + +#define EF_BRIGHTFIELD 1 +#define EF_MUZZLEFLASH 2 +#define EF_BRIGHTLIGHT 4 +#define EF_DIMLIGHT 8 +#define EF_FLAG1 16 +#define EF_FLAG2 32 +#define EF_BLUE 64 +#define EF_RED 128 + +/* +============================================================================== + +BRUSH MODELS + +============================================================================== +*/ + + +// +// in memory representation +// +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + vec3_t position; +} mvertex_t; + +#define SIDE_FRONT 0 +#define SIDE_BACK 1 +#define SIDE_ON 2 + + +// plane_t structure +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct mplane_s +{ + vec3_t normal; + float dist; + byte type; // for texture axis selection and fast side tests + byte signbits; // signx + signy<<1 + signz<<1 + byte pad[2]; +} mplane_t; + +typedef struct texture_s +{ + char name[16]; + unsigned width, height; + int anim_total; // total tenths in sequence ( 0 = no) + int anim_min, anim_max; // time for this frame min <=time< max + struct texture_s *anim_next; // in the animation sequence + struct texture_s *alternate_anims; // bmodels in frmae 1 use these + unsigned offsets[MIPLEVELS]; // four mip maps stored +} texture_t; + + +#define SURF_PLANEBACK 2 +#define SURF_DRAWSKY 4 +#define SURF_DRAWSPRITE 8 +#define SURF_DRAWTURB 0x10 +#define SURF_DRAWTILED 0x20 +#define SURF_DRAWBACKGROUND 0x40 + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + unsigned short v[2]; + unsigned int cachededgeoffset; +} medge_t; + +typedef struct +{ + float vecs[2][4]; + float mipadjust; + texture_t *texture; + int flags; +} mtexinfo_t; + +typedef struct msurface_s +{ + int visframe; // should be drawn when node is crossed + + int dlightframe; + int dlightbits; + + mplane_t *plane; + int flags; + + int firstedge; // look up in model->surfedges[], negative numbers + int numedges; // are backwards edges + +// surface generation data + struct surfcache_s *cachespots[MIPLEVELS]; + + short texturemins[2]; + short extents[2]; + + mtexinfo_t *texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + byte *samples; // [numstyles*surfsize] +} msurface_t; + +typedef struct mnode_s +{ +// common with leaf + int contents; // 0, to differentiate from leafs + int visframe; // node needs to be traversed if current + + short minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// node specific + mplane_t *plane; + struct mnode_s *children[2]; + + unsigned short firstsurface; + unsigned short numsurfaces; +} mnode_t; + + + +typedef struct mleaf_s +{ +// common with node + int contents; // wil be a negative contents number + int visframe; // node needs to be traversed if current + + short minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// leaf specific + byte *compressed_vis; + struct efrag_s *efrags; + + msurface_t **firstmarksurface; + int nummarksurfaces; + int key; // BSP sequence number for leaf's contents + byte ambient_sound_level[NUM_AMBIENTS]; +} mleaf_t; + +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct +{ + dclipnode_t *clipnodes; + mplane_t *planes; + int firstclipnode; + int lastclipnode; + vec3_t clip_mins; + vec3_t clip_maxs; +} hull_t; + +/* +============================================================================== + +SPRITE MODELS + +============================================================================== +*/ + + +// FIXME: shorten these? +typedef struct mspriteframe_s +{ + int width; + int height; + void *pcachespot; // remove? + float up, down, left, right; + byte pixels[4]; +} mspriteframe_t; + +typedef struct +{ + int numframes; + float *intervals; + mspriteframe_t *frames[1]; +} mspritegroup_t; + +typedef struct +{ + spriteframetype_t type; + mspriteframe_t *frameptr; +} mspriteframedesc_t; + +typedef struct +{ + int type; + int maxwidth; + int maxheight; + int numframes; + float beamlength; // remove? + void *cachespot; // remove? + mspriteframedesc_t frames[1]; +} msprite_t; + + +/* +============================================================================== + +ALIAS MODELS + +Alias models are position independent, so the cache manager can move them. +============================================================================== +*/ + +typedef struct +{ + aliasframetype_t type; + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; + char name[16]; +} maliasframedesc_t; + +typedef struct +{ + aliasskintype_t type; + void *pcachespot; + int skin; +} maliasskindesc_t; + +typedef struct +{ + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; +} maliasgroupframedesc_t; + +typedef struct +{ + int numframes; + int intervals; + maliasgroupframedesc_t frames[1]; +} maliasgroup_t; + +typedef struct +{ + int numskins; + int intervals; + maliasskindesc_t skindescs[1]; +} maliasskingroup_t; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct mtriangle_s { + int facesfront; + int vertindex[3]; +} mtriangle_t; + +typedef struct { + int model; + int stverts; + int skindesc; + int triangles; + maliasframedesc_t frames[1]; +} aliashdr_t; + +//=================================================================== + +// +// Whole model +// + +typedef enum {mod_brush, mod_sprite, mod_alias} modtype_t; + +#define EF_ROCKET 1 // leave a trail +#define EF_GRENADE 2 // leave a trail +#define EF_GIB 4 // leave a trail +#define EF_ROTATE 8 // rotate (bonus items) +#define EF_TRACER 16 // green split trail +#define EF_ZOMGIB 32 // small blood trail +#define EF_TRACER2 64 // orange split trail + rotate +#define EF_TRACER3 128 // purple trail + +typedef struct model_s +{ + char name[MAX_QPATH]; + qboolean needload; // bmodels and sprites don't cache normally + + modtype_t type; + int numframes; + synctype_t synctype; + + int flags; + +// +// volume occupied by the model graphics +// + vec3_t mins, maxs; + float radius; + +// +// solid volume for clipping (sent from server) +// + qboolean clipbox; + vec3_t clipmins, clipmaxs; + +// +// brush model +// + int firstmodelsurface, nummodelsurfaces; + + int numsubmodels; + dmodel_t *submodels; + + int numplanes; + mplane_t *planes; + + int numleafs; // number of visible leafs, not counting 0 + mleaf_t *leafs; + + int numvertexes; + mvertex_t *vertexes; + + int numedges; + medge_t *edges; + + int numnodes; + mnode_t *nodes; + + int numtexinfo; + mtexinfo_t *texinfo; + + int numsurfaces; + msurface_t *surfaces; + + int numsurfedges; + int *surfedges; + + int numclipnodes; + dclipnode_t *clipnodes; + + int nummarksurfaces; + msurface_t **marksurfaces; + + hull_t hulls[MAX_MAP_HULLS]; + + int numtextures; + texture_t **textures; + + byte *visdata; + byte *lightdata; + char *entities; + + unsigned checksum; // for world models only + unsigned checksum2; // for world models only + +// +// additional model data +// + cache_user_t cache; // only access through Mod_Extradata + +} model_t; + +//============================================================================ + +void Mod_Init (void); +void Mod_ClearAll (void); +model_t *Mod_ForName (char *name, qboolean crash); +void *Mod_Extradata (model_t *mod); // handles caching +void Mod_TouchModel (char *name); + +mleaf_t *Mod_PointInLeaf (float *p, model_t *model); +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model); + +#endif // __MODEL__ diff --git a/QW/client/modelgen.h b/QW/client/modelgen.h new file mode 100644 index 0000000..be9ad92 --- /dev/null +++ b/QW/client/modelgen.h @@ -0,0 +1,134 @@ +/* +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. + +*/ +// +// modelgen.h: header file for model generation program +// + +// ********************************************************* +// * This file must be identical in the modelgen directory * +// * and in the Quake directory, because it's used to * +// * pass data from one to the other via model files. * +// ********************************************************* + +#ifdef INCLUDELIBS + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <string.h> + +#include "cmdlib.h" +#include "scriplib.h" +#include "trilib.h" +#include "lbmlib.h" +#include "mathlib.h" + +#endif + +#define ALIAS_VERSION 6 + +#define ALIAS_ONSEAM 0x0020 + +// must match definition in spritegn.h +#ifndef SYNCTYPE_T +#define SYNCTYPE_T +typedef enum {ST_SYNC=0, ST_RAND } synctype_t; +#endif + +typedef enum { ALIAS_SINGLE=0, ALIAS_GROUP } aliasframetype_t; + +typedef enum { ALIAS_SKIN_SINGLE=0, ALIAS_SKIN_GROUP } aliasskintype_t; + +typedef struct { + int ident; + int version; + vec3_t scale; + vec3_t scale_origin; + float boundingradius; + vec3_t eyeposition; + int numskins; + int skinwidth; + int skinheight; + int numverts; + int numtris; + int numframes; + synctype_t synctype; + int flags; + float size; +} mdl_t; + +// TODO: could be shorts + +typedef struct { + int onseam; + int s; + int t; +} stvert_t; + +typedef struct dtriangle_s { + int facesfront; + int vertindex[3]; +} dtriangle_t; + +#define DT_FACES_FRONT 0x0010 + +// This mirrors trivert_t in trilib.h, is present so Quake knows how to +// load this data + +typedef struct { + byte v[3]; + byte lightnormalindex; +} trivertx_t; + +typedef struct { + trivertx_t bboxmin; // lightnormal isn't used + trivertx_t bboxmax; // lightnormal isn't used + char name[16]; // frame name from grabbing +} daliasframe_t; + +typedef struct { + int numframes; + trivertx_t bboxmin; // lightnormal isn't used + trivertx_t bboxmax; // lightnormal isn't used +} daliasgroup_t; + +typedef struct { + int numskins; +} daliasskingroup_t; + +typedef struct { + float interval; +} daliasinterval_t; + +typedef struct { + float interval; +} daliasskininterval_t; + +typedef struct { + aliasframetype_t type; +} daliasframetype_t; + +typedef struct { + aliasskintype_t type; +} daliasskintype_t; + +#define IDPOLYHEADER (('O'<<24)+('P'<<16)+('D'<<8)+'I') + // little-endian "IDPO" + diff --git a/QW/client/net.h b/QW/client/net.h new file mode 100644 index 0000000..30be2f7 --- /dev/null +++ b/QW/client/net.h @@ -0,0 +1,112 @@ +/* +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. + +*/ +// net.h -- quake's interface to the networking layer + +#define PORT_ANY -1 + +typedef struct +{ + byte ip[4]; + unsigned short port; + unsigned short pad; +} netadr_t; + +extern netadr_t net_local_adr; +extern netadr_t net_from; // address of who sent the packet +extern sizebuf_t net_message; + +extern cvar_t hostname; + +extern int net_socket; + +void NET_Init (int port); +void NET_Shutdown (void); +qboolean NET_GetPacket (void); +void NET_SendPacket (int length, void *data, netadr_t to); + +qboolean NET_CompareAdr (netadr_t a, netadr_t b); +qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b); +char *NET_AdrToString (netadr_t a); +char *NET_BaseAdrToString (netadr_t a); +qboolean NET_StringToAdr (char *s, netadr_t *a); +qboolean NET_IsClientLegal(netadr_t *adr); + +//============================================================================ + +#define OLD_AVG 0.99 // total = oldtotal*OLD_AVG + new*(1-OLD_AVG) + +#define MAX_LATENT 32 + +typedef struct +{ + qboolean fatal_error; + + float last_received; // for timeouts + +// the statistics are cleared at each client begin, because +// the server connecting process gives a bogus picture of the data + float frame_latency; // rolling average + float frame_rate; + + int drop_count; // dropped packets, cleared each level + int good_count; // cleared each level + + netadr_t remote_address; + int qport; + +// bandwidth estimator + double cleartime; // if realtime > nc->cleartime, free to go + double rate; // seconds / byte + +// sequencing variables + int incoming_sequence; + int incoming_acknowledged; + int incoming_reliable_acknowledged; // single bit + + int incoming_reliable_sequence; // single bit, maintained local + + int outgoing_sequence; + int reliable_sequence; // single bit + int last_reliable_sequence; // sequence number of last send + +// reliable staging and holding areas + sizebuf_t message; // writing buffer to send to server + byte message_buf[MAX_MSGLEN]; + + int reliable_length; + byte reliable_buf[MAX_MSGLEN]; // unacked reliable message + +// time and size data to calculate bandwidth + int outgoing_size[MAX_LATENT]; + double outgoing_time[MAX_LATENT]; +} netchan_t; + +extern int net_drop; // packets dropped before this one + +void Netchan_Init (void); +void Netchan_Transmit (netchan_t *chan, int length, byte *data); +void Netchan_OutOfBand (netadr_t adr, int length, byte *data); +void Netchan_OutOfBandPrint (netadr_t adr, char *format, ...); +qboolean Netchan_Process (netchan_t *chan); +void Netchan_Setup (netchan_t *chan, netadr_t adr, int qport); + +qboolean Netchan_CanPacket (netchan_t *chan); +qboolean Netchan_CanReliable (netchan_t *chan); + diff --git a/QW/client/net_chan.c b/QW/client/net_chan.c new file mode 100644 index 0000000..bd325a1 --- /dev/null +++ b/QW/client/net_chan.c @@ -0,0 +1,452 @@ +/* +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. + +*/ + +#include "quakedef.h" + +#ifdef _WIN32 +#include "winquake.h" +#endif + +#define PACKET_HEADER 8 + +/* + +packet header +------------- +31 sequence +1 does this message contain a reliable payload +31 acknowledge sequence +1 acknowledge receipt of even/odd message +16 qport + +The remote connection never knows if it missed a reliable message, the +local side detects that it has been dropped by seeing a sequence acknowledge +higher thatn the last reliable sequence, but without the correct evon/odd +bit for the reliable set. + +If the sender notices that a reliable message has been dropped, it will be +retransmitted. It will not be retransmitted again until a message after +the retransmit has been acknowledged and the reliable still failed to get there. + +if the sequence number is -1, the packet should be handled without a netcon + +The reliable message can be added to at any time by doing +MSG_Write* (&netchan->message, <data>). + +If the message buffer is overflowed, either by a single message, or by +multiple frames worth piling up while the last reliable transmit goes +unacknowledged, the netchan signals a fatal error. + +Reliable messages are allways placed first in a packet, then the unreliable +message is included if there is sufficient room. + +To the receiver, there is no distinction between the reliable and unreliable +parts of the message, they are just processed out as a single larger message. + +Illogical packet sequence numbers cause the packet to be dropped, but do +not kill the connection. This, combined with the tight window of valid +reliable acknowledgement numbers provides protection against malicious +address spoofing. + +The qport field is a workaround for bad address translating routers that +sometimes remap the client's source port on a packet during gameplay. + +If the base part of the net address matches and the qport matches, then the +channel matches even if the IP port differs. The IP port should be updated +to the new value before sending out any replies. + + +*/ + +int net_drop; +cvar_t showpackets = {"showpackets", "0"}; +cvar_t showdrop = {"showdrop", "0"}; +cvar_t qport = {"qport", "0"}; + +/* +=============== +Netchan_Init + +=============== +*/ +void Netchan_Init (void) +{ + int port; + + // pick a port value that should be nice and random +#ifdef _WIN32 + port = ((int)(timeGetTime()*1000) * time(NULL)) & 0xffff; +#else + port = ((int)(getpid()+getuid()*1000) * time(NULL)) & 0xffff; +#endif + + Cvar_RegisterVariable (&showpackets); + Cvar_RegisterVariable (&showdrop); + Cvar_RegisterVariable (&qport); + Cvar_SetValue("qport", port); +} + +/* +=============== +Netchan_OutOfBand + +Sends an out-of-band datagram +================ +*/ +void Netchan_OutOfBand (netadr_t adr, int length, byte *data) +{ + sizebuf_t send; + byte send_buf[MAX_MSGLEN + PACKET_HEADER]; + +// write the packet header + send.data = send_buf; + send.maxsize = sizeof(send_buf); + send.cursize = 0; + + MSG_WriteLong (&send, -1); // -1 sequence means out of band + SZ_Write (&send, data, length); + +// send the datagram + //zoid, no input in demo playback mode +#ifndef SERVERONLY + if (!cls.demoplayback) +#endif + NET_SendPacket (send.cursize, send.data, adr); +} + +/* +=============== +Netchan_OutOfBandPrint + +Sends a text message in an out-of-band datagram +================ +*/ +void Netchan_OutOfBandPrint (netadr_t adr, char *format, ...) +{ + va_list argptr; + static char string[8192]; // ??? why static? + + va_start (argptr, format); + vsprintf (string, format,argptr); + va_end (argptr); + + + Netchan_OutOfBand (adr, strlen(string), (byte *)string); +} + + +/* +============== +Netchan_Setup + +called to open a channel to a remote system +============== +*/ +void Netchan_Setup (netchan_t *chan, netadr_t adr, int qport) +{ + memset (chan, 0, sizeof(*chan)); + + chan->remote_address = adr; + chan->last_received = realtime; + + chan->message.data = chan->message_buf; + chan->message.allowoverflow = true; + chan->message.maxsize = sizeof(chan->message_buf); + + chan->qport = qport; + + chan->rate = 1.0/2500; +} + + +/* +=============== +Netchan_CanPacket + +Returns true if the bandwidth choke isn't active +================ +*/ +#define MAX_BACKUP 200 +qboolean Netchan_CanPacket (netchan_t *chan) +{ + if (chan->cleartime < realtime + MAX_BACKUP*chan->rate) + return true; + return false; +} + + +/* +=============== +Netchan_CanReliable + +Returns true if the bandwidth choke isn't +================ +*/ +qboolean Netchan_CanReliable (netchan_t *chan) +{ + if (chan->reliable_length) + return false; // waiting for ack + return Netchan_CanPacket (chan); +} + +#ifdef SERVERONLY +qboolean ServerPaused(void); +#endif + +/* +=============== +Netchan_Transmit + +tries to send an unreliable message to a connection, and handles the +transmition / retransmition of the reliable messages. + +A 0 length will still generate a packet and deal with the reliable messages. +================ +*/ +void Netchan_Transmit (netchan_t *chan, int length, byte *data) +{ + sizebuf_t send; + byte send_buf[MAX_MSGLEN + PACKET_HEADER]; + qboolean send_reliable; + unsigned w1, w2; + int i; + +// check for message overflow + if (chan->message.overflowed) + { + chan->fatal_error = true; + Con_Printf ("%s:Outgoing message overflow\n" + , NET_AdrToString (chan->remote_address)); + return; + } + +// if the remote side dropped the last reliable message, resend it + send_reliable = false; + + if (chan->incoming_acknowledged > chan->last_reliable_sequence + && chan->incoming_reliable_acknowledged != chan->reliable_sequence) + send_reliable = true; + +// if the reliable transmit buffer is empty, copy the current message out + if (!chan->reliable_length && chan->message.cursize) + { + memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize); + chan->reliable_length = chan->message.cursize; + chan->message.cursize = 0; + chan->reliable_sequence ^= 1; + send_reliable = true; + } + +// write the packet header + send.data = send_buf; + send.maxsize = sizeof(send_buf); + send.cursize = 0; + + w1 = chan->outgoing_sequence | (send_reliable<<31); + w2 = chan->incoming_sequence | (chan->incoming_reliable_sequence<<31); + + chan->outgoing_sequence++; + + MSG_WriteLong (&send, w1); + MSG_WriteLong (&send, w2); + + // send the qport if we are a client +#ifndef SERVERONLY + MSG_WriteShort (&send, cls.qport); +#endif + +// copy the reliable message to the packet first + if (send_reliable) + { + SZ_Write (&send, chan->reliable_buf, chan->reliable_length); + chan->last_reliable_sequence = chan->outgoing_sequence; + } + +// add the unreliable part if space is available + if (send.maxsize - send.cursize >= length) + SZ_Write (&send, data, length); + +// send the datagram + i = chan->outgoing_sequence & (MAX_LATENT-1); + chan->outgoing_size[i] = send.cursize; + chan->outgoing_time[i] = realtime; + + //zoid, no input in demo playback mode +#ifndef SERVERONLY + if (!cls.demoplayback) +#endif + NET_SendPacket (send.cursize, send.data, chan->remote_address); + + if (chan->cleartime < realtime) + chan->cleartime = realtime + send.cursize*chan->rate; + else + chan->cleartime += send.cursize*chan->rate; +#ifdef SERVERONLY + if (ServerPaused()) + chan->cleartime = realtime; +#endif + + if (showpackets.value) + Con_Printf ("--> s=%i(%i) a=%i(%i) %i\n" + , chan->outgoing_sequence + , send_reliable + , chan->incoming_sequence + , chan->incoming_reliable_sequence + , send.cursize); + +} + +/* +================= +Netchan_Process + +called when the current net_message is from remote_address +modifies net_message so that it points to the packet payload +================= +*/ +qboolean Netchan_Process (netchan_t *chan) +{ + unsigned sequence, sequence_ack; + unsigned reliable_ack, reliable_message; +#ifdef SERVERONLY + int qport; +#endif + int i; + + if ( +#ifndef SERVERONLY + !cls.demoplayback && +#endif + !NET_CompareAdr (net_from, chan->remote_address)) + return false; + +// get sequence numbers + MSG_BeginReading (); + sequence = MSG_ReadLong (); + sequence_ack = MSG_ReadLong (); + + // read the qport if we are a server +#ifdef SERVERONLY + qport = MSG_ReadShort (); +#endif + + reliable_message = sequence >> 31; + reliable_ack = sequence_ack >> 31; + + sequence &= ~(1<<31); + sequence_ack &= ~(1<<31); + + if (showpackets.value) + Con_Printf ("<-- s=%i(%i) a=%i(%i) %i\n" + , sequence + , reliable_message + , sequence_ack + , reliable_ack + , net_message.cursize); + +// get a rate estimation +#if 0 + if (chan->outgoing_sequence - sequence_ack < MAX_LATENT) + { + int i; + double time, rate; + + i = sequence_ack & (MAX_LATENT - 1); + time = realtime - chan->outgoing_time[i]; + time -= 0.1; // subtract 100 ms + if (time <= 0) + { // gotta be a digital link for <100 ms ping + if (chan->rate > 1.0/5000) + chan->rate = 1.0/5000; + } + else + { + if (chan->outgoing_size[i] < 512) + { // only deal with small messages + rate = chan->outgoing_size[i]/time; + if (rate > 5000) + rate = 5000; + rate = 1.0/rate; + if (chan->rate > rate) + chan->rate = rate; + } + } + } +#endif + +// +// discard stale or duplicated packets +// + if (sequence <= (unsigned)chan->incoming_sequence) + { + if (showdrop.value) + Con_Printf ("%s:Out of order packet %i at %i\n" + , NET_AdrToString (chan->remote_address) + , sequence + , chan->incoming_sequence); + return false; + } + +// +// dropped packets don't keep the message from being used +// + net_drop = sequence - (chan->incoming_sequence+1); + if (net_drop > 0) + { + chan->drop_count += 1; + + if (showdrop.value) + Con_Printf ("%s:Dropped %i packets at %i\n" + , NET_AdrToString (chan->remote_address) + , sequence-(chan->incoming_sequence+1) + , sequence); + } + +// +// if the current outgoing reliable message has been acknowledged +// clear the buffer to make way for the next +// + if (reliable_ack == (unsigned)chan->reliable_sequence) + chan->reliable_length = 0; // it has been received + +// +// if this message contains a reliable message, bump incoming_reliable_sequence +// + chan->incoming_sequence = sequence; + chan->incoming_acknowledged = sequence_ack; + chan->incoming_reliable_acknowledged = reliable_ack; + if (reliable_message) + chan->incoming_reliable_sequence ^= 1; + +// +// the message can now be read from the current message pointer +// update statistics counters +// + chan->frame_latency = chan->frame_latency*OLD_AVG + + (chan->outgoing_sequence-sequence_ack)*(1.0-OLD_AVG); + chan->frame_rate = chan->frame_rate*OLD_AVG + + (realtime-chan->last_received)*(1.0-OLD_AVG); + chan->good_count += 1; + + chan->last_received = realtime; + + return true; +} + diff --git a/QW/client/net_udp.c b/QW/client/net_udp.c new file mode 100644 index 0000000..758b9bc --- /dev/null +++ b/QW/client/net_udp.c @@ -0,0 +1,318 @@ +/* +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. + +*/ +// net_main.c + +#include "quakedef.h" + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <sys/param.h> +#include <sys/ioctl.h> +#include <sys/uio.h> +#include <arpa/inet.h> +#include <errno.h> + +#if defined(sun) +#include <unistd.h> +#endif + +#ifdef sun +#include <sys/filio.h> +#endif + +#ifdef NeXT +#include <libc.h> +#endif + +netadr_t net_local_adr; + +netadr_t net_from; +sizebuf_t net_message; +int net_socket; // non blocking, for receives +int net_send_socket; // blocking, for sends + +#define MAX_UDP_PACKET 8192 +byte net_message_buffer[MAX_UDP_PACKET]; + +int gethostname (char *, int); +int close (int); + +//============================================================================= + +void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s) +{ + memset (s, 0, sizeof(*s)); + s->sin_family = AF_INET; + + *(int *)&s->sin_addr = *(int *)&a->ip; + s->sin_port = a->port; +} + +void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a) +{ + *(int *)&a->ip = *(int *)&s->sin_addr; + a->port = s->sin_port; +} + +qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b) +{ + if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3]) + return true; + return false; +} + + +qboolean NET_CompareAdr (netadr_t a, netadr_t b) +{ + if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port) + return true; + return false; +} + +char *NET_AdrToString (netadr_t a) +{ + static char s[64]; + + sprintf (s, "%i.%i.%i.%i:%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3], ntohs(a.port)); + + return s; +} + +char *NET_BaseAdrToString (netadr_t a) +{ + static char s[64]; + + sprintf (s, "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]); + + return s; +} + +/* +============= +NET_StringToAdr + +idnewt +idnewt:28000 +192.246.40.70 +192.246.40.70:28000 +============= +*/ +qboolean NET_StringToAdr (char *s, netadr_t *a) +{ + struct hostent *h; + struct sockaddr_in sadr; + char *colon; + char copy[128]; + + + memset (&sadr, 0, sizeof(sadr)); + sadr.sin_family = AF_INET; + + sadr.sin_port = 0; + + strcpy (copy, s); + // strip off a trailing :port if present + for (colon = copy ; *colon ; colon++) + if (*colon == ':') + { + *colon = 0; + sadr.sin_port = htons(atoi(colon+1)); + } + + if (copy[0] >= '0' && copy[0] <= '9') + { + *(int *)&sadr.sin_addr = inet_addr(copy); + } + else + { + if (! (h = gethostbyname(copy)) ) + return 0; + *(int *)&sadr.sin_addr = *(int *)h->h_addr_list[0]; + } + + SockadrToNetadr (&sadr, a); + + return true; +} + +// Returns true if we can't bind the address locally--in other words, +// the IP is NOT one of our interfaces. +qboolean NET_IsClientLegal(netadr_t *adr) +{ + struct sockaddr_in sadr; + int newsocket; + +#if 0 + if (adr->ip[0] == 127) + return false; // no local connections period + + NetadrToSockadr (adr, &sadr); + + if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + Sys_Error ("NET_IsClientLegal: socket:", strerror(errno)); + + sadr.sin_port = 0; + + if( bind (newsocket, (void *)&sadr, sizeof(sadr)) == -1) + { + // It is not a local address + close(newsocket); + return true; + } + close(newsocket); + return false; +#else + return true; +#endif +} + + +//============================================================================= + +qboolean NET_GetPacket (void) +{ + int ret; + struct sockaddr_in from; + int fromlen; + + fromlen = sizeof(from); + ret = recvfrom (net_socket, net_message_buffer, sizeof(net_message_buffer), 0, (struct sockaddr *)&from, &fromlen); + if (ret == -1) { + if (errno == EWOULDBLOCK) + return false; + if (errno == ECONNREFUSED) + return false; + Sys_Printf ("NET_GetPacket: %s\n", strerror(errno)); + return false; + } + + net_message.cursize = ret; + SockadrToNetadr (&from, &net_from); + + return ret; +} + +//============================================================================= + +void NET_SendPacket (int length, void *data, netadr_t to) +{ + int ret; + struct sockaddr_in addr; + + NetadrToSockadr (&to, &addr); + + ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) ); + if (ret == -1) { + if (errno == EWOULDBLOCK) + return; + if (errno == ECONNREFUSED) + return; + Sys_Printf ("NET_SendPacket: %s\n", strerror(errno)); + } +} + +//============================================================================= + +int UDP_OpenSocket (int port) +{ + int newsocket; + struct sockaddr_in address; + qboolean _true = true; + int i; + + if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + Sys_Error ("UDP_OpenSocket: socket:", strerror(errno)); + if (ioctl (newsocket, FIONBIO, (char *)&_true) == -1) + Sys_Error ("UDP_OpenSocket: ioctl FIONBIO:", strerror(errno)); + address.sin_family = AF_INET; +//ZOID -- check for interface binding option + if ((i = COM_CheckParm("-ip")) != 0 && i < com_argc) { + address.sin_addr.s_addr = inet_addr(com_argv[i+1]); + Con_Printf("Binding to IP Interface Address of %s\n", + inet_ntoa(address.sin_addr)); + } else + address.sin_addr.s_addr = INADDR_ANY; + if (port == PORT_ANY) + address.sin_port = 0; + else + address.sin_port = htons((short)port); + if( bind (newsocket, (void *)&address, sizeof(address)) == -1) + Sys_Error ("UDP_OpenSocket: bind: %s", strerror(errno)); + + return newsocket; +} + +void NET_GetLocalAddress (void) +{ + char buff[MAXHOSTNAMELEN]; + struct sockaddr_in address; + int namelen; + + gethostname(buff, MAXHOSTNAMELEN); + buff[MAXHOSTNAMELEN-1] = 0; + + NET_StringToAdr (buff, &net_local_adr); + + namelen = sizeof(address); + if (getsockname (net_socket, (struct sockaddr *)&address, &namelen) == -1) + Sys_Error ("NET_Init: getsockname:", strerror(errno)); + net_local_adr.port = address.sin_port; + + Con_Printf("IP address %s\n", NET_AdrToString (net_local_adr) ); +} + +/* +==================== +NET_Init +==================== +*/ +void NET_Init (int port) +{ + // + // open the single socket to be used for all communications + // + net_socket = UDP_OpenSocket (port); + + // + // init the message buffer + // + net_message.maxsize = sizeof(net_message_buffer); + net_message.data = net_message_buffer; + + // + // determine my name & address + // + NET_GetLocalAddress (); + + Con_Printf("UDP Initialized\n"); +} + +/* +==================== +NET_Shutdown +==================== +*/ +void NET_Shutdown (void) +{ + close (net_socket); +} + diff --git a/QW/client/net_wins.c b/QW/client/net_wins.c new file mode 100644 index 0000000..85a14a9 --- /dev/null +++ b/QW/client/net_wins.c @@ -0,0 +1,328 @@ +/* +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. + +*/ +// net_wins.c + +#include "quakedef.h" +#include "winquake.h" + +netadr_t net_local_adr; + +netadr_t net_from; +sizebuf_t net_message; +int net_socket; + +#define MAX_UDP_PACKET (MAX_MSGLEN*2) // one more than msg + header +byte net_message_buffer[MAX_UDP_PACKET]; + +WSADATA winsockdata; + +//============================================================================= + +void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s) +{ + memset (s, 0, sizeof(*s)); + s->sin_family = AF_INET; + + *(int *)&s->sin_addr = *(int *)&a->ip; + s->sin_port = a->port; +} + +void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a) +{ + *(int *)&a->ip = *(int *)&s->sin_addr; + a->port = s->sin_port; +} + +qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b) +{ + if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3]) + return true; + return false; +} + +qboolean NET_CompareAdr (netadr_t a, netadr_t b) +{ + if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port) + return true; + return false; +} + +char *NET_AdrToString (netadr_t a) +{ + static char s[64]; + + sprintf (s, "%i.%i.%i.%i:%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3], ntohs(a.port)); + + return s; +} + +char *NET_BaseAdrToString (netadr_t a) +{ + static char s[64]; + + sprintf (s, "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]); + + return s; +} + +/* +============= +NET_StringToAdr + +idnewt +idnewt:28000 +192.246.40.70 +192.246.40.70:28000 +============= +*/ +qboolean NET_StringToAdr (char *s, netadr_t *a) +{ + struct hostent *h; + struct sockaddr_in sadr; + char *colon; + char copy[128]; + + + memset (&sadr, 0, sizeof(sadr)); + sadr.sin_family = AF_INET; + + sadr.sin_port = 0; + + strcpy (copy, s); + // strip off a trailing :port if present + for (colon = copy ; *colon ; colon++) + if (*colon == ':') + { + *colon = 0; + sadr.sin_port = htons((short)atoi(colon+1)); + } + + if (copy[0] >= '0' && copy[0] <= '9') + { + *(int *)&sadr.sin_addr = inet_addr(copy); + } + else + { + if ((h = gethostbyname(copy)) == 0) + return 0; + *(int *)&sadr.sin_addr = *(int *)h->h_addr_list[0]; + } + + SockadrToNetadr (&sadr, a); + + return true; +} + +// Returns true if we can't bind the address locally--in other words, +// the IP is NOT one of our interfaces. +qboolean NET_IsClientLegal(netadr_t *adr) +{ + struct sockaddr_in sadr; + int newsocket; + +#if 0 + if (adr->ip[0] == 127) + return false; // no local connections period + + NetadrToSockadr (adr, &sadr); + + if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + Sys_Error ("NET_IsClientLegal: socket:", strerror(errno)); + + sadr.sin_port = 0; + + if( bind (newsocket, (void *)&sadr, sizeof(sadr)) == -1) + { + // It is not a local address + close(newsocket); + return true; + } + close(newsocket); + return false; +#else + return true; +#endif +} + +//============================================================================= + +qboolean NET_GetPacket (void) +{ + int ret; + struct sockaddr_in from; + int fromlen; + + fromlen = sizeof(from); + ret = recvfrom (net_socket, (char *)net_message_buffer, sizeof(net_message_buffer), 0, (struct sockaddr *)&from, &fromlen); + SockadrToNetadr (&from, &net_from); + + if (ret == -1) + { + int errno = WSAGetLastError(); + + if (errno == WSAEWOULDBLOCK) + return false; + if (errno == WSAEMSGSIZE) { + Con_Printf ("Warning: Oversize packet from %s\n", + NET_AdrToString (net_from)); + return false; + } + + + Sys_Error ("NET_GetPacket: %s", strerror(errno)); + } + + net_message.cursize = ret; + if (ret == sizeof(net_message_buffer) ) + { + Con_Printf ("Oversize packet from %s\n", NET_AdrToString (net_from)); + return false; + } + + return ret; +} + +//============================================================================= + +void NET_SendPacket (int length, void *data, netadr_t to) +{ + int ret; + struct sockaddr_in addr; + + NetadrToSockadr (&to, &addr); + + ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) ); + if (ret == -1) + { + int err = WSAGetLastError(); + +// wouldblock is silent + if (err == WSAEWOULDBLOCK) + return; + +#ifndef SERVERONLY + if (err == WSAEADDRNOTAVAIL) + Con_DPrintf("NET_SendPacket Warning: %i\n", err); + else +#endif + Con_Printf ("NET_SendPacket ERROR: %i\n", errno); + } +} + +//============================================================================= + +int UDP_OpenSocket (int port) +{ + int newsocket; + struct sockaddr_in address; + unsigned long _true = true; + int i; + + if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + Sys_Error ("UDP_OpenSocket: socket:", strerror(errno)); + + if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) + Sys_Error ("UDP_OpenSocket: ioctl FIONBIO:", strerror(errno)); + + address.sin_family = AF_INET; +//ZOID -- check for interface binding option + if ((i = COM_CheckParm("-ip")) != 0 && i < com_argc) { + address.sin_addr.s_addr = inet_addr(com_argv[i+1]); + Con_Printf("Binding to IP Interface Address of %s\n", + inet_ntoa(address.sin_addr)); + } else + address.sin_addr.s_addr = INADDR_ANY; + + if (port == PORT_ANY) + address.sin_port = 0; + else + address.sin_port = htons((short)port); + if( bind (newsocket, (void *)&address, sizeof(address)) == -1) + Sys_Error ("UDP_OpenSocket: bind: %s", strerror(errno)); + + return newsocket; +} + +void NET_GetLocalAddress (void) +{ + char buff[512]; + struct sockaddr_in address; + int namelen; + + gethostname(buff, 512); + buff[512-1] = 0; + + NET_StringToAdr (buff, &net_local_adr); + + namelen = sizeof(address); + if (getsockname (net_socket, (struct sockaddr *)&address, &namelen) == -1) + Sys_Error ("NET_Init: getsockname:", strerror(errno)); + net_local_adr.port = address.sin_port; + + Con_Printf("IP address %s\n", NET_AdrToString (net_local_adr) ); +} + +/* +==================== +NET_Init +==================== +*/ +void NET_Init (int port) +{ + WORD wVersionRequested; + int r; + + wVersionRequested = MAKEWORD(1, 1); + + r = WSAStartup (MAKEWORD(1, 1), &winsockdata); + + if (r) + Sys_Error ("Winsock initialization failed."); + + // + // open the single socket to be used for all communications + // + net_socket = UDP_OpenSocket (port); + + // + // init the message buffer + // + net_message.maxsize = sizeof(net_message_buffer); + net_message.data = net_message_buffer; + + // + // determine my name & address + // + NET_GetLocalAddress (); + + Con_Printf("UDP Initialized\n"); +} + +/* +==================== +NET_Shutdown +==================== +*/ +void NET_Shutdown (void) +{ + closesocket (net_socket); + WSACleanup (); +} + diff --git a/QW/client/nonintel.c b/QW/client/nonintel.c new file mode 100644 index 0000000..9163ee5 --- /dev/null +++ b/QW/client/nonintel.c @@ -0,0 +1,62 @@ +/* +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 + diff --git a/QW/client/notes.txt b/QW/client/notes.txt new file mode 100644 index 0000000..637487c --- /dev/null +++ b/QW/client/notes.txt @@ -0,0 +1,48 @@ + + +movecmd_t movecmd; + + +input from + +packet sender + wake up on alarms or input signal + if on input signal, set skipnextalrm + else + if skipnextalarm + skipnextalarm = false; + continue; + lock packet + get current movecmd + send message + unlock packet + +packet receiver + wake up only on packet arrival + identify the packet source + calculate exact latency + save the packet off + + + + + // cause timer messages to be issued + SetTimer (mainwindow, 1, 50, NULL); + + // cause packet received messages to be issued + WSAAsyncSelect ( net_socket, mainwindow, WM_USER, FD_READ ); + + if (!GetMessage (&msg, NULL, 0, 0)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) + { + if (!GetMessage (&msg, NULL, 0, 0)) + break; + TranslateMessage (&msg); + DispatchMessage (&msg); + } + PrepareToBlock (); + } + diff --git a/QW/client/pmove.c b/QW/client/pmove.c new file mode 100644 index 0000000..e8761be --- /dev/null +++ b/QW/client/pmove.c @@ -0,0 +1,904 @@ +/* +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. + +*/ + +#include "quakedef.h" + + +movevars_t movevars; + +playermove_t pmove; + +int onground; +int waterlevel; +int watertype; + +float frametime; + +vec3_t forward, right, up; + +vec3_t player_mins = {-16, -16, -24}; +vec3_t player_maxs = {16, 16, 32}; + +// #define PM_GRAVITY 800 +// #define PM_STOPSPEED 100 +// #define PM_MAXSPEED 320 +// #define PM_SPECTATORMAXSPEED 500 +// #define PM_ACCELERATE 10 +// #define PM_AIRACCELERATE 0.7 +// #define PM_WATERACCELERATE 10 +// #define PM_FRICTION 6 +// #define PM_WATERFRICTION 1 + +void PM_InitBoxHull (void); + +void Pmove_Init (void) +{ + PM_InitBoxHull (); +} + +#define STEPSIZE 18 + + +#define BUTTON_JUMP 2 + + +/* +================== +PM_ClipVelocity + +Slide off of the impacting object +returns the blocked flags (1 = floor, 2 = step / wall) +================== +*/ +#define STOP_EPSILON 0.1 + +int PM_ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) +{ + float backoff; + float change; + int i, blocked; + + blocked = 0; + if (normal[2] > 0) + blocked |= 1; // floor + if (!normal[2]) + blocked |= 2; // step + + backoff = DotProduct (in, normal) * overbounce; + + for (i=0 ; i<3 ; i++) + { + change = normal[i]*backoff; + out[i] = in[i] - change; + if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON) + out[i] = 0; + } + + return blocked; +} + + +/* +============ +PM_FlyMove + +The basic solid body movement clip that slides along multiple planes +============ +*/ +#define MAX_CLIP_PLANES 5 + +int PM_FlyMove (void) +{ + int bumpcount, numbumps; + vec3_t dir; + float d; + int numplanes; + vec3_t planes[MAX_CLIP_PLANES]; + vec3_t primal_velocity, original_velocity; + int i, j; + pmtrace_t trace; + vec3_t end; + float time_left; + int blocked; + + numbumps = 4; + + blocked = 0; + VectorCopy (pmove.velocity, original_velocity); + VectorCopy (pmove.velocity, primal_velocity); + numplanes = 0; + + time_left = frametime; + + for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++) + { + for (i=0 ; i<3 ; i++) + end[i] = pmove.origin[i] + time_left * pmove.velocity[i]; + + trace = PM_PlayerMove (pmove.origin, end); + + if (trace.startsolid || trace.allsolid) + { // entity is trapped in another solid + VectorCopy (vec3_origin, pmove.velocity); + return 3; + } + + if (trace.fraction > 0) + { // actually covered some distance + VectorCopy (trace.endpos, pmove.origin); + numplanes = 0; + } + + if (trace.fraction == 1) + break; // moved the entire distance + + // save entity for contact + pmove.touchindex[pmove.numtouch] = trace.ent; + pmove.numtouch++; + + if (trace.plane.normal[2] > 0.7) + { + blocked |= 1; // floor + } + if (!trace.plane.normal[2]) + { + blocked |= 2; // step + } + + time_left -= time_left * trace.fraction; + + // cliped to another plane + if (numplanes >= MAX_CLIP_PLANES) + { // this shouldn't really happen + VectorCopy (vec3_origin, pmove.velocity); + break; + } + + VectorCopy (trace.plane.normal, planes[numplanes]); + numplanes++; + +// +// modify original_velocity so it parallels all of the clip planes +// + for (i=0 ; i<numplanes ; i++) + { + PM_ClipVelocity (original_velocity, planes[i], pmove.velocity, 1); + for (j=0 ; j<numplanes ; j++) + if (j != i) + { + if (DotProduct (pmove.velocity, planes[j]) < 0) + break; // not ok + } + if (j == numplanes) + break; + } + + if (i != numplanes) + { // go along this plane + } + else + { // go along the crease + if (numplanes != 2) + { +// Con_Printf ("clip velocity, numplanes == %i\n",numplanes); + VectorCopy (vec3_origin, pmove.velocity); + break; + } + CrossProduct (planes[0], planes[1], dir); + d = DotProduct (dir, pmove.velocity); + VectorScale (dir, d, pmove.velocity); + } + +// +// if original velocity is against the original velocity, stop dead +// to avoid tiny occilations in sloping corners +// + if (DotProduct (pmove.velocity, primal_velocity) <= 0) + { + VectorCopy (vec3_origin, pmove.velocity); + break; + } + } + + if (pmove.waterjumptime) + { + VectorCopy (primal_velocity, pmove.velocity); + } + return blocked; +} + +/* +============= +PM_GroundMove + +Player is on ground, with no upwards velocity +============= +*/ +void PM_GroundMove (void) +{ + vec3_t start, dest; + pmtrace_t trace; + vec3_t original, originalvel, down, up, downvel; + float downdist, updist; + + pmove.velocity[2] = 0; + if (!pmove.velocity[0] && !pmove.velocity[1] && !pmove.velocity[2]) + return; + + // first try just moving to the destination + dest[0] = pmove.origin[0] + pmove.velocity[0]*frametime; + dest[1] = pmove.origin[1] + pmove.velocity[1]*frametime; + dest[2] = pmove.origin[2]; + + // first try moving directly to the next spot + VectorCopy (dest, start); + trace = PM_PlayerMove (pmove.origin, dest); + if (trace.fraction == 1) + { + VectorCopy (trace.endpos, pmove.origin); + return; + } + + // try sliding forward both on ground and up 16 pixels + // take the move that goes farthest + VectorCopy (pmove.origin, original); + VectorCopy (pmove.velocity, originalvel); + + // slide move + PM_FlyMove (); + + VectorCopy (pmove.origin, down); + VectorCopy (pmove.velocity, downvel); + + VectorCopy (original, pmove.origin); + VectorCopy (originalvel, pmove.velocity); + +// move up a stair height + VectorCopy (pmove.origin, dest); + dest[2] += STEPSIZE; + trace = PM_PlayerMove (pmove.origin, dest); + if (!trace.startsolid && !trace.allsolid) + { + VectorCopy (trace.endpos, pmove.origin); + } + +// slide move + PM_FlyMove (); + +// press down the stepheight + VectorCopy (pmove.origin, dest); + dest[2] -= STEPSIZE; + trace = PM_PlayerMove (pmove.origin, dest); + if ( trace.plane.normal[2] < 0.7) + goto usedown; + if (!trace.startsolid && !trace.allsolid) + { + VectorCopy (trace.endpos, pmove.origin); + } + VectorCopy (pmove.origin, up); + + // decide which one went farther + downdist = (down[0] - original[0])*(down[0] - original[0]) + + (down[1] - original[1])*(down[1] - original[1]); + updist = (up[0] - original[0])*(up[0] - original[0]) + + (up[1] - original[1])*(up[1] - original[1]); + + if (downdist > updist) + { +usedown: + VectorCopy (down, pmove.origin); + VectorCopy (downvel, pmove.velocity); + } else // copy z value from slide move + pmove.velocity[2] = downvel[2]; + +// if at a dead stop, retry the move with nudges to get around lips + +} + + + +/* +================== +PM_Friction + +Handles both ground friction and water friction +================== +*/ +void PM_Friction (void) +{ + float *vel; + float speed, newspeed, control; + float friction; + float drop; + vec3_t start, stop; + pmtrace_t trace; + + if (pmove.waterjumptime) + return; + + vel = pmove.velocity; + + speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1] + vel[2]*vel[2]); + if (speed < 1) + { + vel[0] = 0; + vel[1] = 0; + return; + } + + friction = movevars.friction; + +// if the leading edge is over a dropoff, increase friction + if (onground != -1) { + start[0] = stop[0] = pmove.origin[0] + vel[0]/speed*16; + start[1] = stop[1] = pmove.origin[1] + vel[1]/speed*16; + start[2] = pmove.origin[2] + player_mins[2]; + stop[2] = start[2] - 34; + + trace = PM_PlayerMove (start, stop); + + if (trace.fraction == 1) { + friction *= 2; + } + } + + drop = 0; + + if (waterlevel >= 2) // apply water friction + drop += speed*movevars.waterfriction*waterlevel*frametime; + else if (onground != -1) // apply ground friction + { + control = speed < movevars.stopspeed ? movevars.stopspeed : speed; + drop += control*friction*frametime; + } + + +// scale the velocity + newspeed = speed - drop; + if (newspeed < 0) + newspeed = 0; + newspeed /= speed; + + vel[0] = vel[0] * newspeed; + vel[1] = vel[1] * newspeed; + vel[2] = vel[2] * newspeed; +} + + +/* +============== +PM_Accelerate +============== +*/ +void PM_Accelerate (vec3_t wishdir, float wishspeed, float accel) +{ + int i; + float addspeed, accelspeed, currentspeed; + + if (pmove.dead) + return; + if (pmove.waterjumptime) + return; + + currentspeed = DotProduct (pmove.velocity, wishdir); + addspeed = wishspeed - currentspeed; + if (addspeed <= 0) + return; + accelspeed = accel*frametime*wishspeed; + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (i=0 ; i<3 ; i++) + pmove.velocity[i] += accelspeed*wishdir[i]; +} + +void PM_AirAccelerate (vec3_t wishdir, float wishspeed, float accel) +{ + int i; + float addspeed, accelspeed, currentspeed, wishspd = wishspeed; + + if (pmove.dead) + return; + if (pmove.waterjumptime) + return; + + if (wishspd > 30) + wishspd = 30; + currentspeed = DotProduct (pmove.velocity, wishdir); + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; + accelspeed = accel * wishspeed * frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (i=0 ; i<3 ; i++) + pmove.velocity[i] += accelspeed*wishdir[i]; +} + + + +/* +=================== +PM_WaterMove + +=================== +*/ +void PM_WaterMove (void) +{ + int i; + vec3_t wishvel; + float wishspeed; + vec3_t wishdir; + vec3_t start, dest; + pmtrace_t trace; + +// +// user intentions +// + for (i=0 ; i<3 ; i++) + wishvel[i] = forward[i]*pmove.cmd.forwardmove + right[i]*pmove.cmd.sidemove; + + if (!pmove.cmd.forwardmove && !pmove.cmd.sidemove && !pmove.cmd.upmove) + wishvel[2] -= 60; // drift towards bottom + else + wishvel[2] += pmove.cmd.upmove; + + VectorCopy (wishvel, wishdir); + wishspeed = VectorNormalize(wishdir); + + if (wishspeed > movevars.maxspeed) + { + VectorScale (wishvel, movevars.maxspeed/wishspeed, wishvel); + wishspeed = movevars.maxspeed; + } + wishspeed *= 0.7; + +// +// water acceleration +// +// if (pmove.waterjumptime) +// Con_Printf ("wm->%f, %f, %f\n", pmove.velocity[0], pmove.velocity[1], pmove.velocity[2]); + PM_Accelerate (wishdir, wishspeed, movevars.wateraccelerate); + +// assume it is a stair or a slope, so press down from stepheight above + VectorMA (pmove.origin, frametime, pmove.velocity, dest); + VectorCopy (dest, start); + start[2] += STEPSIZE + 1; + trace = PM_PlayerMove (start, dest); + if (!trace.startsolid && !trace.allsolid) // FIXME: check steep slope? + { // walked up the step + VectorCopy (trace.endpos, pmove.origin); + return; + } + + PM_FlyMove (); +// if (pmove.waterjumptime) +// Con_Printf ("<-wm%f, %f, %f\n", pmove.velocity[0], pmove.velocity[1], pmove.velocity[2]); +} + + +/* +=================== +PM_AirMove + +=================== +*/ +void PM_AirMove (void) +{ + int i; + vec3_t wishvel; + float fmove, smove; + vec3_t wishdir; + float wishspeed; + + fmove = pmove.cmd.forwardmove; + smove = pmove.cmd.sidemove; + + forward[2] = 0; + right[2] = 0; + VectorNormalize (forward); + VectorNormalize (right); + + for (i=0 ; i<2 ; i++) + wishvel[i] = forward[i]*fmove + right[i]*smove; + wishvel[2] = 0; + + VectorCopy (wishvel, wishdir); + wishspeed = VectorNormalize(wishdir); + +// +// clamp to server defined max speed +// + if (wishspeed > movevars.maxspeed) + { + VectorScale (wishvel, movevars.maxspeed/wishspeed, wishvel); + wishspeed = movevars.maxspeed; + } + +// if (pmove.waterjumptime) +// Con_Printf ("am->%f, %f, %f\n", pmove.velocity[0], pmove.velocity[1], pmove.velocity[2]); + + if ( onground != -1) + { + pmove.velocity[2] = 0; + PM_Accelerate (wishdir, wishspeed, movevars.accelerate); + pmove.velocity[2] -= movevars.entgravity * movevars.gravity * frametime; + PM_GroundMove (); + } + else + { // not on ground, so little effect on velocity + PM_AirAccelerate (wishdir, wishspeed, movevars.accelerate); + + // add gravity + pmove.velocity[2] -= movevars.entgravity * movevars.gravity * frametime; + + PM_FlyMove (); + + } + +//Con_Printf("airmove:vec: %4.2f %4.2f %4.2f\n", +// pmove.velocity[0], +// pmove.velocity[1], +// pmove.velocity[2]); +// + +// if (pmove.waterjumptime) +// Con_Printf ("<-am%f, %f, %f\n", pmove.velocity[0], pmove.velocity[1], pmove.velocity[2]); +} + + + +/* +============= +PM_CatagorizePosition +============= +*/ +void PM_CatagorizePosition (void) +{ + vec3_t point; + int cont; + pmtrace_t tr; + +// if the player hull point one unit down is solid, the player +// is on ground + +// see if standing on something solid + point[0] = pmove.origin[0]; + point[1] = pmove.origin[1]; + point[2] = pmove.origin[2] - 1; + if (pmove.velocity[2] > 180) + { + onground = -1; + } + else + { + tr = PM_PlayerMove (pmove.origin, point); + if ( tr.plane.normal[2] < 0.7) + onground = -1; // too steep + else + onground = tr.ent; + if (onground != -1) + { + pmove.waterjumptime = 0; + if (!tr.startsolid && !tr.allsolid) + VectorCopy (tr.endpos, pmove.origin); + } + + // standing on an entity other than the world + if (tr.ent > 0) + { + pmove.touchindex[pmove.numtouch] = tr.ent; + pmove.numtouch++; + } + } + +// +// get waterlevel +// + waterlevel = 0; + watertype = CONTENTS_EMPTY; + + point[2] = pmove.origin[2] + player_mins[2] + 1; + cont = PM_PointContents (point); + + if (cont <= CONTENTS_WATER) + { + watertype = cont; + waterlevel = 1; + point[2] = pmove.origin[2] + (player_mins[2] + player_maxs[2])*0.5; + cont = PM_PointContents (point); + if (cont <= CONTENTS_WATER) + { + waterlevel = 2; + point[2] = pmove.origin[2] + 22; + cont = PM_PointContents (point); + if (cont <= CONTENTS_WATER) + waterlevel = 3; + } + } +} + + +/* +============= +JumpButton +============= +*/ +void JumpButton (void) +{ + if (pmove.dead) + { + pmove.oldbuttons |= BUTTON_JUMP; // don't jump again until released + return; + } + + if (pmove.waterjumptime) + { + pmove.waterjumptime -= frametime; + if (pmove.waterjumptime < 0) + pmove.waterjumptime = 0; + return; + } + + if (waterlevel >= 2) + { // swimming, not jumping + onground = -1; + + if (watertype == CONTENTS_WATER) + pmove.velocity[2] = 100; + else if (watertype == CONTENTS_SLIME) + pmove.velocity[2] = 80; + else + pmove.velocity[2] = 50; + return; + } + + if (onground == -1) + return; // in air, so no effect + + if ( pmove.oldbuttons & BUTTON_JUMP ) + return; // don't pogo stick + + onground = -1; + pmove.velocity[2] += 270; + + pmove.oldbuttons |= BUTTON_JUMP; // don't jump again until released +} + +/* +============= +CheckWaterJump +============= +*/ +void CheckWaterJump (void) +{ + vec3_t spot; + int cont; + vec3_t flatforward; + + if (pmove.waterjumptime) + return; + + // ZOID, don't hop out if we just jumped in + if (pmove.velocity[2] < -180) + return; // only hop out if we are moving up + + // see if near an edge + flatforward[0] = forward[0]; + flatforward[1] = forward[1]; + flatforward[2] = 0; + VectorNormalize (flatforward); + + VectorMA (pmove.origin, 24, flatforward, spot); + spot[2] += 8; + cont = PM_PointContents (spot); + if (cont != CONTENTS_SOLID) + return; + spot[2] += 24; + cont = PM_PointContents (spot); + if (cont != CONTENTS_EMPTY) + return; + // jump out of water + VectorScale (flatforward, 50, pmove.velocity); + pmove.velocity[2] = 310; + pmove.waterjumptime = 2; // safety net + pmove.oldbuttons |= BUTTON_JUMP; // don't jump again until released +} + +/* +================= +NudgePosition + +If pmove.origin is in a solid position, +try nudging slightly on all axis to +allow for the cut precision of the net coordinates +================= +*/ +void NudgePosition (void) +{ + vec3_t base; + int x, y, z; + int i; + static int sign[3] = {0, -1, 1}; + + VectorCopy (pmove.origin, base); + + for (i=0 ; i<3 ; i++) + pmove.origin[i] = ((int)(pmove.origin[i]*8)) * 0.125; +// pmove.origin[2] += 0.124; + +// if (pmove.dead) +// return; // might be a squished point, so don'y bother +// if (PM_TestPlayerPosition (pmove.origin) ) +// return; + + for (z=0 ; z<=2 ; z++) + { + for (x=0 ; x<=2 ; x++) + { + for (y=0 ; y<=2 ; y++) + { + pmove.origin[0] = base[0] + (sign[x] * 1.0/8); + pmove.origin[1] = base[1] + (sign[y] * 1.0/8); + pmove.origin[2] = base[2] + (sign[z] * 1.0/8); + if (PM_TestPlayerPosition (pmove.origin)) + return; + } + } + } + VectorCopy (base, pmove.origin); +// Con_DPrintf ("NudgePosition: stuck\n"); +} + +/* +=============== +SpectatorMove +=============== +*/ +void SpectatorMove (void) +{ + float speed, drop, friction, control, newspeed, accel; + float currentspeed, addspeed, accelspeed; + int i; + vec3_t wishvel; + float fmove, smove; + vec3_t wishdir; + float wishspeed; +#ifndef SERVERONLY + extern float server_version; // version of server we connected to +#endif + + // friction + + speed = Length (pmove.velocity); + if (speed < 1) + { + VectorCopy (vec3_origin, pmove.velocity) + } + else + { + drop = 0; + + friction = movevars.friction*1.5; // extra friction + control = speed < movevars.stopspeed ? movevars.stopspeed : speed; + drop += control*friction*frametime; + + // scale the velocity + newspeed = speed - drop; + if (newspeed < 0) + newspeed = 0; + newspeed /= speed; + + VectorScale (pmove.velocity, newspeed, pmove.velocity); + } + + // accelerate + fmove = pmove.cmd.forwardmove; + smove = pmove.cmd.sidemove; + + VectorNormalize (forward); + VectorNormalize (right); + + for (i=0 ; i<3 ; i++) + wishvel[i] = forward[i]*fmove + right[i]*smove; + wishvel[2] += pmove.cmd.upmove; + + VectorCopy (wishvel, wishdir); + wishspeed = VectorNormalize(wishdir); + + // + // clamp to server defined max speed + // + if (wishspeed > movevars.spectatormaxspeed) + { + VectorScale (wishvel, movevars.spectatormaxspeed/wishspeed, wishvel); + wishspeed = movevars.spectatormaxspeed; + } + + currentspeed = DotProduct(pmove.velocity, wishdir); + addspeed = wishspeed - currentspeed; + if (addspeed <= 0) + return; + accelspeed = movevars.accelerate*frametime*wishspeed; + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (i=0 ; i<3 ; i++) + pmove.velocity[i] += accelspeed*wishdir[i]; + + + // move + VectorMA (pmove.origin, frametime, pmove.velocity, pmove.origin); +} + +/* +============= +PlayerMove + +Returns with origin, angles, and velocity modified in place. + +Numtouch and touchindex[] will be set if any of the physents +were contacted during the move. +============= +*/ +void PlayerMove (void) +{ + frametime = pmove.cmd.msec * 0.001; + pmove.numtouch = 0; + + AngleVectors (pmove.angles, forward, right, up); + + if (pmove.spectator) + { + SpectatorMove (); + return; + } + + NudgePosition (); + + // take angles directly from command + VectorCopy (pmove.cmd.angles, pmove.angles); + + // set onground, watertype, and waterlevel + PM_CatagorizePosition (); + + if (waterlevel == 2) + CheckWaterJump (); + + if (pmove.velocity[2] < 0) + pmove.waterjumptime = 0; + + if (pmove.cmd.buttons & BUTTON_JUMP) + JumpButton (); + else + pmove.oldbuttons &= ~BUTTON_JUMP; + + PM_Friction (); + + if (waterlevel >= 2) + PM_WaterMove (); + else + PM_AirMove (); + + // set onground, watertype, and waterlevel for final spot + PM_CatagorizePosition (); +} + diff --git a/QW/client/pmove.h b/QW/client/pmove.h new file mode 100644 index 0000000..302c506 --- /dev/null +++ b/QW/client/pmove.h @@ -0,0 +1,101 @@ +/* +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. + +*/ + +typedef struct +{ + vec3_t normal; + float dist; +} pmplane_t; + +typedef struct +{ + qboolean allsolid; // if true, plane is not valid + qboolean startsolid; // if true, the initial point was in a solid area + qboolean inopen, inwater; + float fraction; // time completed, 1.0 = didn't hit anything + vec3_t endpos; // final position + pmplane_t plane; // surface normal at impact + int ent; // entity the surface is on +} pmtrace_t; + + +#define MAX_PHYSENTS 32 +typedef struct +{ + vec3_t origin; + model_t *model; // only for bsp models + vec3_t mins, maxs; // only for non-bsp models + int info; // for client or server to identify +} physent_t; + + +typedef struct +{ + int sequence; // just for debugging prints + + // player state + vec3_t origin; + vec3_t angles; + vec3_t velocity; + int oldbuttons; + float waterjumptime; + qboolean dead; + int spectator; + + // world state + int numphysent; + physent_t physents[MAX_PHYSENTS]; // 0 should be the world + + // input + usercmd_t cmd; + + // results + int numtouch; + int touchindex[MAX_PHYSENTS]; +} playermove_t; + +typedef struct { + float gravity; + float stopspeed; + float maxspeed; + float spectatormaxspeed; + float accelerate; + float airaccelerate; + float wateraccelerate; + float friction; + float waterfriction; + float entgravity; +} movevars_t; + + +extern movevars_t movevars; +extern playermove_t pmove; +extern int onground; +extern int waterlevel; +extern int watertype; + +void PlayerMove (void); +void Pmove_Init (void); + +int PM_HullPointContents (hull_t *hull, int num, vec3_t p); + +int PM_PointContents (vec3_t point); +qboolean PM_TestPlayerPosition (vec3_t point); +pmtrace_t PM_PlayerMove (vec3_t start, vec3_t stop); diff --git a/QW/client/pmovetst.c b/QW/client/pmovetst.c new file mode 100644 index 0000000..763e341 --- /dev/null +++ b/QW/client/pmovetst.c @@ -0,0 +1,414 @@ +/* +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. + +*/ +#include "quakedef.h" + +static hull_t box_hull; +static dclipnode_t box_clipnodes[6]; +static mplane_t box_planes[6]; + +extern vec3_t player_mins; +extern vec3_t player_maxs; + +/* +=================== +PM_InitBoxHull + +Set up the planes and clipnodes so that the six floats of a bounding box +can just be stored out and get a proper hull_t structure. +=================== +*/ +void PM_InitBoxHull (void) +{ + int i; + int side; + + box_hull.clipnodes = box_clipnodes; + box_hull.planes = box_planes; + box_hull.firstclipnode = 0; + box_hull.lastclipnode = 5; + + for (i=0 ; i<6 ; i++) + { + box_clipnodes[i].planenum = i; + + side = i&1; + + box_clipnodes[i].children[side] = CONTENTS_EMPTY; + if (i != 5) + box_clipnodes[i].children[side^1] = i + 1; + else + box_clipnodes[i].children[side^1] = CONTENTS_SOLID; + + box_planes[i].type = i>>1; + box_planes[i].normal[i>>1] = 1; + } + +} + + +/* +=================== +PM_HullForBox + +To keep everything totally uniform, bounding boxes are turned into small +BSP trees instead of being compared directly. +=================== +*/ +hull_t *PM_HullForBox (vec3_t mins, vec3_t maxs) +{ + box_planes[0].dist = maxs[0]; + box_planes[1].dist = mins[0]; + box_planes[2].dist = maxs[1]; + box_planes[3].dist = mins[1]; + box_planes[4].dist = maxs[2]; + box_planes[5].dist = mins[2]; + + return &box_hull; +} + + +/* +================== +PM_HullPointContents + +================== +*/ +int PM_HullPointContents (hull_t *hull, int num, vec3_t p) +{ + float d; + dclipnode_t *node; + mplane_t *plane; + + while (num >= 0) + { + if (num < hull->firstclipnode || num > hull->lastclipnode) + Sys_Error ("PM_HullPointContents: bad node number"); + + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + if (plane->type < 3) + d = p[plane->type] - plane->dist; + else + d = DotProduct (plane->normal, p) - plane->dist; + if (d < 0) + num = node->children[1]; + else + num = node->children[0]; + } + + return num; +} + +/* +================== +PM_PointContents + +================== +*/ +int PM_PointContents (vec3_t p) +{ + float d; + dclipnode_t *node; + mplane_t *plane; + hull_t *hull; + int num; + + hull = &pmove.physents[0].model->hulls[0]; + + num = hull->firstclipnode; + + while (num >= 0) + { + if (num < hull->firstclipnode || num > hull->lastclipnode) + Sys_Error ("PM_HullPointContents: bad node number"); + + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + if (plane->type < 3) + d = p[plane->type] - plane->dist; + else + d = DotProduct (plane->normal, p) - plane->dist; + if (d < 0) + num = node->children[1]; + else + num = node->children[0]; + } + + return num; +} + +/* +=============================================================================== + +LINE TESTING IN HULLS + +=============================================================================== +*/ + +// 1/32 epsilon to keep floating point happy +#define DIST_EPSILON (0.03125) + +/* +================== +PM_RecursiveHullCheck + +================== +*/ +qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, pmtrace_t *trace) +{ + dclipnode_t *node; + mplane_t *plane; + float t1, t2; + float frac; + int i; + vec3_t mid; + int side; + float midf; + +// check for empty + if (num < 0) + { + if (num != CONTENTS_SOLID) + { + trace->allsolid = false; + if (num == CONTENTS_EMPTY) + trace->inopen = true; + else + trace->inwater = true; + } + else + trace->startsolid = true; + return true; // empty + } + + if (num < hull->firstclipnode || num > hull->lastclipnode) + Sys_Error ("PM_RecursiveHullCheck: bad node number"); + +// +// find the point distances +// + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + if (plane->type < 3) + { + t1 = p1[plane->type] - plane->dist; + t2 = p2[plane->type] - plane->dist; + } + else + { + t1 = DotProduct (plane->normal, p1) - plane->dist; + t2 = DotProduct (plane->normal, p2) - plane->dist; + } + +#if 1 + if (t1 >= 0 && t2 >= 0) + return PM_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); + if (t1 < 0 && t2 < 0) + return PM_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace); +#else + if ( (t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0) ) + return PM_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); + if ( (t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0) ) + return PM_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace); +#endif + +// put the crosspoint DIST_EPSILON pixels on the near side + if (t1 < 0) + frac = (t1 + DIST_EPSILON)/(t1-t2); + else + frac = (t1 - DIST_EPSILON)/(t1-t2); + if (frac < 0) + frac = 0; + if (frac > 1) + frac = 1; + + midf = p1f + (p2f - p1f)*frac; + for (i=0 ; i<3 ; i++) + mid[i] = p1[i] + frac*(p2[i] - p1[i]); + + side = (t1 < 0); + +// move up to the node + if (!PM_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) ) + return false; + +#ifdef PARANOID + if (PM_HullPointContents (pm_hullmodel, mid, node->children[side]) + == CONTENTS_SOLID) + { + Con_Printf ("mid PointInHullSolid\n"); + return false; + } +#endif + + if (PM_HullPointContents (hull, node->children[side^1], mid) + != CONTENTS_SOLID) +// go past the node + return PM_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace); + + if (trace->allsolid) + return false; // never got out of the solid area + +//================== +// the other side of the node is solid, this is the impact point +//================== + if (!side) + { + VectorCopy (plane->normal, trace->plane.normal); + trace->plane.dist = plane->dist; + } + else + { + VectorSubtract (vec3_origin, plane->normal, trace->plane.normal); + trace->plane.dist = -plane->dist; + } + + while (PM_HullPointContents (hull, hull->firstclipnode, mid) + == CONTENTS_SOLID) + { // shouldn't really happen, but does occasionally + frac -= 0.1; + if (frac < 0) + { + trace->fraction = midf; + VectorCopy (mid, trace->endpos); + Con_DPrintf ("backup past 0\n"); + return false; + } + midf = p1f + (p2f - p1f)*frac; + for (i=0 ; i<3 ; i++) + mid[i] = p1[i] + frac*(p2[i] - p1[i]); + } + + trace->fraction = midf; + VectorCopy (mid, trace->endpos); + + return false; +} + + +/* +================ +PM_TestPlayerPosition + +Returns false if the given player position is not valid (in solid) +================ +*/ +qboolean PM_TestPlayerPosition (vec3_t pos) +{ + int i; + physent_t *pe; + vec3_t mins, maxs, test; + hull_t *hull; + + for (i=0 ; i< pmove.numphysent ; i++) + { + pe = &pmove.physents[i]; + // get the clipping hull + if (pe->model) + hull = &pmove.physents[i].model->hulls[1]; + else + { + VectorSubtract (pe->mins, player_maxs, mins); + VectorSubtract (pe->maxs, player_mins, maxs); + hull = PM_HullForBox (mins, maxs); + } + + VectorSubtract (pos, pe->origin, test); + + if (PM_HullPointContents (hull, hull->firstclipnode, test) == CONTENTS_SOLID) + return false; + } + + return true; +} + +/* +================ +PM_PlayerMove +================ +*/ +pmtrace_t PM_PlayerMove (vec3_t start, vec3_t end) +{ + pmtrace_t trace, total; + vec3_t offset; + vec3_t start_l, end_l; + hull_t *hull; + int i; + physent_t *pe; + vec3_t mins, maxs; + +// fill in a default trace + memset (&total, 0, sizeof(pmtrace_t)); + total.fraction = 1; + total.ent = -1; + VectorCopy (end, total.endpos); + + for (i=0 ; i< pmove.numphysent ; i++) + { + pe = &pmove.physents[i]; + // get the clipping hull + if (pe->model) + hull = &pmove.physents[i].model->hulls[1]; + else + { + VectorSubtract (pe->mins, player_maxs, mins); + VectorSubtract (pe->maxs, player_mins, maxs); + hull = PM_HullForBox (mins, maxs); + } + + // PM_HullForEntity (ent, mins, maxs, offset); + VectorCopy (pe->origin, offset); + + VectorSubtract (start, offset, start_l); + VectorSubtract (end, offset, end_l); + + // fill in a default trace + memset (&trace, 0, sizeof(pmtrace_t)); + trace.fraction = 1; + trace.allsolid = true; +// trace.startsolid = true; + VectorCopy (end, trace.endpos); + + // trace a line through the apropriate clipping hull + PM_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace); + + if (trace.allsolid) + trace.startsolid = true; + if (trace.startsolid) + trace.fraction = 0; + + // did we clip the move? + if (trace.fraction < total.fraction) + { + // fix trace up by the offset + VectorAdd (trace.endpos, offset, trace.endpos); + total = trace; + total.ent = i; + } + + } + + return total; +} + + diff --git a/QW/client/protocol.h b/QW/client/protocol.h new file mode 100644 index 0000000..f674c1b --- /dev/null +++ b/QW/client/protocol.h @@ -0,0 +1,282 @@ +/* +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. + +*/ +// protocol.h -- communications protocols + +#define PROTOCOL_VERSION 28 + +#define QW_CHECK_HASH 0x5157 + +//========================================= + +#define PORT_CLIENT 27001 +#define PORT_MASTER 27000 +#define PORT_SERVER 27500 + +//========================================= + +// out of band message id bytes + +// M = master, S = server, C = client, A = any +// the second character will allways be \n if the message isn't a single +// byte long (?? not true anymore?) + +#define S2C_CHALLENGE 'c' +#define S2C_CONNECTION 'j' +#define A2A_PING 'k' // respond with an A2A_ACK +#define A2A_ACK 'l' // general acknowledgement without info +#define A2A_NACK 'm' // [+ comment] general failure +#define A2A_ECHO 'e' // for echoing +#define A2C_PRINT 'n' // print a message on client + +#define S2M_HEARTBEAT 'a' // + serverinfo + userlist + fraglist +#define A2C_CLIENT_COMMAND 'B' // + command line +#define S2M_SHUTDOWN 'C' + + +//================== +// note that there are some defs.qc that mirror to these numbers +// also related to svc_strings[] in cl_parse +//================== + +// +// server to client +// +#define svc_bad 0 +#define svc_nop 1 +#define svc_disconnect 2 +#define svc_updatestat 3 // [byte] [byte] +//define svc_version 4 // [long] server version +#define svc_setview 5 // [short] entity number +#define svc_sound 6 // <see code> +//define svc_time 7 // [float] server time +#define svc_print 8 // [byte] id [string] null terminated string +#define svc_stufftext 9 // [string] stuffed into client's console buffer + // the string should be \n terminated +#define svc_setangle 10 // [angle3] set the view angle to this absolute value + +#define svc_serverdata 11 // [long] protocol ... +#define svc_lightstyle 12 // [byte] [string] +//define svc_updatename 13 // [byte] [string] +#define svc_updatefrags 14 // [byte] [short] +//define svc_clientdata 15 // <shortbits + data> +#define svc_stopsound 16 // <see code> +//define svc_updatecolors 17 // [byte] [byte] [byte] +//define svc_particle 18 // [vec3] <variable> +#define svc_damage 19 + +#define svc_spawnstatic 20 +// svc_spawnbinary 21 +#define svc_spawnbaseline 22 + +#define svc_temp_entity 23 // variable +#define svc_setpause 24 // [byte] on / off +// svc_signonnum 25 // [byte] used for the signon sequence + +#define svc_centerprint 26 // [string] to put in center of the screen + +#define svc_killedmonster 27 +#define svc_foundsecret 28 + +#define svc_spawnstaticsound 29 // [coord3] [byte] samp [byte] vol [byte] aten + +#define svc_intermission 30 // [vec3_t] origin [vec3_t] angle +#define svc_finale 31 // [string] text + +#define svc_cdtrack 32 // [byte] track +#define svc_sellscreen 33 + +#define svc_smallkick 34 // set client punchangle to 2 +#define svc_bigkick 35 // set client punchangle to 4 + +#define svc_updateping 36 // [byte] [short] +#define svc_updateentertime 37 // [byte] [float] + +#define svc_updatestatlong 38 // [byte] [long] + +#define svc_muzzleflash 39 // [short] entity + +#define svc_updateuserinfo 40 // [byte] slot [long] uid + // [string] userinfo + +#define svc_download 41 // [short] size [size bytes] +#define svc_playerinfo 42 // variable +#define svc_nails 43 // [byte] num [48 bits] xyzpy 12 12 12 4 8 +#define svc_chokecount 44 // [byte] packets choked +#define svc_modellist 45 // [strings] +#define svc_soundlist 46 // [strings] +#define svc_packetentities 47 // [...] +#define svc_deltapacketentities 48 // [...] +#define svc_maxspeed 49 // maxspeed change, for prediction +#define svc_entgravity 50 // gravity change, for prediction +#define svc_setinfo 51 // setinfo on a client +#define svc_serverinfo 52 // serverinfo +#define svc_updatepl 53 // [byte] [byte] + + +//============================================== + +// +// client to server +// +#define clc_bad 0 +#define clc_nop 1 +//define clc_doublemove 2 +#define clc_move 3 // [[usercmd_t] +#define clc_stringcmd 4 // [string] message +#define clc_delta 5 // [byte] sequence number, requests delta compression of message +#define clc_tmove 6 // teleport request, spectator only +#define clc_upload 7 // teleport request, spectator only + + +//============================================== + +// playerinfo flags from server +// playerinfo allways sends: playernum, flags, origin[] and framenumber + +#define PF_MSEC (1<<0) +#define PF_COMMAND (1<<1) +#define PF_VELOCITY1 (1<<2) +#define PF_VELOCITY2 (1<<3) +#define PF_VELOCITY3 (1<<4) +#define PF_MODEL (1<<5) +#define PF_SKINNUM (1<<6) +#define PF_EFFECTS (1<<7) +#define PF_WEAPONFRAME (1<<8) // only sent for view player +#define PF_DEAD (1<<9) // don't block movement any more +#define PF_GIB (1<<10) // offset the view height differently +#define PF_NOGRAV (1<<11) // don't apply gravity for prediction + +//============================================== + +// if the high bit of the client to server byte is set, the low bits are +// client move cmd bits +// ms and angle2 are allways sent, the others are optional +#define CM_ANGLE1 (1<<0) +#define CM_ANGLE3 (1<<1) +#define CM_FORWARD (1<<2) +#define CM_SIDE (1<<3) +#define CM_UP (1<<4) +#define CM_BUTTONS (1<<5) +#define CM_IMPULSE (1<<6) +#define CM_ANGLE2 (1<<7) + +//============================================== + +// the first 16 bits of a packetentities update holds 9 bits +// of entity number and 7 bits of flags +#define U_ORIGIN1 (1<<9) +#define U_ORIGIN2 (1<<10) +#define U_ORIGIN3 (1<<11) +#define U_ANGLE2 (1<<12) +#define U_FRAME (1<<13) +#define U_REMOVE (1<<14) // REMOVE this entity, don't add it +#define U_MOREBITS (1<<15) + +// if MOREBITS is set, these additional flags are read in next +#define U_ANGLE1 (1<<0) +#define U_ANGLE3 (1<<1) +#define U_MODEL (1<<2) +#define U_COLORMAP (1<<3) +#define U_SKIN (1<<4) +#define U_EFFECTS (1<<5) +#define U_SOLID (1<<6) // the entity should be solid for prediction + +//============================================== + +// a sound with no channel is a local only sound +// the sound field has bits 0-2: channel, 3-12: entity +#define SND_VOLUME (1<<15) // a byte +#define SND_ATTENUATION (1<<14) // a byte + +#define DEFAULT_SOUND_PACKET_VOLUME 255 +#define DEFAULT_SOUND_PACKET_ATTENUATION 1.0 + +// svc_print messages have an id, so messages can be filtered +#define PRINT_LOW 0 +#define PRINT_MEDIUM 1 +#define PRINT_HIGH 2 +#define PRINT_CHAT 3 // also go to chat buffer + +// +// temp entity events +// +#define TE_SPIKE 0 +#define TE_SUPERSPIKE 1 +#define TE_GUNSHOT 2 +#define TE_EXPLOSION 3 +#define TE_TAREXPLOSION 4 +#define TE_LIGHTNING1 5 +#define TE_LIGHTNING2 6 +#define TE_WIZSPIKE 7 +#define TE_KNIGHTSPIKE 8 +#define TE_LIGHTNING3 9 +#define TE_LAVASPLASH 10 +#define TE_TELEPORT 11 +#define TE_BLOOD 12 +#define TE_LIGHTNINGBLOOD 13 + + +/* +========================================================== + + ELEMENTS COMMUNICATED ACROSS THE NET + +========================================================== +*/ + +#define MAX_CLIENTS 32 + +#define UPDATE_BACKUP 64 // copies of entity_state_t to keep buffered + // must be power of two +#define UPDATE_MASK (UPDATE_BACKUP-1) + +// entity_state_t is the information conveyed from the server +// in an update message +typedef struct +{ + int number; // edict index + + int flags; // nolerp, etc + vec3_t origin; + vec3_t angles; + int modelindex; + int frame; + int colormap; + int skinnum; + int effects; +} entity_state_t; + + +#define MAX_PACKET_ENTITIES 64 // doesn't count nails +typedef struct +{ + int num_entities; + entity_state_t entities[MAX_PACKET_ENTITIES]; +} packet_entities_t; + +typedef struct usercmd_s +{ + byte msec; + vec3_t angles; + short forwardmove, sidemove, upmove; + byte buttons; + byte impulse; +} usercmd_t; + diff --git a/QW/client/q.bat b/QW/client/q.bat new file mode 100644 index 0000000..9a8fdf3 --- /dev/null +++ b/QW/client/q.bat @@ -0,0 +1 @@ +dos\quake -basedir \quake\v2 %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/QW/client/qe3.ico b/QW/client/qe3.ico Binary files differnew file mode 100644 index 0000000..35ee0d2 --- /dev/null +++ b/QW/client/qe3.ico diff --git a/QW/client/quakeasm.h b/QW/client/quakeasm.h new file mode 100644 index 0000000..1ceadda --- /dev/null +++ b/QW/client/quakeasm.h @@ -0,0 +1,274 @@ +/* +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. + +*/ +// +// quakeasm.h: general asm header file +// + +#ifdef _WIN32 +#define __i386__ 1 +#endif + +#ifdef __i386__ +#define id386 1 +#else +#define id386 0 +#endif + +// !!! must be kept the same as in d_iface.h !!! +#define TRANSPARENT_COLOR 255 + +#ifndef NeXT +#ifndef GLQUAKE + .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_apverts) + .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(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_32768 + .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(snd_scaletable) + .extern C(paintbuffer) + .extern C(snd_linear_count) + .extern C(snd_p) + .extern C(snd_vol) + .extern C(snd_out) + .extern C(vright) + .extern C(vup) + .extern C(vpn) + .extern C(BOPS_Error) + +#endif diff --git a/QW/client/quakedef.h b/QW/client/quakedef.h new file mode 100644 index 0000000..2a69d7e --- /dev/null +++ b/QW/client/quakedef.h @@ -0,0 +1,142 @@ +/* +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. + +*/ +// quakedef.h -- primary header for client + +#define QUAKE_GAME // as opposed to utilities + +//define PARANOID // speed sapping error checking + +#ifdef _WIN32 +#pragma warning( disable : 4244 4127 4201 4214 4514 4305 4115 4018) +#endif + + +#include <math.h> +#include <string.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <setjmp.h> +#include <time.h> + +#include "bothdefs.h" + +#include "common.h" +#include "bspfile.h" +#include "vid.h" +#include "sys.h" +#include "zone.h" +#include "mathlib.h" +#include "wad.h" +#include "draw.h" +#include "cvar.h" +#include "screen.h" +#include "net.h" +#include "protocol.h" +#include "cmd.h" +#include "sbar.h" +#include "sound.h" +#include "render.h" +#include "client.h" + +#ifdef GLQUAKE +#include "gl_model.h" +#else +#include "model.h" +#include "d_iface.h" +#endif + +#include "input.h" +#include "keys.h" +#include "console.h" +#include "view.h" +#include "menu.h" +#include "crc.h" +#include "cdaudio.h" +#include "pmove.h" + +#ifdef GLQUAKE +#include "glquake.h" +#endif + +#ifndef max +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +//============================================================================= + +// the host system specifies the base of the directory tree, the +// command line parms passed to the program, and the amount of memory +// available for the program to use + +typedef struct +{ + char *basedir; + char *cachedir; // for development over ISDN lines + int argc; + char **argv; + void *membase; + int memsize; +} quakeparms_t; + + +//============================================================================= + +#define MAX_NUM_ARGVS 50 + + +extern qboolean noclip_anglehack; + + +// +// host +// +extern quakeparms_t host_parms; + +extern cvar_t sys_ticrate; +extern cvar_t sys_nostdout; +extern cvar_t developer; + +extern cvar_t password; + +extern qboolean host_initialized; // true if into command execution +extern double host_frametime; +extern byte *host_basepal; +extern byte *host_colormap; +extern int host_framecount; // incremented every frame, never reset +extern double realtime; // not bounded in any way, changed at + // start of every frame, never reset + +void Host_ServerFrame (void); +void Host_InitCommands (void); +void Host_Init (quakeparms_t *parms); +void Host_Shutdown(void); +void Host_Error (char *error, ...); +void Host_EndGame (char *message, ...); +qboolean Host_SimulationTime(float time); +void Host_Frame (float time); +void Host_Quit_f (void); +void Host_ClientCommands (char *fmt, ...); +void Host_ShutdownServer (qboolean crash); + +extern qboolean msg_suppress_1; // suppresses resolution and cache size console output + // an fullscreen DIB focus gain/loss + diff --git a/QW/client/quakeworld.bmp b/QW/client/quakeworld.bmp Binary files differnew file mode 100644 index 0000000..3dc975d --- /dev/null +++ b/QW/client/quakeworld.bmp diff --git a/QW/client/qwcl.dsp b/QW/client/qwcl.dsp new file mode 100644 index 0000000..3bf5d66 --- /dev/null +++ b/QW/client/qwcl.dsp @@ -0,0 +1,2213 @@ +# Microsoft Developer Studio Project File - Name="qwcl" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=qwcl - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "qwcl.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "qwcl.mak" CFG="qwcl - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "qwcl - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "qwcl - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "qwcl - Win32 GLDebug" (based on "Win32 (x86) Application") +!MESSAGE "qwcl - Win32 GLRelease" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /G5 /GX /O2 /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 ..\scitech\lib\win32\vc\mgllt.lib ..\dxsdk\sdk\lib\dxguid.lib opengl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /incremental:yes /machine:I386 +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /G5 /ML /Gm /GX /ZI /Od /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 ..\scitech\lib\win32\vc\mgllt.lib ..\dxsdk\sdk\lib\dxguid.lib opengl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 +# SUBTRACT LINK32 /profile /map /nodefaultlib + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\qwcl___0" +# PROP BASE Intermediate_Dir ".\qwcl___0" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\GLDebug" +# PROP Intermediate_Dir ".\GLDebug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /ML /Gm /GX /Zi /Od /I "e:\msdev\projects\dxsdk\sdk\inc" /I "e:\msdev\projects\scitech\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /c +# ADD CPP /nologo /G5 /ML /GX /ZI /Od /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "GLQUAKE" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 opengl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib e:\msdev\projects\scitech\lib\win32\vc\mgllt.lib /nologo /subsystem:windows /debug /machine:I386 +# SUBTRACT BASE LINK32 /nodefaultlib +# ADD LINK32 comctl32.lib glu32.lib ..\dxsdk\sdk\lib\dxguid.lib opengl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /out:".\GLDebug\glqwcl.exe" +# SUBTRACT LINK32 /incremental:no /nodefaultlib + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\qwcl___W" +# PROP BASE Intermediate_Dir ".\qwcl___W" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\GLRelease" +# PROP Intermediate_Dir ".\GLRelease" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G5 /ML /GX /Zi /Od /I "e:\msdev\projects\dxsdk\sdk\inc" /I "e:\msdev\projects\scitech\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "GLQUAKE" /FR /YX /c +# ADD CPP /nologo /G5 /ML /GX /Ot /Ow /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "GLQUAKE" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 e:\msdev\projects\winquake\dxsdk\sdk\lib\dxguid.lib winmm.lib wsock32.lib opengl32.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"GLDebug/glqwcl.exe" +# SUBTRACT BASE LINK32 /nodefaultlib +# ADD LINK32 comctl32.lib glu32.lib ..\dxsdk\sdk\lib\dxguid.lib opengl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /incremental:no /debug /machine:I386 /out:".\GLRelease\glqwcl.exe" +# SUBTRACT LINK32 /nodefaultlib + +!ENDIF + +# Begin Target + +# Name "qwcl - Win32 Release" +# Name "qwcl - Win32 Debug" +# Name "qwcl - Win32 GLDebug" +# Name "qwcl - Win32 GLRelease" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\cd_win.c +# End Source File +# Begin Source File + +SOURCE=.\cl_cam.c +# End Source File +# Begin Source File + +SOURCE=.\cl_demo.c +# End Source File +# Begin Source File + +SOURCE=.\cl_ents.c +# End Source File +# Begin Source File + +SOURCE=.\cl_input.c +# End Source File +# Begin Source File + +SOURCE=.\cl_main.c +# End Source File +# Begin Source File + +SOURCE=.\cl_parse.c +# End Source File +# Begin Source File + +SOURCE=.\cl_pred.c +# End Source File +# Begin Source File + +SOURCE=.\cl_tent.c +# End Source File +# Begin Source File + +SOURCE=.\cmd.c +# End Source File +# Begin Source File + +SOURCE=.\common.c +# End Source File +# Begin Source File + +SOURCE=.\console.c +# End Source File +# Begin Source File + +SOURCE=.\crc.c +# End Source File +# Begin Source File + +SOURCE=.\cvar.c +# End Source File +# Begin Source File + +SOURCE=.\d_draw.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\d_draw.s +InputName=d_draw + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\d_draw.s +InputName=d_draw + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_draw16.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\d_draw16.s +InputName=d_draw16 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\d_draw16.s +InputName=d_draw16 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_edge.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_fill.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_init.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_modech.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_part.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_parta.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\d_parta.s +InputName=d_parta + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\d_parta.s +InputName=d_parta + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_polysa.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\d_polysa.s +InputName=d_polysa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\d_polysa.s +InputName=d_polysa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_polyse.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_scan.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_scana.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\d_scana.s +InputName=d_scana + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\d_scana.s +InputName=d_scana + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_sky.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_spr8.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\d_spr8.s +InputName=d_spr8 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\d_spr8.s +InputName=d_spr8 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_sprite.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_surf.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_vars.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_varsa.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\d_varsa.s +InputName=d_varsa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\d_varsa.s +InputName=d_varsa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_zpoint.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\draw.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_draw.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_mesh.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_model.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_ngraph.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_refrag.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_rlight.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_rmain.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_rmisc.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_rsurf.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_screen.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_test.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_vidnt.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_warp.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\in_win.c +# End Source File +# Begin Source File + +SOURCE=.\keys.c +# End Source File +# Begin Source File + +SOURCE=.\math.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\math.s +InputName=math + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\math.s +InputName=math + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# Begin Custom Build +OutDir=.\GLDebug +InputPath=.\math.s +InputName=math + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# Begin Custom Build +OutDir=.\GLRelease +InputPath=.\math.s +InputName=math + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\mathlib.c +# End Source File +# Begin Source File + +SOURCE=.\md4.c +# End Source File +# Begin Source File + +SOURCE=.\menu.c +# End Source File +# Begin Source File + +SOURCE=.\model.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\net_chan.c +# End Source File +# Begin Source File + +SOURCE=.\net_wins.c +# End Source File +# Begin Source File + +SOURCE=.\nonintel.c +# End Source File +# Begin Source File + +SOURCE=.\pmove.c +# End Source File +# Begin Source File + +SOURCE=.\pmovetst.c +# End Source File +# Begin Source File + +SOURCE=.\r_aclip.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_aclipa.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\r_aclipa.s +InputName=r_aclipa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\r_aclipa.s +InputName=r_aclipa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_alias.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_aliasa.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\r_aliasa.s +InputName=r_aliasa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\r_aliasa.s +InputName=r_aliasa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_bsp.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_draw.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_drawa.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\r_drawa.s +InputName=r_drawa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\r_drawa.s +InputName=r_drawa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_edge.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_edgea.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\r_edgea.s +InputName=r_edgea + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\r_edgea.s +InputName=r_edgea + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_efrag.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_light.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_main.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_misc.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_part.c +# End Source File +# Begin Source File + +SOURCE=.\r_sky.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_sprite.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_surf.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_vars.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_varsa.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\r_varsa.s +InputName=r_varsa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\r_varsa.s +InputName=r_varsa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sbar.c +# End Source File +# Begin Source File + +SOURCE=.\screen.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\skin.c +# End Source File +# Begin Source File + +SOURCE=.\snd_dma.c +# End Source File +# Begin Source File + +SOURCE=.\snd_mem.c +# End Source File +# Begin Source File + +SOURCE=.\snd_mix.c +# End Source File +# Begin Source File + +SOURCE=.\snd_mixa.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\snd_mixa.s +InputName=snd_mixa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\snd_mixa.s +InputName=snd_mixa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# Begin Custom Build +OutDir=.\GLDebug +InputPath=.\snd_mixa.s +InputName=snd_mixa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# Begin Custom Build +OutDir=.\GLRelease +InputPath=.\snd_mixa.s +InputName=snd_mixa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\snd_win.c +# End Source File +# Begin Source File + +SOURCE=.\surf16.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\surf16.s +InputName=surf16 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\surf16.s +InputName=surf16 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\surf8.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\surf8.s +InputName=surf8 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\surf8.s +InputName=surf8 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sys_win.c +# End Source File +# Begin Source File + +SOURCE=.\sys_wina.s + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=.\sys_wina.s +InputName=sys_wina + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# Begin Custom Build - GAS2MASM Conversion +OutDir=.\Debug +InputPath=.\sys_wina.s +InputName=sys_wina + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm.exe < $(OUTDIR)\$(InputName).spp >$(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# Begin Custom Build +OutDir=.\GLDebug +InputPath=.\sys_wina.s +InputName=sys_wina + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# Begin Custom Build +OutDir=.\GLRelease +InputPath=.\sys_wina.s +InputName=sys_wina + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\vid_win.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\view.c +# End Source File +# Begin Source File + +SOURCE=.\wad.c +# End Source File +# Begin Source File + +SOURCE=.\winquake.rc +# End Source File +# Begin Source File + +SOURCE=.\zone.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\adivtab.h +# End Source File +# Begin Source File + +SOURCE=.\anorm_dots.h +# End Source File +# Begin Source File + +SOURCE=.\anorms.h +# End Source File +# Begin Source File + +SOURCE=.\bothdefs.h +# End Source File +# Begin Source File + +SOURCE=.\bspfile.h +# End Source File +# Begin Source File + +SOURCE=.\cdaudio.h +# End Source File +# Begin Source File + +SOURCE=.\client.h +# End Source File +# Begin Source File + +SOURCE=.\cmd.h +# End Source File +# Begin Source File + +SOURCE=.\common.h +# End Source File +# Begin Source File + +SOURCE=.\console.h +# End Source File +# Begin Source File + +SOURCE=.\crc.h +# End Source File +# Begin Source File + +SOURCE=.\cvar.h +# End Source File +# Begin Source File + +SOURCE=.\d_iface.h + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_ifacea.h + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_local.h + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GLRelease" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\draw.h +# End Source File +# Begin Source File + +SOURCE=.\gl_model.h +# End Source File +# Begin Source File + +SOURCE=.\gl_warp_sin.h +# End Source File +# Begin Source File + +SOURCE=.\glquake.h +# End Source File +# Begin Source File + +SOURCE=.\input.h +# End Source File +# Begin Source File + +SOURCE=.\keys.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\quake\v2\master\masterpr.h +# End Source File +# Begin Source File + +SOURCE=.\mathlib.h +# End Source File +# Begin Source File + +SOURCE=.\menu.h +# End Source File +# Begin Source File + +SOURCE=.\model.h +# End Source File +# Begin Source File + +SOURCE=.\modelgen.h +# End Source File +# Begin Source File + +SOURCE=.\net.h +# End Source File +# Begin Source File + +SOURCE=.\pmove.h +# End Source File +# Begin Source File + +SOURCE=.\protocol.h +# End Source File +# Begin Source File + +SOURCE=.\quakedef.h +# End Source File +# Begin Source File + +SOURCE=.\r_local.h +# End Source File +# Begin Source File + +SOURCE=.\r_shared.h +# End Source File +# Begin Source File + +SOURCE=.\render.h +# End Source File +# Begin Source File + +SOURCE=.\sbar.h +# End Source File +# Begin Source File + +SOURCE=.\screen.h +# End Source File +# Begin Source File + +SOURCE=.\sound.h +# End Source File +# Begin Source File + +SOURCE=.\spritegn.h +# End Source File +# Begin Source File + +SOURCE=.\sys.h +# End Source File +# Begin Source File + +SOURCE=.\vid.h +# End Source File +# Begin Source File + +SOURCE=.\view.h +# End Source File +# Begin Source File + +SOURCE=.\wad.h +# End Source File +# Begin Source File + +SOURCE=.\winquake.h +# End Source File +# Begin Source File + +SOURCE=.\zone.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\qe3.ico +# End Source File +# Begin Source File + +SOURCE=.\quakeworld.bmp +# End Source File +# Begin Source File + +SOURCE=.\qwcl2.ico +# End Source File +# End Group +# End Target +# End Project diff --git a/QW/client/qwcl.dsw b/QW/client/qwcl.dsw new file mode 100644 index 0000000..5769254 --- /dev/null +++ b/QW/client/qwcl.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "qwcl"=.\qwcl.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/QW/client/qwcl.mak b/QW/client/qwcl.mak new file mode 100644 index 0000000..bc182cc --- /dev/null +++ b/QW/client/qwcl.mak @@ -0,0 +1,10009 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=qwcl - Win32 GL Debug +!MESSAGE No configuration specified. Defaulting to qwcl - Win32 GL Debug. +!ENDIF + +!IF "$(CFG)" != "qwcl - Win32 Release" && "$(CFG)" != "qwcl - Win32 Debug" &&\ + "$(CFG)" != "qwcl - Win32 GL Debug" && "$(CFG)" != "qwcl - Win32 GL Release" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "qwcl.mak" CFG="qwcl - Win32 GL Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "qwcl - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "qwcl - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "qwcl - Win32 GL Debug" (based on "Win32 (x86) Application") +!MESSAGE "qwcl - Win32 GL Release" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "qwcl - Win32 GL Debug" +MTL=mktyplib.exe +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "qwcl___W" +# PROP BASE Intermediate_Dir "qwcl___W" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "release" +# PROP Intermediate_Dir "release" +# PROP Target_Dir "" +OUTDIR=.\release +INTDIR=.\release + +ALL : "$(OUTDIR)\qwcl.exe" + +CLEAN : + -@erase "$(INTDIR)\cd_win.obj" + -@erase "$(INTDIR)\cl_cam.obj" + -@erase "$(INTDIR)\cl_demo.obj" + -@erase "$(INTDIR)\cl_ents.obj" + -@erase "$(INTDIR)\cl_input.obj" + -@erase "$(INTDIR)\cl_main.obj" + -@erase "$(INTDIR)\cl_parse.obj" + -@erase "$(INTDIR)\cl_pred.obj" + -@erase "$(INTDIR)\cl_tent.obj" + -@erase "$(INTDIR)\cmd.obj" + -@erase "$(INTDIR)\common.obj" + -@erase "$(INTDIR)\console.obj" + -@erase "$(INTDIR)\crc.obj" + -@erase "$(INTDIR)\cvar.obj" + -@erase "$(INTDIR)\d_draw.obj" + -@erase "$(INTDIR)\d_draw16.obj" + -@erase "$(INTDIR)\d_edge.obj" + -@erase "$(INTDIR)\d_fill.obj" + -@erase "$(INTDIR)\d_init.obj" + -@erase "$(INTDIR)\d_modech.obj" + -@erase "$(INTDIR)\d_part.obj" + -@erase "$(INTDIR)\d_parta.obj" + -@erase "$(INTDIR)\d_polysa.obj" + -@erase "$(INTDIR)\d_polyse.obj" + -@erase "$(INTDIR)\d_scan.obj" + -@erase "$(INTDIR)\d_scana.obj" + -@erase "$(INTDIR)\d_sky.obj" + -@erase "$(INTDIR)\d_spr8.obj" + -@erase "$(INTDIR)\d_sprite.obj" + -@erase "$(INTDIR)\d_surf.obj" + -@erase "$(INTDIR)\d_vars.obj" + -@erase "$(INTDIR)\d_varsa.obj" + -@erase "$(INTDIR)\d_zpoint.obj" + -@erase "$(INTDIR)\draw.obj" + -@erase "$(INTDIR)\in_win.obj" + -@erase "$(INTDIR)\keys.obj" + -@erase "$(INTDIR)\math.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\md4.obj" + -@erase "$(INTDIR)\menu.obj" + -@erase "$(INTDIR)\model.obj" + -@erase "$(INTDIR)\net_chan.obj" + -@erase "$(INTDIR)\net_wins.obj" + -@erase "$(INTDIR)\pmove.obj" + -@erase "$(INTDIR)\pmovetst.obj" + -@erase "$(INTDIR)\r_aclip.obj" + -@erase "$(INTDIR)\r_aclipa.obj" + -@erase "$(INTDIR)\r_alias.obj" + -@erase "$(INTDIR)\r_aliasa.obj" + -@erase "$(INTDIR)\r_bsp.obj" + -@erase "$(INTDIR)\r_draw.obj" + -@erase "$(INTDIR)\r_drawa.obj" + -@erase "$(INTDIR)\r_edge.obj" + -@erase "$(INTDIR)\r_edgea.obj" + -@erase "$(INTDIR)\r_efrag.obj" + -@erase "$(INTDIR)\r_light.obj" + -@erase "$(INTDIR)\r_main.obj" + -@erase "$(INTDIR)\r_misc.obj" + -@erase "$(INTDIR)\r_part.obj" + -@erase "$(INTDIR)\r_sky.obj" + -@erase "$(INTDIR)\r_sprite.obj" + -@erase "$(INTDIR)\r_surf.obj" + -@erase "$(INTDIR)\r_vars.obj" + -@erase "$(INTDIR)\r_varsa.obj" + -@erase "$(INTDIR)\sbar.obj" + -@erase "$(INTDIR)\screen.obj" + -@erase "$(INTDIR)\skin.obj" + -@erase "$(INTDIR)\snd_dma.obj" + -@erase "$(INTDIR)\snd_mem.obj" + -@erase "$(INTDIR)\snd_mix.obj" + -@erase "$(INTDIR)\snd_mixa.obj" + -@erase "$(INTDIR)\snd_win.obj" + -@erase "$(INTDIR)\surf16.obj" + -@erase "$(INTDIR)\surf8.obj" + -@erase "$(INTDIR)\sys_win.obj" + -@erase "$(INTDIR)\sys_wina.obj" + -@erase "$(INTDIR)\vid_win.obj" + -@erase "$(INTDIR)\view.obj" + -@erase "$(INTDIR)\wad.obj" + -@erase "$(INTDIR)\winquake.res" + -@erase "$(INTDIR)\zone.obj" + -@erase "$(OUTDIR)\qwcl.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /GX /O2 /I "..\..\scitech\include" /I "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# SUBTRACT CPP /X +CPP_PROJ=/nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\release/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/winquake.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qwcl.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 ..\..\scitech\lib\win32\vc\mgllt.lib ..\..\dxsdk\sdk\lib\dxguid.lib comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +LINK32_FLAGS=..\..\scitech\lib\win32\vc\mgllt.lib\ + ..\..\dxsdk\sdk\lib\dxguid.lib comctl32.lib wsock32.lib winmm.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:windows /incremental:no /pdb:"$(OUTDIR)/qwcl.pdb" /machine:I386\ + /out:"$(OUTDIR)/qwcl.exe" +LINK32_OBJS= \ + "$(INTDIR)\cd_win.obj" \ + "$(INTDIR)\cl_cam.obj" \ + "$(INTDIR)\cl_demo.obj" \ + "$(INTDIR)\cl_ents.obj" \ + "$(INTDIR)\cl_input.obj" \ + "$(INTDIR)\cl_main.obj" \ + "$(INTDIR)\cl_parse.obj" \ + "$(INTDIR)\cl_pred.obj" \ + "$(INTDIR)\cl_tent.obj" \ + "$(INTDIR)\cmd.obj" \ + "$(INTDIR)\common.obj" \ + "$(INTDIR)\console.obj" \ + "$(INTDIR)\crc.obj" \ + "$(INTDIR)\cvar.obj" \ + "$(INTDIR)\d_draw.obj" \ + "$(INTDIR)\d_draw16.obj" \ + "$(INTDIR)\d_edge.obj" \ + "$(INTDIR)\d_fill.obj" \ + "$(INTDIR)\d_init.obj" \ + "$(INTDIR)\d_modech.obj" \ + "$(INTDIR)\d_part.obj" \ + "$(INTDIR)\d_parta.obj" \ + "$(INTDIR)\d_polysa.obj" \ + "$(INTDIR)\d_polyse.obj" \ + "$(INTDIR)\d_scan.obj" \ + "$(INTDIR)\d_scana.obj" \ + "$(INTDIR)\d_sky.obj" \ + "$(INTDIR)\d_spr8.obj" \ + "$(INTDIR)\d_sprite.obj" \ + "$(INTDIR)\d_surf.obj" \ + "$(INTDIR)\d_vars.obj" \ + "$(INTDIR)\d_varsa.obj" \ + "$(INTDIR)\d_zpoint.obj" \ + "$(INTDIR)\draw.obj" \ + "$(INTDIR)\in_win.obj" \ + "$(INTDIR)\keys.obj" \ + "$(INTDIR)\math.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\md4.obj" \ + "$(INTDIR)\menu.obj" \ + "$(INTDIR)\model.obj" \ + "$(INTDIR)\net_chan.obj" \ + "$(INTDIR)\net_wins.obj" \ + "$(INTDIR)\pmove.obj" \ + "$(INTDIR)\pmovetst.obj" \ + "$(INTDIR)\r_aclip.obj" \ + "$(INTDIR)\r_aclipa.obj" \ + "$(INTDIR)\r_alias.obj" \ + "$(INTDIR)\r_aliasa.obj" \ + "$(INTDIR)\r_bsp.obj" \ + "$(INTDIR)\r_draw.obj" \ + "$(INTDIR)\r_drawa.obj" \ + "$(INTDIR)\r_edge.obj" \ + "$(INTDIR)\r_edgea.obj" \ + "$(INTDIR)\r_efrag.obj" \ + "$(INTDIR)\r_light.obj" \ + "$(INTDIR)\r_main.obj" \ + "$(INTDIR)\r_misc.obj" \ + "$(INTDIR)\r_part.obj" \ + "$(INTDIR)\r_sky.obj" \ + "$(INTDIR)\r_sprite.obj" \ + "$(INTDIR)\r_surf.obj" \ + "$(INTDIR)\r_vars.obj" \ + "$(INTDIR)\r_varsa.obj" \ + "$(INTDIR)\sbar.obj" \ + "$(INTDIR)\screen.obj" \ + "$(INTDIR)\skin.obj" \ + "$(INTDIR)\snd_dma.obj" \ + "$(INTDIR)\snd_mem.obj" \ + "$(INTDIR)\snd_mix.obj" \ + "$(INTDIR)\snd_mixa.obj" \ + "$(INTDIR)\snd_win.obj" \ + "$(INTDIR)\surf16.obj" \ + "$(INTDIR)\surf8.obj" \ + "$(INTDIR)\sys_win.obj" \ + "$(INTDIR)\sys_wina.obj" \ + "$(INTDIR)\vid_win.obj" \ + "$(INTDIR)\view.obj" \ + "$(INTDIR)\wad.obj" \ + "$(INTDIR)\winquake.res" \ + "$(INTDIR)\zone.obj" + +"$(OUTDIR)\qwcl.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "qwcl___0" +# PROP BASE Intermediate_Dir "qwcl___0" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "debug" +# PROP Intermediate_Dir "debug" +# PROP Target_Dir "" +OUTDIR=.\debug +INTDIR=.\debug + +ALL : "$(OUTDIR)\qwcl.exe" "$(OUTDIR)\qwcl.bsc" + +CLEAN : + -@erase "$(INTDIR)\cd_win.obj" + -@erase "$(INTDIR)\cd_win.sbr" + -@erase "$(INTDIR)\cl_cam.obj" + -@erase "$(INTDIR)\cl_cam.sbr" + -@erase "$(INTDIR)\cl_demo.obj" + -@erase "$(INTDIR)\cl_demo.sbr" + -@erase "$(INTDIR)\cl_ents.obj" + -@erase "$(INTDIR)\cl_ents.sbr" + -@erase "$(INTDIR)\cl_input.obj" + -@erase "$(INTDIR)\cl_input.sbr" + -@erase "$(INTDIR)\cl_main.obj" + -@erase "$(INTDIR)\cl_main.sbr" + -@erase "$(INTDIR)\cl_parse.obj" + -@erase "$(INTDIR)\cl_parse.sbr" + -@erase "$(INTDIR)\cl_pred.obj" + -@erase "$(INTDIR)\cl_pred.sbr" + -@erase "$(INTDIR)\cl_tent.obj" + -@erase "$(INTDIR)\cl_tent.sbr" + -@erase "$(INTDIR)\cmd.obj" + -@erase "$(INTDIR)\cmd.sbr" + -@erase "$(INTDIR)\common.obj" + -@erase "$(INTDIR)\common.sbr" + -@erase "$(INTDIR)\console.obj" + -@erase "$(INTDIR)\console.sbr" + -@erase "$(INTDIR)\crc.obj" + -@erase "$(INTDIR)\crc.sbr" + -@erase "$(INTDIR)\cvar.obj" + -@erase "$(INTDIR)\cvar.sbr" + -@erase "$(INTDIR)\d_draw.obj" + -@erase "$(INTDIR)\d_draw16.obj" + -@erase "$(INTDIR)\d_edge.obj" + -@erase "$(INTDIR)\d_edge.sbr" + -@erase "$(INTDIR)\d_fill.obj" + -@erase "$(INTDIR)\d_fill.sbr" + -@erase "$(INTDIR)\d_init.obj" + -@erase "$(INTDIR)\d_init.sbr" + -@erase "$(INTDIR)\d_modech.obj" + -@erase "$(INTDIR)\d_modech.sbr" + -@erase "$(INTDIR)\d_part.obj" + -@erase "$(INTDIR)\d_part.sbr" + -@erase "$(INTDIR)\d_parta.obj" + -@erase "$(INTDIR)\d_polysa.obj" + -@erase "$(INTDIR)\d_polyse.obj" + -@erase "$(INTDIR)\d_polyse.sbr" + -@erase "$(INTDIR)\d_scan.obj" + -@erase "$(INTDIR)\d_scan.sbr" + -@erase "$(INTDIR)\d_scana.obj" + -@erase "$(INTDIR)\d_sky.obj" + -@erase "$(INTDIR)\d_sky.sbr" + -@erase "$(INTDIR)\d_spr8.obj" + -@erase "$(INTDIR)\d_sprite.obj" + -@erase "$(INTDIR)\d_sprite.sbr" + -@erase "$(INTDIR)\d_surf.obj" + -@erase "$(INTDIR)\d_surf.sbr" + -@erase "$(INTDIR)\d_vars.obj" + -@erase "$(INTDIR)\d_vars.sbr" + -@erase "$(INTDIR)\d_varsa.obj" + -@erase "$(INTDIR)\d_zpoint.obj" + -@erase "$(INTDIR)\d_zpoint.sbr" + -@erase "$(INTDIR)\draw.obj" + -@erase "$(INTDIR)\draw.sbr" + -@erase "$(INTDIR)\in_win.obj" + -@erase "$(INTDIR)\in_win.sbr" + -@erase "$(INTDIR)\keys.obj" + -@erase "$(INTDIR)\keys.sbr" + -@erase "$(INTDIR)\math.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\mathlib.sbr" + -@erase "$(INTDIR)\md4.obj" + -@erase "$(INTDIR)\md4.sbr" + -@erase "$(INTDIR)\menu.obj" + -@erase "$(INTDIR)\menu.sbr" + -@erase "$(INTDIR)\model.obj" + -@erase "$(INTDIR)\model.sbr" + -@erase "$(INTDIR)\net_chan.obj" + -@erase "$(INTDIR)\net_chan.sbr" + -@erase "$(INTDIR)\net_wins.obj" + -@erase "$(INTDIR)\net_wins.sbr" + -@erase "$(INTDIR)\pmove.obj" + -@erase "$(INTDIR)\pmove.sbr" + -@erase "$(INTDIR)\pmovetst.obj" + -@erase "$(INTDIR)\pmovetst.sbr" + -@erase "$(INTDIR)\r_aclip.obj" + -@erase "$(INTDIR)\r_aclip.sbr" + -@erase "$(INTDIR)\r_aclipa.obj" + -@erase "$(INTDIR)\r_alias.obj" + -@erase "$(INTDIR)\r_alias.sbr" + -@erase "$(INTDIR)\r_aliasa.obj" + -@erase "$(INTDIR)\r_bsp.obj" + -@erase "$(INTDIR)\r_bsp.sbr" + -@erase "$(INTDIR)\r_draw.obj" + -@erase "$(INTDIR)\r_draw.sbr" + -@erase "$(INTDIR)\r_drawa.obj" + -@erase "$(INTDIR)\r_edge.obj" + -@erase "$(INTDIR)\r_edge.sbr" + -@erase "$(INTDIR)\r_edgea.obj" + -@erase "$(INTDIR)\r_efrag.obj" + -@erase "$(INTDIR)\r_efrag.sbr" + -@erase "$(INTDIR)\r_light.obj" + -@erase "$(INTDIR)\r_light.sbr" + -@erase "$(INTDIR)\r_main.obj" + -@erase "$(INTDIR)\r_main.sbr" + -@erase "$(INTDIR)\r_misc.obj" + -@erase "$(INTDIR)\r_misc.sbr" + -@erase "$(INTDIR)\r_part.obj" + -@erase "$(INTDIR)\r_part.sbr" + -@erase "$(INTDIR)\r_sky.obj" + -@erase "$(INTDIR)\r_sky.sbr" + -@erase "$(INTDIR)\r_sprite.obj" + -@erase "$(INTDIR)\r_sprite.sbr" + -@erase "$(INTDIR)\r_surf.obj" + -@erase "$(INTDIR)\r_surf.sbr" + -@erase "$(INTDIR)\r_vars.obj" + -@erase "$(INTDIR)\r_vars.sbr" + -@erase "$(INTDIR)\r_varsa.obj" + -@erase "$(INTDIR)\sbar.obj" + -@erase "$(INTDIR)\sbar.sbr" + -@erase "$(INTDIR)\screen.obj" + -@erase "$(INTDIR)\screen.sbr" + -@erase "$(INTDIR)\skin.obj" + -@erase "$(INTDIR)\skin.sbr" + -@erase "$(INTDIR)\snd_dma.obj" + -@erase "$(INTDIR)\snd_dma.sbr" + -@erase "$(INTDIR)\snd_mem.obj" + -@erase "$(INTDIR)\snd_mem.sbr" + -@erase "$(INTDIR)\snd_mix.obj" + -@erase "$(INTDIR)\snd_mix.sbr" + -@erase "$(INTDIR)\snd_mixa.obj" + -@erase "$(INTDIR)\snd_win.obj" + -@erase "$(INTDIR)\snd_win.sbr" + -@erase "$(INTDIR)\surf16.obj" + -@erase "$(INTDIR)\surf8.obj" + -@erase "$(INTDIR)\sys_win.obj" + -@erase "$(INTDIR)\sys_win.sbr" + -@erase "$(INTDIR)\sys_wina.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(INTDIR)\vid_win.obj" + -@erase "$(INTDIR)\vid_win.sbr" + -@erase "$(INTDIR)\view.obj" + -@erase "$(INTDIR)\view.sbr" + -@erase "$(INTDIR)\wad.obj" + -@erase "$(INTDIR)\wad.sbr" + -@erase "$(INTDIR)\winquake.res" + -@erase "$(INTDIR)\zone.obj" + -@erase "$(INTDIR)\zone.sbr" + -@erase "$(OUTDIR)\qwcl.bsc" + -@erase "$(OUTDIR)\qwcl.exe" + -@erase "$(OUTDIR)\qwcl.ilk" + -@erase "$(OUTDIR)\qwcl.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /Gm /GX /Zi /Od /I "..\..\scitech\include" /I "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /c +# SUBTRACT CPP /X +CPP_PROJ=/nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\debug/ +CPP_SBRS=.\debug/ +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/winquake.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qwcl.bsc" +BSC32_SBRS= \ + "$(INTDIR)\cd_win.sbr" \ + "$(INTDIR)\cl_cam.sbr" \ + "$(INTDIR)\cl_demo.sbr" \ + "$(INTDIR)\cl_ents.sbr" \ + "$(INTDIR)\cl_input.sbr" \ + "$(INTDIR)\cl_main.sbr" \ + "$(INTDIR)\cl_parse.sbr" \ + "$(INTDIR)\cl_pred.sbr" \ + "$(INTDIR)\cl_tent.sbr" \ + "$(INTDIR)\cmd.sbr" \ + "$(INTDIR)\common.sbr" \ + "$(INTDIR)\console.sbr" \ + "$(INTDIR)\crc.sbr" \ + "$(INTDIR)\cvar.sbr" \ + "$(INTDIR)\d_edge.sbr" \ + "$(INTDIR)\d_fill.sbr" \ + "$(INTDIR)\d_init.sbr" \ + "$(INTDIR)\d_modech.sbr" \ + "$(INTDIR)\d_part.sbr" \ + "$(INTDIR)\d_polyse.sbr" \ + "$(INTDIR)\d_scan.sbr" \ + "$(INTDIR)\d_sky.sbr" \ + "$(INTDIR)\d_sprite.sbr" \ + "$(INTDIR)\d_surf.sbr" \ + "$(INTDIR)\d_vars.sbr" \ + "$(INTDIR)\d_zpoint.sbr" \ + "$(INTDIR)\draw.sbr" \ + "$(INTDIR)\in_win.sbr" \ + "$(INTDIR)\keys.sbr" \ + "$(INTDIR)\mathlib.sbr" \ + "$(INTDIR)\md4.sbr" \ + "$(INTDIR)\menu.sbr" \ + "$(INTDIR)\model.sbr" \ + "$(INTDIR)\net_chan.sbr" \ + "$(INTDIR)\net_wins.sbr" \ + "$(INTDIR)\pmove.sbr" \ + "$(INTDIR)\pmovetst.sbr" \ + "$(INTDIR)\r_aclip.sbr" \ + "$(INTDIR)\r_alias.sbr" \ + "$(INTDIR)\r_bsp.sbr" \ + "$(INTDIR)\r_draw.sbr" \ + "$(INTDIR)\r_edge.sbr" \ + "$(INTDIR)\r_efrag.sbr" \ + "$(INTDIR)\r_light.sbr" \ + "$(INTDIR)\r_main.sbr" \ + "$(INTDIR)\r_misc.sbr" \ + "$(INTDIR)\r_part.sbr" \ + "$(INTDIR)\r_sky.sbr" \ + "$(INTDIR)\r_sprite.sbr" \ + "$(INTDIR)\r_surf.sbr" \ + "$(INTDIR)\r_vars.sbr" \ + "$(INTDIR)\sbar.sbr" \ + "$(INTDIR)\screen.sbr" \ + "$(INTDIR)\skin.sbr" \ + "$(INTDIR)\snd_dma.sbr" \ + "$(INTDIR)\snd_mem.sbr" \ + "$(INTDIR)\snd_mix.sbr" \ + "$(INTDIR)\snd_win.sbr" \ + "$(INTDIR)\sys_win.sbr" \ + "$(INTDIR)\vid_win.sbr" \ + "$(INTDIR)\view.sbr" \ + "$(INTDIR)\wad.sbr" \ + "$(INTDIR)\zone.sbr" + +"$(OUTDIR)\qwcl.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 ..\..\scitech\lib\win32\vc\mgllt.lib ..\..\dxsdk\sdk\lib\dxguid.lib comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +# SUBTRACT LINK32 /verbose +LINK32_FLAGS=..\..\scitech\lib\win32\vc\mgllt.lib\ + ..\..\dxsdk\sdk\lib\dxguid.lib comctl32.lib wsock32.lib winmm.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)/qwcl.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/qwcl.exe" +LINK32_OBJS= \ + "$(INTDIR)\cd_win.obj" \ + "$(INTDIR)\cl_cam.obj" \ + "$(INTDIR)\cl_demo.obj" \ + "$(INTDIR)\cl_ents.obj" \ + "$(INTDIR)\cl_input.obj" \ + "$(INTDIR)\cl_main.obj" \ + "$(INTDIR)\cl_parse.obj" \ + "$(INTDIR)\cl_pred.obj" \ + "$(INTDIR)\cl_tent.obj" \ + "$(INTDIR)\cmd.obj" \ + "$(INTDIR)\common.obj" \ + "$(INTDIR)\console.obj" \ + "$(INTDIR)\crc.obj" \ + "$(INTDIR)\cvar.obj" \ + "$(INTDIR)\d_draw.obj" \ + "$(INTDIR)\d_draw16.obj" \ + "$(INTDIR)\d_edge.obj" \ + "$(INTDIR)\d_fill.obj" \ + "$(INTDIR)\d_init.obj" \ + "$(INTDIR)\d_modech.obj" \ + "$(INTDIR)\d_part.obj" \ + "$(INTDIR)\d_parta.obj" \ + "$(INTDIR)\d_polysa.obj" \ + "$(INTDIR)\d_polyse.obj" \ + "$(INTDIR)\d_scan.obj" \ + "$(INTDIR)\d_scana.obj" \ + "$(INTDIR)\d_sky.obj" \ + "$(INTDIR)\d_spr8.obj" \ + "$(INTDIR)\d_sprite.obj" \ + "$(INTDIR)\d_surf.obj" \ + "$(INTDIR)\d_vars.obj" \ + "$(INTDIR)\d_varsa.obj" \ + "$(INTDIR)\d_zpoint.obj" \ + "$(INTDIR)\draw.obj" \ + "$(INTDIR)\in_win.obj" \ + "$(INTDIR)\keys.obj" \ + "$(INTDIR)\math.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\md4.obj" \ + "$(INTDIR)\menu.obj" \ + "$(INTDIR)\model.obj" \ + "$(INTDIR)\net_chan.obj" \ + "$(INTDIR)\net_wins.obj" \ + "$(INTDIR)\pmove.obj" \ + "$(INTDIR)\pmovetst.obj" \ + "$(INTDIR)\r_aclip.obj" \ + "$(INTDIR)\r_aclipa.obj" \ + "$(INTDIR)\r_alias.obj" \ + "$(INTDIR)\r_aliasa.obj" \ + "$(INTDIR)\r_bsp.obj" \ + "$(INTDIR)\r_draw.obj" \ + "$(INTDIR)\r_drawa.obj" \ + "$(INTDIR)\r_edge.obj" \ + "$(INTDIR)\r_edgea.obj" \ + "$(INTDIR)\r_efrag.obj" \ + "$(INTDIR)\r_light.obj" \ + "$(INTDIR)\r_main.obj" \ + "$(INTDIR)\r_misc.obj" \ + "$(INTDIR)\r_part.obj" \ + "$(INTDIR)\r_sky.obj" \ + "$(INTDIR)\r_sprite.obj" \ + "$(INTDIR)\r_surf.obj" \ + "$(INTDIR)\r_vars.obj" \ + "$(INTDIR)\r_varsa.obj" \ + "$(INTDIR)\sbar.obj" \ + "$(INTDIR)\screen.obj" \ + "$(INTDIR)\skin.obj" \ + "$(INTDIR)\snd_dma.obj" \ + "$(INTDIR)\snd_mem.obj" \ + "$(INTDIR)\snd_mix.obj" \ + "$(INTDIR)\snd_mixa.obj" \ + "$(INTDIR)\snd_win.obj" \ + "$(INTDIR)\surf16.obj" \ + "$(INTDIR)\surf8.obj" \ + "$(INTDIR)\sys_win.obj" \ + "$(INTDIR)\sys_wina.obj" \ + "$(INTDIR)\vid_win.obj" \ + "$(INTDIR)\view.obj" \ + "$(INTDIR)\wad.obj" \ + "$(INTDIR)\winquake.res" \ + "$(INTDIR)\zone.obj" + +"$(OUTDIR)\qwcl.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "GL Debug" +# PROP BASE Intermediate_Dir "GL Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "GLDebug" +# PROP Intermediate_Dir "GLDebug" +# PROP Target_Dir "" +OUTDIR=.\GLDebug +INTDIR=.\GLDebug + +ALL : "$(OUTDIR)\glqwcl.exe" "$(OUTDIR)\qwcl.bsc" + +CLEAN : + -@erase "$(INTDIR)\cd_win.obj" + -@erase "$(INTDIR)\cd_win.sbr" + -@erase "$(INTDIR)\cl_cam.obj" + -@erase "$(INTDIR)\cl_cam.sbr" + -@erase "$(INTDIR)\cl_demo.obj" + -@erase "$(INTDIR)\cl_demo.sbr" + -@erase "$(INTDIR)\cl_ents.obj" + -@erase "$(INTDIR)\cl_ents.sbr" + -@erase "$(INTDIR)\cl_input.obj" + -@erase "$(INTDIR)\cl_input.sbr" + -@erase "$(INTDIR)\cl_main.obj" + -@erase "$(INTDIR)\cl_main.sbr" + -@erase "$(INTDIR)\cl_parse.obj" + -@erase "$(INTDIR)\cl_parse.sbr" + -@erase "$(INTDIR)\cl_pred.obj" + -@erase "$(INTDIR)\cl_pred.sbr" + -@erase "$(INTDIR)\cl_tent.obj" + -@erase "$(INTDIR)\cl_tent.sbr" + -@erase "$(INTDIR)\cmd.obj" + -@erase "$(INTDIR)\cmd.sbr" + -@erase "$(INTDIR)\common.obj" + -@erase "$(INTDIR)\common.sbr" + -@erase "$(INTDIR)\console.obj" + -@erase "$(INTDIR)\console.sbr" + -@erase "$(INTDIR)\crc.obj" + -@erase "$(INTDIR)\crc.sbr" + -@erase "$(INTDIR)\cvar.obj" + -@erase "$(INTDIR)\cvar.sbr" + -@erase "$(INTDIR)\gl_draw.obj" + -@erase "$(INTDIR)\gl_draw.sbr" + -@erase "$(INTDIR)\gl_mesh.obj" + -@erase "$(INTDIR)\gl_mesh.sbr" + -@erase "$(INTDIR)\gl_model.obj" + -@erase "$(INTDIR)\gl_model.sbr" + -@erase "$(INTDIR)\gl_ngraph.obj" + -@erase "$(INTDIR)\gl_ngraph.sbr" + -@erase "$(INTDIR)\gl_refrag.obj" + -@erase "$(INTDIR)\gl_refrag.sbr" + -@erase "$(INTDIR)\gl_rlight.obj" + -@erase "$(INTDIR)\gl_rlight.sbr" + -@erase "$(INTDIR)\gl_rmain.obj" + -@erase "$(INTDIR)\gl_rmain.sbr" + -@erase "$(INTDIR)\gl_rmisc.obj" + -@erase "$(INTDIR)\gl_rmisc.sbr" + -@erase "$(INTDIR)\gl_rsurf.obj" + -@erase "$(INTDIR)\gl_rsurf.sbr" + -@erase "$(INTDIR)\gl_screen.obj" + -@erase "$(INTDIR)\gl_screen.sbr" + -@erase "$(INTDIR)\gl_test.obj" + -@erase "$(INTDIR)\gl_test.sbr" + -@erase "$(INTDIR)\gl_vidnt.obj" + -@erase "$(INTDIR)\gl_vidnt.sbr" + -@erase "$(INTDIR)\gl_warp.obj" + -@erase "$(INTDIR)\gl_warp.sbr" + -@erase "$(INTDIR)\in_win.obj" + -@erase "$(INTDIR)\in_win.sbr" + -@erase "$(INTDIR)\keys.obj" + -@erase "$(INTDIR)\keys.sbr" + -@erase "$(INTDIR)\math.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\mathlib.sbr" + -@erase "$(INTDIR)\md4.obj" + -@erase "$(INTDIR)\md4.sbr" + -@erase "$(INTDIR)\menu.obj" + -@erase "$(INTDIR)\menu.sbr" + -@erase "$(INTDIR)\net_chan.obj" + -@erase "$(INTDIR)\net_chan.sbr" + -@erase "$(INTDIR)\net_wins.obj" + -@erase "$(INTDIR)\net_wins.sbr" + -@erase "$(INTDIR)\pmove.obj" + -@erase "$(INTDIR)\pmove.sbr" + -@erase "$(INTDIR)\pmovetst.obj" + -@erase "$(INTDIR)\pmovetst.sbr" + -@erase "$(INTDIR)\r_part.obj" + -@erase "$(INTDIR)\r_part.sbr" + -@erase "$(INTDIR)\sbar.obj" + -@erase "$(INTDIR)\sbar.sbr" + -@erase "$(INTDIR)\skin.obj" + -@erase "$(INTDIR)\skin.sbr" + -@erase "$(INTDIR)\snd_dma.obj" + -@erase "$(INTDIR)\snd_dma.sbr" + -@erase "$(INTDIR)\snd_mem.obj" + -@erase "$(INTDIR)\snd_mem.sbr" + -@erase "$(INTDIR)\snd_mix.obj" + -@erase "$(INTDIR)\snd_mix.sbr" + -@erase "$(INTDIR)\snd_mixa.obj" + -@erase "$(INTDIR)\snd_win.obj" + -@erase "$(INTDIR)\snd_win.sbr" + -@erase "$(INTDIR)\sys_win.obj" + -@erase "$(INTDIR)\sys_win.sbr" + -@erase "$(INTDIR)\sys_wina.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(INTDIR)\view.obj" + -@erase "$(INTDIR)\view.sbr" + -@erase "$(INTDIR)\wad.obj" + -@erase "$(INTDIR)\wad.sbr" + -@erase "$(INTDIR)\winquake.res" + -@erase "$(INTDIR)\zone.obj" + -@erase "$(INTDIR)\zone.sbr" + -@erase "$(OUTDIR)\glqwcl.exe" + -@erase "$(OUTDIR)\glqwcl.ilk" + -@erase "$(OUTDIR)\glqwcl.pdb" + -@erase "$(OUTDIR)\qwcl.bsc" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /c +# ADD CPP /nologo /Gm /GX /Zi /Od /I "..\..\scitech\include" /I "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /FR /YX /c +# SUBTRACT CPP /X +CPP_PROJ=/nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\GLDebug/ +CPP_SBRS=.\GLDebug/ +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/winquake.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qwcl.bsc" +BSC32_SBRS= \ + "$(INTDIR)\cd_win.sbr" \ + "$(INTDIR)\cl_cam.sbr" \ + "$(INTDIR)\cl_demo.sbr" \ + "$(INTDIR)\cl_ents.sbr" \ + "$(INTDIR)\cl_input.sbr" \ + "$(INTDIR)\cl_main.sbr" \ + "$(INTDIR)\cl_parse.sbr" \ + "$(INTDIR)\cl_pred.sbr" \ + "$(INTDIR)\cl_tent.sbr" \ + "$(INTDIR)\cmd.sbr" \ + "$(INTDIR)\common.sbr" \ + "$(INTDIR)\console.sbr" \ + "$(INTDIR)\crc.sbr" \ + "$(INTDIR)\cvar.sbr" \ + "$(INTDIR)\gl_draw.sbr" \ + "$(INTDIR)\gl_mesh.sbr" \ + "$(INTDIR)\gl_model.sbr" \ + "$(INTDIR)\gl_ngraph.sbr" \ + "$(INTDIR)\gl_refrag.sbr" \ + "$(INTDIR)\gl_rlight.sbr" \ + "$(INTDIR)\gl_rmain.sbr" \ + "$(INTDIR)\gl_rmisc.sbr" \ + "$(INTDIR)\gl_rsurf.sbr" \ + "$(INTDIR)\gl_screen.sbr" \ + "$(INTDIR)\gl_test.sbr" \ + "$(INTDIR)\gl_vidnt.sbr" \ + "$(INTDIR)\gl_warp.sbr" \ + "$(INTDIR)\in_win.sbr" \ + "$(INTDIR)\keys.sbr" \ + "$(INTDIR)\mathlib.sbr" \ + "$(INTDIR)\md4.sbr" \ + "$(INTDIR)\menu.sbr" \ + "$(INTDIR)\net_chan.sbr" \ + "$(INTDIR)\net_wins.sbr" \ + "$(INTDIR)\pmove.sbr" \ + "$(INTDIR)\pmovetst.sbr" \ + "$(INTDIR)\r_part.sbr" \ + "$(INTDIR)\sbar.sbr" \ + "$(INTDIR)\skin.sbr" \ + "$(INTDIR)\snd_dma.sbr" \ + "$(INTDIR)\snd_mem.sbr" \ + "$(INTDIR)\snd_mix.sbr" \ + "$(INTDIR)\snd_win.sbr" \ + "$(INTDIR)\sys_win.sbr" \ + "$(INTDIR)\view.sbr" \ + "$(INTDIR)\wad.sbr" \ + "$(INTDIR)\zone.sbr" + +"$(OUTDIR)\qwcl.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 ..\..\dxsdk\sdk\lib\dxguid.lib ..\..\scitech\lib\win32\vc\mgllt.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 opengl32.lib ..\..\dxsdk\sdk\lib\dxguid.lib comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"GLDebug/glqwcl.exe" +LINK32_FLAGS=opengl32.lib ..\..\dxsdk\sdk\lib\dxguid.lib comctl32.lib\ + wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\ + odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:yes\ + /pdb:"$(OUTDIR)/glqwcl.pdb" /debug /machine:I386 /out:"$(OUTDIR)/glqwcl.exe" +LINK32_OBJS= \ + "$(INTDIR)\cd_win.obj" \ + "$(INTDIR)\cl_cam.obj" \ + "$(INTDIR)\cl_demo.obj" \ + "$(INTDIR)\cl_ents.obj" \ + "$(INTDIR)\cl_input.obj" \ + "$(INTDIR)\cl_main.obj" \ + "$(INTDIR)\cl_parse.obj" \ + "$(INTDIR)\cl_pred.obj" \ + "$(INTDIR)\cl_tent.obj" \ + "$(INTDIR)\cmd.obj" \ + "$(INTDIR)\common.obj" \ + "$(INTDIR)\console.obj" \ + "$(INTDIR)\crc.obj" \ + "$(INTDIR)\cvar.obj" \ + "$(INTDIR)\gl_draw.obj" \ + "$(INTDIR)\gl_mesh.obj" \ + "$(INTDIR)\gl_model.obj" \ + "$(INTDIR)\gl_ngraph.obj" \ + "$(INTDIR)\gl_refrag.obj" \ + "$(INTDIR)\gl_rlight.obj" \ + "$(INTDIR)\gl_rmain.obj" \ + "$(INTDIR)\gl_rmisc.obj" \ + "$(INTDIR)\gl_rsurf.obj" \ + "$(INTDIR)\gl_screen.obj" \ + "$(INTDIR)\gl_test.obj" \ + "$(INTDIR)\gl_vidnt.obj" \ + "$(INTDIR)\gl_warp.obj" \ + "$(INTDIR)\in_win.obj" \ + "$(INTDIR)\keys.obj" \ + "$(INTDIR)\math.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\md4.obj" \ + "$(INTDIR)\menu.obj" \ + "$(INTDIR)\net_chan.obj" \ + "$(INTDIR)\net_wins.obj" \ + "$(INTDIR)\pmove.obj" \ + "$(INTDIR)\pmovetst.obj" \ + "$(INTDIR)\r_part.obj" \ + "$(INTDIR)\sbar.obj" \ + "$(INTDIR)\skin.obj" \ + "$(INTDIR)\snd_dma.obj" \ + "$(INTDIR)\snd_mem.obj" \ + "$(INTDIR)\snd_mix.obj" \ + "$(INTDIR)\snd_mixa.obj" \ + "$(INTDIR)\snd_win.obj" \ + "$(INTDIR)\sys_win.obj" \ + "$(INTDIR)\sys_wina.obj" \ + "$(INTDIR)\view.obj" \ + "$(INTDIR)\wad.obj" \ + "$(INTDIR)\winquake.res" \ + "$(INTDIR)\zone.obj" + +"$(OUTDIR)\glqwcl.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "GL Release" +# PROP BASE Intermediate_Dir "GL Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "GLRelease" +# PROP Intermediate_Dir "GLRelease" +# PROP Target_Dir "" +OUTDIR=.\GLRelease +INTDIR=.\GLRelease + +ALL : "$(OUTDIR)\glqwcl.exe" + +CLEAN : + -@erase "$(INTDIR)\cd_win.obj" + -@erase "$(INTDIR)\cl_cam.obj" + -@erase "$(INTDIR)\cl_demo.obj" + -@erase "$(INTDIR)\cl_ents.obj" + -@erase "$(INTDIR)\cl_input.obj" + -@erase "$(INTDIR)\cl_main.obj" + -@erase "$(INTDIR)\cl_parse.obj" + -@erase "$(INTDIR)\cl_pred.obj" + -@erase "$(INTDIR)\cl_tent.obj" + -@erase "$(INTDIR)\cmd.obj" + -@erase "$(INTDIR)\common.obj" + -@erase "$(INTDIR)\console.obj" + -@erase "$(INTDIR)\crc.obj" + -@erase "$(INTDIR)\cvar.obj" + -@erase "$(INTDIR)\gl_draw.obj" + -@erase "$(INTDIR)\gl_mesh.obj" + -@erase "$(INTDIR)\gl_model.obj" + -@erase "$(INTDIR)\gl_ngraph.obj" + -@erase "$(INTDIR)\gl_refrag.obj" + -@erase "$(INTDIR)\gl_rlight.obj" + -@erase "$(INTDIR)\gl_rmain.obj" + -@erase "$(INTDIR)\gl_rmisc.obj" + -@erase "$(INTDIR)\gl_rsurf.obj" + -@erase "$(INTDIR)\gl_screen.obj" + -@erase "$(INTDIR)\gl_test.obj" + -@erase "$(INTDIR)\gl_vidnt.obj" + -@erase "$(INTDIR)\gl_warp.obj" + -@erase "$(INTDIR)\in_win.obj" + -@erase "$(INTDIR)\keys.obj" + -@erase "$(INTDIR)\math.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\md4.obj" + -@erase "$(INTDIR)\menu.obj" + -@erase "$(INTDIR)\net_chan.obj" + -@erase "$(INTDIR)\net_wins.obj" + -@erase "$(INTDIR)\pmove.obj" + -@erase "$(INTDIR)\pmovetst.obj" + -@erase "$(INTDIR)\r_part.obj" + -@erase "$(INTDIR)\sbar.obj" + -@erase "$(INTDIR)\skin.obj" + -@erase "$(INTDIR)\snd_dma.obj" + -@erase "$(INTDIR)\snd_mem.obj" + -@erase "$(INTDIR)\snd_mix.obj" + -@erase "$(INTDIR)\snd_mixa.obj" + -@erase "$(INTDIR)\snd_win.obj" + -@erase "$(INTDIR)\sys_win.obj" + -@erase "$(INTDIR)\sys_wina.obj" + -@erase "$(INTDIR)\view.obj" + -@erase "$(INTDIR)\wad.obj" + -@erase "$(INTDIR)\winquake.res" + -@erase "$(INTDIR)\zone.obj" + -@erase "$(OUTDIR)\glqwcl.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /GX /O2 /I "..\..\scitech\include" /I "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /YX /c +# SUBTRACT CPP /X +CPP_PROJ=/nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\GLRelease/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/winquake.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qwcl.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 ..\..\dxsdk\sdk\lib\dxguid.lib ..\..\scitech\lib\win32\vc\mgllt.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 opengl32.lib ..\..\dxsdk\sdk\lib\dxguid.lib comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"GLRelease/glqwcl.exe" +LINK32_FLAGS=opengl32.lib ..\..\dxsdk\sdk\lib\dxguid.lib comctl32.lib\ + wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\ + odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:no\ + /pdb:"$(OUTDIR)/glqwcl.pdb" /machine:I386 /out:"$(OUTDIR)/glqwcl.exe" +LINK32_OBJS= \ + "$(INTDIR)\cd_win.obj" \ + "$(INTDIR)\cl_cam.obj" \ + "$(INTDIR)\cl_demo.obj" \ + "$(INTDIR)\cl_ents.obj" \ + "$(INTDIR)\cl_input.obj" \ + "$(INTDIR)\cl_main.obj" \ + "$(INTDIR)\cl_parse.obj" \ + "$(INTDIR)\cl_pred.obj" \ + "$(INTDIR)\cl_tent.obj" \ + "$(INTDIR)\cmd.obj" \ + "$(INTDIR)\common.obj" \ + "$(INTDIR)\console.obj" \ + "$(INTDIR)\crc.obj" \ + "$(INTDIR)\cvar.obj" \ + "$(INTDIR)\gl_draw.obj" \ + "$(INTDIR)\gl_mesh.obj" \ + "$(INTDIR)\gl_model.obj" \ + "$(INTDIR)\gl_ngraph.obj" \ + "$(INTDIR)\gl_refrag.obj" \ + "$(INTDIR)\gl_rlight.obj" \ + "$(INTDIR)\gl_rmain.obj" \ + "$(INTDIR)\gl_rmisc.obj" \ + "$(INTDIR)\gl_rsurf.obj" \ + "$(INTDIR)\gl_screen.obj" \ + "$(INTDIR)\gl_test.obj" \ + "$(INTDIR)\gl_vidnt.obj" \ + "$(INTDIR)\gl_warp.obj" \ + "$(INTDIR)\in_win.obj" \ + "$(INTDIR)\keys.obj" \ + "$(INTDIR)\math.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\md4.obj" \ + "$(INTDIR)\menu.obj" \ + "$(INTDIR)\net_chan.obj" \ + "$(INTDIR)\net_wins.obj" \ + "$(INTDIR)\pmove.obj" \ + "$(INTDIR)\pmovetst.obj" \ + "$(INTDIR)\r_part.obj" \ + "$(INTDIR)\sbar.obj" \ + "$(INTDIR)\skin.obj" \ + "$(INTDIR)\snd_dma.obj" \ + "$(INTDIR)\snd_mem.obj" \ + "$(INTDIR)\snd_mix.obj" \ + "$(INTDIR)\snd_mixa.obj" \ + "$(INTDIR)\snd_win.obj" \ + "$(INTDIR)\sys_win.obj" \ + "$(INTDIR)\sys_wina.obj" \ + "$(INTDIR)\view.obj" \ + "$(INTDIR)\wad.obj" \ + "$(INTDIR)\winquake.res" \ + "$(INTDIR)\zone.obj" + +"$(OUTDIR)\glqwcl.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "qwcl - Win32 Release" +# Name "qwcl - Win32 Debug" +# Name "qwcl - Win32 GL Debug" +# Name "qwcl - Win32 GL Release" + +!IF "$(CFG)" == "qwcl - Win32 Release" + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\cd_win.c +DEP_CPP_CD_WI=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CD_WI=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\cd_win.obj" : $(SOURCE) $(DEP_CPP_CD_WI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\cd_win.obj" : $(SOURCE) $(DEP_CPP_CD_WI) "$(INTDIR)" + +"$(INTDIR)\cd_win.sbr" : $(SOURCE) $(DEP_CPP_CD_WI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\cd_win.obj" : $(SOURCE) $(DEP_CPP_CD_WI) "$(INTDIR)" + +"$(INTDIR)\cd_win.sbr" : $(SOURCE) $(DEP_CPP_CD_WI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\cd_win.obj" : $(SOURCE) $(DEP_CPP_CD_WI) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cl_cam.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +DEP_CPP_CL_CA=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_CA=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_cam.obj" : $(SOURCE) $(DEP_CPP_CL_CA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +DEP_CPP_CL_CA=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_CA=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_cam.obj" : $(SOURCE) $(DEP_CPP_CL_CA) "$(INTDIR)" + +"$(INTDIR)\cl_cam.sbr" : $(SOURCE) $(DEP_CPP_CL_CA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_CL_CA=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_CA=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_cam.obj" : $(SOURCE) $(DEP_CPP_CL_CA) "$(INTDIR)" + +"$(INTDIR)\cl_cam.sbr" : $(SOURCE) $(DEP_CPP_CL_CA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_CL_CA=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_CA=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_cam.obj" : $(SOURCE) $(DEP_CPP_CL_CA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cl_demo.c +DEP_CPP_CL_DE=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_DE=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\cl_demo.obj" : $(SOURCE) $(DEP_CPP_CL_DE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\cl_demo.obj" : $(SOURCE) $(DEP_CPP_CL_DE) "$(INTDIR)" + +"$(INTDIR)\cl_demo.sbr" : $(SOURCE) $(DEP_CPP_CL_DE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\cl_demo.obj" : $(SOURCE) $(DEP_CPP_CL_DE) "$(INTDIR)" + +"$(INTDIR)\cl_demo.sbr" : $(SOURCE) $(DEP_CPP_CL_DE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\cl_demo.obj" : $(SOURCE) $(DEP_CPP_CL_DE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cl_ents.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +DEP_CPP_CL_EN=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_EN=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_ents.obj" : $(SOURCE) $(DEP_CPP_CL_EN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +DEP_CPP_CL_EN=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_EN=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_ents.obj" : $(SOURCE) $(DEP_CPP_CL_EN) "$(INTDIR)" + +"$(INTDIR)\cl_ents.sbr" : $(SOURCE) $(DEP_CPP_CL_EN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_CL_EN=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\zone.h"\ + + +"$(INTDIR)\cl_ents.obj" : $(SOURCE) $(DEP_CPP_CL_EN) "$(INTDIR)" + +"$(INTDIR)\cl_ents.sbr" : $(SOURCE) $(DEP_CPP_CL_EN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_CL_EN=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_EN=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_ents.obj" : $(SOURCE) $(DEP_CPP_CL_EN) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cl_input.c +DEP_CPP_CL_IN=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_IN=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\cl_input.obj" : $(SOURCE) $(DEP_CPP_CL_IN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\cl_input.obj" : $(SOURCE) $(DEP_CPP_CL_IN) "$(INTDIR)" + +"$(INTDIR)\cl_input.sbr" : $(SOURCE) $(DEP_CPP_CL_IN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\cl_input.obj" : $(SOURCE) $(DEP_CPP_CL_IN) "$(INTDIR)" + +"$(INTDIR)\cl_input.sbr" : $(SOURCE) $(DEP_CPP_CL_IN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\cl_input.obj" : $(SOURCE) $(DEP_CPP_CL_IN) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cl_main.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +DEP_CPP_CL_MA=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_MA=\ + "..\..\scitech\include\mglrect.hpp"\ + + +"$(INTDIR)\cl_main.obj" : $(SOURCE) $(DEP_CPP_CL_MA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +DEP_CPP_CL_MA=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_MA=\ + "..\..\scitech\include\mglrect.hpp"\ + + +"$(INTDIR)\cl_main.obj" : $(SOURCE) $(DEP_CPP_CL_MA) "$(INTDIR)" + +"$(INTDIR)\cl_main.sbr" : $(SOURCE) $(DEP_CPP_CL_MA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_CL_MA=\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + + +"$(INTDIR)\cl_main.obj" : $(SOURCE) $(DEP_CPP_CL_MA) "$(INTDIR)" + +"$(INTDIR)\cl_main.sbr" : $(SOURCE) $(DEP_CPP_CL_MA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_CL_MA=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\quakedef.h"\ + ".\winquake.h"\ + +NODEP_CPP_CL_MA=\ + "..\..\scitech\include\mglrect.hpp"\ + + +"$(INTDIR)\cl_main.obj" : $(SOURCE) $(DEP_CPP_CL_MA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cl_parse.c +DEP_CPP_CL_PA=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_PA=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\cl_parse.obj" : $(SOURCE) $(DEP_CPP_CL_PA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\cl_parse.obj" : $(SOURCE) $(DEP_CPP_CL_PA) "$(INTDIR)" + +"$(INTDIR)\cl_parse.sbr" : $(SOURCE) $(DEP_CPP_CL_PA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\cl_parse.obj" : $(SOURCE) $(DEP_CPP_CL_PA) "$(INTDIR)" + +"$(INTDIR)\cl_parse.sbr" : $(SOURCE) $(DEP_CPP_CL_PA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\cl_parse.obj" : $(SOURCE) $(DEP_CPP_CL_PA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cl_pred.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +DEP_CPP_CL_PR=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_PR=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_pred.obj" : $(SOURCE) $(DEP_CPP_CL_PR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +DEP_CPP_CL_PR=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_PR=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_pred.obj" : $(SOURCE) $(DEP_CPP_CL_PR) "$(INTDIR)" + +"$(INTDIR)\cl_pred.sbr" : $(SOURCE) $(DEP_CPP_CL_PR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_CL_PR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_PR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_pred.obj" : $(SOURCE) $(DEP_CPP_CL_PR) "$(INTDIR)" + +"$(INTDIR)\cl_pred.sbr" : $(SOURCE) $(DEP_CPP_CL_PR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_CL_PR=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_PR=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\cl_pred.obj" : $(SOURCE) $(DEP_CPP_CL_PR) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cl_tent.c +DEP_CPP_CL_TE=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CL_TE=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\cl_tent.obj" : $(SOURCE) $(DEP_CPP_CL_TE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\cl_tent.obj" : $(SOURCE) $(DEP_CPP_CL_TE) "$(INTDIR)" + +"$(INTDIR)\cl_tent.sbr" : $(SOURCE) $(DEP_CPP_CL_TE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\cl_tent.obj" : $(SOURCE) $(DEP_CPP_CL_TE) "$(INTDIR)" + +"$(INTDIR)\cl_tent.sbr" : $(SOURCE) $(DEP_CPP_CL_TE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\cl_tent.obj" : $(SOURCE) $(DEP_CPP_CL_TE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cmd.c +DEP_CPP_CMD_C=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CMD_C=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\cmd.obj" : $(SOURCE) $(DEP_CPP_CMD_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\cmd.obj" : $(SOURCE) $(DEP_CPP_CMD_C) "$(INTDIR)" + +"$(INTDIR)\cmd.sbr" : $(SOURCE) $(DEP_CPP_CMD_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\cmd.obj" : $(SOURCE) $(DEP_CPP_CMD_C) "$(INTDIR)" + +"$(INTDIR)\cmd.sbr" : $(SOURCE) $(DEP_CPP_CMD_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\cmd.obj" : $(SOURCE) $(DEP_CPP_CMD_C) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\common.c +DEP_CPP_COMMO=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_COMMO=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\qwsvdef.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\common.obj" : $(SOURCE) $(DEP_CPP_COMMO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\common.obj" : $(SOURCE) $(DEP_CPP_COMMO) "$(INTDIR)" + +"$(INTDIR)\common.sbr" : $(SOURCE) $(DEP_CPP_COMMO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\common.obj" : $(SOURCE) $(DEP_CPP_COMMO) "$(INTDIR)" + +"$(INTDIR)\common.sbr" : $(SOURCE) $(DEP_CPP_COMMO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\common.obj" : $(SOURCE) $(DEP_CPP_COMMO) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\console.c +DEP_CPP_CONSO=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CONSO=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\console.obj" : $(SOURCE) $(DEP_CPP_CONSO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\console.obj" : $(SOURCE) $(DEP_CPP_CONSO) "$(INTDIR)" + +"$(INTDIR)\console.sbr" : $(SOURCE) $(DEP_CPP_CONSO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\console.obj" : $(SOURCE) $(DEP_CPP_CONSO) "$(INTDIR)" + +"$(INTDIR)\console.sbr" : $(SOURCE) $(DEP_CPP_CONSO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\console.obj" : $(SOURCE) $(DEP_CPP_CONSO) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\crc.c +DEP_CPP_CRC_C=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CRC_C=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\crc.obj" : $(SOURCE) $(DEP_CPP_CRC_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\crc.obj" : $(SOURCE) $(DEP_CPP_CRC_C) "$(INTDIR)" + +"$(INTDIR)\crc.sbr" : $(SOURCE) $(DEP_CPP_CRC_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\crc.obj" : $(SOURCE) $(DEP_CPP_CRC_C) "$(INTDIR)" + +"$(INTDIR)\crc.sbr" : $(SOURCE) $(DEP_CPP_CRC_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\crc.obj" : $(SOURCE) $(DEP_CPP_CRC_C) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cvar.c +DEP_CPP_CVAR_=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_CVAR_=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\qwsvdef.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\cvar.obj" : $(SOURCE) $(DEP_CPP_CVAR_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\cvar.obj" : $(SOURCE) $(DEP_CPP_CVAR_) "$(INTDIR)" + +"$(INTDIR)\cvar.sbr" : $(SOURCE) $(DEP_CPP_CVAR_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\cvar.obj" : $(SOURCE) $(DEP_CPP_CVAR_) "$(INTDIR)" + +"$(INTDIR)\cvar.sbr" : $(SOURCE) $(DEP_CPP_CVAR_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\cvar.obj" : $(SOURCE) $(DEP_CPP_CVAR_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_edge.c +DEP_CPP_D_EDG=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_EDG=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_edge.obj" : $(SOURCE) $(DEP_CPP_D_EDG) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_edge.obj" : $(SOURCE) $(DEP_CPP_D_EDG) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_edge.sbr" : $(SOURCE) $(DEP_CPP_D_EDG) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_fill.c +DEP_CPP_D_FIL=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_FIL=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_fill.obj" : $(SOURCE) $(DEP_CPP_D_FIL) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_fill.obj" : $(SOURCE) $(DEP_CPP_D_FIL) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_fill.sbr" : $(SOURCE) $(DEP_CPP_D_FIL) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_init.c +DEP_CPP_D_INI=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_INI=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_init.obj" : $(SOURCE) $(DEP_CPP_D_INI) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_init.obj" : $(SOURCE) $(DEP_CPP_D_INI) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_init.sbr" : $(SOURCE) $(DEP_CPP_D_INI) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_modech.c +DEP_CPP_D_MOD=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_MOD=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_modech.obj" : $(SOURCE) $(DEP_CPP_D_MOD) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_modech.obj" : $(SOURCE) $(DEP_CPP_D_MOD) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_modech.sbr" : $(SOURCE) $(DEP_CPP_D_MOD) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_part.c +DEP_CPP_D_PAR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_PAR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_part.obj" : $(SOURCE) $(DEP_CPP_D_PAR) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_part.obj" : $(SOURCE) $(DEP_CPP_D_PAR) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_part.sbr" : $(SOURCE) $(DEP_CPP_D_PAR) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_polyse.c +DEP_CPP_D_POL=\ + ".\adivtab.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_POL=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_polyse.obj" : $(SOURCE) $(DEP_CPP_D_POL) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_polyse.obj" : $(SOURCE) $(DEP_CPP_D_POL) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_polyse.sbr" : $(SOURCE) $(DEP_CPP_D_POL) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_scan.c +DEP_CPP_D_SCA=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_SCA=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_scan.obj" : $(SOURCE) $(DEP_CPP_D_SCA) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_scan.obj" : $(SOURCE) $(DEP_CPP_D_SCA) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_scan.sbr" : $(SOURCE) $(DEP_CPP_D_SCA) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_sky.c +DEP_CPP_D_SKY=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_SKY=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_sky.obj" : $(SOURCE) $(DEP_CPP_D_SKY) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_sky.obj" : $(SOURCE) $(DEP_CPP_D_SKY) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_sky.sbr" : $(SOURCE) $(DEP_CPP_D_SKY) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_sprite.c +DEP_CPP_D_SPR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_SPR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_sprite.obj" : $(SOURCE) $(DEP_CPP_D_SPR) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_sprite.obj" : $(SOURCE) $(DEP_CPP_D_SPR) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_sprite.sbr" : $(SOURCE) $(DEP_CPP_D_SPR) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_surf.c +DEP_CPP_D_SUR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_SUR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_surf.obj" : $(SOURCE) $(DEP_CPP_D_SUR) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_surf.obj" : $(SOURCE) $(DEP_CPP_D_SUR) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_surf.sbr" : $(SOURCE) $(DEP_CPP_D_SUR) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_vars.c +DEP_CPP_D_VAR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_VAR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_vars.obj" : $(SOURCE) $(DEP_CPP_D_VAR) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_vars.obj" : $(SOURCE) $(DEP_CPP_D_VAR) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_vars.sbr" : $(SOURCE) $(DEP_CPP_D_VAR) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\d_zpoint.c +DEP_CPP_D_ZPO=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_D_ZPO=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\d_zpoint.obj" : $(SOURCE) $(DEP_CPP_D_ZPO) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\d_zpoint.obj" : $(SOURCE) $(DEP_CPP_D_ZPO) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\d_zpoint.sbr" : $(SOURCE) $(DEP_CPP_D_ZPO) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\draw.c +DEP_CPP_DRAW_=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_DRAW_=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\draw.obj" : $(SOURCE) $(DEP_CPP_DRAW_) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\draw.obj" : $(SOURCE) $(DEP_CPP_DRAW_) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\draw.sbr" : $(SOURCE) $(DEP_CPP_DRAW_) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_draw.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 +DEP_CPP_GL_DR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_DR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 +DEP_CPP_GL_DR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_DR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_GL_DR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\zone.h"\ + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_draw.obj" : $(SOURCE) $(DEP_CPP_GL_DR) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_draw.sbr" : $(SOURCE) $(DEP_CPP_GL_DR) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_GL_DR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_DR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\gl_draw.obj" : $(SOURCE) $(DEP_CPP_GL_DR) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_mesh.c +DEP_CPP_GL_ME=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_ME=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_mesh.obj" : $(SOURCE) $(DEP_CPP_GL_ME) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_mesh.sbr" : $(SOURCE) $(DEP_CPP_GL_ME) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\gl_mesh.obj" : $(SOURCE) $(DEP_CPP_GL_ME) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_model.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 +DEP_CPP_GL_MO=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_MO=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 +DEP_CPP_GL_MO=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_MO=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_GL_MO=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\zone.h"\ + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_model.obj" : $(SOURCE) $(DEP_CPP_GL_MO) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_model.sbr" : $(SOURCE) $(DEP_CPP_GL_MO) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_GL_MO=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_MO=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\gl_model.obj" : $(SOURCE) $(DEP_CPP_GL_MO) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_ngraph.c +DEP_CPP_GL_NG=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_NG=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_ngraph.obj" : $(SOURCE) $(DEP_CPP_GL_NG) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_ngraph.sbr" : $(SOURCE) $(DEP_CPP_GL_NG) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\gl_ngraph.obj" : $(SOURCE) $(DEP_CPP_GL_NG) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_refrag.c +DEP_CPP_GL_RE=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_RE=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_refrag.obj" : $(SOURCE) $(DEP_CPP_GL_RE) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_refrag.sbr" : $(SOURCE) $(DEP_CPP_GL_RE) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\gl_refrag.obj" : $(SOURCE) $(DEP_CPP_GL_RE) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_rlight.c +DEP_CPP_GL_RL=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_RL=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_rlight.obj" : $(SOURCE) $(DEP_CPP_GL_RL) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_rlight.sbr" : $(SOURCE) $(DEP_CPP_GL_RL) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\gl_rlight.obj" : $(SOURCE) $(DEP_CPP_GL_RL) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_rmain.c +DEP_CPP_GL_RM=\ + ".\anorm_dots.h"\ + ".\anorms.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_RM=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_rmain.obj" : $(SOURCE) $(DEP_CPP_GL_RM) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_rmain.sbr" : $(SOURCE) $(DEP_CPP_GL_RM) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\gl_rmain.obj" : $(SOURCE) $(DEP_CPP_GL_RM) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_rmisc.c +DEP_CPP_GL_RMI=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_RMI=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_rmisc.obj" : $(SOURCE) $(DEP_CPP_GL_RMI) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_rmisc.sbr" : $(SOURCE) $(DEP_CPP_GL_RMI) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\gl_rmisc.obj" : $(SOURCE) $(DEP_CPP_GL_RMI) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_rsurf.c +DEP_CPP_GL_RS=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_RS=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_rsurf.obj" : $(SOURCE) $(DEP_CPP_GL_RS) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_rsurf.sbr" : $(SOURCE) $(DEP_CPP_GL_RS) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\gl_rsurf.obj" : $(SOURCE) $(DEP_CPP_GL_RS) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_screen.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 +DEP_CPP_GL_SC=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_SC=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 +DEP_CPP_GL_SC=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_SC=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_GL_SC=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\zone.h"\ + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_screen.obj" : $(SOURCE) $(DEP_CPP_GL_SC) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_screen.sbr" : $(SOURCE) $(DEP_CPP_GL_SC) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_GL_SC=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_SC=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\gl_screen.obj" : $(SOURCE) $(DEP_CPP_GL_SC) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_test.c +DEP_CPP_GL_TE=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_TE=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_test.obj" : $(SOURCE) $(DEP_CPP_GL_TE) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_test.sbr" : $(SOURCE) $(DEP_CPP_GL_TE) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\gl_test.obj" : $(SOURCE) $(DEP_CPP_GL_TE) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_vidnt.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 +DEP_CPP_GL_VI=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_VI=\ + "..\..\scitech\include\mglrect.hpp"\ + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 +DEP_CPP_GL_VI=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_VI=\ + "..\..\scitech\include\mglrect.hpp"\ + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_GL_VI=\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_vidnt.obj" : $(SOURCE) $(DEP_CPP_GL_VI) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_vidnt.sbr" : $(SOURCE) $(DEP_CPP_GL_VI) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_GL_VI=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\quakedef.h"\ + ".\winquake.h"\ + +NODEP_CPP_GL_VI=\ + "..\..\scitech\include\mglrect.hpp"\ + + +"$(INTDIR)\gl_vidnt.obj" : $(SOURCE) $(DEP_CPP_GL_VI) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\gl_warp.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +# PROP Exclude_From_Build 1 +DEP_CPP_GL_WA=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\gl_warp_sin.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_WA=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +# PROP Exclude_From_Build 1 +DEP_CPP_GL_WA=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\gl_warp_sin.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_WA=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_GL_WA=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\gl_warp_sin.h"\ + ".\mathlib.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\zone.h"\ + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c\ + $(SOURCE) \ + + +"$(INTDIR)\gl_warp.obj" : $(SOURCE) $(DEP_CPP_GL_WA) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\gl_warp.sbr" : $(SOURCE) $(DEP_CPP_GL_WA) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_GL_WA=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\gl_warp_sin.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_GL_WA=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\gl_warp.obj" : $(SOURCE) $(DEP_CPP_GL_WA) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\in_win.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +DEP_CPP_IN_WI=\ + "..\..\dxsdk\sdk\inc\dinput.h"\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_IN_WI=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\in_win.obj" : $(SOURCE) $(DEP_CPP_IN_WI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +DEP_CPP_IN_WI=\ + "..\..\dxsdk\sdk\inc\dinput.h"\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_IN_WI=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\in_win.obj" : $(SOURCE) $(DEP_CPP_IN_WI) "$(INTDIR)" + +"$(INTDIR)\in_win.sbr" : $(SOURCE) $(DEP_CPP_IN_WI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_IN_WI=\ + "..\..\dxsdk\sdk\inc\dinput.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + + +"$(INTDIR)\in_win.obj" : $(SOURCE) $(DEP_CPP_IN_WI) "$(INTDIR)" + +"$(INTDIR)\in_win.sbr" : $(SOURCE) $(DEP_CPP_IN_WI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_IN_WI=\ + "..\..\dxsdk\sdk\inc\dinput.h"\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_IN_WI=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\in_win.obj" : $(SOURCE) $(DEP_CPP_IN_WI) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\keys.c +DEP_CPP_KEYS_=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_KEYS_=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\keys.obj" : $(SOURCE) $(DEP_CPP_KEYS_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\keys.obj" : $(SOURCE) $(DEP_CPP_KEYS_) "$(INTDIR)" + +"$(INTDIR)\keys.sbr" : $(SOURCE) $(DEP_CPP_KEYS_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\keys.obj" : $(SOURCE) $(DEP_CPP_KEYS_) "$(INTDIR)" + +"$(INTDIR)\keys.sbr" : $(SOURCE) $(DEP_CPP_KEYS_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\keys.obj" : $(SOURCE) $(DEP_CPP_KEYS_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\mathlib.c +DEP_CPP_MATHL=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_MATHL=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + +"$(INTDIR)\mathlib.sbr" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + +"$(INTDIR)\mathlib.sbr" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\md4.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\md4.obj" : $(SOURCE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\md4.obj" : $(SOURCE) "$(INTDIR)" + +"$(INTDIR)\md4.sbr" : $(SOURCE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\md4.obj" : $(SOURCE) "$(INTDIR)" + +"$(INTDIR)\md4.sbr" : $(SOURCE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\md4.obj" : $(SOURCE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\menu.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +DEP_CPP_MENU_=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_MENU_=\ + "..\..\scitech\include\mglrect.hpp"\ + + +"$(INTDIR)\menu.obj" : $(SOURCE) $(DEP_CPP_MENU_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +DEP_CPP_MENU_=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_MENU_=\ + "..\..\scitech\include\mglrect.hpp"\ + + +"$(INTDIR)\menu.obj" : $(SOURCE) $(DEP_CPP_MENU_) "$(INTDIR)" + +"$(INTDIR)\menu.sbr" : $(SOURCE) $(DEP_CPP_MENU_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_MENU_=\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\cvar.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\mathlib.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + + +"$(INTDIR)\menu.obj" : $(SOURCE) $(DEP_CPP_MENU_) "$(INTDIR)" + +"$(INTDIR)\menu.sbr" : $(SOURCE) $(DEP_CPP_MENU_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_MENU_=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\quakedef.h"\ + ".\winquake.h"\ + +NODEP_CPP_MENU_=\ + "..\..\scitech\include\mglrect.hpp"\ + + +"$(INTDIR)\menu.obj" : $(SOURCE) $(DEP_CPP_MENU_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\model.c +DEP_CPP_MODEL=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_MODEL=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\model.obj" : $(SOURCE) $(DEP_CPP_MODEL) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\model.obj" : $(SOURCE) $(DEP_CPP_MODEL) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\model.sbr" : $(SOURCE) $(DEP_CPP_MODEL) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\net_chan.c +DEP_CPP_NET_C=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_NET_C=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\net_chan.obj" : $(SOURCE) $(DEP_CPP_NET_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\net_chan.obj" : $(SOURCE) $(DEP_CPP_NET_C) "$(INTDIR)" + +"$(INTDIR)\net_chan.sbr" : $(SOURCE) $(DEP_CPP_NET_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\net_chan.obj" : $(SOURCE) $(DEP_CPP_NET_C) "$(INTDIR)" + +"$(INTDIR)\net_chan.sbr" : $(SOURCE) $(DEP_CPP_NET_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\net_chan.obj" : $(SOURCE) $(DEP_CPP_NET_C) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\net_wins.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +DEP_CPP_NET_W=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_NET_W=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\net_wins.obj" : $(SOURCE) $(DEP_CPP_NET_W) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +DEP_CPP_NET_W=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_NET_W=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\net_wins.obj" : $(SOURCE) $(DEP_CPP_NET_W) "$(INTDIR)" + +"$(INTDIR)\net_wins.sbr" : $(SOURCE) $(DEP_CPP_NET_W) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_NET_W=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_NET_W=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\net_wins.obj" : $(SOURCE) $(DEP_CPP_NET_W) "$(INTDIR)" + +"$(INTDIR)\net_wins.sbr" : $(SOURCE) $(DEP_CPP_NET_W) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +DEP_CPP_NET_W=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_NET_W=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\net_wins.obj" : $(SOURCE) $(DEP_CPP_NET_W) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\pmove.c +DEP_CPP_PMOVE=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_PMOVE=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\pmove.obj" : $(SOURCE) $(DEP_CPP_PMOVE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\pmove.obj" : $(SOURCE) $(DEP_CPP_PMOVE) "$(INTDIR)" + +"$(INTDIR)\pmove.sbr" : $(SOURCE) $(DEP_CPP_PMOVE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\pmove.obj" : $(SOURCE) $(DEP_CPP_PMOVE) "$(INTDIR)" + +"$(INTDIR)\pmove.sbr" : $(SOURCE) $(DEP_CPP_PMOVE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\pmove.obj" : $(SOURCE) $(DEP_CPP_PMOVE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\pmovetst.c +DEP_CPP_PMOVET=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_PMOVET=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\pmovetst.obj" : $(SOURCE) $(DEP_CPP_PMOVET) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\pmovetst.obj" : $(SOURCE) $(DEP_CPP_PMOVET) "$(INTDIR)" + +"$(INTDIR)\pmovetst.sbr" : $(SOURCE) $(DEP_CPP_PMOVET) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\pmovetst.obj" : $(SOURCE) $(DEP_CPP_PMOVET) "$(INTDIR)" + +"$(INTDIR)\pmovetst.sbr" : $(SOURCE) $(DEP_CPP_PMOVET) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\pmovetst.obj" : $(SOURCE) $(DEP_CPP_PMOVET) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_aclip.c +DEP_CPP_R_ACL=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_ACL=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_aclip.obj" : $(SOURCE) $(DEP_CPP_R_ACL) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_aclip.obj" : $(SOURCE) $(DEP_CPP_R_ACL) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_aclip.sbr" : $(SOURCE) $(DEP_CPP_R_ACL) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_alias.c +DEP_CPP_R_ALI=\ + ".\anorms.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_ALI=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_alias.obj" : $(SOURCE) $(DEP_CPP_R_ALI) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_alias.obj" : $(SOURCE) $(DEP_CPP_R_ALI) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_alias.sbr" : $(SOURCE) $(DEP_CPP_R_ALI) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_bsp.c +DEP_CPP_R_BSP=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_BSP=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_bsp.obj" : $(SOURCE) $(DEP_CPP_R_BSP) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_bsp.obj" : $(SOURCE) $(DEP_CPP_R_BSP) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_bsp.sbr" : $(SOURCE) $(DEP_CPP_R_BSP) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_draw.c +DEP_CPP_R_DRA=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_DRA=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_draw.obj" : $(SOURCE) $(DEP_CPP_R_DRA) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_draw.obj" : $(SOURCE) $(DEP_CPP_R_DRA) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_draw.sbr" : $(SOURCE) $(DEP_CPP_R_DRA) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_edge.c +DEP_CPP_R_EDG=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_EDG=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_edge.obj" : $(SOURCE) $(DEP_CPP_R_EDG) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_edge.obj" : $(SOURCE) $(DEP_CPP_R_EDG) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_edge.sbr" : $(SOURCE) $(DEP_CPP_R_EDG) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_efrag.c +DEP_CPP_R_EFR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_EFR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_efrag.obj" : $(SOURCE) $(DEP_CPP_R_EFR) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_efrag.obj" : $(SOURCE) $(DEP_CPP_R_EFR) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_efrag.sbr" : $(SOURCE) $(DEP_CPP_R_EFR) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_light.c +DEP_CPP_R_LIG=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_LIG=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_light.obj" : $(SOURCE) $(DEP_CPP_R_LIG) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_light.obj" : $(SOURCE) $(DEP_CPP_R_LIG) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_light.sbr" : $(SOURCE) $(DEP_CPP_R_LIG) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_main.c +DEP_CPP_R_MAI=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_MAI=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_main.obj" : $(SOURCE) $(DEP_CPP_R_MAI) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_main.obj" : $(SOURCE) $(DEP_CPP_R_MAI) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_main.sbr" : $(SOURCE) $(DEP_CPP_R_MAI) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_misc.c +DEP_CPP_R_MIS=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_MIS=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_misc.obj" : $(SOURCE) $(DEP_CPP_R_MIS) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_misc.obj" : $(SOURCE) $(DEP_CPP_R_MIS) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_misc.sbr" : $(SOURCE) $(DEP_CPP_R_MIS) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_part.c +DEP_CPP_R_PAR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_PAR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_part.obj" : $(SOURCE) $(DEP_CPP_R_PAR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\r_part.obj" : $(SOURCE) $(DEP_CPP_R_PAR) "$(INTDIR)" + +"$(INTDIR)\r_part.sbr" : $(SOURCE) $(DEP_CPP_R_PAR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 0 + +"$(INTDIR)\r_part.obj" : $(SOURCE) $(DEP_CPP_R_PAR) "$(INTDIR)" + +"$(INTDIR)\r_part.sbr" : $(SOURCE) $(DEP_CPP_R_PAR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 0 + +"$(INTDIR)\r_part.obj" : $(SOURCE) $(DEP_CPP_R_PAR) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_sky.c +DEP_CPP_R_SKY=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\d_local.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_SKY=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_sky.obj" : $(SOURCE) $(DEP_CPP_R_SKY) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_sky.obj" : $(SOURCE) $(DEP_CPP_R_SKY) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_sky.sbr" : $(SOURCE) $(DEP_CPP_R_SKY) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_sprite.c +DEP_CPP_R_SPR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_SPR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_sprite.obj" : $(SOURCE) $(DEP_CPP_R_SPR) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_sprite.obj" : $(SOURCE) $(DEP_CPP_R_SPR) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_sprite.sbr" : $(SOURCE) $(DEP_CPP_R_SPR) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_surf.c +DEP_CPP_R_SUR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_SUR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_surf.obj" : $(SOURCE) $(DEP_CPP_R_SUR) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_surf.obj" : $(SOURCE) $(DEP_CPP_R_SUR) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_surf.sbr" : $(SOURCE) $(DEP_CPP_R_SUR) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\r_vars.c +DEP_CPP_R_VAR=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_R_VAR=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\r_vars.obj" : $(SOURCE) $(DEP_CPP_R_VAR) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\r_vars.obj" : $(SOURCE) $(DEP_CPP_R_VAR) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\r_vars.sbr" : $(SOURCE) $(DEP_CPP_R_VAR) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\sbar.c +DEP_CPP_SBAR_=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_SBAR_=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\sbar.obj" : $(SOURCE) $(DEP_CPP_SBAR_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\sbar.obj" : $(SOURCE) $(DEP_CPP_SBAR_) "$(INTDIR)" + +"$(INTDIR)\sbar.sbr" : $(SOURCE) $(DEP_CPP_SBAR_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\sbar.obj" : $(SOURCE) $(DEP_CPP_SBAR_) "$(INTDIR)" + +"$(INTDIR)\sbar.sbr" : $(SOURCE) $(DEP_CPP_SBAR_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\sbar.obj" : $(SOURCE) $(DEP_CPP_SBAR_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\screen.c +DEP_CPP_SCREE=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\r_local.h"\ + ".\r_shared.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_SCREE=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\screen.obj" : $(SOURCE) $(DEP_CPP_SCREE) "$(INTDIR)" + $(CPP) /nologo /ML /GX /O2 /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /c $(SOURCE) + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +BuildCmds= \ + $(CPP) /nologo /MLd /Gm /GX /Zi /Od /I "..\..\scitech\include" /I\ + "..\..\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)/"\ + /Fp"$(INTDIR)/qwcl.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\screen.obj" : $(SOURCE) $(DEP_CPP_SCREE) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\screen.sbr" : $(SOURCE) $(DEP_CPP_SCREE) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\skin.c +DEP_CPP_SKIN_=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\zone.h"\ + +NODEP_CPP_SKIN_=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +!IF "$(CFG)" == "qwcl - Win32 Release" + + +"$(INTDIR)\skin.obj" : $(SOURCE) $(DEP_CPP_SKIN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + + +"$(INTDIR)\skin.obj" : $(SOURCE) $(DEP_CPP_SKIN_) "$(INTDIR)" + +"$(INTDIR)\skin.sbr" : $(SOURCE) $(DEP_CPP_SKIN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + + +"$(INTDIR)\skin.obj" : $(SOURCE) $(DEP_CPP_SKIN_) "$(INTDIR)" + +"$(INTDIR)\skin.sbr" : $(SOURCE) $(DEP_CPP_SKIN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Release" + + +"$(INTDIR)\skin.obj" : $(SOURCE) $(DEP_CPP_SKIN_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\snd_dma.c + +!IF "$(CFG)" == "qwcl - Win32 Release" + +DEP_CPP_SND_D=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_SND_D=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\snd_dma.obj" : $(SOURCE) $(DEP_CPP_SND_D) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 Debug" + +DEP_CPP_SND_D=\ + "..\..\scitech\include\debug.h"\ + "..\..\scitech\include\mgldos.h"\ + "..\..\scitech\include\mglwin.h"\ + "..\..\scitech\include\mgraph.h"\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_SND_D=\ + "..\..\scitech\include\mglrect.hpp"\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\snd_dma.obj" : $(SOURCE) $(DEP_CPP_SND_D) "$(INTDIR)" + +"$(INTDIR)\snd_dma.sbr" : $(SOURCE) $(DEP_CPP_SND_D) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qwcl - Win32 GL Debug" + +DEP_CPP_SND_D=\ + ".\bothdefs.h"\ + ".\bspfile.h"\ + ".\cdaudio.h"\ + ".\client.h"\ + ".\cmd.h"\ + ".\common.h"\ + ".\console.h"\ + ".\crc.h"\ + ".\cvar.h"\ + ".\d_iface.h"\ + ".\draw.h"\ + ".\gl_model.h"\ + ".\glquake.h"\ + ".\input.h"\ + ".\keys.h"\ + ".\mathlib.h"\ + ".\menu.h"\ + ".\model.h"\ + ".\modelgen.h"\ + ".\net.h"\ + ".\pmove.h"\ + ".\protocol.h"\ + ".\quakedef.h"\ + ".\render.h"\ + ".\sbar.h"\ + ".\screen.h"\ + ".\sound.h"\ + ".\spritegn.h"\ + ".\sys.h"\ + ".\vid.h"\ + ".\view.h"\ + ".\wad.h"\ + ".\winquake.h"\ + ".\zone.h"\ + +NODEP_CPP_SND_D=\ + ".\cmdlib.h"\ + ".\dictlib.h"\ + ".\lbmlib.h"\ + ".\scriplib.h"\ + ".\trilib.h"\ + + +"$(INTDIR)\snd_dma.obj" : $(SOURCE) $(DE…1ñWV.öMi3ÎÞúû"æÑù°ÿ™k�„wL‡}ƒàEø"Àkkl¸7¹ÿcê‡
è)·‡ÉêäU&rzÔ™Hî¨óÊ•�ªÒT¥^6§€1“ Ÿäð§ÅÍJQi7J~g¢ÜéáÂbĶáC~Kä4›ãŠzþ³™†Á]bçýÂ2tŒÐj\·Eá£üô¿°Õù@ÒWD¼Û“�¹Ú_>‹�ÙÈU¬z«9#KWŠÆ¢1ž—YÖ΀cîC¶m´ºÞ
úå¬#ìႦ!÷¯‡Ô“‹ºƒô2¸µ+é6lMèÈkˆ>‰âîýs½g;J>‚e à%žÝ.é�ws(7ž–f�<Ñ<Úâ‰l ö•’ë[‡vò³N^¢.ýÁˈþ~cú–ëh3}æ¿è–³´k·Ô–vº3¥¯w�sGÙó”ì»,Vû”²»2‰å²‰ÅÏUÌz{1®é$%R££Gî5”11Þ¢K@ÿ$ù7I4r!¨È�®•[–” Ú‹F.ãC=^ßV©¡Æ_îñ›(”ó7 ¿ÿç~ì?=“ÄE¡i±‰Hdðå
0Æ3{ï¿ÃáÍ#ÂFPj@a¿@¦˜h‚å®ÈXïçñ&GÔbî#¶EŒêUйK`lËü«ê/9´Ê�wdo ]׬2ÑÙ(²-:Å„cm©¨R¥ƒ‹¨«U«ýhµ<�®<†%íYm9mVÞ´hÑ«4]�š=QÞۑ؆¡
2í ö>Àp»Äè·/ûËŸ$úè›|CEaN�t°„B*&UG‰ÐQªŸ…¥ëN݇¹],Vz-0 ‡@—‡Œ_±Ö/XX@ì?î rM˾¾òä–m9¡Œ÷Z˜å6tûKÉìÅGâ M,«“mŨ|¿è_¶G¾DÚry¹\²�V
;~áôÙŸý½e«MN^×ú]nyÖ)ì j"ì•Ò¹æu@jÁØÑä
å4ý!0~ÚuBäVëñu.Kf•gÁÊŸ‹m¸MR[ç{�^Vº=É7ÔWnUm+A«hçÄLÜ5püR`ý3'?$îùô~‚2DA-¯?÷Ûƒ¬.ýfR…¢åUζžw‚L§†Å©¢—ýÖ¯Îd»E³úª]¥ò—N¶
Õ…j<—fW(n1·tŠXe;º®,TAïýBüb”Ü\ž ZEé���Q8O ÛŽdGW²,ðÁÑl-§�i©{L@ÃïQU'”ªÄuÕþÉ=D‡~G ÿÙG òS¬í+ÕèLŸA„‚Е@(™bý惢ò=%Au曯*yº³Ìå4ÓÐë]XºËžÐ,\øÂðGÄ’Ö»üÏ*‹¸Th%´m+cØ×ÉÃIo[w]ЇUµweà�Ë9Óë'óX‰öª0öOà� áî0³ä¾²ã6ÖlßòoñC8‹Ê§”ÜRá—á—ª5³gèáÓZtër¤[KJ©ê”¤(EmVJ÷Â×F¯mûÀ\ÇK¯8™v¶ÚžÄÖ«*J™…2ž�÷ˆO£“RtG)XÖ¿„ÞFX”)_Ö.%OÇ€f50}×%ö^o²¥›^¢ðL®€mUס‰9оÛs˧‰~a.i3j‰Ûê[D+Y@Øúð=ôe{m9ƒ?#¹Už�[2&…(hmöpÎu2³`g8f5ˆðÀv-Êhubå2b뻈â´6ümsÔpE/MûÅÿpä¾ÇܯRg«f¹à2Ò»Ú,µY=¹åЯH/ë xuIE+oiôö@›,ÕÊfK�À¸³VŒ�‰NÔK�郬·\eéQžr®e¡„íÖ’òù…¯3£nþ„ ¸"zåJÅÙzo\KI¨±ˆõ`.§ëZG§æ’¿�Ýq«UþJÒ*ËÖºõÌ¥m˜ö#ßÒ¶Eη�Tåõ><íòû]È«-Žky³ƒ²Âô�i?:r«TÛÎÎ)üµüïÇ^øê�ýR'�šå*"ì¤è¥D]Ç6ʳ§$í:¿HÝksH}–2ÞU�(²œñ‹‰éϬ{h* »’%©�ÞR»ûü2*ïÔpÿ5®/Â×ärQêDN¥ï~±Û�ô²Rñ;<$•ýЉÌ<³"¯¯Zž^Î[Ò¡4' |
