mirror of
https://github.com/id-Software/Quake.git
synced 2026-03-19 16:39:38 +01:00
The Quake sources as originally release under the GPL license on December 21, 1999
This commit is contained in:
930
QW/Makefile.Linux
Normal file
930
QW/Makefile.Linux
Normal file
@@ -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) \
|
||||
|
||||
185
QW/Makefile.Solaris
Normal file
185
QW/Makefile.Solaris
Normal file
@@ -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) \
|
||||
|
||||
40
QW/clean.bat
Normal file
40
QW/clean.bat
Normal file
@@ -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
|
||||
|
||||
|
||||
1074
QW/client/adivtab.h
Normal file
1074
QW/client/adivtab.h
Normal file
File diff suppressed because it is too large
Load Diff
37
QW/client/anorm_dots.h
Normal file
37
QW/client/anorm_dots.h
Normal file
@@ -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}
|
||||
}
|
||||
181
QW/client/anorms.h
Normal file
181
QW/client/anorms.h
Normal file
@@ -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},
|
||||
151
QW/client/asm_draw.h
Normal file
151
QW/client/asm_draw.h
Normal file
@@ -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
|
||||
|
||||
97
QW/client/asm_i386.h
Normal file
97
QW/client/asm_i386.h
Normal file
@@ -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
|
||||
|
||||
123
QW/client/block16.h
Normal file
123
QW/client/block16.h
Normal file
@@ -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
|
||||
124
QW/client/block8.h
Normal file
124
QW/client/block8.h
Normal file
@@ -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
|
||||
|
||||
157
QW/client/bothdefs.h
Normal file
157
QW/client/bothdefs.h
Normal file
@@ -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
|
||||
|
||||
271
QW/client/bspfile.h
Normal file
271
QW/client/bspfile.h
Normal file
@@ -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
|
||||
76
QW/client/buildnum.c
Normal file
76
QW/client/buildnum.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
847
QW/client/cd_audio.c
Normal file
847
QW/client/cd_audio.c
Normal file
@@ -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();
|
||||
}
|
||||
418
QW/client/cd_linux.c
Normal file
418
QW/client/cd_linux.c
Normal file
@@ -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;
|
||||
}
|
||||
31
QW/client/cd_null.c
Normal file
31
QW/client/cd_null.c
Normal file
@@ -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)
|
||||
{
|
||||
}
|
||||
479
QW/client/cd_win.c
Normal file
479
QW/client/cd_win.c
Normal file
@@ -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");
|
||||
}
|
||||
27
QW/client/cdaudio.h
Normal file
27
QW/client/cdaudio.h
Normal file
@@ -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);
|
||||
574
QW/client/cl_cam.c
Normal file
574
QW/client/cl_cam.c
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
805
QW/client/cl_demo.c
Normal file
805
QW/client/cl_demo.c
Normal file
@@ -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
|
||||
}
|
||||
|
||||
1083
QW/client/cl_ents.c
Normal file
1083
QW/client/cl_ents.c
Normal file
File diff suppressed because it is too large
Load Diff
533
QW/client/cl_input.c
Normal file
533
QW/client/cl_input.c
Normal file
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
1535
QW/client/cl_main.c
Normal file
1535
QW/client/cl_main.c
Normal file
File diff suppressed because it is too large
Load Diff
1383
QW/client/cl_parse.c
Normal file
1383
QW/client/cl_parse.c
Normal file
File diff suppressed because it is too large
Load Diff
225
QW/client/cl_pred.c
Normal file
225
QW/client/cl_pred.c
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
459
QW/client/cl_tent.c
Normal file
459
QW/client/cl_tent.c
Normal file
@@ -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 ();
|
||||
}
|
||||
515
QW/client/client.h
Normal file
515
QW/client/client.h
Normal file
@@ -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
|
||||
748
QW/client/cmd.c
Normal file
748
QW/client/cmd.c
Normal file
@@ -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
|
||||
}
|
||||
|
||||
107
QW/client/cmd.h
Normal file
107
QW/client/cmd.h
Normal file
@@ -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);
|
||||
2299
QW/client/common.c
Normal file
2299
QW/client/common.c
Normal file
File diff suppressed because it is too large
Load Diff
222
QW/client/common.h
Normal file
222
QW/client/common.h
Normal file
@@ -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 );
|
||||
693
QW/client/console.c
Normal file
693
QW/client/console.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
60
QW/client/console.h
Normal file
60
QW/client/console.h
Normal file
@@ -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
|
||||
|
||||
93
QW/client/crc.c
Normal file
93
QW/client/crc.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
25
QW/client/crc.h
Normal file
25
QW/client/crc.h
Normal file
@@ -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);
|
||||
249
QW/client/cvar.c
Normal file
249
QW/client/cvar.c
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
97
QW/client/cvar.h
Normal file
97
QW/client/cvar.h
Normal file
@@ -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;
|
||||
149
QW/client/d_copy.s
Normal file
149
QW/client/d_copy.s
Normal file
@@ -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
|
||||
|
||||
949
QW/client/d_draw.asm
Normal file
949
QW/client/d_draw.asm
Normal file
@@ -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
|
||||
1037
QW/client/d_draw.s
Normal file
1037
QW/client/d_draw.s
Normal file
File diff suppressed because it is too large
Load Diff
924
QW/client/d_draw16.asm
Normal file
924
QW/client/d_draw16.asm
Normal file
@@ -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
|
||||
974
QW/client/d_draw16.s
Normal file
974
QW/client/d_draw16.s
Normal file
@@ -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
|
||||
336
QW/client/d_edge.c
Normal file
336
QW/client/d_edge.c
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
88
QW/client/d_fill.c
Normal file
88
QW/client/d_fill.c
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
229
QW/client/d_iface.h
Normal file
229
QW/client/d_iface.h
Normal file
@@ -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;
|
||||
|
||||
98
QW/client/d_ifacea.h
Normal file
98
QW/client/d_ifacea.h
Normal file
@@ -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
|
||||
|
||||
174
QW/client/d_init.c
Normal file
174
QW/client/d_init.c
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
111
QW/client/d_local.h
Normal file
111
QW/client/d_local.h
Normal file
@@ -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);
|
||||
|
||||
107
QW/client/d_modech.c
Normal file
107
QW/client/d_modech.c
Normal file
@@ -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 ();
|
||||
}
|
||||
|
||||
207
QW/client/d_part.c
Normal file
207
QW/client/d_part.c
Normal file
@@ -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
|
||||
|
||||
557
QW/client/d_parta.asm
Normal file
557
QW/client/d_parta.asm
Normal file
@@ -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
|
||||
477
QW/client/d_parta.s
Normal file
477
QW/client/d_parta.s
Normal file
@@ -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
|
||||
1120
QW/client/d_polysa.asm
Normal file
1120
QW/client/d_polysa.asm
Normal file
File diff suppressed because it is too large
Load Diff
1744
QW/client/d_polysa.s
Normal file
1744
QW/client/d_polysa.s
Normal file
File diff suppressed because it is too large
Load Diff
1064
QW/client/d_polyse.c
Normal file
1064
QW/client/d_polyse.c
Normal file
File diff suppressed because it is too large
Load Diff
446
QW/client/d_scan.c
Normal file
446
QW/client/d_scan.c
Normal file
@@ -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
|
||||
281
QW/client/d_scana.asm
Normal file
281
QW/client/d_scana.asm
Normal file
@@ -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
|
||||
89
QW/client/d_scana.s
Normal file
89
QW/client/d_scana.s
Normal file
@@ -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
|
||||
|
||||
138
QW/client/d_sky.c
Normal file
138
QW/client/d_sky.c
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
886
QW/client/d_spr8.asm
Normal file
886
QW/client/d_spr8.asm
Normal file
@@ -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
|
||||
900
QW/client/d_spr8.s
Normal file
900
QW/client/d_spr8.s
Normal file
@@ -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
|
||||
442
QW/client/d_sprite.c
Normal file
442
QW/client/d_sprite.c
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
338
QW/client/d_surf.c
Normal file
338
QW/client/d_surf.c
Normal file
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
50
QW/client/d_vars.c
Normal file
50
QW/client/d_vars.c
Normal file
@@ -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
|
||||
|
||||
362
QW/client/d_varsa.asm
Normal file
362
QW/client/d_varsa.asm
Normal file
@@ -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
|
||||
213
QW/client/d_varsa.s
Normal file
213
QW/client/d_varsa.s
Normal file
@@ -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
|
||||
|
||||
47
QW/client/d_zpoint.c
Normal file
47
QW/client/d_zpoint.c
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
118
QW/client/docs.txt
Normal file
118
QW/client/docs.txt
Normal file
@@ -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
|
||||
1020
QW/client/draw.c
Normal file
1020
QW/client/draw.c
Normal file
File diff suppressed because it is too large
Load Diff
43
QW/client/draw.h
Normal file
43
QW/client/draw.h
Normal file
@@ -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);
|
||||
22
QW/client/exitscrn.txt
Normal file
22
QW/client/exitscrn.txt
Normal file
@@ -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
|
||||
1378
QW/client/gl_draw.c
Normal file
1378
QW/client/gl_draw.c
Normal file
File diff suppressed because it is too large
Load Diff
359
QW/client/gl_mesh.c
Normal file
359
QW/client/gl_mesh.c
Normal file
@@ -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]];
|
||||
}
|
||||
|
||||
1884
QW/client/gl_model.c
Normal file
1884
QW/client/gl_model.c
Normal file
File diff suppressed because it is too large
Load Diff
436
QW/client/gl_model.h
Normal file
436
QW/client/gl_model.h
Normal file
@@ -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__
|
||||
141
QW/client/gl_ngraph.c
Normal file
141
QW/client/gl_ngraph.c
Normal file
@@ -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 ();
|
||||
}
|
||||
|
||||
234
QW/client/gl_refrag.c
Normal file
234
QW/client/gl_refrag.c
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
381
QW/client/gl_rlight.c
Normal file
381
QW/client/gl_rlight.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
1144
QW/client/gl_rmain.c
Normal file
1144
QW/client/gl_rmain.c
Normal file
File diff suppressed because it is too large
Load Diff
473
QW/client/gl_rmisc.c
Normal file
473
QW/client/gl_rmisc.c
Normal file
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
1697
QW/client/gl_rsurf.c
Normal file
1697
QW/client/gl_rsurf.c
Normal file
File diff suppressed because it is too large
Load Diff
1188
QW/client/gl_screen.c
Normal file
1188
QW/client/gl_screen.c
Normal file
File diff suppressed because it is too large
Load Diff
182
QW/client/gl_test.c
Normal file
182
QW/client/gl_test.c
Normal file
@@ -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
|
||||
816
QW/client/gl_vidlinux.c
Normal file
816
QW/client/gl_vidlinux.c
Normal file
@@ -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() {}
|
||||
|
||||
855
QW/client/gl_vidlinux_svga.c
Normal file
855
QW/client/gl_vidlinux_svga.c
Normal file
@@ -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) {}
|
||||
|
||||
870
QW/client/gl_vidlinux_x11.c
Normal file
870
QW/client/gl_vidlinux_x11.c
Normal file
@@ -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) {}
|
||||
|
||||
789
QW/client/gl_vidlinuxglx.c
Normal file
789
QW/client/gl_vidlinuxglx.c
Normal file
@@ -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() {}
|
||||
|
||||
1949
QW/client/gl_vidnt.c
Normal file
1949
QW/client/gl_vidnt.c
Normal file
File diff suppressed because it is too large
Load Diff
1087
QW/client/gl_warp.c
Normal file
1087
QW/client/gl_warp.c
Normal file
File diff suppressed because it is too large
Load Diff
51
QW/client/gl_warp_sin.h
Normal file
51
QW/client/gl_warp_sin.h
Normal file
@@ -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,
|
||||
302
QW/client/glquake.h
Normal file
302
QW/client/glquake.h
Normal file
@@ -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);
|
||||
|
||||
190
QW/client/glquake2.h
Normal file
190
QW/client/glquake2.h
Normal file
@@ -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);
|
||||
29
QW/client/in_null.c
Normal file
29
QW/client/in_null.c
Normal file
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
1232
QW/client/in_win.c
Normal file
1232
QW/client/in_win.c
Normal file
File diff suppressed because it is too large
Load Diff
34
QW/client/input.h
Normal file
34
QW/client/input.h
Normal file
@@ -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
|
||||
|
||||
839
QW/client/keys.c
Normal file
839
QW/client/keys.c
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
137
QW/client/keys.h
Normal file
137
QW/client/keys.h
Normal file
@@ -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);
|
||||
|
||||
109
QW/client/makefile.svgalib
Normal file
109
QW/client/makefile.svgalib
Normal file
@@ -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)
|
||||
495
QW/client/math.asm
Normal file
495
QW/client/math.asm
Normal file
@@ -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
|
||||
417
QW/client/math.s
Normal file
417
QW/client/math.s
Normal file
@@ -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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user