diff options
122 files changed, 8434 insertions, 11783 deletions
diff --git a/build/common.mk b/build/common.mk new file mode 100644 index 0000000..6800412 --- /dev/null +++ b/build/common.mk @@ -0,0 +1,43 @@ +# Copyright (C) 2008 Andrey Nazarov +# +# 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. + +SRCFILES+=cmd.c \ + bsp.c \ + cmodel.c \ + common.c \ + prompt.c \ + crc.c \ + cvar.c \ + files.c \ + mdfour.c \ + net_common.c \ + net_chan.c \ + pmove.c \ + q_msg.c \ + q_shared.c \ + q_field.c + +ifdef USE_ZLIB +SRCFILES+=ioapi.c unzip.c +LDFLAGS+=$(ZLIB_LDFLAGS) +CFLAGS+=$(ZLIB_CFLAGS) +endif + +ifdef USE_ASM +ASMFILES+=math.s +endif + diff --git a/build/q2pro.mk b/build/q2pro.mk index 49eb767..39f7ab7 100644 --- a/build/q2pro.mk +++ b/build/q2pro.mk @@ -1,74 +1,77 @@ -# ----------------------------- -# q2pro makefile by [SkulleR] -# ----------------------------- +# Copyright (C) 2008 Andrey Nazarov +# +# 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 ../config.mk TARGET=../q2pro$(EXESUFFIX) LDFLAGS+=-lm - -SRCFILES=cmd.c cmodel.c common.c prompt.c crc.c cvar.c \ - files.c mdfour.c net_common.c net_chan.c pmove.c sv_ccmds.c \ - sv_ents.c sv_game.c sv_init.c sv_main.c sv_send.c \ - sv_user.c sv_world.c sv_mvd.c sv_http.c \ - mvd_client.c mvd_parse.c mvd_game.c \ - q_msg.c q_shared.c q_field.c \ - m_flash.c cl_demo.c cl_draw.c cl_ents.c cl_fx.c cl_input.c \ - cl_locs.c cl_main.c cl_newfx.c cl_parse.c cl_pred.c cl_ref.c \ - cl_scrn.c cl_tent.c cl_view.c cl_console.c cl_keys.c cl_aastat.c \ - snd_main.c snd_mem.c snd_mix.c \ - ui_atoms.c ui_confirm.c ui_demos.c ui_menu.c ui_multiplayer.c \ - ui_playerconfig.c ui_playermodels.c ui_script.c - -ifdef USE_ANTICHEAT -SRCFILES+=sv_ac.c -endif - -ifdef REF_HARD_LINKED - -SRCFILES+=r_images.c \ - r_bsp.c \ - gl_draw.c \ - gl_images.c \ - gl_models.c \ - gl_world.c \ - gl_mesh.c \ - gl_main.c \ - gl_state.c \ - gl_surf.c \ - gl_tess.c \ - gl_sky.c \ - qgl_api.c - -ifdef USE_JPEG -LDFLAGS+=$(JPEG_LDFLAGS) -CFLAGS+=$(JPEG_CFLAGS) +CFLAGS+=-DUSE_CLIENT=1 + +include $(SRCDIR)/build/common.mk + +SRCFILES+=m_flash.c \ + cl_demo.c \ + cl_draw.c \ + cl_ents.c \ + cl_fx.c \ + cl_input.c \ + cl_locs.c \ + cl_main.c \ + cl_newfx.c \ + cl_parse.c \ + cl_pred.c \ + cl_ref.c \ + cl_scrn.c \ + cl_tent.c \ + cl_view.c \ + cl_console.c \ + cl_keys.c \ + cl_aastat.c \ + snd_main.c \ + snd_mem.c \ + snd_mix.c + +ifdef USE_UI +SRCFILES+=ui_atoms.c \ + ui_confirm.c \ + ui_demos.c \ + ui_menu.c \ + ui_multiplayer.c \ + ui_playerconfig.c \ + ui_playermodels.c \ + ui_script.c endif -ifdef USE_PNG -LDFLAGS+=$(PNG_LDFLAGS) -CFLAGS+=$(PNG_CFLAGS) +ifdef USE_REF +SRCFILES+=r_images.c r_models.c +include $(SRCDIR)/build/ref_$(USE_REF).mk endif -endif #REF_HARD_LINKED - -ifdef USE_ZLIB -SRCFILES+=ioapi.c unzip.c -LDFLAGS+=$(ZLIB_LDFLAGS) -CFLAGS+=$(ZLIB_CFLAGS) -endif - -ifdef USE_ASM -ASMFILES+=math.s -endif +# ifdef USE_SERVER +include $(SRCDIR)/build/server.mk +# endif ifdef MINGW -SRCFILES+=sys_win.c snd_wave.c vid_win.c win_glimp.c win_wgl.c +SRCFILES+=sys_win.c snd_wave.c -ifndef REF_HARD_LINKED -SRCFILES+=win_swimp.c +ifdef USE_REF +SRCFILES+=vid_win.c endif ifdef USE_DSOUND diff --git a/build/q2proded.mk b/build/q2proded.mk index 88fad39..a4e4c6c 100644 --- a/build/q2proded.mk +++ b/build/q2proded.mk @@ -1,44 +1,41 @@ -# ----------------------------- -# q2pro makefile by [SkulleR] -# ----------------------------- +# Copyright (C) 2008 Andrey Nazarov +# +# 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 ../config.mk TARGET=../q2proded$(EXESUFFIX) -CFLAGS+=-DDEDICATED_ONLY +CFLAGS+=-DUSE_CLIENT=0 LDFLAGS+=-lm -SRCFILES=cmd.c cmodel.c common.c crc.c cvar.c \ - files.c mdfour.c net_common.c net_chan.c pmove.c sv_ccmds.c \ - sv_ents.c sv_game.c sv_init.c sv_main.c sv_send.c \ - sv_user.c sv_world.c sv_mvd.c sv_http.c \ - mvd_client.c mvd_parse.c mvd_game.c \ - q_shared.c q_msg.c q_field.c prompt.c cl_null.c +include $(SRCDIR)/build/common.mk -ifdef USE_ANTICHEAT -SRCFILES+=sv_ac.c -endif +SRCFILES+=cl_null.c -ifdef USE_ZLIB -SRCFILES+=ioapi.c unzip.c -CFLAGS+=$(ZLIB_CFLAGS) -LDFLAGS+=$(ZLIB_LDFLAGS) -endif +include $(SRCDIR)/build/server.mk ifdef MINGW SRCFILES+=sys_win.c LDFLAGS+=-mconsole -lws2_32 -lwinmm -ladvapi32 RESFILES+=q2proded.rc -RESFLAGS+=-DDEDICATED_ONLY else SRCFILES+=sys_unix.c LDFLAGS+=-ldl endif -ifdef USE_ASM -ASMFILES=math.s -endif - include $(SRCDIR)/build/target.mk diff --git a/build/ref_gl.mk b/build/ref_gl.mk index 0de7bd9..903809c 100644 --- a/build/ref_gl.mk +++ b/build/ref_gl.mk @@ -1,17 +1,41 @@ -# ----------------------------- -# q2pro makefile by [SkulleR] -# ----------------------------- - -include ../config.mk - -TARGET=../ref_gl$(LIBSUFFIX) +# Copyright (C) 2008 Andrey Nazarov +# +# 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. + +CFLAGS+=-DUSE_REF=REF_GL + +SRCFILES+=gl_draw.c \ + gl_images.c \ + gl_models.c \ + gl_world.c \ + gl_mesh.c \ + gl_main.c \ + gl_state.c \ + gl_surf.c \ + gl_tess.c \ + gl_sky.c \ + qgl_api.c -LDFLAGS+=-lm -shared -CFLAGS+=-DOPENGL_RENDERER=1 -DTRUECOLOR_RENDERER=1 +ifdef MINGW +SRCFILES+=win_glimp.c win_wgl.c +endif -ifdef USE_JPEG -LDFLAGS+=$(JPEG_LDFLAGS) -CFLAGS+=$(JPEG_CFLAGS) +ifdef USE_JPG +LDFLAGS+=$(JPG_LDFLAGS) +CFLAGS+=$(JPG_CFLAGS) endif ifdef USE_PNG @@ -19,31 +43,3 @@ LDFLAGS+=$(PNG_LDFLAGS) CFLAGS+=$(PNG_CFLAGS) endif -ifdef MINGW -RESFILES+=ref_gl.rc -else -CFLAGS+=-fPIC -LDFLAGS+=-fPIC -endif - -SRCFILES=q_shared.c \ - r_images.c \ - r_bsp.c \ - gl_draw.c \ - gl_images.c \ - gl_models.c \ - gl_world.c \ - gl_mesh.c \ - gl_main.c \ - gl_state.c \ - gl_surf.c \ - gl_tess.c \ - gl_sky.c \ - qgl_api.c - -ifdef USE_ASM -ASMFILES=math.s -endif - -include $(SRCDIR)/build/target.mk - diff --git a/build/ref_soft.mk b/build/ref_soft.mk index 26ba7f2..803782c 100644 --- a/build/ref_soft.mk +++ b/build/ref_soft.mk @@ -1,16 +1,23 @@ -# ----------------------------- -# q2pro makefile by [SkulleR] -# ----------------------------- - -include ../config.mk - -TARGET=../ref_soft$(LIBSUFFIX) - -LDFLAGS+=-lm -shared -CFLAGS+=-DSOFTWARE_RENDERER - -SRCFILES=q_shared.c \ - sw_aclip.c \ +# Copyright (C) 2008 Andrey Nazarov +# +# 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. + +CFLAGS+=-DUSE_REF=REF_SOFT + +SRCFILES+=sw_aclip.c \ sw_alias.c \ sw_bsp.c \ sw_draw.c \ @@ -28,11 +35,11 @@ SRCFILES=q_shared.c \ sw_sprite.c \ sw_surf.c \ sw_sird.c \ - r_images.c + sw_sky.c ifdef USE_ASM SRCFILES+=sw_protect.c -ASMFILES=r_aclipa.s \ +ASMFILES+=r_aclipa.s \ r_draw16.s \ r_drawa.s \ r_edgea.s \ @@ -41,16 +48,10 @@ ASMFILES=r_aclipa.s \ r_surf8.s \ r_varsa.s \ d_polysa.s \ - fpu.s \ - math.s + fpu.s endif ifdef MINGW -RESFILES=ref_soft.rc -else -LDFLAGS+=-fPIC -CFLAGS+=-fPIC +SRCFILES+=win_swimp.c endif -include $(SRCDIR)/build/target.mk - diff --git a/build/server.mk b/build/server.mk new file mode 100644 index 0000000..6abb1f1 --- /dev/null +++ b/build/server.mk @@ -0,0 +1,37 @@ +# Copyright (C) 2008 Andrey Nazarov +# +# 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. + +CFLAGS+=-DUSE_SERVER=1 + +SRCFILES+=sv_ccmds.c \ + sv_ents.c \ + sv_game.c \ + sv_init.c \ + sv_main.c \ + sv_send.c \ + sv_user.c \ + sv_world.c \ + sv_mvd.c \ + sv_http.c \ + mvd_client.c \ + mvd_parse.c \ + mvd_game.c + +ifdef USE_ANTICHEAT +SRCFILES+=sv_ac.c +endif + diff --git a/build/target.mk b/build/target.mk index 8e580f1..d674245 100644 --- a/build/target.mk +++ b/build/target.mk @@ -1,6 +1,19 @@ -# ----------------------------- -# q2pro makefile by [SkulleR] -# ----------------------------- +# Copyright (C) 2008 Andrey Nazarov +# +# 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. OBJFILES+=$(SRCFILES:%.c=%.o) $(ASMFILES:%.s=%.o) $(RESFILES:%.rc=%.o) @@ -1,7 +1,24 @@ #!/bin/sh +# Copyright (C) 2008 Andrey Nazarov +# +# 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. + # ----------------------------- -# q2pro configuration script by [SkulleR] +# Q2PRO configuration script # ----------------------------- # build directories @@ -9,21 +26,32 @@ sources=$(dirname $0) if [ "$sources" = "." ]; then sources=`pwd` fi - if [ ! -f $sources/source/common.c ] ; then echo "ERROR: $sources does not look like Q2PRO source tree" exit 1 fi - outdir=`pwd` +tmpc="/tmp/q2pro-${RANDOM}.c" +tmpo="/tmp/q2pro-${RANDOM}.o" +config_mk="config.mk" +config_h="config.h" # defaults -prefix="/usr/local" -datadir="share/games/quake2" -libdir="lib/games/quake2" -refdir="lib/games/q2pro" -bindir="games" -mandir="share/man/man6" +revision="238" +help="no" +exesuffix="" +libsuffix=".so" +targets="" +executables="" +libraries="" +cpu="" +singleuser="no" +asmflags="" +if [ -z "$CFLAGS" ]; then + CFLAGS="-O2 -Wall -Wstrict-prototypes" +fi + +# build tools cross_prefix="" cc="gcc" make="make" @@ -32,35 +60,35 @@ strip="strip" mingw="no" pngconfig="libpng-config" sdlconfig="sdl-config" -exesuffix="" -libsuffix=".so" -dsound="no" -dinput="no" -zlib="yes" -png="no" -jpeg="no" -sdl="yes" -dl="no" -x11="yes" -client="yes" -ref_soft="yes" -ref_gl="yes" -server="no" -openffa="no" -help="no" -targets="" -executables="" -libraries="" -hardlink="no" -asm="???" -cpu="" -anticheat="no" -singleuser="no" -gldriver="libGL.so.1" -indriver="" + +# install paths +prefix="/usr/local" +datadir="share/games/quake2" +libdir="lib/games/quake2" +bindir="games" +mandir="share/man/man6" homedir="~/.q2pro" sitecfg="/etc/default/q2pro" -asmflags="" + +# use flags +use_dsound="no" +use_dinput="no" +use_zlib="yes" +use_tga="yes" +use_png="no" +use_jpg="no" +use_sdl="yes" +use_dl="no" +use_x11="yes" +use_client="yes" +use_ref="gl" +use_ui="yes" +use_server="no" +use_anticheat="no" +use_asm="???" +use_openffa="no" + +# constants logfile="console.log" cfgfile="config.cfg" defcfg="default.cfg" @@ -69,15 +97,8 @@ histfile=".conhistory" democache=".democache" screenshots="screenshots" scoreshots="scoreshots" -revision="238" -tmpc="/tmp/q2pro-${RANDOM}.c" -tmpo="/tmp/q2pro-${RANDOM}.o" -config_mk="config.mk" -config_h="config.h" - -if [ -z "$CFLAGS" ]; then - CFLAGS="-O2 -Wall -Wstrict-prototypes" -fi +gldriver="libGL.so.1" +indriver="" #parse options for opt do @@ -102,27 +123,31 @@ for opt do ;; --strip=*) strip=`echo $opt | cut -d '=' -f 2` ;; - --hardlink) hardlink="yes" + --disable-client) use_client="no" + ;; + --enable-server) use_server="yes" ;; - --disable-client) client="no" + --enable-openffa) use_openffa="yes" ;; - --enable-server) server="yes" + --enable-dsound) use_dsound="yes" ;; - --enable-openffa) openffa="yes" + --enable-dinput) use_dinput="yes" ;; - --enable-dsound) dsound="yes" + --disable-zlib) use_zlib="no" ;; - --enable-dinput) dinput="yes" + --disable-tga) use_tga="no" ;; - --disable-zlib) zlib="no" + --enable-png) use_png="yes" ;; - --enable-png) png="yes" + --enable-jpg) use_jpg="yes" ;; - --enable-jpeg) jpeg="yes" + --disable-ui) use_ui="no" ;; - --disable-asm) asm="no" + --use-ref=*) use_ref=`echo $opt | cut -d '=' -f 2` ;; - --enable-anticheat) anticheat="yes" + --disable-asm) use_asm="no" + ;; + --enable-anticheat) use_anticheat="yes" ;; --single-user) singleuser="yes" ;; @@ -130,8 +155,6 @@ for opt do ;; --libdir=*) libdir=`echo $opt | cut -d '=' -f 2` ;; - --refdir=*) refdir=`echo $opt | cut -d '=' -f 2` - ;; --bindir=*) bindir=`echo $opt | cut -d '=' -f 2` ;; --mandir=*) mandir=`echo $opt | cut -d '=' -f 2` @@ -152,7 +175,6 @@ echo " --cross-prefix=PREFIX add PREFIX to compile tools [$cross_prefix]" echo " --cc=CC use C compiler [$cc]" echo " --make=MAKE use MAKE processor [$make]" echo " --windres=WINDRES use RC compiler [$windres]" -echo " --hardlink hard link client with ref_gl" echo " --disable-client do not build client" echo " --enable-server build dedicated server" echo " --enable-openffa build OpenFFA deathmatch mod" @@ -160,15 +182,16 @@ echo " --enable-mingw enable Windows build" echo " --enable-dsound enable direct sound driver" echo " --enable-dinput enable direct input driver" echo " --disable-zlib disable linking with zlib" -echo " --enable-png enable linking with PNG library" -echo " --enable-jpeg enable linking with JPEG library" +echo " --disable-tga disable TGA images support" +echo " --enable-png enable PNG images support" +echo " --enable-jpg enable JPG images support" +echo " --disable-ui disable menu user interface" echo " --disable-asm disable i386 assembly optimizations" echo " --enable-anticheat enable r1ch.net anticheat server interface" echo " --single-user assume to be installed in home dir" echo " --prefix=PREFIX install in PREFIX [$prefix]" -echo " --datadir=DIR game data tree [$datadir]" -echo " --libdir=DIR game libraries tree [$libdir]" -echo " --refdir=DIR refresh libraries directory [$refdir]" +echo " --datadir=DIR path to game data tree [$datadir]" +echo " --libdir=DIR path to game libs tree [$libdir]" echo " --bindir=DIR executables directory [$bindir]" echo " --mandir=DIR manpages directory [$mandir]" echo " --homedir=DIR home directory [$homedir]" @@ -184,8 +207,8 @@ fi case $cpu in i386|i486|i586|i686) cpu="i386" -if [ "$asm" != "no" ] ; then - asm="yes" +if [ "$use_asm" != "no" ] ; then + use_asm="yes" fi CFLAGS="-ffloat-store -ffast-math $CFLAGS" ;; @@ -217,7 +240,7 @@ mingw="yes" make="gmake" ;; Linux) -dl="yes" +use_dl="yes" ;; esac @@ -231,7 +254,7 @@ if [ "$mingw" = "yes" ]; then pathsep='\\' exesuffix=".exe" libsuffix=".dll" - sdl="no" + use_sdl="no" gldriver="opengl32" exported="__attribute__((dllexport))" homedir="" @@ -245,7 +268,6 @@ else prefix="" datadir="." libdir="." - refdir="." bindir="" mandir="" homedir="" @@ -253,7 +275,6 @@ else if [ ! -z "$prefix" ]; then datadir="$prefix/$datadir" libdir="$prefix/$libdir" - refdir="$prefix/$refdir" bindir="$prefix/$bindir" mandir="$prefix/$mandir" fi @@ -272,7 +293,7 @@ fi gamelib="game$cpu.so" vpath="\$(SRCDIR)/source" -if [ "$client" = "yes" ]; then +if [ "$use_asm" = "yes" ]; then vpath="$vpath \$(SRCDIR)/asm" fi @@ -284,70 +305,50 @@ if [ ! -z "$cross_prefix" ]; then fi # echo configuration info -echo "Build client $client" -if [ "$client" = "yes" ]; then - if [ "$hardlink" = "yes" ]; then - echo "Hard linked $hardlink" - else - echo "Software refresh $ref_soft" - echo "OpenGL refresh $ref_gl" - fi -fi -echo "Build server $server" -echo "Build OpenFFA $openffa" +echo "Build client $use_client" +echo "Build server $use_server" +echo "Build OpenFFA $use_openffa" if [ "$mingw" = "no" ]; then if [ "$singleuser" = "yes" ]; then echo "Single user $singleuser" else echo "Data directory $datadir" echo "Game libraries $libdir" - if [ "$client" = "yes" ]; then - echo "Refresh libraries $refdir" - fi echo "Binaries $bindir" echo "Man pages $mandir" echo "Home directory $homedir" fi fi -echo "zlib support $zlib" -if [ "$client" = "yes" ]; then - echo "Direct input $dinput" - echo "Direct sound $dsound" - echo "PNG support $png" - echo "JPEG support $jpeg" +echo "zlib support $use_zlib" +if [ "$use_client" = "yes" ]; then + echo "Refresh type $use_ref" + echo "Direct input $use_dinput" + echo "Direct sound $use_dsound" + echo "TGA support $use_tga" + echo "JPG support $use_jpg" + echo "PNG support $use_png" + echo "UI support $use_ui" fi -test "$cpu" = "i386" && echo "i386 assembly $asm" +test "$cpu" = "i386" && echo "i386 assembly $use_asm" CFLAGS="-I\$(OUTDIR) -MF \$*.d -MMD -pipe $CFLAGS -Wno-strict-aliasing" #LDFLAGS="$LDFLAGS" # determine what needs to be built -if [ "$client" = "yes" ]; then +if [ "$use_client" = "yes" ]; then targets="$targets q2pro" executables="$executables q2pro$exesuffix" - - if [ "$hardlink" = "no" ]; then - if [ "$ref_soft" = "yes" ]; then - targets="$targets ref_soft" - libraries="$libraries ref_soft$libsuffix" - fi - - if [ "$ref_gl" = "yes" ]; then - targets="$targets ref_gl" - libraries="$libraries ref_gl$libsuffix" - fi - fi else - sdl="no" + use_sdl="no" fi -if [ "$server" = "yes" ]; then +if [ "$use_server" = "yes" ]; then targets="$targets q2proded" executables="$executables q2proded$exesuffix" fi -if [ "$openffa" = "yes" ]; then +if [ "$use_openffa" = "yes" ]; then targets="$targets openffa" libraries="$libraries $gamelib" fi @@ -371,7 +372,7 @@ echo "VPATH=$vpath" >> $config_mk echo "CFLAGS=$CFLAGS" >> $config_mk echo "LDFLAGS=$LDFLAGS" >> $config_mk test "$mingw" = "yes" && echo "RESFLAGS=-I\$(OUTDIR) -I\$(SRCDIR)/source" >> $config_mk -test "$asm" = "yes" && echo "ASMFLAGS=$asmflags" >> $config_mk +test "$use_asm" = "yes" && echo "ASMFLAGS=$asmflags" >> $config_mk echo "TARGETS=$targets" >> $config_mk echo "BINARIES=$executables $libraries" >> $config_mk @@ -382,6 +383,8 @@ echo "REVISION=$revision" >> $config_mk echo "#define REVISION $revision" >> $config_h echo "#define VERSION \"r$revision\"" >> $config_h +echo "#define PRIz \"zu\"" >> $config_h + if [ "$mingw" = "no" ]; then echo "DATADIR=$datadir" >> $config_mk echo "#define DATADIR \"$datadir\"" >> $config_h @@ -389,9 +392,6 @@ if [ "$mingw" = "no" ]; then echo "LIBDIR=$libdir" >> $config_mk echo "#define LIBDIR \"$libdir\"" >> $config_h - echo "REFDIR=$refdir" >> $config_mk - echo "#define REFDIR \"$refdir\"" >> $config_h - echo "#define HOMEDIR \"$homedir\"" >> $config_h if [ "$singleuser" = "yes" ]; then @@ -425,13 +425,11 @@ echo "#define BUILDSTRING \"$targetos\"" >> $config_h echo "#define PATH_SEP_CHAR '$pathsep'" >> $config_h echo "#define PATH_SEP_STRING \"$pathsep\"" >> $config_h -echo "#define DEFAULT_OPENGL_DRIVER \"$gldriver\"" >> $config_h - -if [ "$dl" = "yes" ]; then +if [ "$use_dl" = "yes" ]; then echo "USE_DL=yes" >> $config_mk fi -if [ "$zlib" = "yes" ]; then +if [ "$use_zlib" = "yes" ]; then echo "USE_ZLIB=yes" >> $config_mk echo "ZLIB_LDFLAGS=-lz" >> $config_mk echo "ZLIB_CFLAGS=" >> $config_mk @@ -440,26 +438,45 @@ else echo "#define USE_ZLIB 0" >> $config_h fi -if [ "$png" = "yes" ]; then +if [ "$use_ref" != "no" ]; then + echo "USE_REF=$use_ref" >> $config_mk + echo "#define REF_SOFT 1" >> $config_h + echo "#define REF_GL 2" >> $config_h + if [ "$use_ref" = "gl" ]; then + echo "#define DEFAULT_OPENGL_DRIVER \"$gldriver\"" >> $config_h + fi + echo "#define VID_REF \"$use_ref\"" >> $config_h +fi + +if [ "$use_tga" = "yes" ]; then + echo "#define USE_TGA 1" >> $config_h +fi + +if [ "$use_png" = "yes" ]; then echo "USE_PNG=yes" >> $config_mk echo "PNG_LDFLAGS=$($pngconfig --libs)" >> $config_mk echo "PNG_CFLAGS=$($pngconfig --cflags)" >> $config_mk echo "#define USE_PNG 1" >> $config_h fi -if [ "$jpeg" = "yes" ]; then - echo "USE_JPEG=yes" >> $config_mk - echo "JPEG_LDFLAGS=-ljpeg" >> $config_mk - echo "JPEG_CFLAGS=" >> $config_mk - echo "#define USE_JPEG 1" >> $config_h +if [ "$use_jpg" = "yes" ]; then + echo "USE_JPG=yes" >> $config_mk + echo "JPG_LDFLAGS=-ljpeg" >> $config_mk + echo "JPG_CFLAGS=" >> $config_mk + echo "#define USE_JPG 1" >> $config_h fi -if [ "$sdl" = "yes" ]; then +if [ "$use_ui" = "yes" ]; then + echo "USE_UI=yes" >> $config_mk + echo "#define USE_UI 1" >> $config_h +fi + +if [ "$use_sdl" = "yes" ]; then echo "USE_SDL=yes" >> $config_mk echo "SDL_LDFLAGS=$($sdlconfig --libs)" >> $config_mk echo "SDL_CFLAGS=$($sdlconfig --cflags)" >> $config_mk echo "#define USE_SDL 1" >> $config_h - if [ "$x11" = "yes" ]; then + if [ "$use_x11" = "yes" ]; then echo "USE_X11=yes" >> $config_mk echo "X11_LDFLAGS=-lX11" >> $config_mk echo "X11_CFLAGS=" >> $config_mk @@ -467,22 +484,22 @@ if [ "$sdl" = "yes" ]; then fi fi -if [ "$dsound" = "yes" ]; then +if [ "$use_dsound" = "yes" ]; then echo "USE_DSOUND=yes" >> $config_mk echo "#define USE_DSOUND 1" >> $config_h fi -if [ "$dinput" = "yes" ]; then +if [ "$use_dinput" = "yes" ]; then echo "USE_DINPUT=yes" >> $config_mk echo "#define USE_DINPUT 1" >> $config_h fi -if [ "$asm" = "yes" ]; then +if [ "$use_asm" = "yes" ]; then echo "USE_ASM=yes" >> $config_mk echo "#define USE_ASM 1" >> $config_h fi -if [ "$anticheat" = "yes" ]; then +if [ "$use_anticheat" = "yes" ]; then echo "USE_ANTICHEAT=yes" >> $config_mk echo "#define USE_ANTICHEAT 2" >> $config_h fi @@ -490,19 +507,6 @@ fi echo "#define USE_MAPCHECKSUM 1" >> $config_h echo "#define USE_AUTOREPLY 1" >> $config_h -if [ "$hardlink" = "yes" ]; then - echo "REF_HARD_LINKED=yes" >> $config_mk - echo "#define REF_HARD_LINKED 1" >> $config_h - - echo "#define OPENGL_RENDERER 1" >> $config_h - echo "#define TRUECOLOR_RENDERER 1" >> $config_h - echo "#define DEFAULT_REFRESH_DRIVER \"gl\"" >> $config_h -else - echo "#define DEFAULT_REFRESH_DRIVER \"soft\"" >> $config_h -fi - -echo "#define PRIz \"zu\"" >> $config_h - for t in $targets ; do mkdir -p .$t ; done diff --git a/debian/control b/debian/control index 745bec9..f1b9c34 100644 --- a/debian/control +++ b/debian/control @@ -19,9 +19,7 @@ Description: Enhanced Quake2 engine (graphical client) increased security and overall performance, basic built-in demo editing capabilities, built-in server and demo browsers. . - Both OpenGL and software refresh modules are included, so that 3D graphics - accelerator is not mandatory to play Q2PRO, although recommended to - take most of Q2PRO features. + This version of Q2PRO requires 3D graphics accelerator to play. . Homepage: http://q2pro.sf.net/ diff --git a/debian/rules b/debian/rules index ff21d66..68cc988 100755 --- a/debian/rules +++ b/debian/rules @@ -6,5 +6,5 @@ include /usr/share/cdbs/1/class/autotools.mk DEB_DH_INSTALL_SOURCEDIR := debian/tmp DEB_CONFIGURE_NORMAL_ARGS := --prefix=$(DEB_CONFIGURE_PREFIX) \ - --enable-png --enable-jpeg --enable-dsound --enable-server --enable-anticheat --enable-openffa + --enable-png --enable-jpg --enable-dsound --enable-server --enable-anticheat --enable-openffa diff --git a/source/bsp.c b/source/bsp.c new file mode 100644 index 0000000..2a30dc2 --- /dev/null +++ b/source/bsp.c @@ -0,0 +1,1179 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. +Copyright (C) 2008 Andrey Nazarov + +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. + +*/ + +// bsp.c -- model loading + +#include "com_local.h" +#include "q_list.h" +#include "files.h" +#include "sys_public.h" +#include "bsp.h" + +void BSP_SetError( const char *fmt, ... ) q_printf( 1, 2 ); + +extern mtexinfo_t nulltexinfo; + +static cvar_t *map_override; + +/* +=============================================================================== + + LUMP LOADING + +=============================================================================== +*/ + +#define BSP_Malloc( size ) Hunk_Alloc( &bsp->pool, size ) + +#define LOAD( Func ) \ + static qboolean BSP_Load##Func( bsp_t *bsp, void *base, size_t count ) + +/* +================= +Visibility +================= +*/ +LOAD( Visibility ) { + unsigned numclusters, bitofs; + int i, j; + + if( !count ) { + return qtrue; + } + + bsp->numvisibility = count; + bsp->vis = BSP_Malloc( count ); + memcpy( bsp->vis, base, count ); + + numclusters = LittleLong( bsp->vis->numclusters ); + if( numclusters > ( count - 4 ) / 8 ) { + BSP_SetError( "%s: bad numclusters", __func__ ); + } + bsp->vis->numclusters = numclusters; + bsp->visrowsize = ( numclusters + 7 ) >> 3; + for( i = 0; i < numclusters; i++ ) { + for( j = 0; j < 2; j++ ) { + bitofs = LittleLong( bsp->vis->bitofs[i][j] ); + if( bitofs >= count ) { + BSP_SetError( "%s: bad bitofs", __func__ ); + return qfalse; + } + bsp->vis->bitofs[i][j] = bitofs; + } + } + + return qtrue; +} + +/* +================= +Texinfo +================= +*/ +LOAD( Texinfo ) { + dtexinfo_t *in; + mtexinfo_t *out; + int i; +#if USE_REF + int j, k; + int next; + mtexinfo_t *step; +#endif + + bsp->numtexinfo = count; + bsp->texinfo = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->texinfo; + for( i = 0; i < count; i++, in++, out++ ) { + memcpy( out->c.name, in->texture, sizeof( out->c.name ) ); + out->c.name[ sizeof( out->c.name ) - 1 ] = 0; + memcpy( out->name, in->texture, sizeof( out->name ) ); + out->name[ sizeof( out->name ) - 1 ] = 0; + out->c.flags = LittleLong (in->flags); + out->c.value = LittleLong (in->value); + +#if USE_REF + for( j = 0; j < 2; j++ ) { + for( k = 0; k < 3; k++ ) { + out->axis[j][k] = LittleFloat( in->vecs[j][k] ); + } + out->offset[j] = LittleFloat( in->vecs[j][k] ); + } + + next = LittleLong( in->nexttexinfo ); + if( next > 0 ) { + if( next >= count ) { + BSP_SetError( "%s: bad anim chain", __func__ ); + return qfalse; + } + out->next = bsp->texinfo + next; + } else { + out->next = NULL; + } +#endif + } + +#if USE_REF + // count animation frames + out = bsp->texinfo; + for( i = 0; i < count; i++, out++ ) { + out->numframes = 1; + for( step = out->next; step && step != out; step = step->next ) { + out->numframes++; + } + } +#endif + return qtrue; +} + +/* +================= +Planes +================= +*/ +LOAD( Planes ) { + dplane_t *in; + cplane_t *out; + int i, j; + + bsp->numplanes = count; + bsp->planes = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->planes; + for( i = 0; i < count; i++, in++, out++ ) { + for( j = 0; j < 3; j++ ) { + out->normal[j] = LittleFloat( in->normal[j] ); + } + out->dist = LittleFloat( in->dist ); + SetPlaneType( out ); + SetPlaneSignbits( out ); + } + return qtrue; +} + +/* +================= +BrushSides +================= +*/ +LOAD( BrushSides ) { + dbrushside_t *in; + mbrushside_t *out; + int i; + unsigned planenum, texinfo; + + bsp->numbrushsides = count; + bsp->brushsides = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->brushsides; + for( i = 0; i < count; i++, in++, out++ ) { + planenum = LittleShort (in->planenum); + if( planenum >= bsp->numplanes ) { + BSP_SetError( "%s: bad planenum", __func__ ); + return qfalse; + } + out->plane = bsp->planes + planenum; + texinfo = LittleShort (in->texinfo); + if( texinfo == ( uint16_t )-1 ) { + out->texinfo = &nulltexinfo; + } else { + if (texinfo >= bsp->numtexinfo) { + BSP_SetError( "%s: bad texinfo", __func__ ); + return qfalse; + } + out->texinfo = bsp->texinfo + texinfo; + } + } + return qtrue; +} + +/* +================= +Brushes +================= +*/ +LOAD( Brushes ) { + dbrush_t *in; + mbrush_t *out; + int i; + unsigned firstside, numsides, lastside; + + bsp->numbrushes = count; + bsp->brushes = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->brushes; + for( i = 0; i < count; i++, out++, in++ ) { + firstside = LittleLong(in->firstside); + numsides = LittleLong(in->numsides); + lastside = firstside + numsides; + if( lastside < firstside || lastside > bsp->numbrushsides ) { + BSP_SetError( "%s: bad brushsides", __func__ ); + return qfalse; + } + out->firstbrushside = bsp->brushsides + firstside; + out->numsides = numsides; + out->contents = LittleLong(in->contents); + out->checkcount = 0; + } + return qtrue; +} + +/* +================= +LeafBrushes +================= +*/ +LOAD( LeafBrushes ) { + uint16_t *in; + mbrush_t **out; + int i; + unsigned brushnum; + + bsp->numleafbrushes = count; + bsp->leafbrushes = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->leafbrushes; + for( i = 0; i < count; i++, in++, out++ ) { + brushnum = LittleShort( *in ); + if( brushnum >= bsp->numbrushes ) { + BSP_SetError( "%s: bad brushnum", __func__ ); + return qfalse; + } + *out = bsp->brushes + brushnum; + } + return qtrue; +} + + +#if USE_REF +/* +================= +Lightmap +================= +*/ +LOAD( Lightmap ) { +#if USE_REF == REF_SOFT + byte *in; + byte *out; + int i; + + count /= 3; +#endif + + if( !count ) { + return qtrue; + } + + bsp->numlightmapbytes = count; + bsp->lightmap = BSP_Malloc( count ); + +#if USE_REF == REF_SOFT + // convert the 24 bit lighting down to 8 bit + // by taking the brightest component + in = base; + out = bsp->lightmap; + for( i = 0; i < count; i++, in += 3, out++ ) { + if( in[0] > in[1] && in[0] > in[2] ) + *out = in[0]; + else if( in[1] > in[0] && in[1] > in[2] ) + *out = in[1]; + else + *out = in[2]; + } +#else + memcpy( bsp->lightmap, base, count ); +#endif + return qtrue; +} + +/* +================= +Vertices +================= +*/ +LOAD( Vertices ) { + dvertex_t *in; + mvertex_t *out; + int i, j; + + bsp->numvertices = count; + bsp->vertices = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->vertices; + for( i = 0; i < count; i++, out++, in++ ) { + for( j = 0; j < 3; j++ ) { + out->point[j] = LittleFloat( in->point[j] ); + } + } + return qtrue; +} + +/* +================= +Edges +================= +*/ +LOAD( Edges ) { + dedge_t *in; + medge_t *out; + int i, j; + unsigned vertnum; + + bsp->numedges = count; + bsp->edges = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->edges; + for( i = 0; i < count; i++, out++, in++ ) { + for( j = 0; j < 2; j++ ) { + vertnum = LittleShort( in->v[j] ); + if( vertnum >= bsp->numvertices ) { + BSP_SetError( "%s: bad vertnum", __func__ ); + return qfalse; + } + out->v[j] = bsp->vertices + vertnum; + } + } + return qtrue; +} + +/* +================= +SurfEdges +================= +*/ +LOAD( SurfEdges ) { + int *in; + msurfedge_t *out; + int i; + int index, vert; + + bsp->numsurfedges = count; + bsp->surfedges = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->surfedges; + for( i = 0; i < count; i++, out++, in++ ) { + index = ( signed int )LittleLong( *in ); + + vert = 0; + if( index < 0 ) { + index = -index; + vert = 1; + } + + if( index >= bsp->numedges ) { + BSP_SetError( "%s: bad edgenum", __func__ ); + } + + out->edge = bsp->edges + index; + out->vert = vert; + } + return qtrue; +} + +/* +================= +Faces +================= +*/ +LOAD( Faces ) { + dface_t *in; + mface_t *out; + int i; +#if USE_REF == REF_SOFT + int j; +#endif + unsigned texinfo, lightofs; + unsigned firstedge, numedges, lastedge; + unsigned planenum, side; + + bsp->numfaces = count; + bsp->faces = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->faces; + for( i = 0; i < count; i++, in++, out++ ) { + firstedge = LittleLong( in->firstedge ); + numedges = LittleShort( in->numedges ); + lastedge = firstedge + numedges; + if( numedges < 3 || lastedge < firstedge || lastedge > bsp->numsurfedges ) { + BSP_SetError( "%s: bad surfedges", __func__ ); + return qfalse; + } + out->firstsurfedge = bsp->surfedges + firstedge; + out->numsurfedges = numedges; + + planenum = LittleShort( in->planenum ); + if( planenum >= bsp->numplanes ) { + BSP_SetError( "%s: bad planenum", __func__ ); + return qfalse; + } + out->plane = bsp->planes + planenum; + + texinfo = LittleShort( in->texinfo ); + if( texinfo >= bsp->numtexinfo ) { + BSP_SetError( "%s: bad texinfo", __func__ ); + return qfalse; + } + out->texinfo = bsp->texinfo + texinfo; + +#if USE_REF == REF_SOFT + for( j = 0; j < MAX_LIGHTMAPS; j++ ) { + out->styles[j] = in->styles[j]; + } +#endif + + lightofs = LittleLong( in->lightofs ); + if( lightofs == ( uint32_t )-1 || bsp->numlightmapbytes == 0 ) { + out->lightmap = NULL; + } else { +#if USE_REF == REF_SOFT + // lighting info is converted from 24 bit on disk to 8 bit + lightofs /= 3; +#endif + if( lightofs >= bsp->numlightmapbytes ) { + BSP_SetError( "%s: bad lightofs", __func__ ); + return qfalse; + } + out->lightmap = bsp->lightmap + lightofs; + } + + side = LittleShort( in->side ); + out->drawflags = side & DSURF_PLANEBACK; + } + return qtrue; +} + +/* +================= +LeafFaces +================= +*/ +LOAD( LeafFaces ) { + uint16_t *in; + mface_t **out; + int i; + unsigned facenum; + + bsp->numleaffaces = count; + bsp->leaffaces = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->leaffaces; + for( i = 0; i < count; i++, in++, out++ ) { + facenum = LittleShort( *in ); + if( facenum >= bsp->numfaces ) { + BSP_SetError( "%s: bad facenum", __func__ ); + return qfalse; + } + *out = bsp->faces + facenum; + } + return qtrue; +} +#endif + +/* +================= +Leafs +================= +*/ +LOAD( Leafs ) { + dleaf_t *in; + mleaf_t *out; + int i, cluster; + unsigned area, firstleafbrush, numleafbrushes; +#if USE_REF + int j; + unsigned firstleafface, numleaffaces; +#endif + + bsp->numleafs = count; + bsp->leafs = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->leafs; + for( i = 0; i < count; i++, in++, out++ ) { + out->plane = NULL; + out->contents = LittleLong (in->contents); + cluster = ( signed short )LittleShort (in->cluster); + if( bsp->vis && cluster != -1 ) { + if( cluster < 0 || cluster >= bsp->vis->numclusters ) { + BSP_SetError( "%s: bad cluster", __func__ ); + return qfalse; + } + } + out->cluster = cluster; + + area = LittleShort( in->area ); + if( area >= bsp->numareas ) { + BSP_SetError( "%s: bad area", __func__ ); + return qfalse; + } + out->area = area; + + firstleafbrush = LittleShort (in->firstleafbrush); + numleafbrushes = LittleShort (in->numleafbrushes); + if( firstleafbrush + numleafbrushes > bsp->numleafbrushes ) { + BSP_SetError( "%s: bad leafbrushes", __func__ ); + return qfalse; + } + out->firstleafbrush = bsp->leafbrushes + firstleafbrush; + out->numleafbrushes = numleafbrushes; + +#if USE_REF + firstleafface = LittleShort (in->firstleafface); + numleaffaces = LittleShort (in->numleaffaces); + if( firstleafface + numleaffaces > bsp->numleaffaces ) { + BSP_SetError( "%s: bad leaffaces", __func__ ); + return qfalse; + } + out->firstleafface = bsp->leaffaces + firstleafface; + out->numleaffaces = numleaffaces; + + for( j = 0; j < 3; j++ ) { + out->mins[j] = ( signed short )LittleShort( in->mins[j] ); + out->maxs[j] = ( signed short )LittleShort( in->maxs[j] ); + } + + out->parent = NULL; + out->visframe = -1; +#endif + } + + if (bsp->leafs[0].contents != CONTENTS_SOLID) { + BSP_SetError( "%s: map leaf 0 is not CONTENTS_SOLID", __func__ ); + return qfalse; + } + return qtrue; +} + +/* +================= +Nodes +================= +*/ +LOAD( Nodes ) { + dnode_t *in; + uint32_t child; + mnode_t *out; + int i, j; + unsigned planeNum; +#if USE_REF + unsigned firstface, numfaces, lastface; +#endif + + if( !count ) { + BSP_SetError( "%s: map with no nodes", __func__ ); + return qfalse; + } + + bsp->numnodes = count; + bsp->nodes = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->nodes; + for( i = 0; i < count; i++, out++, in++ ) { + planeNum = LittleLong(in->planenum); + if( planeNum >= bsp->numplanes ) { + BSP_SetError( "%s: bad planenum", __func__ ); + return qfalse; + } + out->plane = bsp->planes + planeNum; + + for( j = 0; j < 2; j++ ) { + child = LittleLong( in->children[j] ); + if( child & 0x80000000 ) { + child = ~child; + if( child >= bsp->numleafs ) { + BSP_SetError( "%s: bad leafnum", __func__ ); + return qfalse; + } + out->children[j] = ( mnode_t * )( bsp->leafs + child ); + } else { + if( child >= count ) { + BSP_SetError( "%s: bad nodenum", __func__ ); + return qfalse; + } + out->children[j] = bsp->nodes + child; + } + } + +#if USE_REF + firstface = LittleLong( in->firstface ); + numfaces = LittleLong( in->numfaces ); + lastface = firstface + numfaces; + if( lastface < firstface || lastface > bsp->numfaces ) { + BSP_SetError( "%s: bad faces", __func__ ); + return qfalse; + } + out->firstface = bsp->faces + firstface; + out->numfaces = numfaces; + + for( j = 0; j < 3; j++ ) { + out->mins[j] = ( signed short )LittleShort( in->mins[j] ); + out->maxs[j] = ( signed short )LittleShort( in->maxs[j] ); + } + + out->parent = NULL; + out->visframe = -1; +#endif + } + return qtrue; +} + +/* +================= +Submodels +================= +*/ +LOAD( Submodels ) { + dmodel_t *in; + mmodel_t *out; + int i, j; + unsigned headnode; +#if USE_REF + unsigned firstface, numfaces, lastface; +#endif + + bsp->models = BSP_Malloc( sizeof( *out ) * count ); + bsp->nummodels = count; + + in = base; + out = bsp->models; + for( i = 0; i < count; i++, in++, out++ ) { + for( j = 0; j < 3; j++ ) { + // spread the mins / maxs by a pixel + out->mins[j] = LittleFloat (in->mins[j]) - 1; + out->maxs[j] = LittleFloat (in->maxs[j]) + 1; + out->origin[j] = LittleFloat (in->origin[j]); + } + headnode = LittleLong (in->headnode); + if( headnode >= bsp->numnodes ) { + // FIXME: headnode may be garbage for some models + Com_DPrintf( "%s: bad headnode\n", __func__ ); + out->headnode = NULL; + } else { + out->headnode = bsp->nodes + headnode; + } +#if USE_REF + firstface = LittleLong( in->firstface ); + numfaces = LittleLong( in->numfaces ); + lastface = firstface + numfaces; + if( lastface < firstface || lastface > bsp->numfaces ) { + BSP_SetError( "%s: bad faces", __func__ ); + return qfalse; + } + out->firstface = bsp->faces + firstface; + out->numfaces = numfaces; + + out->radius = RadiusFromBounds( out->mins, out->maxs ); +#endif + } + return qtrue; +} + +/* +================= +AreaPortals +================= +*/ +LOAD( AreaPortals ) { + dareaportal_t *in; + mareaportal_t *out; + int i; + unsigned portalnum, otherarea; + + bsp->numareaportals = count; + bsp->areaportals = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->areaportals; + for( i = 0; i < count; i++, in++, out++ ) { + portalnum = LittleLong (in->portalnum); + if( portalnum >= MAX_MAP_AREAPORTALS ) { + BSP_SetError( "%s: bad portalnum", __func__ ); + return qfalse; + } + out->portalnum = portalnum; + otherarea = LittleLong (in->otherarea); + if( otherarea >= MAX_MAP_AREAS ) { + BSP_SetError( "%s: bad otherarea", __func__ ); + return qfalse; + } + out->otherarea = otherarea; + } + return qtrue; +} + +/* +================= +Areas +================= +*/ +LOAD( Areas ) { + darea_t *in; + marea_t *out; + int i; + unsigned numareaportals, firstareaportal, lastareaportal; + + bsp->numareas = count; + bsp->areas = BSP_Malloc( sizeof( *out ) * count ); + + in = base; + out = bsp->areas; + for( i = 0; i < count; i++, in++, out++ ) { + numareaportals = LittleLong (in->numareaportals); + firstareaportal = LittleLong (in->firstareaportal); + lastareaportal = firstareaportal + numareaportals; + if( lastareaportal < firstareaportal || lastareaportal > bsp->numareaportals ) { + BSP_SetError( "%s: bad areaportals", __func__ ); + return qfalse; + } + out->numareaportals = numareaportals; + out->firstareaportal = firstareaportal; + out->floodvalid = 0; + } + return qtrue; +} + +/* +================= +EntityString +================= +*/ +LOAD( EntityString ) { + // optionally load the entity string from external source + if( map_override->integer ) { + char buffer[MAX_QPATH], *str; + size_t len; + + COM_StripExtension( bsp->name, buffer, sizeof( buffer ) ); + Q_strcat( buffer, sizeof( buffer ), ".ent" ); + len = FS_LoadFile( buffer, ( void ** )&str ); + if( str ) { + Com_DPrintf( "Loaded entity string from %s\n", buffer ); + bsp->entitystring = BSP_Malloc( len + 1 ); + memcpy( bsp->entitystring, str, len + 1 ); + bsp->numentitychars = len; + FS_FreeFile( str ); + return qtrue; + } + } + + bsp->numentitychars = count; + bsp->entitystring = BSP_Malloc( count + 1 ); + memcpy( bsp->entitystring, base, count ); + bsp->entitystring[count] = 0; + return qtrue; +} + + +/* +=============================================================================== + + MAP LOADING + +=============================================================================== +*/ + +typedef struct { + qboolean (*load)( bsp_t *, void *, size_t ); + int lump; + size_t size; + size_t maxcount; +} lump_info_t; + +#define LUMP( Func, Lump, Type ) \ + { BSP_Load##Func, LUMP_##Lump, sizeof( Type ), MAX_MAP_##Lump } + +static const lump_info_t bsp_lumps[] = { + LUMP( Visibility, VISIBILITY, byte ), + LUMP( Texinfo, TEXINFO, dtexinfo_t ), + LUMP( Planes, PLANES, dplane_t ), + LUMP( BrushSides, BRUSHSIDES, dbrushside_t ), + LUMP( Brushes, BRUSHES, dbrush_t ), + LUMP( LeafBrushes, LEAFBRUSHES, uint16_t ), + LUMP( AreaPortals, AREAPORTALS, dareaportal_t ), + LUMP( Areas, AREAS, darea_t ), +#if USE_REF + LUMP( Lightmap, LIGHTING, byte ), + LUMP( Vertices, VERTEXES, dvertex_t ), + LUMP( Edges, EDGES, dedge_t ), + LUMP( SurfEdges, SURFEDGES, uint32_t ), + LUMP( Faces, FACES, dface_t ), + LUMP( LeafFaces, LEAFFACES, uint16_t ), +#endif + LUMP( Leafs, LEAFS, dleaf_t ), + LUMP( Nodes, NODES, dnode_t ), + LUMP( Submodels, MODELS, dmodel_t ), + LUMP( EntityString, ENTSTRING, char ), + { NULL } +}; + +static list_t bsp_cache; +static char bsp_error[MAX_QPATH]; + +static void BSP_List_f( void ) { + bsp_t *bsp; + size_t bytes; + + if( LIST_EMPTY( &bsp_cache ) ) { + Com_Printf( "BSP cache is empty\n" ); + return; + } + + Com_Printf( "------------------\n"); + bytes = 0; + + LIST_FOR_EACH( bsp_t, bsp, &bsp_cache, entry ) { + Com_Printf( "%8"PRIz" : %s (%d refs)\n", + bsp->pool.mapped, bsp->name, bsp->refcount ); + bytes += bsp->pool.mapped; + } + Com_Printf( "Total resident: %"PRIz"\n", bytes ); +} + +static bsp_t *BSP_Find( const char *name ) { + bsp_t *bsp; + + LIST_FOR_EACH( bsp_t, bsp, &bsp_cache, entry ) { + if( !FS_pathcmp( bsp->name, name ) ) { + return bsp; + } + } + return NULL; +} + +static qboolean BSP_SetParent( mnode_t *node ) { + mnode_t *child; + + while( node->plane ) { + child = node->children[0]; + if( child->parent ) { + return qfalse; + } + child->parent = node; + BSP_SetParent( child ); + + child = node->children[1]; + if( child->parent ) { + return qfalse; + } + child->parent = node; + node = child; + } + return qtrue; +} + +void BSP_SetError( const char *fmt, ... ) { + va_list argptr; + + va_start( argptr, fmt ); + Q_vsnprintf( bsp_error, sizeof( bsp_error ), fmt, argptr ); + va_end( argptr ); +} + +const char *BSP_GetError( void ) { + return bsp_error; +} + +void BSP_Free( bsp_t *bsp ) { + if( !bsp ) { + return; + } + if( bsp->refcount <= 0 ) { + Com_Error( ERR_FATAL, "%s: negative refcount", __func__ ); + } + if( --bsp->refcount == 0 ) { + Hunk_Free( &bsp->pool ); + List_Remove( &bsp->entry ); + Z_Free( bsp ); + } +} + + +/* +================== +BSP_Load + +Loads in the map and all submodels +================== +*/ +bsp_t *BSP_Load( const char *name ) { + bsp_t *bsp; + byte *buf; + dheader_t *header; + const lump_info_t *info; + size_t filelen, ofs, len, end, count; + + if( !name || !name[0] ) { + Com_Error( ERR_FATAL, "%s: NULL", __func__ ); + } + + BSP_SetError( "no error" ); + + if( ( bsp = BSP_Find( name ) ) != NULL ) { + bsp->refcount++; + return bsp; + } + + + // + // load the file + // + filelen = FS_LoadFile( name, ( void ** )&buf ); + if( !buf ) { + BSP_SetError( "file not found" ); + return NULL; + } + + len = strlen( name ); + bsp = Z_Mallocz( sizeof( *bsp ) + len ); + memcpy( bsp->name, name, len + 1 ); + bsp->refcount = 1; + + // byte swap and validate the header + header = ( dheader_t * )buf; + if( LittleLong( header->ident ) != IDBSPHEADER ) { + BSP_SetError( "not an IBSP file" ); + goto fail2; + } + if( LittleLong( header->version ) != BSPVERSION ) { + BSP_SetError( "unsupported IBSP version" ); + goto fail2; + } + + // load into hunk + Hunk_Begin( &bsp->pool, 0x1000000 ); + + // calculate the checksum + bsp->checksum = LittleLong( Com_BlockChecksum( buf, filelen ) ); + + // byte swap, validate and load all lumps + for( info = bsp_lumps; info->load; info++ ) { + ofs = LittleLong( header->lumps[info->lump].fileofs ); + len = LittleLong( header->lumps[info->lump].filelen ); + end = ofs + len; + if( end < ofs || end > filelen ) { + BSP_SetError( "lump %d extents are out of bounds", info->lump ); + goto fail1; + } + if( len % info->size ) { + BSP_SetError( "lump %d has funny size", info->lump ); + goto fail1; + } + count = len / info->size; + if( count > info->maxcount ) { + BSP_SetError( "lump %d has too many elements", info->lump ); + goto fail1; + } + if( !info->load( bsp, buf + ofs, count ) ) { + goto fail1; + } + } + + if( !BSP_SetParent( bsp->nodes ) ) { + BSP_SetError( "cycle encountered in BSP graph" ); + goto fail1; + } + + Hunk_End( &bsp->pool ); + + FS_FreeFile( buf ); + + List_Append( &bsp_cache, &bsp->entry ); + return bsp; + +fail1: + Hunk_Free( &bsp->pool ); +fail2: + FS_FreeFile( buf ); + Z_Free( bsp ); + return NULL; +} + +/* +=============================================================================== + +HELPER FUNCTIONS + +=============================================================================== +*/ + +#if USE_REF + +mface_t *BSP_LightPoint( mnode_t *node, vec3_t start, vec3_t end, int *ps, int *pt ) { + vec_t startFrac, endFrac, midFrac; + vec3_t _start, mid; + int side; + mface_t *surf; + mtexinfo_t *texinfo; + int i; + int s, t; + + VectorCopy( start, _start ); + while( node->plane ) { + // calculate distancies + startFrac = PlaneDiffFast( _start, node->plane ); + endFrac = PlaneDiffFast( end, node->plane ); + side = ( startFrac < 0 ); + + if( ( endFrac < 0 ) == side ) { + // both points are one the same side + node = node->children[side]; + continue; + } + + // find crossing point + midFrac = startFrac / ( startFrac - endFrac ); + LerpVector( _start, end, midFrac, mid ); + + // check near side + surf = BSP_LightPoint( node->children[side], _start, mid, ps, pt ); + if( surf ) { + return surf; + } + + for( i = 0, surf = node->firstface; i < node->numfaces; i++, surf++ ) { + texinfo = surf->texinfo; + if( texinfo->c.flags & SURF_NOLM_MASK ) { + continue; + } + if( !surf->lightmap ) { + continue; + } + s = DotProduct( texinfo->axis[0], mid ) + texinfo->offset[0]; + t = DotProduct( texinfo->axis[1], mid ) + texinfo->offset[1]; + + s -= surf->texturemins[0]; + t -= surf->texturemins[1]; + if( s < 0 || t < 0 ) { + continue; + } + if( s > surf->extents[0] || t > surf->extents[1] ) { + continue; + } + + *ps = s; + *pt = t; + + return surf; + } + + // check far side + VectorCopy( mid, _start ); + node = node->children[side^1]; + } + + return NULL; +} + +#endif + +byte *BSP_ClusterVis( bsp_t *bsp, byte *mask, int cluster, int vis ) { + byte *in, *out; + int c; + + if( !bsp || !bsp->vis ) { + return memset( mask, 0xff, MAX_MAP_VIS ); + } + if( cluster == -1 ) { + return memset( mask, 0, bsp->visrowsize ); + } + if( cluster < 0 || cluster >= bsp->vis->numclusters ) { + Com_Error( ERR_DROP, "%s: bad cluster", __func__ ); + } + + // decompress vis + in = ( byte * )bsp->vis + bsp->vis->bitofs[cluster][vis]; + out = mask; + do { + if( *in ) { + *out++ = *in++; + continue; + } + + c = in[1]; + in += 2; + if( ( out - mask ) + c > bsp->visrowsize ) { + c = bsp->visrowsize - ( out - mask ); + Com_WPrintf( "%s: overrun\n", __func__ ); + } + while( c ) { + *out++ = 0; + c--; + } + } while( out - mask < bsp->visrowsize ); + + return mask; +} + +mleaf_t *BSP_PointLeaf( mnode_t *node, vec3_t p ) { + float d; + + while( node->plane ) { + d = PlaneDiffFast( p, node->plane ); + if( d < 0 ) + node = node->children[1]; + else + node = node->children[0]; + } + + return ( mleaf_t * )node; +} + +/* +================== +BSP_InlineModel +================== +*/ +mmodel_t *BSP_InlineModel( bsp_t *bsp, const char *name ) { + int num; + + if( !bsp || !name ) { + Com_Error( ERR_DROP, "%s: NULL", __func__ ); + } + if( name[0] != '*' ) { + Com_Error( ERR_DROP, "%s: bad name: %s", __func__, name ); + } + num = atoi( name + 1 ); + if( num < 1 || num >= bsp->nummodels ) { + Com_Error ( ERR_DROP, "%s: bad number: %d", __func__, num ); + } + + return &bsp->models[num]; +} + +void BSP_Init( void ) { + map_override = Cvar_Get( "map_override", "0", 0 ); + + Cmd_AddCommand( "bsplist", BSP_List_f ); + + List_Init( &bsp_cache ); +} + diff --git a/source/bsp.h b/source/bsp.h new file mode 100644 index 0000000..5094220 --- /dev/null +++ b/source/bsp.h @@ -0,0 +1,274 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. +Copyright (C) 2008 Andrey Nazarov + +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 "d_bsp.h" + +#ifndef MIPLEVELS +#define MIPLEVELS 4 +#endif + +#define MAX_MAP_VIS ( MAX_MAP_LEAFS / 8 ) + +typedef struct mtexinfo_s { // used internally due to name len probs //ZOID + csurface_t c; + char name[MAX_TEXNAME]; + +#if USE_REF + vec3_t axis[2]; + vec2_t offset; + struct image_s *image; // used for texturing + int numframes; + struct mtexinfo_s *next; // used for animation +#if USE_REF == REF_SOFT + vec_t mipadjust; +#endif +#endif +} mtexinfo_t; + +#if USE_REF +typedef struct { + vec3_t point; +} mvertex_t; + +typedef struct { + mvertex_t *v[2]; +#if USE_REF == REF_SOFT + unsigned cachededgeoffset; +#endif +} medge_t; + +typedef struct { + medge_t *edge; + int vert; +} msurfedge_t; + +#define SURF_NOLM_MASK \ + (SURF_SKY|SURF_WARP|SURF_FLOWING|SURF_TRANS33|SURF_TRANS66) + +#define DSURF_PLANEBACK 1 + +typedef struct mface_s { + msurfedge_t *firstsurfedge; + int numsurfedges; + + cplane_t *plane; + int drawflags; // DSURF_PLANEBACK, etc + + byte *lightmap; +#if USE_REF == REF_SOFT + byte styles[MAX_LIGHTMAPS]; +#endif + + mtexinfo_t *texinfo; + int texturemins[2]; + int extents[2]; + +#if USE_REF == REF_GL + int texnum[2]; + int firstvert; +#else + struct surfcache_s *cachespots[MIPLEVELS]; // surface generation data +#endif + + int drawframe; + +#if USE_REF == REF_SOFT // && USE_DYNAMIC + int dlightframe; + int dlightbits; +#endif + struct mface_s *next; +} mface_t; +#endif + +typedef struct mnode_s { +/* ======> */ + cplane_t *plane; // never NULL to differentiate from leafs +#if USE_REF + union { + vec_t minmaxs[6]; + struct { + vec3_t mins; + vec3_t maxs; + }; + }; + + int visframe; +#endif + struct mnode_s *parent; +/* <====== */ + + struct mnode_s *children[2]; + +#if USE_REF + int numfaces; + mface_t *firstface; +#endif +} mnode_t; + +typedef struct { + cplane_t *plane; + mtexinfo_t *texinfo; +} mbrushside_t; + +typedef struct { + int contents; + int numsides; + mbrushside_t *firstbrushside; + int checkcount; // to avoid repeated testings +} mbrush_t; + +typedef struct { +/* ======> */ + cplane_t *plane; // always NULL to differentiate from nodes +#if USE_REF + vec3_t mins; + vec3_t maxs; + + int visframe; +#endif + struct mnode_s *parent; +/* <====== */ + + int contents; + int cluster; + int area; + mbrush_t **firstleafbrush; + int numleafbrushes; +#if USE_REF + mface_t **firstleafface; + int numleaffaces; +#if USE_REF == REF_SOFT + unsigned key; +#endif +#endif +} mleaf_t; + +typedef struct { + int numareaportals; + int firstareaportal; + int floodvalid; +} marea_t; + +typedef struct { + unsigned portalnum; + unsigned otherarea; +} mareaportal_t; + +typedef struct mmodel_s { +#if USE_REF +/* ======> */ + int type; +/* <====== */ +#endif + vec3_t mins, maxs; + vec3_t origin; // for sounds or lights + mnode_t *headnode; + +#if USE_REF + float radius; + + int numfaces; + mface_t *firstface; +#endif +} mmodel_t; + +typedef struct bsp_s { + list_t entry; + int refcount; + + unsigned checksum; + + mempool_t pool; + + int numbrushsides; + mbrushside_t *brushsides; + + int numtexinfo; + mtexinfo_t *texinfo; + + int numplanes; + cplane_t *planes; + + int numnodes; + mnode_t *nodes; + + int numleafs; + mleaf_t *leafs; + + int numleafbrushes; + mbrush_t **leafbrushes; + + int nummodels; + mmodel_t *models; + + int numbrushes; + mbrush_t *brushes; + + int numvisibility; + int visrowsize; + dvis_t *vis; + + int numentitychars; + char *entitystring; + + int numareas; + marea_t *areas; + + int numareaportals; + mareaportal_t *areaportals; + +#if USE_REF + int numfaces; + mface_t *faces; + + int numleaffaces; + mface_t **leaffaces; + + int numlightmapbytes; + byte *lightmap; + + int numvertices; + mvertex_t *vertices; + + int numedges; + medge_t *edges; + + int numsurfedges; + msurfedge_t *surfedges; +#endif + + char name[1]; +} bsp_t; + +bsp_t *BSP_Load( const char *name ); +void BSP_Free( bsp_t *bsp ); +const char *BSP_GetError( void ); + +#if USE_REF +mface_t *BSP_LightPoint( mnode_t *node, vec3_t start, vec3_t end, int *ps, int *pt ); +#endif +byte *BSP_ClusterVis( bsp_t *bsp, byte *mask, int cluster, int vis ); +mleaf_t *BSP_PointLeaf( mnode_t *node, vec3_t p ); +mmodel_t *BSP_InlineModel( bsp_t *bsp, const char *name ); + +void BSP_Init( void ); + + diff --git a/source/cl_console.c b/source/cl_console.c index 4e4ac72..5cdf159 100644 --- a/source/cl_console.c +++ b/source/cl_console.c @@ -578,19 +578,19 @@ Con_RegisterMedia ================ */ void Con_RegisterMedia( void ) { - con.charsetImage = ref.RegisterFont( con_font->string ); + con.charsetImage = R_RegisterFont( con_font->string ); if( !con.charsetImage && strcmp( con_font->string, "conchars" ) ) { Com_WPrintf( "Couldn't load console font: %s\n", con_font->string ); - con.charsetImage = ref.RegisterFont( "conchars" ); + con.charsetImage = R_RegisterFont( "conchars" ); } if( !con.charsetImage ) { Com_Error( ERR_FATAL, "Couldn't load pics/conchars.pcx" ); } - con.backImage = ref.RegisterPic( con_background->string ); + con.backImage = R_RegisterPic( con_background->string ); if( !con.backImage && strcmp( con_background->string, "conback" ) ) { Com_WPrintf( "Couldn't load console background: %s\n", con_background->string ); - con.backImage = ref.RegisterFont( "conback" ); + con.backImage = R_RegisterFont( "conback" ); } } @@ -652,14 +652,14 @@ void Con_DrawNotify( void ) { alpha = 1; // don't fade } - ref.SetColor( DRAW_COLOR_ALPHA, ( byte * )&alpha ); - ref.DrawString( CHAR_WIDTH, v, 0, con.linewidth, text, + R_SetColor( DRAW_COLOR_ALPHA, ( byte * )&alpha ); + R_DrawString( CHAR_WIDTH, v, 0, con.linewidth, text, con.charsetImage ); v += CHAR_HEIGHT; } - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); if( cls.key_dest & KEY_MESSAGE ) { if( con.chat == CHAT_TEAM ) { @@ -670,7 +670,7 @@ void Con_DrawNotify( void ) { skip = 5; } - ref.DrawString( CHAR_WIDTH, v, 0, MAX_STRING_CHARS, text, + R_DrawString( CHAR_WIDTH, v, 0, MAX_STRING_CHARS, text, con.charsetImage ); IF_Draw( &con.chatPrompt.inputLine, skip * CHAR_WIDTH, v, UI_DRAWCURSOR, con.charsetImage ); @@ -712,23 +712,23 @@ void Con_DrawSolidConsole( void ) { Cvar_ClampValue( con_alpha, 0, 1 ); alpha *= con_alpha->value; - ref.SetColor( DRAW_COLOR_ALPHA, ( byte * )&alpha ); + R_SetColor( DRAW_COLOR_ALPHA, ( byte * )&alpha ); } clip.left = 0; clip.top = 0; clip.right = 0; clip.bottom = 0; - ref.SetClipRect( DRAW_CLIP_TOP, &clip ); + R_SetClipRect( DRAW_CLIP_TOP, &clip ); // draw the background if( cls.state != ca_active || ( cls.key_dest & KEY_MENU ) || con_alpha->value ) { - ref.DrawStretchPic( 0, vislines - con.vidHeight, + R_DrawStretchPic( 0, vislines - con.vidHeight, con.vidWidth, con.vidHeight, con.backImage ); } #if 0 if( cls.state > ca_disconnected && cls.state < ca_active ) { - ref.DrawFill( 0, vislines, con.vidWidth, con.vidHeight - vislines, 0 ); + R_DrawFill( 0, vislines, con.vidWidth, con.vidHeight - vislines, 0 ); } #endif @@ -738,9 +738,9 @@ void Con_DrawSolidConsole( void ) { // draw arrows to show the buffer is backscrolled if( con.display != con.current ) { - ref.SetColor( DRAW_COLOR_RGBA, colorRed ); + R_SetColor( DRAW_COLOR_RGBA, colorRed ); for( i = 1; i < con.linewidth / 2; i += 4 ) { - ref.DrawChar( i * CHAR_WIDTH, y, 0, '^', con.charsetImage ); + R_DrawChar( i * CHAR_WIDTH, y, 0, '^', con.charsetImage ); } y -= CHAR_HEIGHT; @@ -748,7 +748,7 @@ void Con_DrawSolidConsole( void ) { } // draw from the bottom up - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); row = con.display; for( i = 0; i < rows; i++ ) { if( row < 0 ) @@ -758,7 +758,7 @@ void Con_DrawSolidConsole( void ) { text = con.text[row & CON_TOTALLINES_MASK]; - x = ref.DrawString( CHAR_WIDTH, y, 0, con.linewidth, text, con.charsetImage ); + x = R_DrawString( CHAR_WIDTH, y, 0, con.linewidth, text, con.charsetImage ); if( i < 2 ) { widths[i] = x; } @@ -808,7 +808,7 @@ void Con_DrawSolidConsole( void ) { // draw it y = vislines - 10; - ref.DrawString( CHAR_WIDTH, y, 0, CON_LINEWIDTH, buffer, con.charsetImage ); + R_DrawString( CHAR_WIDTH, y, 0, CON_LINEWIDTH, buffer, con.charsetImage ); } //ZOID @@ -829,9 +829,9 @@ void Con_DrawSolidConsole( void ) { i = 17; break; } - ref.SetColor( DRAW_COLOR_RGBA, colorYellow ); - ref.DrawChar( CHAR_WIDTH, y, 0, i, con.charsetImage ); - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_RGBA, colorYellow ); + R_DrawChar( CHAR_WIDTH, y, 0, i, con.charsetImage ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); // draw input line x = IF_Draw( &con.prompt.inputLine, 2 * CHAR_WIDTH, y, @@ -845,13 +845,13 @@ void Con_DrawSolidConsole( void ) { row++; } - ref.SetColor( DRAW_COLOR_RGBA, colorCyan ); + R_SetColor( DRAW_COLOR_RGBA, colorCyan ); // draw clock if( con_clock->integer ) { x = Com_Time_m( buffer, sizeof( buffer ) ) * CHAR_WIDTH; if( widths[row] + x + CHAR_WIDTH <= con.vidWidth ) { - ref.DrawString( con.vidWidth - CHAR_WIDTH - x, y - CHAR_HEIGHT, + R_DrawString( con.vidWidth - CHAR_WIDTH - x, y - CHAR_HEIGHT, UI_RIGHT, MAX_STRING_CHARS, buffer, con.charsetImage ); } } @@ -861,8 +861,8 @@ void Con_DrawSolidConsole( void ) { MAX_STRING_CHARS, APPLICATION " " VERSION, con.charsetImage ); // restore rendering parameters - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); - ref.SetClipRect( DRAW_CLIP_DISABLED, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetClipRect( DRAW_CLIP_DISABLED, NULL ); } //============================================================================= @@ -920,13 +920,13 @@ void Con_DrawConsole( void ) { Cvar_ClampValue( con_scale, 1, 9 ); con.scale = 1.0f / con_scale->value; - ref.SetScale( &con.scale ); + R_SetScale( &con.scale ); Con_CheckResize(); Con_DrawSolidConsole(); Con_DrawNotify(); - ref.SetScale( NULL ); + R_SetScale( NULL ); } diff --git a/source/cl_draw.c b/source/cl_draw.c index 68dd0be..0d56a6a 100644 --- a/source/cl_draw.c +++ b/source/cl_draw.c @@ -53,7 +53,7 @@ int SCR_DrawStringEx( int x, int y, int flags, size_t maxlen, x -= w; } - return ref.DrawString( x, y, flags, maxlen, s, font ); + return R_DrawString( x, y, flags, maxlen, s, font ); } @@ -163,7 +163,7 @@ static void SCR_LagDraw( int x, int y ) { v = LAG_HEIGHT; } - ref.DrawFill( x + LAG_WIDTH - i - 1, y + LAG_HEIGHT - v, 1, v, c ); + R_DrawFill( x + LAG_WIDTH - i - 1, y + LAG_HEIGHT - v, 1, v, c ); } } @@ -359,7 +359,7 @@ static void draw_objects( void ) { y += scr_hudHeight - CHAR_HEIGHT + 1; } if( !( obj->flags & UI_IGNORECOLOR ) ) { - ref.SetColor( DRAW_COLOR_RGBA, obj->color ); + R_SetColor( DRAW_COLOR_RGBA, obj->color ); } if( obj->macro ) { obj->macro->function( buffer, sizeof( buffer ) ); @@ -367,7 +367,7 @@ static void draw_objects( void ) { } else { SCR_DrawString( x, y, obj->flags, obj->cvar->string ); } - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); } } @@ -442,10 +442,10 @@ void SCR_DrawLoading( void ) { int i; qhandle_t h; - if( !cl.mapname[0] || !( h = ref.RegisterPic( va( "*levelshots/%s.jpg", cl.mapname ) ) ) ) { - ref.DrawFill( 0, 0, scr_glconfig.vidWidth, scr_glconfig.vidHeight, 0 ); + if( !cl.mapname[0] || !( h = R_RegisterPic( va( "*levelshots/%s.jpg", cl.mapname ) ) ) ) { + R_DrawFill( 0, 0, scr_glconfig.vidWidth, scr_glconfig.vidHeight, 0 ); } else { - ref.DrawStretchPic( 0, 0, scr_glconfig.vidWidth, scr_glconfig.vidHeight, h ); + R_DrawStretchPic( 0, 0, scr_glconfig.vidWidth, scr_glconfig.vidHeight, h ); } x = scr_glconfig.vidWidth / 2; @@ -458,9 +458,9 @@ void SCR_DrawLoading( void ) { s = cl.configstrings[CS_NAME]; if( *s ) { - ref.SetColor( DRAW_COLOR_RGB, colorYellow ); + R_SetColor( DRAW_COLOR_RGB, colorYellow ); SCR_DrawString( x, y, UI_CENTER|UI_DROPSHADOW, s ); - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); } y += 16; @@ -527,9 +527,9 @@ void SCR_DrawLoading( void ) { // draw message string if( cls.state < ca_connected && cls.messageString[0] ) { - ref.SetColor( DRAW_COLOR_RGB, colorRed ); + R_SetColor( DRAW_COLOR_RGB, colorRed ); SCR_DrawString( x, y + 16, UI_CENTER|UI_MULTILINE, cls.messageString ); - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); } } @@ -571,7 +571,7 @@ static void draw_crosshair( void ) { x = ( scr_hudWidth - crosshair_width ) / 2; y = ( scr_hudHeight - crosshair_height ) / 2; - ref.DrawPic( x, y, crosshair_pic ); + R_DrawPic( x, y, crosshair_pic ); } static void draw_following( void ) { @@ -596,7 +596,7 @@ static void draw_following( void ) { x = ( scr_hudWidth - strlen( string ) * CHAR_WIDTH ) / 2; - ref.DrawString( x, 48, 0, MAX_STRING_CHARS, string, scr_font ); + R_DrawString( x, 48, 0, MAX_STRING_CHARS, string, scr_font ); } static void draw_turtle( void ) { @@ -635,10 +635,10 @@ static void SCR_DrawStats( void ) { for( i = 0; i < j; i++ ) { Com_sprintf( buffer, sizeof( buffer ), "%2d: %d", i, cl.frame.ps.stats[i] ); if( cl.oldframe.ps.stats[i] != cl.frame.ps.stats[i] ) { - ref.SetColor( DRAW_COLOR_RGBA, colorRed ); + R_SetColor( DRAW_COLOR_RGBA, colorRed ); } - ref.DrawString( x, y, 0, MAX_STRING_CHARS, buffer, scr_font ); - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_DrawString( x, y, 0, MAX_STRING_CHARS, buffer, scr_font ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); y += CHAR_HEIGHT; } } @@ -660,13 +660,13 @@ static void SCR_DrawPmove( void ) { if( i > PM_FREEZE ) { i = PM_FREEZE; } - ref.DrawString( x, y, 0, MAX_STRING_CHARS, types[i], scr_font ); + R_DrawString( x, y, 0, MAX_STRING_CHARS, types[i], scr_font ); y += CHAR_HEIGHT; j = cl.frame.ps.pmove.pm_flags; for( i = 0; i < 8; i++ ) { if( j & ( 1 << i ) ) { - x = ref.DrawString( x, y, 0, MAX_STRING_CHARS, flags[i], scr_font ); + x = R_DrawString( x, y, 0, MAX_STRING_CHARS, flags[i], scr_font ); x += CHAR_WIDTH; } } @@ -692,17 +692,17 @@ void SCR_Draw2D( void ) { rc.right = scr_hudWidth; rc.bottom = scr_hudHeight; - ref.SetClipRect( DRAW_CLIP_MASK, &rc ); + R_SetClipRect( DRAW_CLIP_MASK, &rc ); } - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); if( crosshair->integer ) { draw_crosshair(); } Cvar_ClampValue( scr_alpha, 0, 1 ); - ref.SetColor( DRAW_COLOR_ALPHA, ( byte * )&scr_alpha->value ); + R_SetColor( DRAW_COLOR_ALPHA, ( byte * )&scr_alpha->value ); if( scr_draw2d->integer > 1 ) { SCR_ExecuteLayoutString( cl.configstrings[CS_STATUSBAR] ); @@ -737,7 +737,7 @@ void SCR_Draw2D( void ) { // draw ping graph if( scr_lag_draw->integer ) { if( scr_lag_draw->integer > 1 ) { - ref.DrawFill( x, y, LAG_WIDTH, LAG_HEIGHT, 4 ); + R_DrawFill( x, y, LAG_WIDTH, LAG_HEIGHT, 4 ); } SCR_LagDraw( x, y ); } @@ -745,13 +745,13 @@ void SCR_Draw2D( void ) { // draw phone jack if( cls.netchan && cls.netchan->outgoing_sequence - cls.netchan->incoming_acknowledged >= CMD_BACKUP ) { if( ( cls.realtime >> 8 ) & 3 ) { - ref.DrawStretchPic( x, y, LAG_WIDTH, LAG_HEIGHT, scr_net ); + R_DrawStretchPic( x, y, LAG_WIDTH, LAG_HEIGHT, scr_net ); } } draw_objects(); - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); if( scr_showturtle->integer && cl.frameflags ) { draw_turtle(); @@ -767,7 +767,7 @@ void SCR_Draw2D( void ) { SCR_DrawPause(); if( scr_glconfig.renderer == GL_RENDERER_SOFTWARE ) { - ref.SetClipRect( DRAW_CLIP_DISABLED, NULL ); + R_SetClipRect( DRAW_CLIP_DISABLED, NULL ); } } diff --git a/source/cl_ents.c b/source/cl_ents.c index 7f63640..c9ae431 100644 --- a/source/cl_ents.c +++ b/source/cl_ents.c @@ -294,7 +294,7 @@ static void CL_AddPacketEntities( void ) { char buffer[MAX_QPATH]; Q_concat( buffer, sizeof( buffer ), "players/", ci->model_name, "/disguise.pcx", NULL ); - ent.skin = ref.RegisterSkin( buffer ); + ent.skin = R_RegisterSkin( buffer ); } //PGM //============ @@ -651,43 +651,6 @@ skip: } } - -#if 0 -static cvar_t *test_model; -static cvar_t *test_pitch; -static cvar_t *test_yaw; - -static void CL_AddTestModel( void ) { - entity_t test; - - if( !test_model ) { - test_model = Cvar_Get( "test_model", "", 0 ); - test_pitch = Cvar_Get( "test_pitch", "0", 0 ); - test_yaw = Cvar_Get( "test_yaw", "0", 0 ); - } - if( !test_model->string[0] ) { - return; - } - - memset( &test, 0, sizeof( test ) ); - test.model = ref.RegisterModel( test_model->string ); - if( !test.model ) { - return; - } - test.frame = 1; - - VectorMA( cl.refdef.vieworg, 160, cl.v_forward, test.origin ); -// VectorCopy( cl.refdef.viewangles, test.angles ); - test.angles[YAW]+=test_yaw->value; - test.angles[PITCH]+=test_pitch->value; - test.flags = RF_MINLIGHT | RF_DEPTHHACK; - - VectorCopy( test.origin, test.oldorigin ); // don't lerp at all - V_AddEntity( &test ); -} -#endif - - /* ============== CL_AddViewWeapon @@ -784,7 +747,7 @@ static void CL_SetupThirdPersionView( void ) { VectorMA( cl.refdef.vieworg, -range * rscale, cl.v_right, cl.refdef.vieworg ); CM_BoxTrace( &trace, cl.playerEntityOrigin, cl.refdef.vieworg, - mins, maxs, cl.cm.cache->nodes, MASK_SOLID ); + mins, maxs, cl.bsp->nodes, MASK_SOLID ); if( trace.fraction != 1.0f ) { VectorCopy( trace.endpos, cl.refdef.vieworg ); } @@ -962,7 +925,6 @@ static void CL_CalcViewValues( void ) { // add the weapon CL_AddViewWeapon( ps, ops ); - //CL_AddTestModel(); cl.thirdPersonView = qfalse; } @@ -997,7 +959,7 @@ Called to get the sound spatialization origin */ void CL_GetEntitySoundOrigin( int entnum, vec3_t org ) { centity_t *ent; - cmodel_t *cm; + mmodel_t *cm; vec3_t mid; if( entnum < 0 || entnum >= MAX_EDICTS ) { diff --git a/source/cl_input.c b/source/cl_input.c index 007edcf..d659de7 100644 --- a/source/cl_input.c +++ b/source/cl_input.c @@ -142,7 +142,9 @@ void IN_MouseEvent( int x, int y ) { input.api.Grab( IN_SHOW ); input.hideCursor = 2; } +#if USE_UI UI_MouseEvent( x, y ); +#endif } /* diff --git a/source/cl_keys.c b/source/cl_keys.c index 1a403ed..4329c26 100644 --- a/source/cl_keys.c +++ b/source/cl_keys.c @@ -725,19 +725,28 @@ void Key_Event( unsigned key, qboolean down, unsigned time ) { if( cls.key_dest & KEY_CONSOLE ) { if( cls.state == ca_disconnected && !( cls.key_dest & KEY_MENU ) ) { +#if USE_UI UI_OpenMenu( UIMENU_MAIN_FORCE ); +#endif } else { Con_Close(); } - } else if( cls.key_dest & KEY_MENU ) { + } +#if USE_UI + else if( cls.key_dest & KEY_MENU ) { UI_Keydown( key ); - } else if( cls.key_dest & KEY_MESSAGE ) { + } +#endif + else if( cls.key_dest & KEY_MESSAGE ) { Key_Message( key ); - } else if( cls.state == ca_active ) { + } +#if USE_UI + else if( cls.state == ca_active ) { UI_OpenMenu( UIMENU_INGAME ); } else { UI_OpenMenu( UIMENU_MAIN_FORCE ); } +#endif return; } @@ -815,9 +824,13 @@ void Key_Event( unsigned key, qboolean down, unsigned time ) { if( cls.key_dest & KEY_CONSOLE ) { Key_Console( key ); - } else if( cls.key_dest & KEY_MENU ) { + } +#if USE_UI + else if( cls.key_dest & KEY_MENU ) { UI_Keydown( key ); - } else if( cls.key_dest & KEY_MESSAGE ) { + } +#endif + else if( cls.key_dest & KEY_MESSAGE ) { Key_Message( key ); } @@ -886,9 +899,13 @@ void Key_Event( unsigned key, qboolean down, unsigned time ) { if( cls.key_dest & KEY_CONSOLE ) { Char_Console( key ); - } else if( cls.key_dest & KEY_MENU ) { + } +#if USE_UI + else if( cls.key_dest & KEY_MENU ) { UI_CharEvent( key ); - } else if( cls.key_dest & KEY_MESSAGE ) { + } +#endif + else if( cls.key_dest & KEY_MESSAGE ) { Char_Message( key ); } @@ -910,9 +927,13 @@ void Key_CharEvent( int key ) { if( cls.key_dest & KEY_CONSOLE ) { Char_Console( key ); - } else if( cls.key_dest & KEY_MENU ) { + } +#if USE_UI + else if( cls.key_dest & KEY_MENU ) { UI_CharEvent( key ); - } else if( cls.key_dest & KEY_MESSAGE ) { + } +#endif + else if( cls.key_dest & KEY_MESSAGE ) { Char_Message( key ); } } diff --git a/source/cl_local.h b/source/cl_local.h index e5a15d2..8f9605c 100644 --- a/source/cl_local.h +++ b/source/cl_local.h @@ -21,12 +21,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "com_local.h" #include "q_list.h" +#include "files.h" +#include "sys_public.h" +#include "pmove.h" +#include "bsp.h" +#include "cmodel.h" +#include "protocol.h" +#include "q_msg.h" +#include "net_sock.h" +#include "net_chan.h" #include "q_field.h" #include "ref_public.h" #include "key_public.h" #include "snd_public.h" #include "cl_public.h" #include "ui_public.h" +#include "sv_public.h" #if USE_ZLIB #include <zlib.h> #endif @@ -198,10 +208,10 @@ typedef struct client_state_s { // // locally derived information from server state // - cm_t cm; + bsp_t *bsp; qhandle_t model_draw[MAX_MODELS]; - cmodel_t *model_clip[MAX_MODELS]; + mmodel_t *model_clip[MAX_MODELS]; qhandle_t sound_precache[MAX_SOUNDS]; qhandle_t image_precache[MAX_IMAGES]; @@ -228,6 +238,17 @@ of server connections #define CONNECT_DELAY 3000 +typedef enum { + ca_uninitialized, + ca_disconnected, // not talking to a server + ca_challenging, // sending getchallenge packets to the server + ca_connecting, // sending connect packets to the server + ca_connected, // netchan_t established, waiting for svc_serverdata + ca_loading, // loading level data + ca_precached, // loaded level data, waiting for svc_frame + ca_active // game views should be displayed +} connstate_t; + typedef struct client_static_s { connstate_t state; keydest_t key_dest; @@ -643,6 +664,7 @@ void Char_Message( int key ); // void CL_InitRefresh( void ); void CL_ShutdownRefresh( void ); +void CL_RunRefresh( void ); // // cl_ui.c diff --git a/source/cl_locs.c b/source/cl_locs.c index cb5b8c9..8b97ba9 100644 --- a/source/cl_locs.c +++ b/source/cl_locs.c @@ -149,7 +149,7 @@ static location_t *LOC_FindClosest( vec3_t pos ) { if( loc_trace->integer ) { CM_BoxTrace( &trace, pos, loc->origin, vec3_origin, vec3_origin, - cl.cm.cache->nodes, MASK_SOLID ); + cl.bsp->nodes, MASK_SOLID ); if( trace.fraction != 1.0f ) { continue; } @@ -180,8 +180,8 @@ void LOC_AddLocationsToScene( void ) { } memset( &ent, 0, sizeof( ent ) ); - ent.model = ref.RegisterModel( "models/items/c_head/tris.md2" ); - ent.skin = ref.RegisterSkin( "models/items/c_head/skin.pcx" ); + ent.model = R_RegisterModel( "models/items/c_head/tris.md2" ); + ent.skin = R_RegisterSkin( "models/items/c_head/skin.pcx" ); nearest = LOC_FindClosest( cl.playerEntityOrigin ); if( !nearest ) { @@ -248,7 +248,7 @@ static size_t LOC_There_m( char *buffer, size_t size ) { VectorMA( cl.playerEntityOrigin, 8192, cl.v_forward, pos ); CM_BoxTrace( &trace, cl.playerEntityOrigin, pos, vec3_origin, vec3_origin, - cl.cm.cache->nodes, MASK_SOLID ); + cl.bsp->nodes, MASK_SOLID ); loc = LOC_FindClosest( trace.endpos ); if( loc ) { diff --git a/source/cl_main.c b/source/cl_main.c index 2a6b22a..39864e8 100644 --- a/source/cl_main.c +++ b/source/cl_main.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // cl_main.c -- client main loop #include "cl_local.h" +#include "d_md2.h" cvar_t *adr0; cvar_t *adr1; @@ -343,7 +344,9 @@ static void CL_CheckForResend( void ) { cls.passive = qfalse; Con_Close(); +#if USE_UI UI_OpenMenu( UIMENU_NONE ); +#endif } // resend if we haven't gotten a reply yet @@ -481,7 +484,9 @@ usage: Cvar_Set( "timedemo", "0" ); Con_Close(); +#if USE_UI UI_OpenMenu( UIMENU_NONE ); +#endif } static void CL_PassiveConnect_f( void ) { @@ -583,7 +588,7 @@ void CL_ClearState( void ) { LOC_FreeLocations(); // wipe the entire cl structure - CM_FreeMap( &cl.cm ); + BSP_Free( cl.bsp ); memset( &cl, 0, sizeof( cl ) ); memset( &cl_entities, 0, sizeof( cl_entities ) ); @@ -606,9 +611,6 @@ void CL_Disconnect( comErrorType_t type, const char *text ) { EXEC_TRIGGER( cl_disconnectcmd ); } - if( cls.ref_initialized ) - ref.CinematicSetPalette( NULL ); - cls.connect_time = 0; cls.connect_count = 0; cls.passive = qfalse; @@ -660,7 +662,9 @@ void CL_Disconnect( comErrorType_t type, const char *text ) { cls.messageString[ 0 ] = 0; cls.userinfo_modified = 0; +#if USE_UI UI_ErrorMenu( type, text ); +#endif } /* @@ -872,11 +876,13 @@ static void CL_ParsePrintMessage( void ) { break; case REQ_INFO: break; +#if USE_UI case REQ_PING: if( CL_ServerStatusResponse( string, &net_from, &serverStatus ) ) { UI_AddToServerList( &serverStatus ); } break; +#endif case REQ_RCON: Com_Printf( "%s", string ); CL_AddRequest( &net_from, REQ_RCON ); @@ -1411,7 +1417,7 @@ static void CL_ConnectionlessPacket( void ) { CL_PacketEvent ================= */ -void CL_PacketEvent( neterr_t ret ) { +static void CL_PacketEvent( neterr_t ret ) { // // remote command packet // @@ -1573,7 +1579,7 @@ static void CL_RegisterModels( void ) { break; } if( name[0] == '*' ) - cl.model_clip[i] = CM_InlineModel( &cl.cm, name ); + cl.model_clip[i] = BSP_InlineModel( cl.bsp, name ); else cl.model_clip[i] = NULL; } @@ -1603,9 +1609,8 @@ static void *precache_model; // used for skin checking in alias models static const char env_suf[6][3] = { "rt", "bk", "lf", "ft", "up", "dn" }; void CL_RequestNextDownload ( void ) { - unsigned map_checksum; // for detecting cheater maps char fn[ MAX_QPATH ]; - dmdl_t *pheader; + dmd2header_t *pheader; size_t length; if ( cls.state != ca_connected && cls.state != ca_loading ) @@ -1648,10 +1653,10 @@ void CL_RequestNextDownload ( void ) { precache_check++; continue; // couldn't load it } - pheader = ( dmdl_t * ) precache_model; + pheader = ( dmd2header_t * ) precache_model; if( length < sizeof( *pheader ) || - LittleLong( pheader->ident ) != IDALIASHEADER || - LittleLong( pheader->version ) != ALIAS_VERSION ) + LittleLong( pheader->ident ) != MD2_IDENT || + LittleLong( pheader->version ) != MD2_VERSION ) { // not an alias model FS_FreeFile( precache_model ); @@ -1662,8 +1667,8 @@ void CL_RequestNextDownload ( void ) { } num_skins = LittleLong( pheader->num_skins ); ofs_skins = LittleLong( pheader->ofs_skins ); - end_skins = ofs_skins + num_skins * MAX_SKINNAME; - if( num_skins > MAX_MD2SKINS || end_skins < ofs_skins || end_skins > length ) { + end_skins = ofs_skins + num_skins * MD2_MAX_SKINNAME; + if( num_skins > MD2_MAX_SKINS || end_skins < ofs_skins || end_skins > length ) { // bad alias model FS_FreeFile( precache_model ); precache_model = NULL; @@ -1673,13 +1678,13 @@ void CL_RequestNextDownload ( void ) { } } - pheader = ( dmdl_t * ) precache_model; + pheader = ( dmd2header_t * ) precache_model; num_skins = LittleLong( pheader->num_skins ); ofs_skins = LittleLong( pheader->ofs_skins ); while ( precache_model_skin - 1 < num_skins ) { Q_strncpyz( fn, ( char * )precache_model + ofs_skins + - ( precache_model_skin - 1 ) * MAX_SKINNAME, sizeof( fn ) ); + ( precache_model_skin - 1 ) * MD2_MAX_SKINNAME, sizeof( fn ) ); if ( !CL_CheckOrDownloadFile( fn ) ) { precache_model_skin++; return; // started a download @@ -1808,12 +1813,15 @@ void CL_RequestNextDownload ( void ) { if ( precache_check == ENV_CNT ) { precache_check = ENV_CNT + 1; - CM_LoadMap ( &cl.cm, cl.configstrings[ CS_MODELS + 1 ], CM_LOAD_CLIENT, &map_checksum ); + if( ( cl.bsp = BSP_Load( cl.configstrings[ CS_MODELS + 1 ] ) ) == NULL ) { + Com_Error( ERR_DROP, "Couldn't load %s: %s", + cl.configstrings[ CS_MODELS + 1 ], BSP_GetError() ); + } #if USE_MAPCHECKSUM - if ( map_checksum != atoi( cl.configstrings[ CS_MAPCHECKSUM ] ) ) { + if ( cl.bsp->checksum != atoi( cl.configstrings[ CS_MAPCHECKSUM ] ) ) { Com_Error ( ERR_DROP, "Local map version differs from server: %i != '%s'\n", - map_checksum, cl.configstrings[ CS_MAPCHECKSUM ] ); + cl.bsp->checksum, cl.configstrings[ CS_MAPCHECKSUM ] ); return; } #endif @@ -1846,8 +1854,8 @@ void CL_RequestNextDownload ( void ) { // confirm existance of textures, download any that don't exist if ( precache_check == TEXTURE_CNT + 1 ) { if ( allow_download->integer && allow_download_maps->integer ) { - while ( precache_tex < cl.cm.cache->numtexinfo ) { - char *texname = cl.cm.cache->surfaces[ precache_tex++ ].rname; + while ( precache_tex < cl.bsp->numtexinfo ) { + char *texname = cl.bsp->texinfo[ precache_tex++ ].name; // Also check if 32bit images are present Q_concat( fn, sizeof( fn ), "textures/", texname, ".jpg", NULL ); @@ -1908,8 +1916,10 @@ static void CL_Precache_f( void ) { //Yet another hack to let old demos work //the old precache sequence if( cls.demo.playback ) { - CM_LoadMap( &cl.cm, cl.configstrings[ CS_MODELS + 1 ], - CM_LOAD_CLIENT, NULL ); + if( ( cl.bsp = BSP_Load( cl.configstrings[ CS_MODELS + 1 ] ) ) == NULL ) { + Com_Error( ERR_DROP, "Couldn't load %s: %s", + cl.configstrings[ CS_MODELS + 1 ], BSP_GetError() ); + } CL_RegisterModels(); CL_PrepRefresh(); CL_LoadState( LOAD_SOUNDS ); @@ -2194,39 +2204,46 @@ Flush caches and restart the VFS. void CL_RestartFilesystem( void ) { int cls_state; - if ( !cl_running->integer ) { + if( !cl_running->integer ) { FS_Restart(); return; } // temporary switch to loading state cls_state = cls.state; - if ( cls.state >= ca_precached ) { + if( cls.state >= ca_precached ) { cls.state = ca_loading; } +#if USE_UI UI_Shutdown(); +#endif S_StopAllSounds(); S_FreeAllSounds(); if( cls.ref_initialized ) { - ref.Shutdown( qfalse ); + R_Shutdown( qfalse ); FS_Restart(); - ref.Init( qfalse ); + R_Init( qfalse ); SCR_RegisterMedia(); Con_RegisterMedia(); +#if USE_UI UI_Init(); +#endif } else { FS_Restart(); } - if ( cls_state == ca_disconnected ) { +#if USE_UI + if( cls_state == ca_disconnected ) { UI_OpenMenu( UIMENU_MAIN ); - } else if ( cls_state >= ca_loading ) { + } else +#endif + if( cls_state >= ca_loading ) { CL_LoadState( LOAD_MAP ); CL_RegisterModels(); CL_PrepRefresh(); @@ -2237,7 +2254,6 @@ void CL_RestartFilesystem( void ) { // switch back to original state cls.state = cls_state; - } /* @@ -2265,9 +2281,12 @@ static void CL_RestartRefresh_f( void ) { CL_InitRefresh(); IN_Init(); - if ( cls_state == ca_disconnected ) { +#if USE_UI + if( cls_state == ca_disconnected ) { UI_OpenMenu( UIMENU_MAIN ); - } else if ( cls_state >= ca_loading ) { + } else +#endif + if( cls_state >= ca_loading ) { CL_LoadState( LOAD_MAP ); CL_PrepRefresh(); CL_LoadState( LOAD_FINISH ); @@ -2803,6 +2822,40 @@ void CL_Frame( int msec ) { main_extra = 0; } +/* +============ +CL_ProcessEvents +============ +*/ +void CL_ProcessEvents( void ) { + neterr_t ret; + + if( !cl_running->integer ) { + return; + } + + CL_RunRefresh(); + + IN_Frame(); + + memset( &net_from, 0, sizeof( net_from ) ); + net_from.type = NA_LOOPBACK; + + // process loopback packets + while( NET_GetLoopPacket( NS_CLIENT ) ) { + CL_PacketEvent( NET_OK ); + } + + do { + ret = NET_GetPacket( NS_CLIENT ); + if( ret == NET_AGAIN ) { + break; + } + CL_PacketEvent( ret ); + } while( ret == NET_OK ); + +} + //============================================================================ /* @@ -2841,7 +2894,9 @@ void CL_Init( void ) { } #endif +#if USE_UI UI_OpenMenu( UIMENU_MAIN ); +#endif Con_PostInit(); Con_RunConsole(); diff --git a/source/cl_null.c b/source/cl_null.c index d49b42f..875c584 100644 --- a/source/cl_null.c +++ b/source/cl_null.c @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // for pure dedicated servers #include "com_local.h" +#include "files.h" cvar_t *cl_paused; @@ -57,9 +58,6 @@ qboolean CL_CheatsOK( void ) { return qtrue; } -void CL_PacketEvent( neterr_t ret ) { -} - void CL_UpdateUserinfo( cvar_t *var, cvarSetSource_t source ) { } diff --git a/source/cl_parse.c b/source/cl_parse.c index 28d52bb..e67500c 100644 --- a/source/cl_parse.c +++ b/source/cl_parse.c @@ -704,16 +704,16 @@ static void CL_ConfigString( int index, const char *string, size_t length ) { return; } - if (index >= CS_MODELS && index < CS_MODELS+MAX_MODELS) { - cl.model_draw[index-CS_MODELS] = ref.RegisterModel (string); + if (index >= CS_MODELS+2 && index < CS_MODELS+MAX_MODELS) { + cl.model_draw[index-CS_MODELS] = R_RegisterModel (string); if (*string == '*') - cl.model_clip[index-CS_MODELS] = CM_InlineModel (&cl.cm, string); + cl.model_clip[index-CS_MODELS] = BSP_InlineModel (cl.bsp, string); else - cl.model_clip[index-CS_MODELS] = 0; + cl.model_clip[index-CS_MODELS] = NULL; } else if (index >= CS_SOUNDS && index < CS_SOUNDS+MAX_MODELS) { cl.sound_precache[index-CS_SOUNDS] = S_RegisterSound (string); } else if (index >= CS_IMAGES && index < CS_IMAGES+MAX_MODELS) { - cl.image_precache[index-CS_IMAGES] = ref.RegisterPic (string); + cl.image_precache[index-CS_IMAGES] = R_RegisterPic (string); } else if (index >= CS_PLAYERSKINS && index < CS_PLAYERSKINS+MAX_CLIENTS) { CL_LoadClientinfo( &cl.clientinfo[index - CS_PLAYERSKINS], string ); } else if( index == CS_AIRACCEL && !cl.pmp.qwmod ) { @@ -974,24 +974,24 @@ void CL_LoadClientinfo( clientinfo_t *ci, const char *s ) { // model file Q_concat( model_filename, sizeof( model_filename ), "players/", model_name, "/tris.md2", NULL ); - ci->model = ref.RegisterModel( model_filename ); + ci->model = R_RegisterModel( model_filename ); if( !ci->model && Q_stricmp( model_name, "male" ) ) { strcpy( model_name, "male" ); strcpy( model_filename, "players/male/tris.md2" ); - ci->model = ref.RegisterModel( model_filename ); + ci->model = R_RegisterModel( model_filename ); } // skin file Q_concat( skin_filename, sizeof( skin_filename ), "players/", model_name, "/", skin_name, ".pcx", NULL ); - ci->skin = ref.RegisterSkin( skin_filename ); + ci->skin = R_RegisterSkin( skin_filename ); // if we don't have the skin and the model was female, // see if athena skin exists if( !ci->skin && !Q_stricmp( model_name, "female" ) ) { strcpy( skin_name, "athena" ); strcpy( skin_filename, "players/female/athena.pcx" ); - ci->skin = ref.RegisterSkin( skin_filename ); + ci->skin = R_RegisterSkin( skin_filename ); } // if we don't have the skin and the model wasn't male, @@ -1000,12 +1000,12 @@ void CL_LoadClientinfo( clientinfo_t *ci, const char *s ) { // change model to male strcpy( model_name, "male" ); strcpy( model_filename, "players/male/tris.md2" ); - ci->model = ref.RegisterModel( model_filename ); + ci->model = R_RegisterModel( model_filename ); // see if the skin exists for the male model Q_concat( skin_filename, sizeof( skin_filename ), "players/male/", skin_name, ".pcx", NULL ); - ci->skin = ref.RegisterSkin( skin_filename ); + ci->skin = R_RegisterSkin( skin_filename ); } // if we still don't have a skin, it means that the male model @@ -1014,26 +1014,26 @@ void CL_LoadClientinfo( clientinfo_t *ci, const char *s ) { // see if the skin exists for the male model strcpy( skin_name, "grunt" ); strcpy( skin_filename, "players/male/grunt.pcx" ); - ci->skin = ref.RegisterSkin( skin_filename ); + ci->skin = R_RegisterSkin( skin_filename ); } // weapon file for( i = 0; i < cl.numWeaponModels; i++ ) { Q_concat( weapon_filename, sizeof( weapon_filename ), "players/", model_name, "/", cl.weaponModels[i], NULL ); - ci->weaponmodel[i] = ref.RegisterModel( weapon_filename ); + ci->weaponmodel[i] = R_RegisterModel( weapon_filename ); if( !ci->weaponmodel[i] && Q_stricmp( model_name, "male" ) ) { // try male Q_concat( weapon_filename, sizeof( weapon_filename ), "players/male/", cl.weaponModels[i], NULL ); - ci->weaponmodel[i] = ref.RegisterModel( weapon_filename ); + ci->weaponmodel[i] = R_RegisterModel( weapon_filename ); } } // icon file Q_concat( icon_filename, sizeof( icon_filename ), "/players/", model_name, "/", skin_name, "_i.pcx", NULL ); - ci->icon = ref.RegisterPic( icon_filename ); + ci->icon = R_RegisterPic( icon_filename ); strcpy( ci->model_name, model_name ); strcpy( ci->skin_name, skin_name ); diff --git a/source/cl_pred.c b/source/cl_pred.c index edf43dc..05edcb3 100644 --- a/source/cl_pred.c +++ b/source/cl_pred.c @@ -87,9 +87,9 @@ CL_ClipMoveToEntities static void CL_ClipMoveToEntities( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, trace_t *tr ) { int i; trace_t trace; - cnode_t *headnode; + mnode_t *headnode; centity_t *ent; - cmodel_t *cmodel; + mmodel_t *cmodel; for( i = 0; i < cl.numSolidEntities; i++ ) { ent = cl.solidEntities[i]; @@ -125,7 +125,7 @@ static trace_t CL_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) { trace_t t; // check against world - CM_BoxTrace (&t, start, end, mins, maxs, cl.cm.cache->nodes, MASK_PLAYERSOLID); + CM_BoxTrace (&t, start, end, mins, maxs, cl.bsp->nodes, MASK_PLAYERSOLID); if (t.fraction < 1.0) t.ent = (struct edict_s *)1; @@ -138,10 +138,10 @@ static trace_t CL_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) { static int CL_PointContents (vec3_t point) { int i; centity_t *ent; - cmodel_t *cmodel; + mmodel_t *cmodel; int contents; - contents = CM_PointContents (point, cl.cm.cache->nodes); + contents = CM_PointContents (point, cl.bsp->nodes); for (i=0 ; i<cl.numSolidEntities ; i++) { ent = cl.solidEntities[i]; diff --git a/source/cl_public.h b/source/cl_public.h index 0f43f16..b6d9dac 100644 --- a/source/cl_public.h +++ b/source/cl_public.h @@ -22,17 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAX_DEMOINFO_CLIENTS 20 #define MAX_STATUS_PLAYERS 64 -typedef enum { - ca_uninitialized, - ca_disconnected, // not talking to a server - ca_challenging, // sending getchallenge packets to the server - ca_connecting, // sending connect packets to the server - ca_connected, // netchan_t established, waiting for svc_serverdata - ca_loading, // loading level data - ca_precached, // loaded level data, waiting for svc_frame - ca_active // game views should be displayed -} connstate_t; - typedef struct { char name[MAX_CLIENT_NAME]; int ping; @@ -52,6 +41,45 @@ typedef struct { char pov[MAX_CLIENT_NAME]; } demoInfo_t; +typedef enum { + ACT_MINIMIZED, + ACT_RESTORED, + ACT_ACTIVATED +} active_t; +void CL_ProcessEvents( void ); +void CL_Init (void); +void CL_Disconnect( comErrorType_t type, const char *text ); +void CL_Shutdown (void); +void CL_Frame (int msec); +void CL_LocalConnect( void ); +void CL_RestartFilesystem( void ); +void CL_Activate( active_t active ); +void CL_UpdateUserinfo( cvar_t *var, cvarSetSource_t source ); qboolean CL_SendStatusRequest( char *buffer, size_t size ); demoInfo_t *CL_GetDemoInfo( const char *path, demoInfo_t *info ); + +void Con_Print( const char *text ); +void Con_Printf( const char *fmt, ... ); +void Con_Close( void ); + +// this is in the client code, but can be used for debugging from server +void SCR_DebugGraph (float value, int color); +void SCR_BeginLoadingPlaque (void); +void SCR_ModeChanged( void ); +void SCR_UpdateScreen( void ); + +void IN_Frame( void ); +void IN_Activate( void ); +void IN_MouseEvent( int x, int y ); +void IN_WarpMouse( int x, int y ); + +void Key_Init( void ); +void Key_Event( unsigned key, qboolean down, unsigned time ); +void Key_CharEvent( int key ); +void Key_WriteBindings( fileHandle_t f ); + +char *VID_GetClipboardData( void ); +void VID_SetClipboardData( const char *data ); +void VID_FatalShutdown( void ); + diff --git a/source/cl_ref.c b/source/cl_ref.c index 7c130b7..5c15700 100644 --- a/source/cl_ref.c +++ b/source/cl_ref.c @@ -28,9 +28,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "in_public.h" #include "vid_local.h" -// Structure containing functions exported from refresh DLL -refAPI_t ref; - // Console variables that we need to access from this module cvar_t *vid_ref; // Name of Refresh DLL loaded cvar_t *vid_geometry; @@ -41,18 +38,9 @@ cvar_t *_vid_fullscreen; #define MODE_GEOMETRY 1 #define MODE_FULLSCREEN 2 #define MODE_MODELIST 4 -#define MODE_REFRESH 8 static int mode_changed; - -#ifdef REF_HARD_LINKED -qboolean Ref_APISetupCallback( api_type_t type, void *api ); -#else -// Global variables used internally by this module -static void *reflib_library; // Handle to refresh DLL -#endif - /* ========================================================================== @@ -188,141 +176,11 @@ LOADING / SHUTDOWN */ /* -============== -CL_FreeRefresh -============== -*/ -static void CL_FreeRefresh( void ) { -#ifndef REF_HARD_LINKED - Sys_FreeLibrary( reflib_library ); - reflib_library = NULL; -#endif - memset( &ref, 0, sizeof( ref ) ); - cls.ref_initialized = qfalse; -} - -#ifndef REF_HARD_LINKED - -/* -============== -CL_RefSetupCallback -============== -*/ -static qboolean CL_RefSetupCallback( api_type_t type, void *api ) { - switch( type ) { - case API_CMD: - Cmd_FillAPI( ( cmdAPI_t * )api ); - break; - case API_CVAR: - Cvar_FillAPI( ( cvarAPI_t * )api ); - break; - case API_FS: - FS_FillAPI( ( fsAPI_t * )api ); - break; - case API_COMMON: - Com_FillAPI( ( commonAPI_t * )api ); - break; - case API_SYSTEM: - Sys_FillAPI( ( sysAPI_t * )api ); - break; - case API_VIDEO_SOFTWARE: - VID_FillSWAPI( ( videoAPI_t * )api ); - break; - case API_VIDEO_OPENGL: - VID_FillGLAPI( ( videoAPI_t * )api ); - break; - default: - Com_Error( ERR_FATAL, "CL_RefSetupCallback: bad api type" ); - } - - return qtrue; -} - -#endif - -/* -============== -CL_LoadRefresh -============== -*/ -static qboolean CL_LoadRefresh( const char *name ) { -#ifndef REF_HARD_LINKED - char path[MAX_OSPATH]; - moduleEntry_t entry; - moduleInfo_t info; - moduleCapability_t caps; - APISetupCallback_t callback; -#endif - - if( cls.ref_initialized ) { - ref.Shutdown( qtrue ); - CL_FreeRefresh(); - } - - Com_Printf( "------- Loading %s -------\n", name ); - -#ifdef REF_HARD_LINKED -#ifdef SOFTWARE_RENDERER - VID_FillSWAPI( &video ); -#else - VID_FillGLAPI( &video ); -#endif - - Ref_APISetupCallback( API_REFRESH, &ref ); -#else - - Q_concat( path, sizeof( path ), sys_refdir->string, PATH_SEP_STRING, - name, LIBSUFFIX, NULL ); - entry = Sys_LoadLibrary( path, "moduleEntry", &reflib_library ); - if( !entry ) { - Com_WPrintf( "Couldn't load %s\n", name ); - return qfalse; - } - - entry( MQ_GETINFO, &info ); - if( info.api_version != MODULES_APIVERSION ) { - Com_WPrintf( "%s has incompatible api_version: %i, should be %i\n", - name, info.api_version, MODULES_APIVERSION ); - goto fail; - } - - caps = ( moduleCapability_t )entry( MQ_GETCAPS, NULL ); - if( !( caps & MCP_REFRESH ) ) { - Com_WPrintf( "%s doesn't have REFRESH capability\n", name ); - goto fail; - } - - callback = ( APISetupCallback_t )entry( MQ_SETUPAPI, ( void * )CL_RefSetupCallback ); - if( !callback ) { - Com_WPrintf( "%s returned NULL callback\n", name ); - goto fail; - } - - callback( API_REFRESH, &ref ); -#endif - - cls.ref_initialized = qtrue; - if( !ref.Init( qtrue ) ) { - goto fail; - } - - Sys_FixFPCW(); - - Com_Printf( "------------------------------------\n" ); - - return qtrue; - -fail: - CL_FreeRefresh(); - return qfalse; -} - -/* ============ -CL_PumpEvents +CL_RunResfresh ============ */ -void CL_PumpEvents( void ) { +void CL_RunRefresh( void ) { if( !cls.ref_initialized ) { return; } @@ -330,24 +188,19 @@ void CL_PumpEvents( void ) { VID_PumpEvents(); if( mode_changed ) { -#ifndef REF_HARD_LINKED - if( mode_changed & MODE_REFRESH ) { - Cbuf_AddText( "vid_restart\n" ); - } else -#endif if( mode_changed & MODE_FULLSCREEN ) { if( vid_fullscreen->integer ) { Cvar_Set( "_vid_fullscreen", vid_fullscreen->string ); } - VID_ModeChanged(); + VID_SetMode(); } else { if( vid_fullscreen->integer ) { if( mode_changed & MODE_MODELIST ) { - VID_ModeChanged(); + VID_SetMode(); } } else { if( mode_changed & MODE_GEOMETRY ) { - VID_ModeChanged(); + VID_SetMode(); } } } @@ -367,12 +220,6 @@ static void vid_modelist_changed( cvar_t *self ) { mode_changed |= MODE_MODELIST; } -#ifndef REF_HARD_LINKED -static void vid_ref_changed( cvar_t *self ) { - mode_changed |= MODE_REFRESH; -} -#endif - /* ============ CL_InitRefresh @@ -384,6 +231,7 @@ void CL_InitRefresh( void ) { } // Create the video variables so we know how to start the graphics drivers + vid_ref = Cvar_Get( "vid_ref", VID_REF, CVAR_ROM ); vid_geometry = Cvar_Get( "vid_geometry", "640x480", CVAR_ARCHIVE ); vid_fullscreen = Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE ); _vid_fullscreen = Cvar_Get( "_vid_fullscreen", "1", CVAR_ARCHIVE ); @@ -395,33 +243,12 @@ void CL_InitRefresh( void ) { Cvar_Set( "_vid_fullscreen", "1" ); } -#if REF_HARD_LINKED - vid_ref = Cvar_Get( "vid_ref", DEFAULT_REFRESH_DRIVER, CVAR_ROM ); - if( !CL_LoadRefresh( "ref_" DEFAULT_REFRESH_DRIVER ) ) { - Com_Error( ERR_FATAL, "Couldn't load built-in video driver!" ); - } -#else - vid_ref = Cvar_Get( "vid_ref", DEFAULT_REFRESH_DRIVER, CVAR_ARCHIVE ); - - // Start the graphics mode and load refresh DLL - while( 1 ) { - char buffer[MAX_QPATH]; - - Q_concat( buffer, sizeof( buffer ), "ref_", vid_ref->string, NULL ); - if( CL_LoadRefresh( buffer ) ) { - break; - } - - if( !strcmp( vid_ref->string, DEFAULT_REFRESH_DRIVER ) ) { - Com_Error( ERR_FATAL, "Couldn't fall back to %s driver!", buffer ); - } - - Com_Printf( "Falling back to default refresh...\n" ); - Cvar_Set( "vid_ref", DEFAULT_REFRESH_DRIVER ); + if( !R_Init( qtrue ) ) { + Com_Error( ERR_FATAL, "Couldn't initialize refresh" ); } - vid_ref->changed = vid_ref_changed; -#endif + cls.ref_initialized = qtrue; + vid_geometry->changed = vid_geometry_changed; vid_fullscreen->changed = vid_fullscreen_changed; vid_modelist->changed = vid_modelist_changed; @@ -431,7 +258,9 @@ void CL_InitRefresh( void ) { // Initialize the rest of graphics subsystems V_Init(); SCR_Init(); +#if USE_UI UI_Init(); +#endif SCR_RegisterMedia(); Con_RegisterMedia(); @@ -450,21 +279,18 @@ void CL_ShutdownRefresh( void ) { // Shutdown the rest of graphics subsystems V_Shutdown(); SCR_Shutdown(); +#if USE_UI UI_Shutdown(); +#endif vid_geometry->changed = NULL; vid_fullscreen->changed = NULL; vid_modelist->changed = NULL; -#if !REF_HARD_LINKED - vid_ref->changed = NULL; -#endif - ref.Shutdown( qtrue ); - CL_FreeRefresh(); + R_Shutdown( qtrue ); - Z_LeakTest( TAG_RENDERER ); + cls.ref_initialized = qfalse; + Z_LeakTest( TAG_RENDERER ); } - - diff --git a/source/cl_scrn.c b/source/cl_scrn.c index 00882ff..3e8a119 100644 --- a/source/cl_scrn.c +++ b/source/cl_scrn.c @@ -164,7 +164,7 @@ void SCR_DrawDebugGraph (void) x = w-1; y = scr_glconfig.vidHeight; - ref.DrawFill (x, y-scr_graphheight->value, + R_DrawFill (x, y-scr_graphheight->value, w, scr_graphheight->value, 8); for (a=0 ; a<w ; a++) @@ -177,7 +177,7 @@ void SCR_DrawDebugGraph (void) if (v < 0) v += scr_graphheight->value * (1+(int)(-v/scr_graphheight->value)); h = (int)v % (int)scr_graphheight->value; - ref.DrawFill (x, y - h, 1, h, color); + R_DrawFill (x, y - h, 1, h, color); x--; } } @@ -191,12 +191,12 @@ static void SCR_DrawPercentBar( int percent ) { w = scr_hudWidth * percent / 100; - ref.DrawFill( 0, scr_hudHeight, w, CHAR_HEIGHT, 4 ); - ref.DrawFill( w, scr_hudHeight, scr_hudWidth - w, CHAR_HEIGHT, 0 ); + R_DrawFill( 0, scr_hudHeight, w, CHAR_HEIGHT, 4 ); + R_DrawFill( w, scr_hudHeight, scr_hudWidth - w, CHAR_HEIGHT, 0 ); length = sprintf( buffer, "%d%%", percent ); x = ( scr_hudWidth - length * CHAR_WIDTH ) / 2; - ref.DrawString( x, scr_hudHeight, 0, MAX_STRING_CHARS, buffer, scr_font ); + R_DrawString( x, scr_hudHeight, 0, MAX_STRING_CHARS, buffer, scr_font ); } /* @@ -291,14 +291,14 @@ void SCR_DrawCenterString( void ) { return; } - ref.SetColor( DRAW_COLOR_ALPHA, ( byte * )&alpha ); + R_SetColor( DRAW_COLOR_ALPHA, ( byte * )&alpha ); y = scr_hudHeight / 4 - scr_center_lines * 8 / 2; SCR_DrawStringMulti( scr_hudWidth / 2, y, UI_CENTER, MAX_STRING_CHARS, scr_centerstring, scr_font ); - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); } //============================================================================ @@ -376,7 +376,7 @@ static void SCR_Sky_f( void ) { axis[2] = atof(Cmd_Argv(5)); } - ref.SetSky (Cmd_Argv(1), rotate, axis); + R_SetSky (Cmd_Argv(1), rotate, axis); } /* @@ -398,19 +398,19 @@ static void SCR_TimeRefresh_f (void) { if (Cmd_Argc() == 2) { // run without page flipping - ref.BeginFrame(); + R_BeginFrame(); for (i=0 ; i<128 ; i++) { cl.refdef.viewangles[1] = i/128.0f*360.0f; - ref.RenderFrame (&cl.refdef); + R_RenderFrame (&cl.refdef); } - ref.EndFrame(); + R_EndFrame(); } else { for (i=0 ; i<128 ; i++) { cl.refdef.viewangles[1] = i/128.0f*360.0f; - ref.BeginFrame(); - ref.RenderFrame (&cl.refdef); - ref.EndFrame(); + R_BeginFrame(); + R_RenderFrame (&cl.refdef); + R_EndFrame(); } } @@ -435,10 +435,10 @@ void SCR_TouchPics( void ) { for( i = 0; i < 2; i++ ) for( j = 0; j < 11; j++ ) - sb_pics[i][j] = ref.RegisterPic( sb_nums[i][j] ); + sb_pics[i][j] = R_RegisterPic( sb_nums[i][j] ); - sb_inventory = ref.RegisterPic( "inventory" ); - sb_field = ref.RegisterPic( "field_3" ); + sb_inventory = R_RegisterPic( "inventory" ); + sb_field = R_RegisterPic( "field_3" ); if( crosshair->integer ) { if( crosshair->integer < 0 ) { @@ -446,16 +446,17 @@ void SCR_TouchPics( void ) { } Com_sprintf( buffer, sizeof( buffer ), "ch%i", crosshair->integer ); - crosshair_pic = ref.RegisterPic( buffer ); - ref.DrawGetPicSize( &crosshair_width, &crosshair_height, - crosshair_pic ); + crosshair_pic = R_RegisterPic( buffer ); + R_GetPicSize( &crosshair_width, &crosshair_height, crosshair_pic ); } } void SCR_ModeChanged( void ) { - ref.GetConfig( &scr_glconfig ); + R_GetConfig( &scr_glconfig ); IN_Activate(); +#if USE_UI UI_ModeChanged(); +#endif } /* @@ -464,18 +465,18 @@ SCR_RegisterMedia ================== */ void SCR_RegisterMedia( void ) { - ref.GetConfig( &scr_glconfig ); + R_GetConfig( &scr_glconfig ); - scr_backtile = ref.RegisterPic( "backtile" ); - scr_pause = ref.RegisterPic( "pause" ); - scr_net = ref.RegisterPic( "net" ); - scr_font = ref.RegisterFont( scr_fontvar->string ); + scr_backtile = R_RegisterPic( "backtile" ); + scr_pause = R_RegisterPic( "pause" ); + scr_net = R_RegisterPic( "net" ); + scr_font = R_RegisterFont( scr_fontvar->string ); - ref.DrawGetPicSize( &scr_pause_width, &scr_pause_height, scr_pause ); + R_GetPicSize( &scr_pause_width, &scr_pause_height, scr_pause ); } static void scr_fontvar_changed( cvar_t *self ) { - scr_font = ref.RegisterFont( self->string ); + scr_font = R_RegisterFont( self->string ); } static const cmdreg_t scr_cmds[] = { @@ -547,7 +548,7 @@ void SCR_DrawPause( void ) { x = ( scr_hudWidth - scr_pause_width ) / 2; y = ( scr_hudHeight - scr_pause_height ) / 2; - ref.DrawPic( x, y, scr_pause ); + R_DrawPic( x, y, scr_pause ); } //============================================================================= @@ -559,7 +560,9 @@ SCR_BeginLoadingPlaque */ void SCR_BeginLoadingPlaque( void ) { Con_Close(); +#if USE_UI UI_OpenMenu( UIMENU_NONE ); +#endif S_StopAllSounds(); } @@ -595,17 +598,17 @@ static void SCR_TileClear( void ) { // clear above view screen - ref.DrawTileClear( 0, 0, scr_glconfig.vidWidth, top, scr_backtile ); + R_TileClear( 0, 0, scr_glconfig.vidWidth, top, scr_backtile ); // clear below view screen - ref.DrawTileClear( 0, bottom, scr_glconfig.vidWidth, + R_TileClear( 0, bottom, scr_glconfig.vidWidth, scr_glconfig.vidHeight - bottom, scr_backtile ); // clear left of view screen - ref.DrawTileClear( 0, top, left, scr_vrect.height, scr_backtile ); + R_TileClear( 0, top, left, scr_vrect.height, scr_backtile ); // clear right of view screen - ref.DrawTileClear( right, top, scr_glconfig.vidWidth - right, + R_TileClear( right, top, scr_glconfig.vidWidth - right, scr_vrect.height, scr_backtile ); } @@ -619,10 +622,10 @@ STAT PROGRAMS */ #define HUD_DrawString( x, y, string ) \ - ref.DrawString( x, y, 0, MAX_STRING_CHARS, string, scr_font ) + R_DrawString( x, y, 0, MAX_STRING_CHARS, string, scr_font ) #define HUD_DrawAltString( x, y, string ) \ - ref.DrawString( x, y, UI_ALTCOLOR, MAX_STRING_CHARS, string, scr_font ) + R_DrawString( x, y, UI_ALTCOLOR, MAX_STRING_CHARS, string, scr_font ) #define HUD_DrawCenterString( x, y, string ) \ SCR_DrawStringEx( x, y, UI_CENTER, MAX_STRING_CHARS, string, scr_font ) @@ -663,7 +666,7 @@ void HUD_DrawNumber( int x, int y, int color, int width, int value ) { else frame = *ptr - '0'; - ref.DrawPic( x, y, sb_pics[color][frame] ); + R_DrawPic( x, y, sb_pics[color][frame] ); x += DIGIT_WIDTH; ptr++; l--; @@ -707,7 +710,7 @@ void SCR_DrawInventory( void ) { x = ( scr_hudWidth - 256 ) / 2; y = ( scr_hudHeight - 240 ) / 2; - ref.DrawPic( x, y + 8, sb_inventory ); + R_DrawPic( x, y + 8, sb_inventory ); y += 24; x += 24; @@ -732,7 +735,7 @@ void SCR_DrawInventory( void ) { } else { // draw a blinky cursor by the selected item HUD_DrawString( x, y, string ); if( ( cls.realtime >> 8 ) & 1 ) { - ref.DrawChar( x - CHAR_WIDTH, y, 0, 15, scr_font ); + R_DrawChar( x - CHAR_WIDTH, y, 0, 15, scr_font ); } } @@ -820,7 +823,7 @@ void SCR_ExecuteLayoutString( const char *s ) { } token = cl.configstrings[CS_IMAGES + value]; if( token[0] ) { - ref.DrawPic( x, y, ref.RegisterPic( token ) ); + R_DrawPic( x, y, R_RegisterPic( token ) ); } continue; } @@ -861,7 +864,7 @@ void SCR_ExecuteLayoutString( const char *s ) { if( !ci->icon ) { ci = &cl.baseclientinfo; } - ref.DrawPic( x, y, ci->icon ); + R_DrawPic( x, y, ci->icon ); continue; } @@ -902,7 +905,7 @@ void SCR_ExecuteLayoutString( const char *s ) { if( !strcmp( token, "picn" ) ) { // draw a pic from a name token = COM_Parse( &s ); - ref.DrawPic( x, y, ref.RegisterPic( token ) ); + R_DrawPic( x, y, R_RegisterPic( token ) ); continue; } @@ -934,7 +937,7 @@ void SCR_ExecuteLayoutString( const char *s ) { color = 1; if( cl.frame.ps.stats[STAT_FLASHES] & 1 ) - ref.DrawPic( x, y, sb_field ); + R_DrawPic( x, y, sb_field ); HUD_DrawNumber( x, y, color, width, value ); continue; @@ -954,7 +957,7 @@ void SCR_ExecuteLayoutString( const char *s ) { continue; // negative number = don't show if( cl.frame.ps.stats[STAT_FLASHES] & 4 ) - ref.DrawPic( x, y, sb_field ); + R_DrawPic( x, y, sb_field ); HUD_DrawNumber( x, y, color, width, value ); continue; @@ -972,7 +975,7 @@ void SCR_ExecuteLayoutString( const char *s ) { color = 0; // green if( cl.frame.ps.stats[STAT_FLASHES] & 2 ) - ref.DrawPic( x, y, sb_field ); + R_DrawPic( x, y, sb_field ); HUD_DrawNumber( x, y, color, width, value ); continue; @@ -1055,7 +1058,7 @@ static void SCR_DrawActiveFrame( void ) { Cvar_ClampValue( scr_scale, 1, 9 ); scale = 1.0f / scr_scale->value; - ref.SetScale( &scale ); + R_SetScale( &scale ); scr_hudHeight *= scale; scr_hudWidth *= scale; @@ -1063,7 +1066,7 @@ static void SCR_DrawActiveFrame( void ) { // draw all 2D elements SCR_Draw2D(); - ref.SetScale( NULL ); + R_SetScale( NULL ); } //======================================================= @@ -1088,7 +1091,7 @@ void SCR_UpdateScreen( void ) { recursive++; - ref.BeginFrame(); + R_BeginFrame(); switch( cls.state ) { case ca_disconnected: @@ -1098,13 +1101,18 @@ void SCR_UpdateScreen( void ) { Con_RunConsole(); } - if( UI_IsTransparent() ) { - ref.DrawFill( 0, 0, scr_glconfig.vidWidth, +#if USE_UI + if( UI_IsTransparent() ) +#endif + { + R_DrawFill( 0, 0, scr_glconfig.vidWidth, scr_glconfig.vidHeight, 0 ); } +#if USE_UI // draw main menu UI_Draw( cls.realtime ); +#endif break; case ca_challenging: @@ -1112,23 +1120,30 @@ void SCR_UpdateScreen( void ) { case ca_connected: case ca_loading: case ca_precached: +#if USE_UI // make sure main menu is down if( cls.key_dest & KEY_MENU ) { UI_OpenMenu( UIMENU_NONE ); } +#endif // draw loading screen SCR_DrawLoading(); break; case ca_active: - if( UI_IsTransparent() ) { +#if USE_UI + if( UI_IsTransparent() ) +#endif + { // do 3D refresh drawing SCR_DrawActiveFrame(); } +#if USE_UI // draw ingame menu UI_Draw( cls.realtime ); +#endif break; default: @@ -1145,7 +1160,7 @@ void SCR_UpdateScreen( void ) { SCR_DrawDebugGraph(); } - ref.EndFrame(); + R_EndFrame(); recursive--; } diff --git a/source/cl_tent.c b/source/cl_tent.c index a2c2a23..5ae43a4 100644 --- a/source/cl_tent.c +++ b/source/cl_tent.c @@ -235,37 +235,37 @@ CL_RegisterTEntModels */ void CL_RegisterTEntModels (void) { - cl_mod_explode = ref.RegisterModel ("models/objects/explode/tris.md2"); - cl_mod_smoke = ref.RegisterModel ("models/objects/smoke/tris.md2"); - cl_mod_flash = ref.RegisterModel ("models/objects/flash/tris.md2"); - cl_mod_parasite_segment = ref.RegisterModel ("models/monsters/parasite/segment/tris.md2"); - cl_mod_grapple_cable = ref.RegisterModel ("models/ctf/segment/tris.md2"); - cl_mod_parasite_tip = ref.RegisterModel ("models/monsters/parasite/tip/tris.md2"); - cl_mod_explo4 = ref.RegisterModel ("models/objects/r_explode/tris.md2"); - cl_mod_bfg_explo = ref.RegisterModel ("sprites/s_bfg2.sp2"); - cl_mod_powerscreen = ref.RegisterModel ("models/items/armor/effect/tris.md2"); - - ref.RegisterModel ("models/objects/laser/tris.md2"); - ref.RegisterModel ("models/objects/grenade2/tris.md2"); - ref.RegisterModel ("models/weapons/v_machn/tris.md2"); - ref.RegisterModel ("models/weapons/v_handgr/tris.md2"); - ref.RegisterModel ("models/weapons/v_shotg2/tris.md2"); - ref.RegisterModel ("models/objects/gibs/bone/tris.md2"); - ref.RegisterModel ("models/objects/gibs/sm_meat/tris.md2"); - ref.RegisterModel ("models/objects/gibs/bone2/tris.md2"); + cl_mod_explode = R_RegisterModel ("models/objects/explode/tris.md2"); + cl_mod_smoke = R_RegisterModel ("models/objects/smoke/tris.md2"); + cl_mod_flash = R_RegisterModel ("models/objects/flash/tris.md2"); + cl_mod_parasite_segment = R_RegisterModel ("models/monsters/parasite/segment/tris.md2"); + cl_mod_grapple_cable = R_RegisterModel ("models/ctf/segment/tris.md2"); + cl_mod_parasite_tip = R_RegisterModel ("models/monsters/parasite/tip/tris.md2"); + cl_mod_explo4 = R_RegisterModel ("models/objects/r_explode/tris.md2"); + cl_mod_bfg_explo = R_RegisterModel ("sprites/s_bfg2.sp2"); + cl_mod_powerscreen = R_RegisterModel ("models/items/armor/effect/tris.md2"); + + R_RegisterModel ("models/objects/laser/tris.md2"); + R_RegisterModel ("models/objects/grenade2/tris.md2"); + R_RegisterModel ("models/weapons/v_machn/tris.md2"); + R_RegisterModel ("models/weapons/v_handgr/tris.md2"); + R_RegisterModel ("models/weapons/v_shotg2/tris.md2"); + R_RegisterModel ("models/objects/gibs/bone/tris.md2"); + R_RegisterModel ("models/objects/gibs/sm_meat/tris.md2"); + R_RegisterModel ("models/objects/gibs/bone2/tris.md2"); // RAFAEL - // ref.RegisterModel ("models/objects/blaser/tris.md2"); + // R_RegisterModel ("models/objects/blaser/tris.md2"); - ref.RegisterPic ("w_machinegun"); - ref.RegisterPic ("a_bullets"); - ref.RegisterPic ("i_health"); - ref.RegisterPic ("a_grenades"); + R_RegisterPic ("w_machinegun"); + R_RegisterPic ("a_bullets"); + R_RegisterPic ("i_health"); + R_RegisterPic ("a_grenades"); //ROGUE - cl_mod_explo4_big = ref.RegisterModel ("models/objects/r_explode2/tris.md2"); - cl_mod_lightning = ref.RegisterModel ("models/proj/lightning/tris.md2"); - cl_mod_heatbeam = ref.RegisterModel ("models/proj/beam/tris.md2"); - cl_mod_monster_heatbeam = ref.RegisterModel ("models/proj/widowbeam/tris.md2"); + cl_mod_explo4_big = R_RegisterModel ("models/objects/r_explode2/tris.md2"); + cl_mod_lightning = R_RegisterModel ("models/proj/lightning/tris.md2"); + cl_mod_heatbeam = R_RegisterModel ("models/proj/beam/tris.md2"); + cl_mod_monster_heatbeam = R_RegisterModel ("models/proj/widowbeam/tris.md2"); //ROGUE } diff --git a/source/cl_view.c b/source/cl_view.c index 53a90d1..6e9a269 100644 --- a/source/cl_view.c +++ b/source/cl_view.c @@ -253,10 +253,12 @@ void CL_PrepRefresh (void) { return; // no map loaded Con_Close(); +#if USE_UI UI_OpenMenu( UIMENU_NONE ); +#endif // register models, pics, and skins - ref.BeginRegistration( cl.mapname ); + R_BeginRegistration( cl.mapname ); CL_LoadState( LOAD_MODELS ); @@ -265,7 +267,7 @@ void CL_PrepRefresh (void) { cl.numWeaponModels = 1; strcpy(cl.weaponModels[0], "weapon.md2"); - for (i=1 ; i<MAX_MODELS ; i++) { + for (i=2 ; i<MAX_MODELS ; i++) { name = cl.configstrings[CS_MODELS+i]; if( !name[0] ) { break; @@ -276,7 +278,7 @@ void CL_PrepRefresh (void) { strcpy( cl.weaponModels[cl.numWeaponModels++], name + 1 ); } } else { - cl.model_draw[i] = ref.RegisterModel( name ); + cl.model_draw[i] = R_RegisterModel( name ); } } @@ -290,7 +292,7 @@ void CL_PrepRefresh (void) { if( !name[0] ) { break; } - cl.image_precache[i] = ref.RegisterPic (name); + cl.image_precache[i] = R_RegisterPic (name); } CL_LoadState( LOAD_CLIENTS ); @@ -308,10 +310,10 @@ void CL_PrepRefresh (void) { rotate = atof (cl.configstrings[CS_SKYROTATE]); sscanf (cl.configstrings[CS_SKYAXIS], "%f %f %f", &axis[0], &axis[1], &axis[2]); - ref.SetSky (cl.configstrings[CS_SKY], rotate, axis); + R_SetSky (cl.configstrings[CS_SKY], rotate, axis); // the renderer can now free unneeded stuff - ref.EndRegistration (); + R_EndRegistration (); // clear any lines of console text Con_ClearNotify_f (); @@ -343,7 +345,7 @@ static void V_Gun_Model_f (void) { return; } Q_concat (name, sizeof(name), "models/", Cmd_Argv(1), "/tris.md2", NULL ); - gun_model = ref.RegisterModel (name); + gun_model = R_RegisterModel (name); } //============================================================================ @@ -367,7 +369,7 @@ static void V_SetLightLevel( void ) { vec3_t shadelight; // save off light value for server to look at (BIG HACK!) - ref.LightPoint( cl.refdef.vieworg, shadelight ); + R_LightPoint( cl.refdef.vieworg, shadelight ); // pick the greatest component, which should be the same // as the mono value returned by software @@ -463,7 +465,7 @@ void V_RenderView( void ) { qsort( cl.refdef.entities, cl.refdef.num_entities, sizeof( cl.refdef.entities[0] ), (int (QDECL *)(const void *, const void *))entitycmpfnc ); } - ref.RenderFrame (&cl.refdef); + R_RenderFrame (&cl.refdef); if (cl_stats->integer) Com_Printf ("ent:%i lt:%i part:%i\n", r_numentities, r_numdlights, r_numparticles); diff --git a/source/cmd.c b/source/cmd.c index d743b90..b725526 100644 --- a/source/cmd.c +++ b/source/cmd.c @@ -20,13 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // cmd.c -- Quake script command processing module #include "com_local.h" +#include "files.h" #include "q_list.h" #define Cmd_Malloc( size ) Z_TagMalloc( size, TAG_CMD ) #define Cmd_CopyString( string ) Z_TagCopyString( string, TAG_CMD ) -cmdAPI_t cmd; - /* ============================================================================= @@ -390,7 +389,7 @@ static void Cmd_UnAlias_f( void ) { Z_Free( a ); } -#ifndef DEDICATED_ONLY +#if USE_CLIENT void Cmd_WriteAliases( fileHandle_t f ) { cmdalias_t *a; @@ -1465,23 +1464,6 @@ static void Cmd_Complete_f( void ) { void Com_Mixed_c( genctx_t *ctx, int argnum ) { } -/* -============ -Cmd_FillAPI -============ -*/ -void Cmd_FillAPI( cmdAPI_t *api ) { - api->AddCommand = Cmd_AddCommand; - api->Register = Cmd_Register; - api->Deregister = Cmd_Deregister; - api->RemoveCommand = Cmd_RemoveCommand; - api->Argc = Cmd_Argc; - api->Argv = Cmd_Argv; - api->ArgsFrom = Cmd_ArgsFrom; - api->ExecuteText = Cbuf_ExecuteText; - api->FindFunction = Cmd_FindFunction; -} - static const cmdreg_t c_cmd[] = { { "cmdlist", Cmd_List_f }, { "macrolist", Cmd_MacroList_f }, @@ -1516,6 +1498,5 @@ void Cmd_Init( void ) { } Cmd_Register( c_cmd ); - Cmd_FillAPI( &cmd ); } diff --git a/source/cmodel.c b/source/cmodel.c index c2c1aa3..de0c01c 100644 --- a/source/cmodel.c +++ b/source/cmodel.c @@ -20,13 +20,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // cmodel.c -- model loading #include "com_local.h" +#include "q_list.h" +#include "files.h" +#include "sys_public.h" +#include "bsp.h" +#include "cmodel.h" -#define CM_Malloc( size ) Z_TagMalloc( size, TAG_CMODEL ) -#define CM_Mallocz( size ) Z_TagMallocz( size, TAG_CMODEL ) -#define CM_Free( ptr ) Z_Free( ptr ) +mtexinfo_t nulltexinfo; -static mapsurface_t nullsurface; -static cleaf_t nullleaf; +static mleaf_t nullleaf; static int floodvalid; static int checkcount; @@ -36,513 +38,20 @@ static cvar_t *map_override; void CM_FloodAreaConnections( cm_t *cm ); -typedef struct { - void *base; - size_t count; -} cmlump_t; - -typedef struct { - size_t size; - size_t mincount; - size_t maxcount; - const char *name; -} lump_info_t; - -static const lump_info_t lump_info[HEADER_LUMPS] = { - { 1, 0, MAX_MAP_ENTSTRING, "entities" }, - { sizeof( dplane_t ), 1, MAX_MAP_PLANES, "planes" }, - { sizeof( dvertex_t ), 0, MAX_MAP_VERTS, "verts" }, - { 1, 0, MAX_MAP_VISIBILITY, "visibility" }, - { sizeof( dnode_t ), 1, MAX_MAP_NODES, "nodes" }, - { sizeof( texinfo_t ), 1, MAX_MAP_TEXINFO, "texinfo" }, - { sizeof( dface_t ), 0, MAX_MAP_FACES, "faces" }, - { 1, 0, MAX_MAP_LIGHTING, "lighting" }, - { sizeof( dleaf_t ), 1, MAX_MAP_LEAFS, "leafs" }, - { sizeof( uint16_t ), 0, MAX_MAP_LEAFFACES, "leaf faces" }, - { sizeof( uint16_t ), 1, MAX_MAP_LEAFBRUSHES, "leaf brushes" }, - { sizeof( dedge_t ), 0, MAX_MAP_EDGES, "edges" }, - { sizeof( uint32_t ), 0, MAX_MAP_SURFEDGES, "surf edges" }, - { sizeof( dmodel_t ), 1, MAX_MAP_MODELS, "models" }, - { sizeof( dbrush_t ), 1, MAX_MAP_BRUSHES, "brushes" }, - { sizeof( dbrushside_t ), 1, MAX_MAP_BRUSHSIDES, "brush sides" }, - { 0, 0, 0, NULL }, - { sizeof( darea_t ), 0, MAX_MAP_AREAS, "areas" }, - { sizeof( dareaportal_t ), 0, MAX_MAP_AREAPORTALS, "area portals" } -}; - -/* -=============================================================================== - - MAP LOADING - -=============================================================================== -*/ - -#define CM_FUNC( Func ) \ - static qboolean CM_Load##Func( cmcache_t *cache, cmlump_t *l ) - -/* -================= -CM_LoadSubmodels -================= -*/ -CM_FUNC( Submodels ) { - dmodel_t *in; - cmodel_t *out; - int i, j; - unsigned headnode; - - cache->cmodels = CM_Malloc( sizeof( *out ) * l->count ); - cache->numcmodels = l->count; - - in = l->base; - out = cache->cmodels; - for( i = 0; i < l->count; i++, in++, out++ ) { - for( j = 0; j < 3; j++ ) { - // spread the mins / maxs by a pixel - out->mins[j] = LittleFloat (in->mins[j]) - 1; - out->maxs[j] = LittleFloat (in->maxs[j]) + 1; - out->origin[j] = LittleFloat (in->origin[j]); - } - headnode = LittleLong (in->headnode); - if( headnode >= cache->numnodes ) { - // FIXME: headnode may be garbage for some models - Com_DPrintf( "%s: bad headnode for model %d\n", __func__, i ); - out->headnode = NULL; - } else { - out->headnode = cache->nodes + headnode; - } - } - return qtrue; -} - - -/* -================= -CM_LoadSurfaces -================= -*/ -CM_FUNC( Surfaces ) { - texinfo_t *in; - mapsurface_t *out; - int i; - - cache->numtexinfo = l->count; - cache->surfaces = CM_Malloc( sizeof( *out ) * l->count ); - - in = l->base; - out = cache->surfaces; - for( i = 0; i < l->count; i++, in++, out++ ) { - memcpy( out->c.name, in->texture, sizeof( out->c.name ) ); - out->c.name[ sizeof( out->c.name ) - 1 ] = 0; - memcpy( out->rname, in->texture, sizeof( out->rname ) ); - out->rname[ sizeof( out->rname ) - 1 ] = 0; - out->c.flags = LittleLong (in->flags); - out->c.value = LittleLong (in->value); - } - return qtrue; -} - - -/* -================= -CM_LoadNodes -================= -*/ -CM_FUNC( Nodes ) { - dnode_t *in; - uint32_t child; - cnode_t *out; - int i, j; - unsigned planeNum; - - cache->numnodes = l->count; - cache->nodes = CM_Malloc( sizeof( *out ) * l->count ); - - in = l->base; - out = cache->nodes; - for( i = 0; i < l->count; i++, out++, in++ ) { - planeNum = LittleLong(in->planenum); - if( planeNum >= cache->numplanes ) { - Com_DPrintf( "%s: bad planenum\n", __func__ ); - return qfalse; - } - out->plane = cache->planes + planeNum; - - for( j = 0; j < 2; j++ ) { - child = LittleLong( in->children[j] ); - if( child & 0x80000000 ) { - child = ~child; - if( child >= cache->numleafs ) { - Com_DPrintf( "%s: bad leafnum\n", __func__ ); - return qfalse; - } - out->children[j] = ( cnode_t * )( cache->leafs + child ); - } else { - if( child >= l->count ) { - Com_DPrintf( "%s: bad nodenum\n", __func__ ); - return qfalse; - } - out->children[j] = cache->nodes + child; - } - } - } - return qtrue; -} - -/* -================= -CM_LoadBrushes -================= -*/ -CM_FUNC( Brushes ) { - dbrush_t *in; - cbrush_t *out; - int i; - unsigned firstSide, numSides, lastSide; - - cache->numbrushes = l->count; - cache->brushes = CM_Malloc( sizeof( *out ) * l->count ); - - in = l->base; - out = cache->brushes; - for( i = 0; i < l->count; i++, out++, in++ ) { - firstSide = LittleLong(in->firstside); - numSides = LittleLong(in->numsides); - lastSide = firstSide + numSides; - if( lastSide < firstSide || lastSide > cache->numbrushsides ) { - Com_DPrintf( "%s: bad brushsides\n", __func__ ); - return qfalse; - } - out->firstbrushside = cache->brushsides + firstSide; - out->numsides = numSides; - out->contents = LittleLong(in->contents); - out->checkcount = 0; - } - return qtrue; -} - /* -================= -CM_LoadLeafs -================= -*/ -CM_FUNC( Leafs ) { - cleaf_t *out; - dleaf_t *in; - int i; - unsigned areaNum, firstBrush, numBrushes; - - cache->numleafs = l->count; - cache->numclusters = 0; - cache->leafs = CM_Malloc( sizeof( *out ) * l->count ); - - in = l->base; - out = cache->leafs; - for( i = 0; i < l->count; i++, in++, out++ ) { - out->plane = NULL; - out->contents = LittleLong (in->contents); - out->cluster = ( signed short )LittleShort (in->cluster); - areaNum = LittleShort (in->area); - if( areaNum >= cache->numareas ) { - Com_DPrintf( "%s: bad areanum\n", __func__ ); - return qfalse; - } - out->area = areaNum; - - firstBrush = LittleShort (in->firstleafbrush); - numBrushes = LittleShort (in->numleafbrushes); - if( firstBrush + numBrushes > cache->numleafbrushes ) { - Com_DPrintf( "%s: bad brushnum\n", __func__ ); - return qfalse; - } - - out->firstleafbrush = cache->leafbrushes + firstBrush; - out->numleafbrushes = numBrushes; - - if (out->cluster >= cache->numclusters) - cache->numclusters = out->cluster + 1; - } - - if (cache->leafs[0].contents != CONTENTS_SOLID) { - Com_DPrintf( "%s: map leaf 0 is not CONTENTS_SOLID\n", __func__ ); - return qfalse; - } - return qtrue; -} - -/* -================= -CM_LoadPlanes -================= -*/ -CM_FUNC( Planes ) { - cplane_t *out; - dplane_t *in; - int i; - - cache->numplanes = l->count; - cache->planes = CM_Malloc( sizeof( *out ) * l->count ); - - in = l->base; - out = cache->planes; - for( i = 0; i < l->count; i++, in++, out++ ) { - out->normal[0] = LittleFloat( in->normal[0] ); - out->normal[1] = LittleFloat( in->normal[1] ); - out->normal[2] = LittleFloat( in->normal[2] ); - out->dist = LittleFloat (in->dist); - SetPlaneType( out ); - SetPlaneSignbits( out ); - } - return qtrue; -} - -/* -================= -CMLoadLeafBrushes -================= -*/ -CM_FUNC( LeafBrushes ) { - cbrush_t **out; - uint16_t *in; - int i; - unsigned brushNum; - - cache->numleafbrushes = l->count; - cache->leafbrushes = CM_Malloc( sizeof( *out ) * l->count ); - - in = l->base; - out = cache->leafbrushes; - for( i = 0; i < l->count; i++, in++, out++ ) { - brushNum = LittleShort (*in); - if( brushNum >= cache->numbrushes ) { - Com_DPrintf( "%s: bad brushnum\n", __func__ ); - return qfalse; - } - *out = cache->brushes + brushNum; - } - return qtrue; -} - -/* -================= -CM_LoadBrushSides -================= -*/ -CM_FUNC( BrushSides ) { - cbrushside_t *out; - dbrushside_t *in; - int i; - unsigned planeNum, texinfoNum; - - cache->numbrushsides = l->count; - cache->brushsides = CM_Malloc( sizeof( *out ) * l->count ); - - in = l->base; - out = cache->brushsides; - for( i = 0; i < l->count; i++, in++, out++ ) { - planeNum = LittleShort (in->planenum); - if( planeNum >= cache->numplanes ) { - Com_DPrintf( "%s: bad planenum\n", __func__ ); - return qfalse; - } - out->plane = cache->planes + planeNum; - texinfoNum = LittleShort (in->texinfo); - if( texinfoNum == ( uint16_t )-1 ) { - out->surface = &nullsurface; - } else { - if (texinfoNum >= cache->numtexinfo) { - Com_DPrintf( "%s: bad texinfo\n", __func__ ); - return qfalse; - } - out->surface = cache->surfaces + texinfoNum; - } - } - return qtrue; -} - -/* -================= -CM_LoadAreas -================= -*/ -CM_FUNC( Areas ) { - carea_t *out; - darea_t *in; - int i; - unsigned numPortals, firstPortal, lastPortal; - - cache->numareas = l->count; - cache->areas = CM_Malloc( sizeof( *out ) * l->count ); - - in = l->base; - out = cache->areas; - for( i = 0; i < l->count; i++, in++, out++ ) { - numPortals = LittleLong (in->numareaportals); - firstPortal = LittleLong (in->firstareaportal); - lastPortal = firstPortal + numPortals; - if( lastPortal < firstPortal || lastPortal > cache->numareaportals ) { - Com_DPrintf( "%s: bad areaportals\n", __func__ ); - return qfalse; - } - out->numareaportals = numPortals; - out->firstareaportal = firstPortal; - out->floodvalid = 0; - } - return qtrue; -} - -/* -================= -CM_LoadAreaPortals -================= -*/ -CM_FUNC( AreaPortals ) { - careaportal_t *out; - dareaportal_t *in; - int i; - unsigned portalNum, otherArea; - - cache->numareaportals = l->count; - cache->areaportals = CM_Malloc( sizeof( *out ) * l->count ); - - in = l->base; - out = cache->areaportals; - for( i = 0; i < l->count; i++, in++, out++ ) { - portalNum = LittleLong (in->portalnum); - if( portalNum >= MAX_MAP_AREAPORTALS ) { - Com_DPrintf( "%s: bad portalnum\n", __func__ ); - } - out->portalnum = portalNum; - otherArea = LittleLong (in->otherarea); - if( otherArea >= MAX_MAP_AREAS ) { - Com_DPrintf( "%s: bad otherarea\n", __func__ ); - } - out->otherarea = otherArea; - } - return qtrue; -} - -/* -================= -CM_LoadVisibility -================= -*/ -CM_FUNC( Visibility ) { - unsigned numClusters; - int i; - - if( !l->count ) { - cache->numvisibility = cache->visrowsize = 0; - return qtrue; - } - - cache->numvisibility = l->count; - cache->vis = CM_Malloc( l->count ); - memcpy( cache->vis, l->base, l->count ); - - numClusters = LittleLong( cache->vis->numclusters ); - cache->vis->numclusters = numClusters; - for( i = 0; i < numClusters; i++ ) { - cache->vis->bitofs[i][0] = LittleLong( cache->vis->bitofs[i][0] ); - cache->vis->bitofs[i][1] = LittleLong( cache->vis->bitofs[i][1] ); - } - - cache->visrowsize = ( numClusters + 7 ) >> 3; - return qtrue; -} - - -/* -================= -CM_LoadEntityString -================= +================== +CM_FreeMap +================== */ -CM_FUNC( EntityString ) { - cache->numEntityChars = l->count; - cache->entitystring = CM_Malloc( l->count + 1 ); - memcpy( cache->entitystring, l->base, l->count ); - cache->entitystring[l->count] = 0; - return qtrue; -} - -#define CM_CACHESIZE 16 - -static cmcache_t cm_cache[CM_CACHESIZE]; - -static void CM_FreeCache( cmcache_t *cache ) { -#define CM_FREE( f ) if( cache->f ) CM_Free( cache->f ) - - CM_FREE( vis ); - CM_FREE( surfaces ); - CM_FREE( planes ); - CM_FREE( brushsides ); - CM_FREE( brushes ); - CM_FREE( leafbrushes ); - CM_FREE( areaportals ); - CM_FREE( areas ); - CM_FREE( leafs ); - CM_FREE( nodes ); - CM_FREE( cmodels ); - CM_FREE( entitystring ); - - memset( cache, 0, sizeof( *cache ) ); -} - void CM_FreeMap( cm_t *cm ) { - cmcache_t *cache; - if( cm->floodnums ) { Z_Free( cm->floodnums ); } - - cache = cm->cache; - if( cache ) { - if( cache->refcount <= 0 ) { - Com_Error( ERR_FATAL, "CM_FreeMap: negative refcount" ); - } - if( --cache->refcount == 0 ) { - CM_FreeCache( cache ); - } - } + BSP_Free( cm->cache ); memset( cm, 0, sizeof( *cm ) ); } -static void CM_AllocPortals( cm_t *cm, int flags ) { - if( flags & CM_LOAD_CLIENT ) { - cm->floodnums = NULL; - cm->portalopen = NULL; - return; - } - cm->floodnums = CM_Mallocz( sizeof( int ) * cm->cache->numareas + - sizeof( qboolean ) * cm->cache->numareaportals ); - cm->portalopen = ( qboolean * )( cm->floodnums + cm->cache->numareas ); - CM_FloodAreaConnections( cm ); -} - -typedef struct { - qboolean (*func)( cmcache_t *, cmlump_t * ); - int lump; -} lump_load_t; - -#define CM_LOAD( Func, Lump ) { CM_Load##Func, LUMP_##Lump } - -static const lump_load_t lump_load[] = { - CM_LOAD( Visibility, VISIBILITY ), - CM_LOAD( Surfaces, TEXINFO ), - CM_LOAD( Planes, PLANES ), - CM_LOAD( BrushSides, BRUSHSIDES ), - CM_LOAD( Brushes, BRUSHES ), - CM_LOAD( LeafBrushes, LEAFBRUSHES ), - CM_LOAD( AreaPortals, AREAPORTALS ), - CM_LOAD( Areas, AREAS ), - CM_LOAD( Leafs, LEAFS ), - CM_LOAD( Nodes, NODES ), - CM_LOAD( Submodels, MODELS ), - { NULL } -}; - /* ================== CM_LoadMap @@ -550,216 +59,30 @@ CM_LoadMap Loads in the map and all submodels ================== */ -const char *CM_LoadMapEx( cm_t *cm, const char *name, int flags, uint32_t *checksum ) { - cmcache_t *cache; - byte *buf; - int i; - dheader_t *header; - lump_t *in; - cmlump_t lumps[HEADER_LUMPS]; - cmlump_t *out; - const lump_info_t *info; - const lump_load_t *load; - size_t length, endpos, fileofs, filelen; - char *error; - - if( !name || !name[0] ) { - Com_Error( ERR_FATAL, "CM_LoadMap: NULL name" ); - } - - memset( cm, 0, sizeof( *cm ) ); +qboolean CM_LoadMap( cm_t *cm, const char *name ) { + bsp_t *cache; - for( i = 0, cache = cm_cache; i < CM_CACHESIZE; i++, cache++ ) { - if( !cache->name[0] ) { - continue; - } - if( strcmp( cache->name, name ) ) { - continue; - } - //if( !( cache->flags & CM_LOAD_VISONLY ) || ( flags & CM_LOAD_VISONLY ) ) - { - cm->cache = cache; - if( checksum ) { - *checksum = cache->checksum; - } - CM_AllocPortals( cm, flags ); - cache->refcount++; - return NULL; // still have the right version - } - break; - } - - // find a free slot - for( i = 0, cache = cm_cache; i < CM_CACHESIZE; i++, cache++ ) { - if( !cache->name[0] ) { - break; - } - } - if( i == CM_CACHESIZE ) { - return "out of cache slots"; - } - - // - // load the file - // - length = FS_LoadFile( name, (void **)&buf ); - if( !buf ) { - return "file not found"; - } - - cache->checksum = LittleLong( Com_BlockChecksum( buf, length ) ); - if( checksum ) { - *checksum = cache->checksum; - } - - // byte swap and validate the header - header = ( dheader_t * )buf; - if( LittleLong( header->ident ) != IDBSPHEADER ) { - error = "not an IBSP file"; - goto fail; - } - if( LittleLong( header->version ) != BSPVERSION ) { - error = "wrong IBSP version"; - goto fail; - } - - // byte swap and validate lumps - in = header->lumps; - out = lumps; - info = lump_info; - for( i = 0; i < HEADER_LUMPS; i++, in++, out++, info++ ) { - if( !info->size ) { - continue; - } - fileofs = LittleLong( in->fileofs ); - filelen = LittleLong( in->filelen ); - endpos = fileofs + filelen; - if( endpos < fileofs || endpos > length ) { - error = va( "%s lump is out of bounds", info->name ); - goto fail; - } - out->base = buf + fileofs; - if( filelen % info->size ) { - error = va( "%s lump has funny size", info->name ); - goto fail; - } - out->count = filelen / info->size; - if( out->count < info->mincount || out->count > info->maxcount ) { - error = va( "%s lump has bad number of elements", info->name ); - goto fail; - } - } - - - // load into heap - if( !( flags & CM_LOAD_ENTONLY ) ) { - for( load = lump_load; load->func; load++ ) { - if( !load->func( cache, &lumps[load->lump] ) ) { - error = va( "%s lump has invalid structure", lump_info[load->lump].name ); - goto fail; - } - } - } - - // optionally load the entity string from external source - if( map_override->integer && !( flags & CM_LOAD_CLIENT ) ) { - char *entstring; - char buffer[MAX_QPATH]; - - COM_StripExtension( name, buffer, sizeof( buffer ) ); - Q_strcat( buffer, sizeof( buffer ), ".ent" ); - length = FS_LoadFileEx( buffer, ( void ** )&entstring, 0, TAG_CMODEL ); - if( entstring ) { - Com_DPrintf( "Loaded entity string from %s\n", buffer ); - cache->entitystring = entstring; - cache->numEntityChars = length; - } else { - CM_LoadEntityString( cache, &lumps[LUMP_ENTITIES] ); - } - } else { - CM_LoadEntityString( cache, &lumps[LUMP_ENTITIES] ); + if( !( cache = BSP_Load( name ) ) ) { + return qfalse; } - FS_FreeFile( buf ); - - Q_strncpyz( cache->name, name, sizeof( cache->name ) ); - - cache->refcount = 1; cm->cache = cache; + cm->floodnums = Z_TagMallocz( sizeof( int ) * cm->cache->numareas + + sizeof( qboolean ) * cm->cache->numareaportals, TAG_CMODEL ); + cm->portalopen = ( qboolean * )( cm->floodnums + cm->cache->numareas ); + CM_FloodAreaConnections( cm ); - CM_AllocPortals( cm, flags ); - - return NULL; - -fail: - FS_FreeFile( buf ); - CM_FreeCache( cache ); - return error; -} - -void CM_LoadMap( cm_t *cm, const char *name, int flags, uint32_t *checksum ) { - const char *error = CM_LoadMapEx( cm, name, flags, checksum ); - - if( error ) { - Com_Error( ERR_DROP, "Couldn't load %s: %s", name, error ); - } -} - -/* -================== -CM_InlineModel -================== -*/ -cmodel_t *CM_InlineModel( cm_t *cm, const char *name ) { - int num; - cmodel_t *cmodel; - - if( !name || name[0] != '*' ) { - Com_Error( ERR_DROP, "%s: bad name: %s", __func__, name ); - } - if( !cm->cache ) { - Com_Error( ERR_DROP, "%s: NULL cache", __func__ ); - } - num = atoi( name + 1 ); - if( num < 1 || num >= cm->cache->numcmodels ) { - Com_Error ( ERR_DROP, "%s: bad number: %d", __func__, num ); - } - - cmodel = &cm->cache->cmodels[num]; - - return cmodel; -} - -int CM_NumClusters( cm_t *cm ) { - if( !cm->cache ) { - return 0; - } - return cm->cache->numclusters; + return qtrue; } -int CM_NumInlineModels( cm_t *cm ) { - if( !cm->cache ) { - return 0; - } - return cm->cache->numcmodels; -} -char *CM_EntityString( cm_t *cm ) { - if( !cm->cache ) { - return ""; - } - if( !cm->cache->entitystring ) { - return ""; - } - return cm->cache->entitystring; -} -cnode_t *CM_NodeNum( cm_t *cm, int number ) { +mnode_t *CM_NodeNum( cm_t *cm, int number ) { if( !cm->cache ) { Com_Error( ERR_DROP, "%s: NULL cache", __func__ ); } if( number == -1 ) { - return ( cnode_t * )cm->cache->leafs; // special case for solid leaf + return ( mnode_t * )cm->cache->leafs; // special case for solid leaf } if( number < 0 || number >= cm->cache->numnodes ) { Com_Error( ERR_DROP, "%s: bad number: %d", __func__, number ); @@ -767,7 +90,7 @@ cnode_t *CM_NodeNum( cm_t *cm, int number ) { return cm->cache->nodes + number; } -cleaf_t *CM_LeafNum( cm_t *cm, int number ) { +mleaf_t *CM_LeafNum( cm_t *cm, int number ) { if( !cm->cache ) { Com_Error( ERR_DROP, "%s: NULL cache", __func__ ); } @@ -780,13 +103,13 @@ cleaf_t *CM_LeafNum( cm_t *cm, int number ) { //======================================================================= static cplane_t box_planes[12]; -static cnode_t box_nodes[6]; -static cnode_t *box_headnode; -static cbrush_t box_brush; -static cbrush_t *box_leafbrush; -static cbrushside_t box_brushsides[6]; -static cleaf_t box_leaf; -static cleaf_t box_emptyleaf; +static mnode_t box_nodes[6]; +static mnode_t *box_headnode; +static mbrush_t box_brush; +static mbrush_t *box_leafbrush; +static mbrushside_t box_brushsides[6]; +static mleaf_t box_leaf; +static mleaf_t box_emptyleaf; /* =================== @@ -799,9 +122,9 @@ can just be stored out and get a proper clipping hull structure. static void CM_InitBoxHull( void ) { int i; int side; - cnode_t *c; + mnode_t *c; cplane_t *p; - cbrushside_t *s; + mbrushside_t *s; box_headnode = &box_nodes[0]; @@ -821,16 +144,16 @@ static void CM_InitBoxHull( void ) { // brush sides s = &box_brushsides[i]; s->plane = &box_planes[i*2+side]; - s->surface = &nullsurface; + s->texinfo = &nulltexinfo; // nodes c = &box_nodes[i]; c->plane = &box_planes[i*2]; - c->children[side] = ( cnode_t * )&box_emptyleaf; + c->children[side] = ( mnode_t * )&box_emptyleaf; if( i != 5 ) c->children[side^1] = &box_nodes[i + 1]; else - c->children[side^1] = ( cnode_t * )&box_leaf; + c->children[side^1] = ( mnode_t * )&box_leaf; // planes p = &box_planes[i*2]; @@ -856,7 +179,7 @@ To keep everything totally uniform, bounding boxes are turned into small BSP trees instead of being compared directly. =================== */ -cnode_t *CM_HeadnodeForBox( vec3_t mins, vec3_t maxs ) { +mnode_t *CM_HeadnodeForBox( vec3_t mins, vec3_t maxs ) { box_planes[0].dist = maxs[0]; box_planes[1].dist = -maxs[0]; box_planes[2].dist = mins[0]; @@ -874,34 +197,13 @@ cnode_t *CM_HeadnodeForBox( vec3_t mins, vec3_t maxs ) { } -/* -================== -CM_PointLeaf_r - -================== -*/ -static cleaf_t *CM_PointLeaf_r( vec3_t p, cnode_t *node ) { - float d; - - while( node->plane ) { - d = PlaneDiffFast( p, node->plane ); - if( d < 0 ) - node = node->children[1]; - else - node = node->children[0]; - } - - return ( cleaf_t * )node; -} - -cleaf_t *CM_PointLeaf( cm_t *cm, vec3_t p ) { +mleaf_t *CM_PointLeaf( cm_t *cm, vec3_t p ) { if( !cm->cache ) { return &nullleaf; // server may call this without map loaded } - return CM_PointLeaf_r( p, cm->cache->nodes ); + return BSP_PointLeaf( cm->cache->nodes, p ); } - /* ============= CM_BoxLeafnums @@ -910,11 +212,11 @@ Fills in a list of all the leafs touched ============= */ static int leaf_count, leaf_maxcount; -static cleaf_t **leaf_list; +static mleaf_t **leaf_list; static float *leaf_mins, *leaf_maxs; -static cnode_t *leaf_topnode; +static mnode_t *leaf_topnode; -static void CM_BoxLeafs_r( cnode_t *node ) { +static void CM_BoxLeafs_r( mnode_t *node ) { int s; while( node->plane ) { @@ -934,12 +236,12 @@ static void CM_BoxLeafs_r( cnode_t *node ) { } if( leaf_count < leaf_maxcount ) { - leaf_list[leaf_count++] = ( cleaf_t * )node; + leaf_list[leaf_count++] = ( mleaf_t * )node; } } -static int CM_BoxLeafs_headnode( vec3_t mins, vec3_t maxs, cleaf_t **list, int listsize, - cnode_t *headnode, cnode_t **topnode ) +static int CM_BoxLeafs_headnode( vec3_t mins, vec3_t maxs, mleaf_t **list, int listsize, + mnode_t *headnode, mnode_t **topnode ) { leaf_list = list; leaf_count = 0; @@ -957,7 +259,7 @@ static int CM_BoxLeafs_headnode( vec3_t mins, vec3_t maxs, cleaf_t **list, int l return leaf_count; } -int CM_BoxLeafs( cm_t *cm, vec3_t mins, vec3_t maxs, cleaf_t **list, int listsize, cnode_t **topnode ) { +int CM_BoxLeafs( cm_t *cm, vec3_t mins, vec3_t maxs, mleaf_t **list, int listsize, mnode_t **topnode ) { if( !cm->cache ) // map not loaded return 0; return CM_BoxLeafs_headnode( mins, maxs, list, @@ -972,14 +274,14 @@ CM_PointContents ================== */ -int CM_PointContents( vec3_t p, cnode_t *headnode ) { - cleaf_t *leaf; +int CM_PointContents( vec3_t p, mnode_t *headnode ) { + mleaf_t *leaf; if( !headnode ) { return 0; } - leaf = CM_PointLeaf_r( p, headnode ); + leaf = BSP_PointLeaf( headnode, p ); return leaf->contents; } @@ -992,11 +294,11 @@ Handles offseting and rotation of the end points for moving and rotating entities ================== */ -int CM_TransformedPointContents( vec3_t p, cnode_t *headnode, vec3_t origin, vec3_t angles ) { +int CM_TransformedPointContents( vec3_t p, mnode_t *headnode, vec3_t origin, vec3_t angles ) { vec3_t p_l; vec3_t temp; vec3_t forward, right, up; - cleaf_t *leaf; + mleaf_t *leaf; if( !headnode ) { return 0; @@ -1017,7 +319,7 @@ int CM_TransformedPointContents( vec3_t p, cnode_t *headnode, vec3_t origin, vec p_l[2] = DotProduct (temp, up); } - leaf = CM_PointLeaf_r( p_l, headnode ); + leaf = BSP_PointLeaf( headnode, p_l ); return leaf->contents; } @@ -1048,7 +350,7 @@ CM_ClipBoxToBrush ================ */ static void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, - trace_t *trace, cbrush_t *brush) + trace_t *trace, mbrush_t *brush) { int i, j; cplane_t *plane, *clipplane; @@ -1058,7 +360,7 @@ static void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, float d1, d2; qboolean getout, startout; float f; - cbrushside_t *side, *leadside; + mbrushside_t *side, *leadside; enterfrac = -1; leavefrac = 1; @@ -1149,7 +451,7 @@ static void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, enterfrac = 0; trace->fraction = enterfrac; trace->plane = *clipplane; - trace->surface = &(leadside->surface->c); + trace->surface = &(leadside->texinfo->c); trace->contents = brush->contents; } } @@ -1161,14 +463,14 @@ CM_TestBoxInBrush ================ */ static void CM_TestBoxInBrush (vec3_t mins, vec3_t maxs, vec3_t p1, - trace_t *trace, cbrush_t *brush) + trace_t *trace, mbrush_t *brush) { int i, j; cplane_t *plane; float dist; vec3_t ofs; float d1; - cbrushside_t *side; + mbrushside_t *side; if (!brush->numsides) return; @@ -1215,10 +517,10 @@ static void CM_TestBoxInBrush (vec3_t mins, vec3_t maxs, vec3_t p1, CM_TraceToLeaf ================ */ -static void CM_TraceToLeaf ( cleaf_t *leaf ) +static void CM_TraceToLeaf ( mleaf_t *leaf ) { int k; - cbrush_t *b, **leafbrush; + mbrush_t *b, **leafbrush; if( !( leaf->contents & trace_contents ) ) return; @@ -1246,10 +548,10 @@ static void CM_TraceToLeaf ( cleaf_t *leaf ) CM_TestInLeaf ================ */ -static void CM_TestInLeaf ( cleaf_t *leaf ) +static void CM_TestInLeaf ( mleaf_t *leaf ) { int k; - cbrush_t *b, **leafbrush; + mbrush_t *b, **leafbrush; if( !( leaf->contents & trace_contents ) ) return; @@ -1278,7 +580,7 @@ CM_RecursiveHullCheck ================== */ -static void CM_RecursiveHullCheck ( cnode_t *node, float p1f, float p2f, vec3_t p1, vec3_t p2) +static void CM_RecursiveHullCheck ( mnode_t *node, float p1f, float p2f, vec3_t p1, vec3_t p2) { cplane_t *plane; float t1, t2, offset; @@ -1296,7 +598,7 @@ recheck: // if plane is NULL, we are in a leaf node plane = node->plane; if (!plane) { - CM_TraceToLeaf ( ( cleaf_t * )node ); + CM_TraceToLeaf ( ( mleaf_t * )node ); return; } @@ -1393,7 +695,7 @@ CM_BoxTrace */ void CM_BoxTrace( trace_t *trace, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, - cnode_t *headnode, int brushmask ) + mnode_t *headnode, int brushmask ) { int i; @@ -1403,7 +705,7 @@ void CM_BoxTrace( trace_t *trace, vec3_t start, vec3_t end, trace_trace = trace; memset (trace_trace, 0, sizeof( *trace_trace )); trace_trace->fraction = 1; - trace_trace->surface = &(nullsurface.c); + trace_trace->surface = &(nulltexinfo.c); if( !headnode ) { return; @@ -1420,7 +722,7 @@ void CM_BoxTrace( trace_t *trace, vec3_t start, vec3_t end, // if (start[0] == end[0] && start[1] == end[1] && start[2] == end[2]) { - cleaf_t *leafs[1024]; + mleaf_t *leafs[1024]; int i, numleafs; vec3_t c1, c2; @@ -1488,7 +790,7 @@ rotating entities */ void CM_TransformedBoxTrace ( trace_t *trace, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, - cnode_t *headnode, int brushmask, + mnode_t *headnode, int brushmask, vec3_t origin, vec3_t angles) { vec3_t start_l, end_l; @@ -1561,80 +863,6 @@ void CM_ClipEntity( trace_t *dst, trace_t *src, struct edict_s *ent ) { /* =============================================================================== -PVS / PHS - -=============================================================================== -*/ - -static byte pvsrow[MAX_MAP_LEAFS/8]; -static byte phsrow[MAX_MAP_LEAFS/8]; - -/* -=================== -CM_DecompressVis -=================== -*/ -static void CM_DecompressVis( byte *in, byte *out, int rowsize ) { - int c; - byte *out_p; - - out_p = out; - do { - if( *in ) { - *out_p++ = *in++; - continue; - } - - c = in[1]; - in += 2; - if( ( out_p - out ) + c > rowsize ) { - c = rowsize - ( out_p - out ); - Com_WPrintf( "CM_DecompressVis: overrun\n" ); - } - while( c ) { - *out_p++ = 0; - c--; - } - } while( out_p - out < rowsize ); -} - -byte *CM_ClusterPVS( cm_t *cm, int cluster ) { - cmcache_t *cache = cm->cache; - - if( !cache || !cache->vis ) { - memset( pvsrow, 0xff, sizeof( pvsrow ) ); - } else if( cluster == -1 ) { - memset( pvsrow, 0, cache->visrowsize ); - } else { - if( cluster < 0 || cluster >= cache->vis->numclusters ) { - Com_Error( ERR_DROP, "CM_ClusterPVS: bad cluster" ); - } - CM_DecompressVis( ( byte * )cache->vis + cache->vis->bitofs[cluster][DVIS_PVS], - pvsrow, cache->visrowsize ); - } - return pvsrow; -} - -byte *CM_ClusterPHS( cm_t *cm, int cluster ) { - cmcache_t *cache = cm->cache; - - if( !cache || !cache->vis ) { - memset( phsrow, 0xff, sizeof( phsrow ) ); - } else if( cluster == -1 ) { - memset( phsrow, 0, cache->visrowsize ); - } else { - if( cluster < 0 || cluster >= cache->vis->numclusters ) { - Com_Error( ERR_DROP, "CM_ClusterPVS: bad cluster" ); - } - CM_DecompressVis( ( byte * )cache->vis + cache->vis->bitofs[cluster][DVIS_PHS], - phsrow, cache->visrowsize ); - } - return phsrow; -} - -/* -=============================================================================== - AREAPORTALS =============================================================================== @@ -1642,8 +870,8 @@ AREAPORTALS static void FloodArea_r( cm_t *cm, int number, int floodnum ) { int i; - careaportal_t *p; - carea_t *area; + mareaportal_t *p; + marea_t *area; area = &cm->cache->areas[number]; if( area->floodvalid == floodvalid ) { @@ -1668,7 +896,7 @@ CM_FloodAreaConnections */ void CM_FloodAreaConnections( cm_t *cm ) { int i; - carea_t *area; + marea_t *area; int floodnum; // all current floods are now invalid @@ -1695,7 +923,7 @@ void CM_SetAreaPortalState( cm_t *cm, int portalnum, qboolean open ) { } qboolean CM_AreasConnected( cm_t *cm, int area1, int area2 ) { - cmcache_t *cache = cm->cache; + bsp_t *cache = cm->cache; if( !cache ) { return qfalse; @@ -1728,7 +956,7 @@ This is used by the client refreshes to cull visibility ================= */ int CM_WriteAreaBits( cm_t *cm, byte *buffer, int area ) { - cmcache_t *cache = cm->cache; + bsp_t *cache = cm->cache; int i; int floodnum; int bytes; @@ -1811,8 +1039,8 @@ Returns qtrue if any leaf under headnode has a cluster that is potentially visible ============= */ -qboolean CM_HeadnodeVisible( cnode_t *node, byte *visbits ) { - cleaf_t *leaf; +qboolean CM_HeadnodeVisible( mnode_t *node, byte *visbits ) { + mleaf_t *leaf; int cluster; while( node->plane ) { @@ -1821,7 +1049,7 @@ qboolean CM_HeadnodeVisible( cnode_t *node, byte *visbits ) { node = node->children[1]; } - leaf = ( cleaf_t * )node; + leaf = ( mleaf_t * )node; cluster = leaf->cluster; if( cluster == -1 ) return qfalse; @@ -1839,18 +1067,20 @@ The client will interpolate the view position, so we can't use a single PVS point =========== */ -byte *CM_FatPVS( cm_t *cm, const vec3_t org ) { - static byte fatpvs[MAX_MAP_LEAFS/8]; - cleaf_t *leafs[64]; +byte *CM_FatPVS( cm_t *cm, byte *mask, const vec3_t org ) { + byte temp[MAX_MAP_VIS]; + mleaf_t *leafs[64]; int clusters[64]; int i, j, count; int longs; uint32_t *src, *dst; vec3_t mins, maxs; - + if( !cm->cache ) { // map not loaded - memset( fatpvs, 0, sizeof( fatpvs ) ); - return fatpvs; + return memset( mask, 0, MAX_MAP_VIS ); + } + if( !cm->cache->vis ) { + return memset( mask, 0xff, MAX_MAP_VIS ); } for( i = 0; i < 3; i++ ) { @@ -1861,18 +1091,14 @@ byte *CM_FatPVS( cm_t *cm, const vec3_t org ) { count = CM_BoxLeafs( cm, mins, maxs, leafs, 64, NULL ); if( count < 1 ) Com_Error( ERR_DROP, "CM_FatPVS: leaf count < 1" ); - longs = ( cm->cache->numclusters + 31 ) >> 5; + longs = ( cm->cache->vis->numclusters + 31 ) >> 5; // convert leafs to clusters for( i = 0 ; i < count; i++ ) { clusters[i] = leafs[i]->cluster; } - src = ( uint32_t * )CM_ClusterPVS( cm, clusters[0] ); - dst = ( uint32_t * )fatpvs; - for( j = 0; j < longs; j++ ) { - *dst++ = *src++; - } + BSP_ClusterVis( cm->cache, mask, clusters[0], DVIS_PVS ); // or in all the other leaf bits for( i = 1; i < count; i++ ) { @@ -1881,8 +1107,8 @@ byte *CM_FatPVS( cm_t *cm, const vec3_t org ) { goto nextleaf; // already have the cluster we want } } - src = ( uint32_t * )CM_ClusterPVS( cm, clusters[i] ); - dst = ( uint32_t * )fatpvs; + src = ( uint32_t * )BSP_ClusterVis( cm->cache, temp, clusters[i], DVIS_PVS ); + dst = ( uint32_t * )mask; for( j = 0; j < longs; j++ ) { *dst++ |= *src++; } @@ -1890,7 +1116,7 @@ byte *CM_FatPVS( cm_t *cm, const vec3_t org ) { nextleaf:; } - return fatpvs; + return mask; } /* diff --git a/source/cmodel.h b/source/cmodel.h new file mode 100644 index 0000000..d835c95 --- /dev/null +++ b/source/cmodel.h @@ -0,0 +1,86 @@ +/* +Copyright (C) 1997-2001 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. + +*/ + +// +// cmodel.h +// + +typedef struct { + bsp_t *cache; + int *floodnums; // if two areas have equal floodnums, + // they are connected + qboolean *portalopen; +} cm_t; + +void CM_Init( void ); + +void CM_FreeMap( cm_t *cm ); +qboolean CM_LoadMap( cm_t *cm, const char *name ); + +int CM_NumClusters( cm_t *cm ); +int CM_NumInlineModels( cm_t *cm ); +char *CM_EntityString( cm_t *cm ); +mnode_t *CM_NodeNum( cm_t *cm, int number ); +mleaf_t *CM_LeafNum( cm_t *cm, int number ); +#define CM_InlineModel( cm, name ) BSP_InlineModel( (cm)->cache, name ) + +#define CM_NumNode( cm, node ) ( (node) ? ( (node) - (cm)->cache->nodes ) : -1 ) + +// creates a clipping hull for an arbitrary box +mnode_t *CM_HeadnodeForBox( vec3_t mins, vec3_t maxs ); + + +// returns an ORed contents mask +int CM_PointContents( vec3_t p, mnode_t *headnode ); +int CM_TransformedPointContents( vec3_t p, mnode_t *headnode, + vec3_t origin, vec3_t angles ); + +void CM_BoxTrace( trace_t *trace, vec3_t start, vec3_t end, + vec3_t mins, vec3_t maxs, + mnode_t *headnode, int brushmask ); +void CM_TransformedBoxTrace( trace_t *trace, vec3_t start, vec3_t end, + vec3_t mins, vec3_t maxs, + mnode_t * headnode, int brushmask, + vec3_t origin, vec3_t angles ); +void CM_ClipEntity( trace_t *dst, trace_t *src, struct edict_s *ent ); + +// call with topnode set to the headnode, returns with topnode +// set to the first node that splits the box +int CM_BoxLeafs( cm_t *cm, vec3_t mins, vec3_t maxs, mleaf_t **list, + int listsize, mnode_t **topnode ); +mleaf_t *CM_PointLeaf( cm_t *cm, vec3_t p ); + +#define CM_LeafContents( leaf ) (leaf)->contents +#define CM_LeafCluster( leaf ) (leaf)->cluster +#define CM_LeafArea( leaf ) (leaf)->area + +byte *CM_FatPVS( cm_t *cm, byte *mask, const vec3_t org ); + +void CM_SetAreaPortalState ( cm_t *cm, int portalnum, qboolean open ); +qboolean CM_AreasConnected( cm_t *cm, int area1, int area2 ); + +int CM_WriteAreaBits( cm_t *cm, byte *buffer, int area ); +int CM_WritePortalBits( cm_t *cm, byte *buffer ); +void CM_SetPortalStates( cm_t *cm, byte *buffer, int bytes ); +qboolean CM_HeadnodeVisible( mnode_t *headnode, byte *visbits ); + +void CM_WritePortalState( cm_t *cm, fileHandle_t f ); +void CM_ReadPortalState( cm_t *cm, fileHandle_t f ); + diff --git a/source/com_local.h b/source/com_local.h index 30ce0d9..5a7a687 100644 --- a/source/com_local.h +++ b/source/com_local.h @@ -22,19 +22,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include <config.h> #include "q_shared.h" -#include "q_files.h" -#include "com_public.h" -#include "protocol.h" -#include "q_msg.h" -#ifdef DEDICATED_ONLY -#define APPLICATION "q2proded" -#else +#if USE_CLIENT #define APPLICATION "q2pro" +#else +#define APPLICATION "q2proded" #endif #define BASEGAME "baseq2" -#define BASEGAMEDESCRIPTION "Quake II" /* ============================================================== @@ -107,9 +102,25 @@ then searches for a command or variable that matches the first token. */ -typedef struct { - const char *sh, *lo, *help; -} cmd_option_t; +typedef enum cbufExecWhen_e { + EXEC_NOW, // don't return until completed + EXEC_INSERT, // insert at current position, but don't run yet + EXEC_APPEND // add to end of the command buffer +} cbufExecWhen_t; + +typedef struct genctx_s { + const char *partial; + size_t length; + int argnum; + char **matches; + int count, size; + void *data; + qboolean ignorecase; +} genctx_t; + +typedef void ( *xcommand_t )( void ); +typedef size_t ( *xmacro_t )( char *, size_t ); +typedef void ( *xcompleter_t )( struct genctx_s *, int ); typedef struct cmd_macro_s { struct cmd_macro_s *next, *hashNext; @@ -117,6 +128,16 @@ typedef struct cmd_macro_s { xmacro_t function; } cmd_macro_t; +typedef struct { + const char *sh, *lo, *help; +} cmd_option_t; + +typedef struct cmdreg_s { + const char *name; + xcommand_t function; + xcompleter_t completer; +} cmdreg_t; + void Cmd_Init( void ); qboolean Cmd_Exists( const char *cmd_name ); @@ -187,9 +208,6 @@ void Cmd_Alias_f( void ); void Cmd_WriteAliases( fileHandle_t f ); -void Cmd_FillAPI( cmdAPI_t *api ); - - #define EXEC_TRIGGER( var ) \ do { \ if( (var)->string[0] ) { \ @@ -230,6 +248,20 @@ Cvars are restricted from having the same names as commands to keep this interface from being ambiguous. */ +#define CVAR_CHEAT ( 1 << 5 ) +#define CVAR_PRIVATE ( 1 << 6 ) +#define CVAR_ROM ( 1 << 7 ) +#define CVAR_CUSTOM ( 1 << 9 ) +#define CVAR_VOLATILE ( 1 << 10 ) +#define CVAR_GAME ( 1 << 11 ) +#define CVAR_FILES ( 1 << 13 ) +#define CVAR_REFRESH ( 1 << 14 ) +#define CVAR_SOUND ( 1 << 15 ) + +#define CVAR_INFOMASK (CVAR_USERINFO|CVAR_SERVERINFO) +#define CVAR_MODIFYMASK (CVAR_INFOMASK|CVAR_FILES|CVAR_REFRESH|CVAR_SOUND) +#define CVAR_EXTENDED_MASK (~31) + typedef enum { CVAR_SET_CONSOLE, CVAR_SET_COMMAND_LINE, @@ -242,7 +274,7 @@ extern int cvar_modified; void Cvar_SetByVar( cvar_t *var, const char *value, cvarSetSource_t source ); #define Cvar_Reset( x ) \ - Cvar_SetByVar( x, (x)->default_string, CVAR_SET_CONSOLE ) + Cvar_SetByVar( x, (x)->default_string, CVAR_SET_DIRECT ) cvar_t *Cvar_UserSet( const char *var_name, const char *value ); @@ -252,8 +284,8 @@ cvar_t *Cvar_ForceSet (const char *var_name, const char *value); cvar_t *Cvar_FullSet( const char *var_name, const char *value, int flags, cvarSetSource_t source ); -void Cvar_ClampInteger( cvar_t *var, int min, int max ); -void Cvar_ClampValue( cvar_t *var, float min, float max ); +int Cvar_ClampInteger( cvar_t *var, int min, int max ); +float Cvar_ClampValue( cvar_t *var, float min, float max ); xgenerator_t Cvar_FindGenerator( const char *var_name ); @@ -314,599 +346,54 @@ cvar_t *Cvar_FindVar( const char *var_name ); void Cvar_Set_f( void ); -void Cvar_FillAPI( cvarAPI_t *api ); - -/* -============================================================== - -FIFO - -============================================================== -*/ - -typedef struct { - byte *data; - size_t size; - size_t ax, ay, bs; -} fifo_t; - -static inline void *FIFO_Reserve( fifo_t *fifo, size_t *reserved ) { - size_t tail; - - if( fifo->bs ) { - *reserved = fifo->ax - fifo->bs; - return fifo->data + fifo->bs; - } - - tail = fifo->size - fifo->ay; - if( fifo->ax < tail ) { - *reserved = tail; - return fifo->data + fifo->ay; - } - - *reserved = fifo->ax; - return fifo->data; -} - -static inline void FIFO_Commit( fifo_t *fifo, size_t len ) { - size_t tail; - - if( fifo->bs ) { - fifo->bs += len; - return; - } - - tail = fifo->size - fifo->ay; - if( fifo->ax < tail ) { - fifo->ay += len; - return; - } - - fifo->bs = len; -} - -static inline void *FIFO_Peek( fifo_t *fifo, size_t *len ) { - *len = fifo->ay - fifo->ax; - return fifo->data + fifo->ax; -} - -static inline void FIFO_Decommit( fifo_t *fifo, size_t len ) { - if( fifo->ax + len < fifo->ay ) { - fifo->ax += len; - return; - } - - fifo->ay = fifo->bs; - fifo->ax = fifo->bs = 0; -} - -static inline size_t FIFO_Usage( fifo_t *fifo ) { - return fifo->ay - fifo->ax + fifo->bs; -} - -static inline int FIFO_Percent( fifo_t *fifo ) { - if( !fifo->size ) { - return 0; - } - return ( int )( FIFO_Usage( fifo ) * 100 / fifo->size ); -} - -static inline void FIFO_Clear( fifo_t *fifo ) { - fifo->ax = fifo->ay = fifo->bs = 0; -} - -size_t FIFO_Read( fifo_t *fifo, void *buffer, size_t len ); -size_t FIFO_Write( fifo_t *fifo, const void *buffer, size_t len ); - -static inline qboolean FIFO_TryRead( fifo_t *fifo, void *buffer, size_t len ) { - if( FIFO_Read( fifo, NULL, len ) < len ) { - return qfalse; - } - FIFO_Read( fifo, buffer, len ); - return qtrue; -} - -static inline qboolean FIFO_TryWrite( fifo_t *fifo, void *buffer, size_t len ) { - if( FIFO_Write( fifo, NULL, len ) < len ) { - return qfalse; - } - FIFO_Write( fifo, buffer, len ); - return qtrue; -} - -/* -============================================================== - -NET - -============================================================== -*/ - -// net.h -- quake's interface to the networking layer - -#define PORT_ANY -1 - -#define MAX_PACKETLEN 4096 // max length of a single packet -#define PACKET_HEADER 10 // two ints and a short (worst case) -#define MAX_PACKETLEN_DEFAULT 1400 // default quake2 limit -#define MAX_PACKETLEN_WRITABLE ( MAX_PACKETLEN - PACKET_HEADER ) -#define MAX_PACKETLEN_WRITABLE_DEFAULT ( MAX_PACKETLEN_DEFAULT - PACKET_HEADER ) - -typedef enum netadrtype_e { - NA_BAD, - NA_LOOPBACK, - NA_BROADCAST, - NA_IP -} netadrtype_t; - -typedef enum netsrc_e { - NS_CLIENT, - NS_SERVER, - NS_COUNT -} netsrc_t; - -typedef enum netflag_e { - NET_NONE = 0, - NET_CLIENT = ( 1 << 0 ), - NET_SERVER = ( 1 << 1 ) -} netflag_t; - -typedef enum netstat_e { - NET_OK, - NET_AGAIN, - NET_CLOSED, - NET_ERROR, -} neterr_t; - -typedef struct netadr_s { - netadrtype_t type; - uint8_t ip[4]; - uint16_t port; -} netadr_t; - -static inline qboolean NET_IsEqualAdr( const netadr_t *a, const netadr_t *b ) { - if( a->type != b->type ) { - return qfalse; - } - - switch( a->type ) { - case NA_LOOPBACK: - return qtrue; - case NA_IP: - case NA_BROADCAST: - if( *( uint32_t * )a->ip == *( uint32_t * )b->ip && a->port == b->port ) { - return qtrue; - } - return qfalse; - default: - break; - } - - return qfalse; -} - -static inline qboolean NET_IsEqualBaseAdr( const netadr_t *a, const netadr_t *b ) { - if( a->type != b->type ) { - return qfalse; - } - - switch( a->type ) { - case NA_LOOPBACK: - return qtrue; - case NA_IP: - case NA_BROADCAST: - if( *( uint32_t * )a->ip == *( uint32_t * )b->ip ) { - return qtrue; - } - return qfalse; - default: - break; - } - - return qfalse; -} - -static inline qboolean NET_IsLanAddress( const netadr_t *adr ) { - switch( adr->type ) { - case NA_LOOPBACK: - return qtrue; - case NA_IP: - case NA_BROADCAST: - if( adr->ip[0] == 127 || adr->ip[0] == 10 ) { - return qtrue; - } - if( *( uint16_t * )adr->ip == MakeShort( 192, 168 ) || - *( uint16_t * )adr->ip == MakeShort( 172, 16 ) ) - { - return qtrue; - } - return qfalse; - default: - break; - } - - return qfalse; -} - -void NET_Init( void ); -void NET_Shutdown( void ); - -void NET_Config( netflag_t flag ); -qboolean NET_GetAddress( netsrc_t sock, netadr_t *adr ); - -neterr_t NET_GetPacket( netsrc_t sock ); -neterr_t NET_SendPacket( netsrc_t sock, const netadr_t *to, size_t length, const void *data ); -qboolean NET_GetLoopPacket( netsrc_t sock ); - -char * NET_AdrToString( const netadr_t *a ); -qboolean NET_StringToAdr( const char *s, netadr_t *a, int port ); -void NET_Sleep( int msec ); - -#ifdef DEDICATED_ONLY -#define NET_IsLocalAddress( adr ) 0 -#else -#define NET_IsLocalAddress( adr ) ( (adr)->type == NA_LOOPBACK ) -#endif - -const char *NET_ErrorString( void ); - -extern cvar_t *net_ip; -extern cvar_t *net_port; - -//============================================================================ - -typedef enum netstate_e { - NS_DISCONNECTED,// no socket opened - NS_CONNECTING, // connect() not yet completed - NS_CONNECTED, // may transmit data - NS_CLOSED, // peer has preformed orderly shutdown - NS_BROKEN // fatal error has been signaled -} netstate_t; - -typedef struct netstream_s { - int socket; - netadr_t address; - netstate_t state; - fifo_t recv; - fifo_t send; -} netstream_t; - -void NET_Close( netstream_t *s ); -neterr_t NET_Listen( qboolean listen ); -neterr_t NET_Accept( netadr_t *peer, netstream_t *s ); -neterr_t NET_Connect( const netadr_t *peer, netstream_t *s ); -neterr_t NET_Run( netstream_t *s ); - -//============================================================================ - -typedef enum netchan_type_e { - NETCHAN_OLD, - NETCHAN_NEW -} netchan_type_t; - -typedef struct netchan_s { - netchan_type_t type; - int protocol; - size_t maxpacketlen; - - qboolean fatal_error; - - netsrc_t sock; - - int dropped; // between last packet and previous - - unsigned last_received; // for timeouts - unsigned last_sent; // for retransmits - - netadr_t remote_address; - int qport; // qport value to write when transmitting - - sizebuf_t message; // writing buffer for reliable data - - size_t reliable_length; - - qboolean reliable_ack_pending; // set to qtrue each time reliable is received - qboolean fragment_pending; - - // sequencing variables - int incoming_sequence; - int incoming_acknowledged; - int outgoing_sequence; - - size_t (*Transmit)( struct netchan_s *, size_t, const void * ); - size_t (*TransmitNextFragment)( struct netchan_s * ); - qboolean (*Process)( struct netchan_s * ); - qboolean (*ShouldUpdate)( struct netchan_s * ); -} netchan_t; - -extern netadr_t net_from; - -extern cvar_t *net_qport; -extern cvar_t *net_maxmsglen; -extern cvar_t *net_chantype; - -void Netchan_Init( void ); -neterr_t Netchan_OutOfBandPrint( netsrc_t sock, const netadr_t *adr, - const char *format, ... ); -netchan_t *Netchan_Setup( netsrc_t sock, netchan_type_t type, - const netadr_t *adr, int qport, size_t maxpacketlen, int protocol ); -void Netchan_Close( netchan_t *netchan ); - -#define OOB_PRINT( sock, addr, string ) \ - NET_SendPacket( sock, addr, sizeof( "\xff\xff\xff\xff" string ) - 1, "\xff\xff\xff\xff" string ) - /* ============================================================== -CMODEL +ZONE ============================================================== */ -typedef struct mapsurface_s { // used internally due to name len probs //ZOID - csurface_t c; - char rname[32]; -} mapsurface_t; - -typedef struct cnode_s { - cplane_t *plane; // never NULL to differentiate from leafs - struct cnode_s *children[2]; -} cnode_t; - -typedef struct { - cplane_t *plane; - mapsurface_t *surface; -} cbrushside_t; - -typedef struct { - int contents; - int numsides; - cbrushside_t *firstbrushside; - int checkcount; // to avoid repeated testings -} cbrush_t; - -typedef struct { - cplane_t *plane; // always NULL to differentiate from nodes - int contents; - int cluster; - int area; - cbrush_t **firstleafbrush; - int numleafbrushes; -} cleaf_t; - -typedef struct { - int numareaportals; - int firstareaportal; - int floodvalid; -} carea_t; - -typedef struct { - unsigned portalnum; - unsigned otherarea; -} careaportal_t; - -typedef struct cmodel_s { - vec3_t mins, maxs; - vec3_t origin; // for sounds or lights - cnode_t *headnode; -} cmodel_t; - -typedef struct cmcache_s { - char name[MAX_QPATH]; - mempool_t pool; - uint32_t checksum; - qboolean onlyVis; - int refcount; - - int numbrushsides; - cbrushside_t *brushsides; - - int numtexinfo; - mapsurface_t *surfaces; - - int numplanes; - cplane_t *planes; - - int numnodes; - cnode_t *nodes; - - int numleafs; - cleaf_t *leafs; - - int numleafbrushes; - cbrush_t **leafbrushes; - - int numcmodels; - cmodel_t *cmodels; - - int numbrushes; - cbrush_t *brushes; - - int numclusters; - int numvisibility; - int visrowsize; - dvis_t *vis; - - int numEntityChars; - char *entitystring; - - int numareas; - carea_t *areas; - - int numareaportals; - careaportal_t *areaportals; -} cmcache_t; - -typedef struct { - cmcache_t *cache; - int *floodnums; // if two areas have equal floodnums, they are connected - qboolean *portalopen; -} cm_t; - -#define CM_LOAD_CLIENT 1 -#define CM_LOAD_VISONLY 2 -#define CM_LOAD_ENTONLY 4 - -void CM_Init( void ); - -void CM_FreeMap( cm_t *cm ); -const char *CM_LoadMapEx( cm_t *cm, const char *name, int flags, uint32_t *checksum ); -void CM_LoadMap( cm_t *cm, const char *name, int flags, uint32_t *checksum ); -cmodel_t *CM_InlineModel( cm_t *cm, const char *name ); // *1, *2, etc - -int CM_NumClusters( cm_t *cm ); -int CM_NumInlineModels( cm_t *cm ); -char *CM_EntityString( cm_t *cm ); -cnode_t *CM_NodeNum( cm_t *cm, int number ); -cleaf_t *CM_LeafNum( cm_t *cm, int number ); - -#define CM_NumNode( cm, node ) ( (node) ? ( (node) - (cm)->cache->nodes ) : -1 ) - -// creates a clipping hull for an arbitrary box -cnode_t *CM_HeadnodeForBox( vec3_t mins, vec3_t maxs ); - - -// returns an ORed contents mask -int CM_PointContents( vec3_t p, cnode_t *headnode ); -int CM_TransformedPointContents( vec3_t p, cnode_t *headnode, - vec3_t origin, vec3_t angles ); - -void CM_BoxTrace( trace_t *trace, vec3_t start, vec3_t end, - vec3_t mins, vec3_t maxs, - cnode_t *headnode, int brushmask ); -void CM_TransformedBoxTrace( trace_t *trace, vec3_t start, vec3_t end, - vec3_t mins, vec3_t maxs, - cnode_t * headnode, int brushmask, - vec3_t origin, vec3_t angles ); -void CM_ClipEntity( trace_t *dst, trace_t *src, struct edict_s *ent ); - -byte *CM_ClusterPVS( cm_t *cm, int cluster); -byte *CM_ClusterPHS( cm_t *cm, int cluster ); -byte *CM_FatPVS( cm_t *cm, const vec3_t org ); - -cleaf_t *CM_PointLeaf( cm_t *cm, vec3_t p ); - -// call with topnode set to the headnode, returns with topnode -// set to the first node that splits the box -int CM_BoxLeafs( cm_t *cm, vec3_t mins, vec3_t maxs, cleaf_t **list, - int listsize, cnode_t **topnode ); - -#define CM_LeafContents( leaf ) (leaf)->contents -#define CM_LeafCluster( leaf ) (leaf)->cluster -#define CM_LeafArea( leaf ) (leaf)->area - -void CM_SetAreaPortalState ( cm_t *cm, int portalnum, qboolean open ); -qboolean CM_AreasConnected( cm_t *cm, int area1, int area2 ); - -int CM_WriteAreaBits( cm_t *cm, byte *buffer, int area ); -int CM_WritePortalBits( cm_t *cm, byte *buffer ); -void CM_SetPortalStates( cm_t *cm, byte *buffer, int bytes ); -qboolean CM_HeadnodeVisible( cnode_t *headnode, byte *visbits ); - -void CM_WritePortalState( cm_t *cm, fileHandle_t f ); -void CM_ReadPortalState( cm_t *cm, fileHandle_t f ); - -/* -============================================================== - -PLAYER MOVEMENT CODE - -Common between server and client so prediction matches - -============================================================== -*/ - -typedef struct { - qboolean airaccelerate; - qboolean strafeHack; - qboolean flyfix; - int qwmod; - float speedMultiplier; -// float upspeed; - float maxspeed; - float friction; - float waterfriction; - float flyfriction; -#ifdef PMOVE_HACK - vec3_t origin; - vec3_t velocity; - qboolean highprec; -#endif -} pmoveParams_t; - -void Pmove( pmove_t *pmove, pmoveParams_t *params ); - -/* -============================================================== - -FILESYSTEM - -============================================================== -*/ - -#define FS_Malloc( size ) Z_TagMalloc( size, TAG_FILESYSTEM ) -#define FS_Mallocz( size ) Z_TagMallocz( size, TAG_FILESYSTEM ) -#define FS_CopyString( string ) Z_TagCopyString( string, TAG_FILESYSTEM ) - -void FS_Init( void ); -void FS_Shutdown( qboolean total ); -qboolean FS_NeedRestart( void ); -void FS_Restart( void ); -qboolean FS_SafeToRestart( void ); - -qboolean FS_CopyFile( const char *src, const char *dst ); -qboolean FS_RemoveFile( const char *path ); -qboolean FS_RenameFile( const char *from, const char *to ); - -char *FS_CopyExtraInfo( const char *name, const fsFileInfo_t *info ); - -size_t FS_FOpenFile( const char *filename, fileHandle_t *f, int mode ); -void FS_FCloseFile( fileHandle_t hFile ); -qboolean FS_FilterFile( fileHandle_t f ); - -size_t FS_LoadFile( const char *path, void **buffer ); -size_t FS_LoadFileEx( const char *path, void **buffer, int flags, memtag_t tag ); -void *FS_AllocTempMem( size_t length ); -void FS_FreeFile( void *buffer ); -// a null buffer will just return the file length without loading -// a -1 length is not present - -size_t FS_Read( void *buffer, size_t len, fileHandle_t hFile ); -size_t FS_Write( const void *buffer, size_t len, fileHandle_t hFile ); -// properly handles partial reads - -void FS_FPrintf( fileHandle_t f, const char *format, ... ) q_printf( 2, 3 ); -size_t FS_ReadLine( fileHandle_t f, char *buffer, int size ); - -void FS_Flush( fileHandle_t f ); - -int FS_Tell( fileHandle_t f ); -int FS_RawTell( fileHandle_t f ); - -size_t FS_GetFileLength( fileHandle_t f ); - -qboolean FS_WildCmp( const char *filter, const char *string ); -qboolean FS_ExtCmp( const char *extension, const char *string ); - -void **FS_ListFiles( const char *path, const char *extension, int flags, int *numFiles ); -void **FS_CopyList( void **list, int count ); -fsFileInfo_t *FS_CopyInfo( const char *name, size_t size, time_t ctime, time_t mtime ); -void FS_FreeList( void **list ); - -qboolean FS_LastFileFromPak( void ); - -void FS_CreatePath( const char *path ); - -//const char *FS_GetFileName( fileHandle_t f ); -const char *FS_GetFileFullPath( fileHandle_t f ); +#define Z_Malloc( size ) Z_TagMalloc( size, TAG_GENERAL ) +#define Z_Mallocz( size ) Z_TagMallocz( size, TAG_GENERAL ) +#define Z_Reserve( size ) Z_TagReserve( size, TAG_GENERAL ) +#define Z_CopyString( string ) Z_TagCopyString( string, TAG_GENERAL ) -char *FS_ReplaceSeparators( char *s, int separator ); +// memory tags to allow dynamic memory to be cleaned up +// game DLL has separate tag namespace starting at TAG_MAX +typedef enum memtag_e { + TAG_FREE, // should have never been set + TAG_STATIC, + + TAG_GENERAL, + TAG_CMD, + TAG_CVAR, + TAG_FILESYSTEM, + TAG_RENDERER, + TAG_UI, + TAG_SERVER, + TAG_MVD, + TAG_SOUND, + TAG_CMODEL, + + TAG_MAX +} memtag_t; -void FS_File_g( const char *path, const char *ext, int flags, genctx_t *ctx ); +// may return pointer to static memory +char *Cvar_CopyString( const char *in ); -void FS_FillAPI( fsAPI_t *api ); +void Z_Free( void *ptr ); +void *Z_TagMalloc( size_t size, memtag_t tag ) q_malloc; +void *Z_TagMallocz( size_t size, memtag_t tag ) q_malloc; +char *Z_TagCopyString( const char *in, memtag_t tag ) q_malloc; +void Z_FreeTags( memtag_t tag ); +void Z_LeakTest( memtag_t tag ); +void Z_Check( void ); -extern cvar_t *fs_game; +void Z_TagReserve( size_t size, memtag_t tag ); +void *Z_ReservedAlloc( size_t size ) q_malloc; +void *Z_ReservedAllocz( size_t size ) q_malloc; +char *Z_ReservedCopyString( const char *in ) q_malloc; /* ============================================================== @@ -916,6 +403,8 @@ MISC ============================================================== */ +#define MAXPRINTMSG 4096 + typedef struct { const char *name; void (* const func)( void ); @@ -943,8 +432,6 @@ void Com_EndRedirect (void); void Com_LevelPrint( comPrintType_t type, const char *str ); void Com_LevelError( comErrorType_t code, const char *str ) q_noreturn; -void Com_FillAPI( commonAPI_t *api ); - void Com_Quit( const char *reason ); byte COM_BlockSequenceCRCByte (byte *base, size_t length, int sequence); @@ -962,28 +449,6 @@ size_t Com_Uptime_m( char *buffer, size_t size ); uint32_t Com_BlockChecksum( void *buffer, size_t len ); - -// may return pointer to static memory -char *Cvar_CopyString( const char *in ); - -void Z_Free( void *ptr ); -void *Z_TagMalloc( size_t size, memtag_t tag ) q_malloc; -void *Z_TagMallocz( size_t size, memtag_t tag ) q_malloc; -char *Z_TagCopyString( const char *in, memtag_t tag ) q_malloc; -void Z_FreeTags( memtag_t tag ); -void Z_LeakTest( memtag_t tag ); -void Z_Check( void ); - -void Z_TagReserve( size_t size, memtag_t tag ); -void *Z_ReservedAlloc( size_t size ) q_malloc; -void *Z_ReservedAllocz( size_t size ) q_malloc; -char *Z_ReservedCopyString( const char *in ) q_malloc; - -#define Z_Malloc( size ) Z_TagMalloc( size, TAG_GENERAL ) -#define Z_Mallocz( size ) Z_TagMallocz( size, TAG_GENERAL ) -#define Z_Reserve( size ) Z_TagReserve( size, TAG_GENERAL ) -#define Z_CopyString( string ) Z_TagCopyString( string, TAG_GENERAL ) - extern cvar_t *developer; extern cvar_t *dedicated; extern cvar_t *host_speeds; @@ -999,7 +464,7 @@ extern cvar_t *com_sleep; extern FILE *log_stats_file; -#ifndef DEDICATED_ONLY +#if USE_CLIENT // host_speeds times extern unsigned time_before_game; extern unsigned time_after_game; @@ -1019,63 +484,6 @@ void Qcommon_Init( int argc, char **argv ); void Qcommon_Frame( void ); void Qcommon_Shutdown( qboolean fatalError ); -// this is in the client code, but can be used for debugging from server -void SCR_DebugGraph (float value, int color); - -/* -============================================================== - -NON-PORTABLE SYSTEM SERVICES - -============================================================== -*/ - -// loads the dll and returns entry pointer -void *Sys_LoadLibrary( const char *path, const char *sym, void **handle ); -void Sys_FreeLibrary( void *handle ); -void *Sys_GetProcAddress( void *handle, const char *sym ); - -unsigned Sys_Milliseconds( void ); -void Sys_Sleep( int msec ); - -void Hunk_Begin( mempool_t *pool, size_t maxsize ); -void *Hunk_Alloc( mempool_t *pool, size_t size ); -void Hunk_Free( mempool_t *pool ); - -void Sys_Init( void ); -void Sys_FillAPI( sysAPI_t *api ); -void Sys_AddDefaultConfig( void ); - -void Sys_RunConsole( void ); -void Sys_ConsoleOutput( const char *string ); -void Sys_SetConsoleTitle( const char *title ); -void Sys_Printf( const char *fmt, ... ) q_printf( 1, 2 ); -void Sys_Error( const char *error, ... ) q_noreturn q_printf( 1, 2 ); -void Sys_Quit( void ); - -void **Sys_ListFiles( const char *path, const char *extension, int flags, size_t length, int *numFiles ); - -qboolean Sys_GetPathInfo( const char *path, fsFileInfo_t *info ); -qboolean Sys_GetFileInfo( FILE *fp, fsFileInfo_t *info ); - -char *Sys_GetCurrentDirectory( void ); - -void Sys_DebugBreak( void ); - -void Sys_FixFPCW( void ); - -#ifdef USE_ANTICHEAT -qboolean Sys_GetAntiCheatAPI( void ); -#endif - -extern cvar_t *sys_basedir; -extern cvar_t *sys_libdir; -extern cvar_t *sys_refdir; -extern cvar_t *sys_homedir; -#ifdef __unix__ -extern cvar_t *sys_stdio; -#endif - /* ============================================================== @@ -1092,59 +500,4 @@ extern cvar_t *allow_download_maps; extern cvar_t *allow_download_demos; extern cvar_t *allow_download_other; -typedef enum { - ACT_MINIMIZED, - ACT_RESTORED, - ACT_ACTIVATED -} active_t; - -void CL_PumpEvents( void ); -void CL_PacketEvent( neterr_t ret ); -void CL_Init (void); -void CL_Disconnect( comErrorType_t type, const char *text ); -void CL_Shutdown (void); -void CL_Frame (int msec); -void Con_Print( const char *text ); -void Con_Printf( const char *fmt, ... ); -void Con_Close( void ); -void SCR_BeginLoadingPlaque (void); -void SCR_ModeChanged( void ); -void SCR_UpdateScreen( void ); -void CL_LocalConnect( void ); -void CL_RestartFilesystem( void ); -void CL_Activate( active_t active ); -void CL_UpdateUserinfo( cvar_t *var, cvarSetSource_t source ); - -void IN_Frame( void ); -void IN_Activate( void ); -void IN_MouseEvent( int x, int y ); -void IN_WarpMouse( int x, int y ); - -void Key_Init( void ); -void Key_Event( unsigned key, qboolean down, unsigned time ); -void Key_CharEvent( int key ); -void Key_WriteBindings( fileHandle_t f ); - -char *VID_GetClipboardData( void ); -void VID_SetClipboardData( const char *data ); -void VID_FatalShutdown( void ); - -typedef enum { - ss_dead, // no map loaded - ss_loading, // spawning level edicts - ss_game, // actively running - ss_broadcast -} server_state_t; - -typedef enum { - KILL_RESTART, - KILL_DISCONNECT, - KILL_DROP -} killtype_t; - -void SV_PacketEvent( neterr_t ret ); -void SV_Init (void); -void SV_Shutdown( const char *finalmsg, killtype_t type ); -void SV_Frame (int msec); -qboolean MVD_GetDemoPercent( int *percent, int *bufferPercent ); diff --git a/source/com_public.h b/source/com_public.h deleted file mode 100644 index 8f79815..0000000 --- a/source/com_public.h +++ /dev/null @@ -1,340 +0,0 @@ -/* -Copyright (C) 1997-2001 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. - -*/ - -// com_public.h -- interfaces for common subsystems - -#ifndef _COM_PUBLIC_H_ -#define _COM_PUBLIC_H_ - -/* -============================================================== - -COMMON - -============================================================== -*/ - -#define MAXPRINTMSG 4096 - -// memory tags to allow dynamic memory to be cleaned up -typedef enum memtag_e { - TAG_FREE, // should have never been set - TAG_STATIC, - - TAG_GENERAL, - TAG_CMD, - TAG_CVAR, - TAG_FILESYSTEM, - TAG_RENDERER, - TAG_UI, - TAG_SERVER, - TAG_MVD, - TAG_SOUND, - TAG_CMODEL, - - TAG_MAX, - - TAG_GAME = 765, // clear when unloading the dll - TAG_LEVEL = 766 // clear when loading a new level -} memtag_t; - -typedef struct commonAPI_s { - void (* q_noreturn Error)( comErrorType_t code, const char *str ); - void (*Print)( comPrintType_t type, const char *str ); - - void *(*TagMalloc)( size_t size, memtag_t tag ); - void *(*Realloc)( void *ptr, size_t size ); - void (*Free)( void *ptr ); -} commonAPI_t; - -extern commonAPI_t com; - - -/* -============================================================== - -CMD - -============================================================== -*/ - -typedef enum cbufExecWhen_e { - EXEC_NOW, // don't return until completed - EXEC_INSERT, // insert at current position, but don't run yet - EXEC_APPEND // add to end of the command buffer -} cbufExecWhen_t; - -typedef void ( *xcommand_t )( void ); -typedef size_t ( *xmacro_t )( char *, size_t ); -typedef void ( *xcompleter_t )( struct genctx_s *, int ); - -typedef struct genctx_s { - const char *partial; - size_t length; - int argnum; - char **matches; - int count, size; - void *data; - qboolean ignorecase; -} genctx_t; - -typedef struct cmdreg_s { - const char *name; - xcommand_t function; - xcompleter_t completer; -} cmdreg_t; - -typedef struct cmdAPI_s { - void (*ExecuteText)( cbufExecWhen_t exec_when, const char *text ); - int (*Argc)( void ); - char *(*Argv)( int arg ); - void (*ArgvBuffer)( int arg, char *buffer, int bufferSize ); - char *(*Args)( void ); - void (*ArgsBuffer)( char *buffer, int bufferSize ); - char *(*ArgsFrom)( int from ); - void (*Register)( const cmdreg_t *regs ); - void (*Deregister)( const cmdreg_t *regs ); - void (*AddCommand)( const char *cmd_name, xcommand_t function ); - void (*RemoveCommand)( const char *cmd_name ); - xcommand_t (*FindFunction)( const char *name ); -} cmdAPI_t; - -extern cmdAPI_t cmd; - -/* -============================================================== - -CVAR - -============================================================== -*/ - -#define CVAR_CHEAT ( 1 << 5 ) -#define CVAR_PRIVATE ( 1 << 6 ) -#define CVAR_ROM ( 1 << 7 ) -#define CVAR_CUSTOM ( 1 << 9 ) -#define CVAR_VOLATILE ( 1 << 10 ) -#define CVAR_GAME ( 1 << 11 ) -#define CVAR_FILES ( 1 << 13 ) -#define CVAR_REFRESH ( 1 << 14 ) -#define CVAR_SOUND ( 1 << 15 ) - -#define CVAR_INFOMASK (CVAR_USERINFO|CVAR_SERVERINFO) -#define CVAR_MODIFYMASK (CVAR_INFOMASK|CVAR_FILES|CVAR_REFRESH|CVAR_SOUND) -#define CVAR_EXTENDED_MASK (~31) - -typedef struct cvarAPI_s { - float (*VariableValue)( const char *var_name ); - int (*VariableInteger)( const char *var_name ); - char *(*VariableString)( const char *var_name ); - void (*VariableStringBuffer)( const char *var_name, char *buffer, int bufferSize ); - cvar_t *(*Get)( const char *var_name, const char *var_value, int flags ); - cvar_t *(*Set)( const char *var_name, const char *value ); - cvar_t *(*Find)( const char *var_name ); -} cvarAPI_t; - -extern cvarAPI_t cvar; - -/* -============================================================== - -FILESYSTEM - -============================================================== -*/ - -#define MAX_LISTED_FILES 4096 - -typedef struct fsFileInfo_s { - size_t size; - time_t ctime; - time_t mtime; - char name[1]; -} fsFileInfo_t; - -/* bits 0 - 1, enum */ -#define FS_MODE_APPEND 0x00000000 -#define FS_MODE_READ 0x00000001 -#define FS_MODE_WRITE 0x00000002 -#define FS_MODE_RDWR 0x00000003 -#define FS_MODE_MASK 0x00000003 - -/* bits 0 - 1, enum */ -#define FS_SEARCHDIRS_NO 0x00000000 -#define FS_SEARCHDIRS_YES 0x00000001 -#define FS_SEARCHDIRS_ONLY 0x00000002 -#define FS_SEARCHDIRS_RESERVED 0x00000003 -#define FS_SEARCHDIRS_MASK 0x00000003 - -/* bit 2, enum */ -#define FS_FLUSH_NONE 0x00000000 -#define FS_FLUSH_SYNC 0x00000004 -#define FS_FLUSH_MASK 0x00000004 - -/* bits 3 - 4, enum */ -#define FS_TYPE_ANY 0x00000000 -#define FS_TYPE_REAL 0x00000008 -#define FS_TYPE_PAK 0x00000010 -#define FS_TYPE_RESERVED 0x00000018 -#define FS_TYPE_MASK 0x00000018 - -/* bits 5 - 6, flag */ -#define FS_PATH_ANY 0x00000000 -#define FS_PATH_BASE 0x00000020 -#define FS_PATH_GAME 0x00000040 -#define FS_PATH_MASK 0x00000060 - -/* bits 7 - 10, flag */ -#define FS_SEARCH_BYFILTER 0x00000080 -#define FS_SEARCH_SAVEPATH 0x00000100 -#define FS_SEARCH_EXTRAINFO 0x00000200 -#define FS_SEARCH_NOSORT 0x00000400 - -/* bits 7 - 8, flag */ -#define FS_FLAG_RESERVED1 0x00000080 -#define FS_FLAG_RESERVED2 0x00000100 - -#define INVALID_LENGTH ((size_t)-1) - -typedef struct fsAPI_s { - void (*FCloseFile)( fileHandle_t f ); - size_t (*Read)( void *buffer, size_t len, fileHandle_t f ); - size_t (*Write)( const void *buffer, size_t len, fileHandle_t f ); - size_t (*FOpenFile)( const char *filename, fileHandle_t *f, int mode ); - void (*FPrintf)( fileHandle_t f, const char *format, ... ); - size_t (*ReadLine)( fileHandle_t f, char *buffer, int size ); - int (*Tell)( fileHandle_t f ); - int (*RawTell)( fileHandle_t f ); - size_t (*LoadFile)( const char *path, void **buffer ); - size_t (*LoadFileEx)( const char *path, void **buffer, int flags, memtag_t tag ); - void *(*AllocTempMem)( size_t length ); - void (*FreeFile)( void *buffer ); - void **(*ListFiles)( const char *path, const char *extension, int flags, int *numFiles ); - void (*FreeList)( void **list ); -} fsAPI_t; - -extern fsAPI_t fs; - -/* -============================================================== - -SYSTEM - -============================================================== -*/ - -typedef struct { - void *base; - size_t maxsize; - size_t cursize; - size_t mapped; -} mempool_t; - -typedef struct sysAPI_s { - unsigned (*Milliseconds)( void ); - void (*HunkBegin)( mempool_t *pool, size_t maxsize ); - void *(*HunkAlloc)( mempool_t *pool, size_t size ); - void (*HunkEnd)( mempool_t *pool ); - void (*HunkFree)( mempool_t *pool ); -} sysAPI_t; - -extern sysAPI_t sys; - -/* -============================================================== - -MODULES - -============================================================== -*/ - -// if api_version is different, the dll cannot be used -#define MODULES_APIVERSION 318 - -typedef enum moduleQuery_e { - MQ_GETINFO, - MQ_GETCAPS, - MQ_SETUPAPI -} moduleQuery_t; - -typedef enum moduleCapability_e { - MCP_EMPTY = (0<<0), - MCP_VIDEO_SOFTWARE = (1<<0), - MCP_VIDEO_OPENGL = (1<<1), - MCP_REFRESH = (1<<2), - MCP_SOUND = (1<<3), - MCP_INPUT = (1<<4), - MCP_UI = (1<<5) -} moduleCapability_t; - -typedef struct moduleInfo_s { - // if api_version is different, the dll cannot be used - int api_version; - char fullname[MAX_QPATH]; - char author[MAX_QPATH]; -} moduleInfo_t; - -// this is the only function actually exported at the linker level -typedef void *(*moduleEntry_t)( int, void * ); - -// API types used in MQ_SETUPAPI query -typedef enum api_type_e { - API_CMD, - API_CVAR, - API_FS, - API_COMMON, - API_KEYS, - API_SYSTEM, - API_VIDEO_SOFTWARE, - API_VIDEO_OPENGL, - API_REFRESH, - API_INPUT, - API_UI, - API_CLIENT -} api_type_t; - -// passed along with MQ_SETUPAPI query -typedef void (*APISetupCallback_t)( int, void * ); - -#if 0 -typedef enum { - // exported - API_REFRESH, - API_UI, - API_GAME, - - // imported - API_CMD, - API_CVAR, - API_FS, - API_COMMON, - API_KEYS, - API_SYSTEM, - API_VIDEO_SOFTWARE, - API_VIDEO_OPENGL -} api_type_t; - -typedef void (*api_callback_t)( int, void * ); - -// this is the only function actually exported at the linker level -typedef void *(*moduleEntry_t)( api_type_t, api_callback_t ); -#endif - -#endif // _COM_PUBLIC_H_ diff --git a/source/common.c b/source/common.c index 1ef854b..d1f3109 100644 --- a/source/common.c +++ b/source/common.c @@ -19,13 +19,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // common.c -- misc functions used in client and server #include "com_local.h" +#include "files.h" +#include "protocol.h" +#include "q_msg.h" +#include "q_fifo.h" +#include "net_sock.h" +#include "net_chan.h" +#include "sys_public.h" +#include "cl_public.h" +#include "sv_public.h" +#include "q_list.h" +#include "bsp.h" +#include "cmodel.h" #include <setjmp.h> #if USE_ZLIB #include <zlib.h> #endif -commonAPI_t com; - static jmp_buf abortframe; // an ERR_DROP occured, exit the entire frame static char com_errorMsg[MAXPRINTMSG]; @@ -33,9 +43,6 @@ static char com_errorMsg[MAXPRINTMSG]; static char **com_argv; static int com_argc; -#ifndef DEDICATED_ONLY -cvar_t *host_speeds; -#endif cvar_t *developer; cvar_t *timescale; cvar_t *fixedtime; @@ -64,7 +71,9 @@ unsigned com_localTime; qboolean com_initialized; time_t com_startTime; -#ifndef DEDICATED_ONLY +#if USE_CLIENT +cvar_t *host_speeds; + // host_speeds times unsigned time_before_game; unsigned time_after_game; @@ -85,9 +94,9 @@ CLIENT / SERVER interactions */ static int rd_target; -static char *rd_buffer; +static char *rd_buffer; static size_t rd_buffersize; -static size_t rd_length; +static size_t rd_length; static rdflush_t rd_flush; void Com_BeginRedirect( int target, char *buffer, size_t buffersize, rdflush_t flush ) { @@ -950,19 +959,6 @@ size_t FIFO_Write( fifo_t *fifo, const void *buffer, size_t len ) { /* ============= -Com_FillAPI -============= -*/ -void Com_FillAPI( commonAPI_t *api ) { - api->Print = Com_LevelPrint; - api->Error = Com_LevelError; - api->TagMalloc = Z_TagMalloc; - api->Realloc = Z_Realloc; - api->Free = Z_Free; -} - -/* -============= Com_Time_m ============= */ @@ -1277,13 +1273,11 @@ void Qcommon_Init( int argc, char **argv ) { Prompt_Init(); Con_Init(); - Com_FillAPI( &com ); - // // init commands and vars // z_perturb = Cvar_Get( "z_perturb", "0", 0 ); -#ifndef DEDICATED_ONLY +#if USE_CLIENT host_speeds = Cvar_Get ("host_speeds", "0", 0); #endif developer = Cvar_Get ("developer", "0", 0); @@ -1293,10 +1287,10 @@ void Qcommon_Init( int argc, char **argv ) { logfile_flush = Cvar_Get( "logfile_flush", "0", 0 ); logfile_name = Cvar_Get( "logfile_name", COM_LOGFILE_NAME, 0 ); logfile_prefix = Cvar_Get( "logfile_prefix", "[%Y-%m-%d %H:%M] ", 0 ); -#ifdef DEDICATED_ONLY - dedicated = Cvar_Get ("dedicated", "1", CVAR_ROM); -#else +#if USE_CLIENT dedicated = Cvar_Get ("dedicated", "0", CVAR_NOSET); +#else + dedicated = Cvar_Get ("dedicated", "1", CVAR_ROM); #endif sv_running = Cvar_Get( "sv_running", "0", CVAR_ROM ); sv_paused = Cvar_Get( "sv_paused", "0", CVAR_ROM ); @@ -1340,7 +1334,7 @@ void Qcommon_Init( int argc, char **argv ) { Sys_RunConsole(); - // do not accept CVAR_NOSET variable changes anymore + // no longer allow CVAR_NOSET modifications com_initialized = qtrue; // after FS is initialized, open logfile @@ -1375,6 +1369,7 @@ void Qcommon_Init( int argc, char **argv ) { Netchan_Init(); NET_Init(); + BSP_Init(); CM_Init(); SV_Init(); CL_Init(); @@ -1421,62 +1416,13 @@ Com_ProcessEvents ============== */ void Com_ProcessEvents( void ) { - neterr_t ret; - - do { - ret = NET_GetPacket( NS_SERVER ); - if( ret == NET_AGAIN ) { - break; - } - SV_PacketEvent( ret ); - } while( ret == NET_OK ); - Sys_RunConsole(); - -#ifndef DEDICATED_ONLY - do { - ret = NET_GetPacket( NS_CLIENT ); - if( ret == NET_AGAIN ) { - break; - } - if( cl_running->integer ) { - CL_PacketEvent( ret ); - } - } while( ret == NET_OK ); - - CL_PumpEvents(); - IN_Frame(); + SV_ProcessEvents(); +#if USE_CLIENT + CL_ProcessEvents(); #endif } -#ifndef DEDICATED_ONLY -/* -============== -Com_ProcessLoopback -============== -*/ -static void Com_ProcessLoopback( void ) { - int i; - - memset( &net_from, 0, sizeof( net_from ) ); - net_from.type = NA_LOOPBACK; - - // Process loopback packets - for( i = 0; i < 2; i++ ) { - while( NET_GetLoopPacket( NS_SERVER ) ) { - if( sv_running->integer ) { - SV_PacketEvent( NET_OK ); - } - } - - while( NET_GetLoopPacket( NS_CLIENT ) ) { - if( cl_running->integer ) { - CL_PacketEvent( NET_OK ); - } - } - } -} -#endif /* ================= @@ -1484,7 +1430,7 @@ Qcommon_Frame ================= */ void Qcommon_Frame( void ) { -#ifndef DEDICATED_ONLY +#if USE_CLIENT unsigned time_before, time_event, time_between, time_after; #endif unsigned oldtime, msec; @@ -1494,7 +1440,7 @@ void Qcommon_Frame( void ) { return; // an ERR_DROP was thrown } -#ifndef DEDICATED_ONLY +#if USE_CLIENT time_before = time_event = time_between = time_after = 0; if( host_speeds->integer ) @@ -1511,7 +1457,7 @@ void Qcommon_Frame( void ) { Com_ProcessEvents(); -#ifndef DEDICATED_ONLY +#if USE_CLIENT // spin until msec is non-zero if running a client if( !dedicated->integer ) { while( msec < 1 ) { @@ -1540,19 +1486,17 @@ void Qcommon_Frame( void ) { // this is the only place where console commands are processed. Cbuf_Execute(); -#ifndef DEDICATED_ONLY +#if USE_CLIENT if( host_speeds->integer ) time_event = Sys_Milliseconds(); #endif SV_Frame( msec ); -#ifndef DEDICATED_ONLY +#if USE_CLIENT if( host_speeds->integer ) time_between = Sys_Milliseconds(); - Com_ProcessLoopback(); - CL_Frame( msec ); if( host_speeds->integer ) diff --git a/source/cvar.c b/source/cvar.c index 564c989..0d18cf4 100644 --- a/source/cvar.c +++ b/source/cvar.c @@ -20,8 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // cvar.c -- dynamic variable tracking #include "com_local.h" - -cvarAPI_t cvar; +#include "cl_public.h" +#include "files.h" cvar_t *cvar_vars; @@ -531,16 +531,20 @@ void Cvar_SetHex( cvar_t *var, int value, cvarSetSource_t source ) { Cvar_ClampInteger ============ */ -void Cvar_ClampInteger( cvar_t *var, int min, int max ) { +int Cvar_ClampInteger( cvar_t *var, int min, int max ) { char val[32]; if( var->integer < min ) { Com_sprintf( val, sizeof( val ), "%i", min ); Cvar_SetByVar( var, val, CVAR_SET_DIRECT ); - } else if( var->integer > max ) { + return min; + } + if( var->integer > max ) { Com_sprintf( val, sizeof( val ), "%i", max ); Cvar_SetByVar( var, val, CVAR_SET_DIRECT ); + return max; } + return var->integer; } /* @@ -548,7 +552,7 @@ void Cvar_ClampInteger( cvar_t *var, int min, int max ) { Cvar_ClampValue ============ */ -void Cvar_ClampValue( cvar_t *var, float min, float max ) { +float Cvar_ClampValue( cvar_t *var, float min, float max ) { char val[32]; if( var->value < min ) { @@ -558,14 +562,18 @@ void Cvar_ClampValue( cvar_t *var, float min, float max ) { Com_sprintf( val, sizeof( val ), "%f", min ); } Cvar_SetByVar( var, val, CVAR_SET_DIRECT ); - } else if( var->value > max ) { + return min; + } + if( var->value > max ) { if( max == (int)max ) { Com_sprintf( val, sizeof( val ), "%i", (int)max ); } else { Com_sprintf( val, sizeof( val ), "%f", max ); } Cvar_SetByVar( var, val, CVAR_SET_DIRECT ); + return max; } + return var->value; } /* @@ -726,7 +734,7 @@ static void Cvar_SetFlag_f( void ) { Cvar_FullSet( Cmd_Argv( 1 ), Cmd_ArgsFrom( 2 ), flags, CVAR_SET_CONSOLE ); } -#ifndef DEDICATED_ONLY +#if USE_CLIENT /* ============ @@ -1060,22 +1068,6 @@ size_t Cvar_BitInfo( char *info, int bit ) { return total; } - -/* -============ -Cvar_FillAPI -============ -*/ -void Cvar_FillAPI( cvarAPI_t *api ) { - api->Get = Cvar_Get; - api->Set = Cvar_Set; - api->Find = Cvar_FindVar; - api->VariableValue = Cvar_VariableValue; - api->VariableInteger = Cvar_VariableInteger; - api->VariableString = Cvar_VariableString; - api->VariableStringBuffer = Cvar_VariableStringBuffer; -} - static const cmdreg_t c_cvar[] = { { "set", Cvar_Set_f, Cvar_Set_c }, { "setu", Cvar_SetFlag_f, Cvar_Set_c }, @@ -1099,7 +1091,5 @@ void Cvar_Init( void ) { cvar_silent = Cvar_Get( "cvar_silent", "0", 0 ); Cmd_Register( c_cvar ); - - Cvar_FillAPI( &cvar ); } diff --git a/source/d_bsp.h b/source/d_bsp.h new file mode 100644 index 0000000..8036860 --- /dev/null +++ b/source/d_bsp.h @@ -0,0 +1,212 @@ +/* +Copyright (C) 1997-2001 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. + +*/ + +/* +============================================================================== + +.BSP file format + +============================================================================== +*/ + +#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') +#define BSPVERSION 38 + + +// upper design bounds +// leaffaces, leafbrushes, planes, and verts are still bounded by +// 16 bit short limits +#define MAX_MAP_MODELS 1024 +#define MAX_MAP_BRUSHES 8192 +#define MAX_MAP_ENTITIES 2048 +#define MAX_MAP_ENTSTRING 0x40000 +#define MAX_MAP_TEXINFO 8192 + +#define MAX_MAP_AREAS 256 +#define MAX_MAP_AREAPORTALS 1024 +#define MAX_MAP_PLANES 65536 +#define MAX_MAP_NODES 65536 +#define MAX_MAP_BRUSHSIDES 65536 +#define MAX_MAP_LEAFS 65536 +#define MAX_MAP_VERTS 65536 +#define MAX_MAP_VERTEXES MAX_MAP_VERTS +#define MAX_MAP_FACES 65536 +#define MAX_MAP_LEAFFACES 65536 +#define MAX_MAP_LEAFBRUSHES 65536 +#define MAX_MAP_PORTALS 65536 +#define MAX_MAP_EDGES 128000 +#define MAX_MAP_SURFEDGES 256000 +#define MAX_MAP_LIGHTING 0x200000 +#define MAX_MAP_VISIBILITY 0x100000 + +// key / value pair sizes + +#define MAX_KEY 32 +#define MAX_VALUE 1024 + +#define MAX_TEXNAME 32 + +//============================================================================= + +typedef struct { + uint32_t fileofs, filelen; +} lump_t; + +#define LUMP_ENTITIES 0 +#define LUMP_ENTSTRING LUMP_ENTITIES +#define LUMP_PLANES 1 +#define LUMP_VERTEXES 2 +#define LUMP_VISIBILITY 3 +#define LUMP_NODES 4 +#define LUMP_TEXINFO 5 +#define LUMP_FACES 6 +#define LUMP_LIGHTING 7 +#define LUMP_LEAFS 8 +#define LUMP_LEAFFACES 9 +#define LUMP_LEAFBRUSHES 10 +#define LUMP_EDGES 11 +#define LUMP_SURFEDGES 12 +#define LUMP_MODELS 13 +#define LUMP_BRUSHES 14 +#define LUMP_BRUSHSIDES 15 +#define LUMP_POP 16 +#define LUMP_AREAS 17 +#define LUMP_AREAPORTALS 18 +#define HEADER_LUMPS 19 + +typedef struct { + uint32_t ident; + uint32_t version; + lump_t lumps[HEADER_LUMPS]; +} dheader_t; + +typedef struct { + float mins[3], maxs[3]; + float origin[3]; // for sounds or lights + uint32_t headnode; + uint32_t firstface, numfaces; // submodels just draw faces + // without walking the bsp tree +} dmodel_t; + +typedef struct { + float point[3]; +} dvertex_t; + +typedef struct { + float normal[3]; + float dist; + uint32_t type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate +} dplane_t; + +typedef struct { + uint32_t planenum; + uint32_t children[2]; // negative numbers are -(leafs+1), not nodes + int16_t mins[3]; // for frustom culling + int16_t maxs[3]; + uint16_t firstface; + uint16_t numfaces; // counting both sides +} dnode_t; + +typedef struct { + float vecs[2][4]; // [s/t][xyz offset] + uint32_t flags; // miptex flags + overrides + int32_t value; // light emission, etc + char texture[MAX_TEXNAME]; // texture name (textures/*.wal) + uint32_t nexttexinfo; // for animations, -1 = end of chain +} dtexinfo_t; + +// note that edge 0 is never used, because negative edge nums are used for +// counterclockwise use of the edge in a face +typedef struct { + uint16_t v[2]; // vertex numbers +} dedge_t; + +#define MAX_LIGHTMAPS 4 + +typedef struct { + uint16_t planenum; + uint16_t side; + + uint32_t firstedge; // we must support > 64k edges + uint16_t numedges; + uint16_t texinfo; + +// lighting info + uint8_t styles[MAX_LIGHTMAPS]; + uint32_t lightofs; // start of [numstyles*surfsize] samples +} dface_t; + +typedef struct { + uint32_t contents; // OR of all brushes (not needed?) + + uint16_t cluster; + uint16_t area; + + int16_t mins[3]; // for frustum culling + int16_t maxs[3]; + + uint16_t firstleafface; + uint16_t numleaffaces; + + uint16_t firstleafbrush; + uint16_t numleafbrushes; +} dleaf_t; + +typedef struct { + uint16_t planenum; // facing out of the leaf + uint16_t texinfo; +} dbrushside_t; + +typedef struct { + uint32_t firstside; + uint32_t numsides; + uint32_t contents; +} dbrush_t; + +#define ANGLE_UP -1 +#define ANGLE_DOWN -2 + + +// the visibility lump consists of a header with a count, then +// byte offsets for the PVS and PHS of each cluster, then the raw +// compressed bit vectors +#define DVIS_PVS 0 +#define DVIS_PHS 1 + +#define DVIS_CLUSTERS 8 + +typedef struct { + uint32_t numclusters; + uint32_t bitofs[DVIS_CLUSTERS][2]; // bitofs[numclusters][2] +} dvis_t; + +// each area has a list of portals that lead into other areas +// when portals are closed, other areas may not be visible or +// hearable even if the vis info says that it should be +typedef struct { + uint32_t portalnum; + uint32_t otherarea; +} dareaportal_t; + +typedef struct { + uint32_t numareaportals; + uint32_t firstareaportal; +} darea_t; + diff --git a/source/d_md2.h b/source/d_md2.h new file mode 100644 index 0000000..be907ed --- /dev/null +++ b/source/d_md2.h @@ -0,0 +1,97 @@ +/* +Copyright (C) 1997-2001 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. + +*/ + +/* +======================================================================== + +.MD2 triangle model file format + +======================================================================== +*/ + +#define MD2_IDENT (('2'<<24)+('P'<<16)+('D'<<8)+'I') +#define MD2_VERSION 8 + +#define MD2_MAX_TRIANGLES 4096 +#define MD2_MAX_VERTS 2048 +#define MD2_MAX_FRAMES 512 +#define MD2_MAX_SKINS 32 +#define MD2_MAX_SKINNAME 64 +#define MD2_MAX_SKINWIDTH 640 +#define MD2_MAX_SKINHEIGHT 480 + +typedef struct { + int16_t s; + int16_t t; +} dmd2stvert_t; + +typedef struct { + uint16_t index_xyz[3]; + uint16_t index_st[3]; +} dmd2triangle_t; + +typedef struct { + uint8_t v[3]; // scaled byte to fit in frame mins/maxs + uint8_t lightnormalindex; +} dmd2trivertx_t; + +typedef struct { + float scale[3]; // multiply byte verts by this + float translate[3]; // then add this + char name[16]; // frame name from grabbing + dmd2trivertx_t verts[1]; // variable sized +} dmd2frame_t; + +#define MD2_MAX_FRAMESIZE \ + ( sizeof( dmd2frame_t ) + sizeof( dmd2trivertx_t ) * ( MD2_MAX_VERTS - 1 ) ) + + +// the glcmd format: +// a positive integer starts a tristrip command, followed by that many +// vertex structures. +// a negative integer starts a trifan command, followed by -x vertexes +// a zero indicates the end of the command list. +// a vertex consists of a floating point s, a floating point t, +// and an integer vertex index. + + +typedef struct dmd2header_s { + uint32_t ident; + uint32_t version; + + uint32_t skinwidth; + uint32_t skinheight; + uint32_t framesize; // byte size of each frame + + uint32_t num_skins; + uint32_t num_xyz; + uint32_t num_st; // greater than num_xyz for seams + uint32_t num_tris; + uint32_t num_glcmds; // dwords in strip/fan command list + uint32_t num_frames; + + uint32_t ofs_skins; // each skin is a MAX_SKINNAME string + uint32_t ofs_st; // byte offset from start for stverts + uint32_t ofs_tris; // offset for dtriangles + uint32_t ofs_frames; // offset for first frame + uint32_t ofs_glcmds; + uint32_t ofs_end; // end of file +} dmd2header_t; + diff --git a/source/d_md3.h b/source/d_md3.h new file mode 100644 index 0000000..332d732 --- /dev/null +++ b/source/d_md3.h @@ -0,0 +1,110 @@ +/* +Copyright (C) 1997-2001 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. + +*/ + +/* +======================================================================= + +.MD3 triangle model file format + +======================================================================= +*/ + +#define MD3_IDENT (('3'<<24)+('P'<<16)+('D'<<8)+'I') +#define MD3_VERSION 15 + +// limits +#define MD3_MAX_LODS 3 +#define MD3_MAX_TRIANGLES 8192 // per mesh +#define MD3_MAX_VERTS 4096 // per mesh +#define MD3_MAX_SKINS 256 // per mesh +#define MD3_MAX_FRAMES 1024 // per model +#define MD3_MAX_MESHES 32 // per model +#define MD3_MAX_TAGS 16 // per frame +#define MD3_MAX_PATH 64 + +// vertex scales +#define MD3_XYZ_SCALE (1.0f/64.0f) + +typedef struct { + float st[2]; +} dmd3coord_t; + +typedef struct { + int16_t point[3]; + uint8_t norm[2]; +} dmd3vertex_t; + +typedef struct { + float mins[3]; + float maxs[3]; + float translate[3]; + float radius; + char creator[16]; +} dmd3frame_t; + +typedef struct { + char name[MD3_MAX_PATH]; // tag name + float origin[3]; + float axis[3][3]; +} dmd3tag_t; + +typedef struct { + char name[MD3_MAX_PATH]; + uint32_t unused; // shader +} dmd3skin_t; + +typedef struct { + uint32_t ident; + + char name[MD3_MAX_PATH]; + uint32_t flags; + + uint32_t num_frames; + uint32_t num_skins; + uint32_t num_verts; + uint32_t num_tris; + + uint32_t ofs_indexes; + uint32_t ofs_skins; + uint32_t ofs_tcs; + uint32_t ofs_verts; + + uint32_t meshsize; +} dmd3mesh_t; + +typedef struct { + uint32_t ident; + uint32_t version; + + char filename[MD3_MAX_PATH]; + + uint32_t flags; + + uint32_t num_frames; + uint32_t num_tags; + uint32_t num_meshes; + uint32_t num_skins; + + uint32_t ofs_frames; + uint32_t ofs_tags; + uint32_t ofs_meshes; + uint32_t ofs_end; +} dmd3header_t; + diff --git a/source/d_pak.h b/source/d_pak.h new file mode 100644 index 0000000..a5556ee --- /dev/null +++ b/source/d_pak.h @@ -0,0 +1,43 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/* +======================================================================== + +The .pak files are just a linear collapse of a directory tree + +======================================================================== +*/ + +#define IDPAKHEADER (('K'<<24)+('C'<<16)+('A'<<8)+'P') + +#define MAX_FILES_IN_PACK 4096 + +typedef struct { + char name[56]; + uint32_t filepos, filelen; +} dpackfile_t; + +typedef struct { + uint32_t ident; // == IDPAKHEADER + uint32_t dirofs; + uint32_t dirlen; +} dpackheader_t; + diff --git a/source/d_pcx.h b/source/d_pcx.h new file mode 100644 index 0000000..43dc416 --- /dev/null +++ b/source/d_pcx.h @@ -0,0 +1,44 @@ +/* +Copyright (C) 1997-2001 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. + +*/ + +/* +======================================================================== + +PCX files are used for as many images as possible + +======================================================================== +*/ + +typedef struct { + uint8_t manufacturer; + uint8_t version; + uint8_t encoding; + uint8_t bits_per_pixel; + uint16_t xmin, ymin, xmax, ymax; + uint16_t hres, vres; + uint8_t palette[48]; + uint8_t reserved; + uint8_t color_planes; + uint16_t bytes_per_line; + uint16_t palette_type; + uint8_t filler[58]; + uint8_t data[1]; // unbounded +} dpcx_t; + diff --git a/source/d_sp2.h b/source/d_sp2.h new file mode 100644 index 0000000..7421050 --- /dev/null +++ b/source/d_sp2.h @@ -0,0 +1,47 @@ +/* +Copyright (C) 1997-2001 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. + +*/ + +/* +======================================================================== + +.SP2 sprite file format + +======================================================================== +*/ + +#define SP2_IDENT (('2'<<24)+('S'<<16)+('D'<<8)+'I') +#define SP2_VERSION 2 + +#define SP2_MAX_FRAMES 32 +#define SP2_MAX_FRAMENAME 64 + +typedef struct { + uint32_t width, height; + uint32_t origin_x, origin_y; // raster coordinates inside pic + char name[SP2_MAX_FRAMENAME]; // name of pcx file +} dsp2frame_t; + +typedef struct { + uint32_t ident; + uint32_t version; + uint32_t numframes; + // dsp2frame_t frames[1]; // variable sized +} dsp2header_t; + diff --git a/source/d_wal.h b/source/d_wal.h new file mode 100644 index 0000000..700502a --- /dev/null +++ b/source/d_wal.h @@ -0,0 +1,40 @@ +/* +Copyright (C) 1997-2001 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. + +*/ + +/* +============================================================================== + +.WAL texture file format + +============================================================================== +*/ + +#define MIPLEVELS 4 + +typedef struct { + char name[32]; + uint32_t width, height; + uint32_t offsets[MIPLEVELS]; // four mip maps stored + char animname[32]; // next frame in animation chain + uint32_t flags; + uint32_t contents; + uint32_t value; +} miptex_t; + diff --git a/source/files.c b/source/files.c index 120d564..6790b7f 100644 --- a/source/files.c +++ b/source/files.c @@ -19,6 +19,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "com_local.h" +#include "files.h" +#include "sys_public.h" +#include "cl_public.h" +#include "d_pak.h" #if USE_ZLIB #include <zlib.h> #include "unzip.h" @@ -137,8 +141,6 @@ static int fs_count_read, fs_count_strcmp, fs_count_open; cvar_t *fs_game; -fsAPI_t fs; - /* All of Quake's data access is through a hierchal file system, @@ -164,7 +166,7 @@ FS_pathcmp Portably compares quake paths ================ */ -static int FS_pathcmp( const char *s1, const char *s2 ) { +int FS_pathcmp( const char *s1, const char *s2 ) { int c1, c2; do { @@ -184,7 +186,7 @@ static int FS_pathcmp( const char *s1, const char *s2 ) { return 0; /* strings are equal */ } -static int FS_pathcmpn( const char *s1, const char *s2, size_t n ) { +int FS_pathcmpn( const char *s1, const char *s2, size_t n ) { int c1, c2; do { @@ -263,11 +265,7 @@ static fsFile_t *FS_FileForHandle( fileHandle_t f ) { } file = &fs_files[f - 1]; - if( file->type == FS_FREE ) { - Com_Error( ERR_FATAL, "%s: free handle: %i", __func__, f ); - } - - if( file->type < FS_FREE || file->type >= FS_BAD ) { + if( file->type <= FS_FREE || file->type >= FS_BAD ) { Com_Error( ERR_FATAL, "%s: invalid file type: %i", __func__, file->type ); } @@ -301,12 +299,14 @@ static qboolean FS_ValidatePath( const char *s ) { return qfalse; } } +#ifdef _WIN32 if( *s == ':' ) { // check for "X:\" if( s[1] == '\\' || s[1] == '/' ) { return qfalse; } } +#endif s++; } @@ -318,6 +318,7 @@ static qboolean FS_ValidatePath( const char *s ) { return qtrue; } +#ifdef _WIN32 /* ================ FS_ReplaceSeparators @@ -336,7 +337,7 @@ char *FS_ReplaceSeparators( char *s, int separator ) { return s; } - +#endif /* ================ @@ -2629,28 +2630,6 @@ static void FS_Restart_f( void ) { CL_RestartFilesystem(); } -/* -================ -FS_FillAPI -================ -*/ -void FS_FillAPI( fsAPI_t *api ) { - api->LoadFile = FS_LoadFile; - api->LoadFileEx = FS_LoadFileEx; - api->AllocTempMem = FS_AllocTempMem; - api->FreeFile = FS_FreeFile; - api->FOpenFile = FS_FOpenFile; - api->FCloseFile = FS_FCloseFile; - api->Tell = FS_Tell; - api->RawTell = FS_RawTell; - api->Read = FS_Read; - api->Write = FS_Write; - api->ListFiles = FS_ListFiles; - api->FreeList = FS_FreeList; - api->FPrintf = FS_FPrintf; - api->ReadLine = FS_ReadLine; -} - static const cmdreg_t c_fs[] = { { "path", FS_Path_f }, { "fdir", FS_FDir_f }, @@ -2699,8 +2678,6 @@ void FS_Init( void ) { FS_Path_f(); - FS_FillAPI( &fs ); - end = Sys_Milliseconds(); Com_DPrintf( "%i msec to init filesystem\n", end - start ); Com_Printf( "-----------------------------\n" ); diff --git a/source/files.h b/source/files.h new file mode 100644 index 0000000..252499a --- /dev/null +++ b/source/files.h @@ -0,0 +1,138 @@ +/* +Copyright (C) 1997-2001 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. + +*/ + +#define MAX_LISTED_FILES 4096 + +typedef struct fsFileInfo_s { + size_t size; + time_t ctime; + time_t mtime; + char name[1]; +} fsFileInfo_t; + +/* bits 0 - 1, enum */ +#define FS_MODE_APPEND 0x00000000 +#define FS_MODE_READ 0x00000001 +#define FS_MODE_WRITE 0x00000002 +#define FS_MODE_RDWR 0x00000003 +#define FS_MODE_MASK 0x00000003 + +/* bits 0 - 1, enum */ +#define FS_SEARCHDIRS_NO 0x00000000 +#define FS_SEARCHDIRS_YES 0x00000001 +#define FS_SEARCHDIRS_ONLY 0x00000002 +#define FS_SEARCHDIRS_RESERVED 0x00000003 +#define FS_SEARCHDIRS_MASK 0x00000003 + +/* bit 2, enum */ +#define FS_FLUSH_NONE 0x00000000 +#define FS_FLUSH_SYNC 0x00000004 +#define FS_FLUSH_MASK 0x00000004 + +/* bits 3 - 4, enum */ +#define FS_TYPE_ANY 0x00000000 +#define FS_TYPE_REAL 0x00000008 +#define FS_TYPE_PAK 0x00000010 +#define FS_TYPE_RESERVED 0x00000018 +#define FS_TYPE_MASK 0x00000018 + +/* bits 5 - 6, flag */ +#define FS_PATH_ANY 0x00000000 +#define FS_PATH_BASE 0x00000020 +#define FS_PATH_GAME 0x00000040 +#define FS_PATH_MASK 0x00000060 + +/* bits 7 - 10, flag */ +#define FS_SEARCH_BYFILTER 0x00000080 +#define FS_SEARCH_SAVEPATH 0x00000100 +#define FS_SEARCH_EXTRAINFO 0x00000200 +#define FS_SEARCH_NOSORT 0x00000400 + +/* bits 7 - 8, flag */ +#define FS_FLAG_RESERVED1 0x00000080 +#define FS_FLAG_RESERVED2 0x00000100 + +#define INVALID_LENGTH ((size_t)-1) + +#define FS_Malloc( size ) Z_TagMalloc( size, TAG_FILESYSTEM ) +#define FS_Mallocz( size ) Z_TagMallocz( size, TAG_FILESYSTEM ) +#define FS_CopyString( string ) Z_TagCopyString( string, TAG_FILESYSTEM ) + +void FS_Init( void ); +void FS_Shutdown( qboolean total ); +qboolean FS_NeedRestart( void ); +void FS_Restart( void ); +qboolean FS_SafeToRestart( void ); + +qboolean FS_CopyFile( const char *src, const char *dst ); +qboolean FS_RemoveFile( const char *path ); +qboolean FS_RenameFile( const char *from, const char *to ); + +char *FS_CopyExtraInfo( const char *name, const fsFileInfo_t *info ); + +size_t FS_FOpenFile( const char *filename, fileHandle_t *f, int mode ); +void FS_FCloseFile( fileHandle_t hFile ); +qboolean FS_FilterFile( fileHandle_t f ); + +size_t FS_LoadFile( const char *path, void **buffer ); +size_t FS_LoadFileEx( const char *path, void **buffer, int flags, memtag_t tag ); +void *FS_AllocTempMem( size_t length ); +void FS_FreeFile( void *buffer ); +// a null buffer will just return the file length without loading +// a -1 length is not present + +size_t FS_Read( void *buffer, size_t len, fileHandle_t hFile ); +size_t FS_Write( const void *buffer, size_t len, fileHandle_t hFile ); +// properly handles partial reads + +void FS_FPrintf( fileHandle_t f, const char *format, ... ) q_printf( 2, 3 ); +size_t FS_ReadLine( fileHandle_t f, char *buffer, int size ); + +void FS_Flush( fileHandle_t f ); + +int FS_Tell( fileHandle_t f ); +int FS_RawTell( fileHandle_t f ); + +size_t FS_GetFileLength( fileHandle_t f ); + +qboolean FS_WildCmp( const char *filter, const char *string ); +qboolean FS_ExtCmp( const char *extension, const char *string ); + +void **FS_ListFiles( const char *path, const char *extension, int flags, int *numFiles ); +void **FS_CopyList( void **list, int count ); +fsFileInfo_t *FS_CopyInfo( const char *name, size_t size, time_t ctime, time_t mtime ); +void FS_FreeList( void **list ); + +qboolean FS_LastFileFromPak( void ); + +void FS_CreatePath( const char *path ); + +//const char *FS_GetFileName( fileHandle_t f ); +const char *FS_GetFileFullPath( fileHandle_t f ); + +char *FS_ReplaceSeparators( char *s, int separator ); + +int FS_pathcmp( const char *s1, const char *s2 ); +int FS_pathcmpn( const char *s1, const char *s2, size_t n ); + +void FS_File_g( const char *path, const char *ext, int flags, genctx_t *ctx ); + +extern cvar_t *fs_game; + diff --git a/source/g_public.h b/source/g_public.h index 1384ff9..789423e 100644 --- a/source/g_public.h +++ b/source/g_public.h @@ -155,9 +155,9 @@ typedef struct void (*WriteAngle) (float f); // managed memory allocation - void *(*TagMalloc) (size_t size, memtag_t tag); + void *(*TagMalloc) (size_t size, unsigned tag); void (*TagFree) (void *block); - void (*FreeTags) (memtag_t tag); + void (*FreeTags) (unsigned tag); // console variable interaction cvar_t *(*cvar) (const char *var_name, const char *value, int flags); diff --git a/source/gl_draw.c b/source/gl_draw.c index 8cb1bdf..b9376df 100644 --- a/source/gl_draw.c +++ b/source/gl_draw.c @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. drawStatic_t draw; -void Draw_SetColor( int flags, const color_t color ) { +void R_SetColor( int flags, const color_t color ) { draw.flags &= ~DRAW_COLOR_MASK; if( flags == DRAW_COLOR_CLEAR ) { @@ -45,7 +45,7 @@ void Draw_SetColor( int flags, const color_t color ) { draw.flags |= flags; } -void Draw_SetClipRect( int flags, const clipRect_t *clip ) { +void R_SetClipRect( int flags, const clipRect_t *clip ) { clipRect_t rc; float scale; @@ -106,7 +106,7 @@ void Draw_SetClipRect( int flags, const clipRect_t *clip ) { draw.flags = ( draw.flags & ~DRAW_CLIP_MASK ) | flags; } -void Draw_SetScale( float *scale ) { +void R_SetScale( float *scale ) { float f = scale ? *scale : 1; if( draw.scale == f ) { @@ -123,10 +123,9 @@ void Draw_SetScale( float *scale ) { draw.scale = f; } -qboolean Draw_GetPicSize( int *w, int *h, qhandle_t hPic ) { - image_t *image; +qboolean R_GetPicSize( int *w, int *h, qhandle_t pic ) { + image_t *image = IMG_ForHandle( pic ); - image = R_ImageForHandle( hPic ); if( w ) { *w = image->width; } @@ -136,130 +135,49 @@ qboolean Draw_GetPicSize( int *w, int *h, qhandle_t hPic ) { return image->flags & if_transparent; } -qhandle_t GL_RegisterFont( const char *name ) { - image_t *image; - char fullname[MAX_QPATH]; - - if( name[0] != '/' && name[0] != '\\' ) { - Q_concat( fullname, sizeof( fullname ), "pics/", name, NULL ); - COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) ); - image = R_FindImage( fullname, it_charset ); - } else { - image = R_FindImage( name + 1, it_charset ); - } - - if( !image ) { - return 0; - } - - return ( image - r_images ); -} - -void Draw_StretchPicST( int x, int y, int w, int h, float s1, float t1, - float s2, float t2, qhandle_t hPic ) +void R_DrawStretchPicST( int x, int y, int w, int h, float s1, float t1, + float s2, float t2, qhandle_t pic ) { /* TODO: scrap support */ - GL_StretchPic( x, y, w, h, s1, t1, s2, t2, draw.color, - R_ImageForHandle( hPic ) ); + GL_StretchPic( x, y, w, h, s1, t1, s2, t2, draw.color, IMG_ForHandle( pic ) ); } -void Draw_StretchPic( int x, int y, int w, int h, qhandle_t hPic ) { - image_t *image; +void R_DrawStretchPic( int x, int y, int w, int h, qhandle_t pic ) { + image_t *image = IMG_ForHandle( pic ); - image = R_ImageForHandle( hPic ); GL_StretchPic( x, y, w, h, image->sl, image->tl, image->sh, image->th, draw.color, image ); } -void Draw_Pic( int x, int y, qhandle_t hPic ) { - image_t *image; +void R_DrawPic( int x, int y, qhandle_t pic ) { + image_t *image = IMG_ForHandle( pic ); - image = R_ImageForHandle( hPic ); GL_StretchPic( x, y, image->width, image->height, - image->sl, image->tl, image->sh, image->th, - draw.color, image ); + image->sl, image->tl, image->sh, image->th, draw.color, image ); } -#define DOSTRETCH do { \ - tbyte = src[u >> 16]; \ - *dst++ = gl_static.palette[tbyte]; \ - u += ustep; \ - } while( 0 ) +#define DIV64 ( 1.0f / 64.0f ) -void Draw_StretchRaw( int x, int y, int w, int h, int cols, - int rows, const byte *data ) -{ - uint32_t resampled[256*256]; - int width, height; - const byte *src; - byte tbyte; - uint32_t *dst; - int u, v, ustep, vstep; - - vstep = rows * 0x10000 / 256; - ustep = cols * 0x10000 / 256; - - dst = resampled; - v = 0; - height = 256; - do { - src = &data[( v >> 16 ) * cols]; - - u = 0; - width = 256/8; - do { - DOSTRETCH; - DOSTRETCH; - DOSTRETCH; - DOSTRETCH; - DOSTRETCH; - DOSTRETCH; - DOSTRETCH; - DOSTRETCH; - } while( --width ); - - v += vstep; - } while( --height ); - - qglBindTexture( GL_TEXTURE_2D, 0 ); - qglTexImage2D( GL_TEXTURE_2D, 0, gl_tex_solid_format, 256, 256, 0, - GL_RGBA, GL_UNSIGNED_BYTE, resampled ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - - qglBegin( GL_QUADS ); - qglTexCoord2f( 0, 0 ); qglVertex2f( x, y ); - qglTexCoord2f( 1, 0 ); qglVertex2f( x + w, y ); - qglTexCoord2f( 1, 1 ); qglVertex2f( x + w, y + h ); - qglTexCoord2f( 0, 1 ); qglVertex2f( x, y + h ); - qglEnd(); -} - -#define DIV64 ( 1.0f / 64.0f ) - -void Draw_TileClear( int x, int y, int w, int h, qhandle_t hPic ) { - image_t *image; +void R_TileClear( int x, int y, int w, int h, qhandle_t pic ) { + image_t *image = IMG_ForHandle( pic ); - if( !( image = R_ImageForHandle( hPic ) ) ) { - GL_StretchPic( x, y, w, h, 0, 0, 1, 1, colorBlack, r_whiteimage ); - return; - } - GL_StretchPic( x, y, w, h, x * DIV64, y * DIV64, ( x + w ) * DIV64, ( y + h ) * DIV64, colorWhite, image ); + GL_StretchPic( x, y, w, h, x * DIV64, y * DIV64, + ( x + w ) * DIV64, ( y + h ) * DIV64, colorWhite, image ); } -void Draw_Fill( int x, int y, int w, int h, int c ) { +void R_DrawFill( int x, int y, int w, int h, int c ) { GL_StretchPic( x, y, w, h, 0, 0, 1, 1, ( byte * )&d_8to24table[c & 255], - r_whiteimage ); + r_whiteimage ); } -void Draw_FillEx( int x, int y, int w, int h, const color_t color ) { +void R_DrawFillEx( int x, int y, int w, int h, const color_t color ) { GL_StretchPic( x, y, w, h, 0, 0, 1, 1, color, r_whiteimage ); } -void Draw_FadeScreen( void ) { +void R_FadeScreen( void ) { } -void Draw_Char( int x, int y, int flags, int ch, qhandle_t hFont ) { +void R_DrawChar( int x, int y, int flags, int ch, qhandle_t font ) { float s, t; ch &= 255; @@ -267,11 +185,11 @@ void Draw_Char( int x, int y, int flags, int ch, qhandle_t hFont ) { t = ( ch >> 4 ) * 0.0625f; GL_StretchPic( x, y, 8, 8, s, t, s + 0.0625f, t + 0.0625f, - draw.color, R_ImageForHandle( hFont ) ); + draw.color, IMG_ForHandle( font ) ); } -int Draw_String( int x, int y, int flags, size_t maxChars, - const char *string, qhandle_t hFont ) +int R_DrawString( int x, int y, int flags, size_t maxChars, + const char *string, qhandle_t font ) { byte c; float s, t; @@ -279,7 +197,7 @@ int Draw_String( int x, int y, int flags, size_t maxChars, color_t colors[2]; int mask, altmask = 0; - image = R_ImageForHandle( hFont ); + image = IMG_ForHandle( font ); if( flags & UI_ALTCOLOR ) { altmask |= 128; @@ -336,9 +254,9 @@ void Draw_Stringf( int x, int y, const char *fmt, ... ) { if( !r_charset ) { qhandle_t tmp; - tmp = GL_RegisterFont( "conchars" ); + tmp = R_RegisterFont( "conchars" ); if(!tmp) return; - r_charset = R_ImageForHandle( tmp ); + r_charset = IMG_ForHandle( tmp ); } string = buffer; @@ -348,146 +266,39 @@ void Draw_Stringf( int x, int y, const char *fmt, ... ) { s = ( c & 15 ) * 0.0625f; t = ( c >> 4 ) * 0.0625f; -#if 0 - glBegin( GL_QUADS ); - glTexCoord2f( s, t ); - glVertex2i( x, y ); - glTexCoord2f( s + 0.0625f, t ); - glVertex2i( x + 8, y ); - glTexCoord2f( s + 0.0625f, t + 0.0625f ); - glVertex2i( x + 8, y + 16 ); - glTexCoord2f( s, t + 0.0625f ); - glVertex2i( x, y + 16 ); - glEnd(); -#endif - GL_StretchPic( x, y, 8, 16, s, t, s + 0.0625f, t + 0.0625f, - colorWhite, r_charset ); + GL_StretchPic( x, y, 8, 8, s, t, s + 0.0625f, t + 0.0625f, + colorWhite, r_charset ); x += 8; } - } -#if 0 - -void Draw_FPS( int x, int y ) { - int time; - static int realtime; - static int frameTimes[4] = { 1 }; - static int current; - int fps; - - time = sys.Milliseconds(); - frameTimes[current & 3] = time - realtime; - current++; - realtime = time; - - fps = 4000 / ( frameTimes[0] + frameTimes[1] + - frameTimes[2] + frameTimes[3] ); - Draw_Stringf( x, y, "FPS: %i", fps ); -} - -#else - -#define FPS_APERTURE 9 - -int QDECL SortCmp( const void *v1, const void *v2 ) { - int i1 = *( int * )v1; - int i2 = *( int * )v2; - - if( i1 < i2 ) { - return -1; - } - if( i1 > i2 ) { - return 1; - } - return 0; -} - -void Draw_FPS( int x, int y ) { - int time; - static int realtime; - static int frameTimes[FPS_APERTURE]; - static int current; - int buffer[FPS_APERTURE]; - int fps, i; - - time = sys.Milliseconds(); - frameTimes[current % FPS_APERTURE] = time - realtime; - current++; - realtime = time; - - for( i = 0; i < FPS_APERTURE; i++ ) { - buffer[i] = frameTimes[i]; - } - - qsort( buffer, FPS_APERTURE, sizeof( buffer[0] ), SortCmp ); - if( buffer[4] ) { - fps = 1000 / buffer[4]; - Draw_Stringf( x, y, "FPS: %i", fps ); - } -} -#endif - void Draw_Stats( void ) { - int x, y; - //const char *orderStr[2] = { "unordered", "inorder" }; - //const char *enableStr[2] = { "disabled", "enabled" }; - //const char *algStr[2] = { "mergesort", "quicksort" }; - statCounters_t st = c; - -#if 0 - GL_Flush2D(); - // GL_StretchPic( 0, 0, gl_config.vidWidth, gl_config.vidHeight, -0.5f, -0.5f, 1.5f, 1.5f, - GL_StretchPic( 0, 0, gl_config.vidWidth, gl_config.vidHeight, 0, 0, 1, 1, - colorWhite, r_beamtexture ); - // qglBlendFunc( GL_ONE, GL_ONE ); - // -#endif + int x = 10, y = 10; - y = 16; - x = 16; - - Draw_FPS( gl_config.vidWidth - 80, y ); -// qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - //GL_Flush2D(); - - Draw_Stringf( x, y, "Nodes visible : %i", st.nodesVisible ); y += 16; - Draw_Stringf( x, y, "Nodes culled : %i", st.nodesCulled ); y += 16; - //Draw_String( x, y, "Nodes drawn : %i", c_nodesDrawn ); y += 16; - //Draw_String( x, y, "Faces marked : %i", c_facesMarked ); y += 16; - Draw_Stringf( x, y, "Faces drawn : %i", st.facesDrawn ); y += 16; - if( st.facesCulled ) { - Draw_Stringf( x, y, "Faces culled : %i", st.facesCulled ); y += 16; + Draw_Stringf( x, y, "Nodes visible : %i", c.nodesVisible ); y += 10; + Draw_Stringf( x, y, "Nodes culled : %i", c.nodesCulled ); y += 10; + Draw_Stringf( x, y, "Faces drawn : %i", c.facesDrawn ); y += 10; + if( c.facesCulled ) { + Draw_Stringf( x, y, "Faces culled : %i", c.facesCulled ); y += 10; } - if( st.boxesCulled ) { - Draw_Stringf( x, y, "Boxes culled : %i", st.boxesCulled ); y += 16; + if( c.boxesCulled ) { + Draw_Stringf( x, y, "Boxes culled : %i", c.boxesCulled ); y += 10; } - if( st.spheresCulled ) { - Draw_Stringf( x, y, "Spheres culled : %i", st.spheresCulled ); y += 16; + if( c.spheresCulled ) { + Draw_Stringf( x, y, "Spheres culled : %i", c.spheresCulled ); y += 10; } - if( st.rotatedBoxesCulled ) { - Draw_Stringf( x, y, "RtBoxes culled : %i", st.rotatedBoxesCulled ); y += 16; + if( c.rotatedBoxesCulled ) { + Draw_Stringf( x, y, "RtBoxes culled : %i", c.rotatedBoxesCulled ); y += 10; } - Draw_Stringf( x, y, "Tris drawn : %i", st.trisDrawn ); y += 16; - Draw_Stringf( x, y, "Tex switches : %i", st.texSwitches ); y += 16; - if( st.batchesDrawn ) { - Draw_Stringf( x, y, "Batches drawn: %i", st.batchesDrawn ); y += 16; - Draw_Stringf( x, y, "Faces / batch: %i", st.facesDrawn / st.batchesDrawn ); - y += 16; - Draw_Stringf( x, y, "Tris / batch : %i", st.trisDrawn / st.batchesDrawn ); - y += 16; + Draw_Stringf( x, y, "Tris drawn : %i", c.trisDrawn ); y += 10; + Draw_Stringf( x, y, "Tex switches : %i", c.texSwitches ); y += 10; + if( c.batchesDrawn ) { + Draw_Stringf( x, y, "Batches drawn: %i", c.batchesDrawn ); y += 10; + Draw_Stringf( x, y, "Faces / batch: %i", c.facesDrawn / c.batchesDrawn ); + y += 10; + Draw_Stringf( x, y, "Tris / batch : %i", c.trisDrawn / c.batchesDrawn ); + y += 10; } - - y += 16; - /* - Draw_String( x, y, "Drawing order: %s", orderStr[r_drawOrder] ); y += 16; - Draw_String( x, y, "Depth test : %s", enableStr[r_depthTest] ); y += 16; - Draw_String( x, y, "Faces culling: %s", enableStr[r_cullFace] ); y += 16; - Draw_String( x, y, "Faces sorting: %s", enableStr[enableSort] ); y += 16; - Draw_String( x, y, "Algorithm : %s", algStr[doMergeSort] ); y += 16; - */ - - y += 16; } diff --git a/source/gl_images.c b/source/gl_images.c index 489a6e7..edd2b98 100644 --- a/source/gl_images.c +++ b/source/gl_images.c @@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "gl_local.h" +#include "d_pcx.h" +#include "d_wal.h" image_t *r_notexture; image_t *r_particletexture; @@ -37,7 +39,7 @@ int gl_tex_solid_format; static int upload_width; static int upload_height; static image_t *upload_image; -bspTexinfo_t *upload_texinfo; +mtexinfo_t *upload_texinfo; static cvar_t *gl_noscrap; static cvar_t *gl_round_down; @@ -53,7 +55,7 @@ static cvar_t *gl_intensity; static cvar_t *gl_gamma; static cvar_t *gl_invert; -qboolean GL_Upload8( byte *data, int width, int height, qboolean mipmap ); +static qboolean GL_Upload8( byte *data, int width, int height, qboolean mipmap ); typedef struct { char *name; @@ -112,9 +114,9 @@ static void gl_texturemode_changed( cvar_t *self ) { } if( i == numFilterModes ) { - Com_WPrintf( "Bad texture filter name\n" ); - cvar.Set( "gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST" ); - gl_filter_min = GL_LINEAR_MIPMAP_NEAREST; + Com_WPrintf( "Bad texture mode: %s\n", self->string ); + Cvar_Reset( self ); + gl_filter_min = GL_LINEAR_MIPMAP_LINEAR; gl_filter_max = GL_LINEAR; } else { gl_filter_min = filterModes[i].minimize; @@ -133,6 +135,16 @@ static void gl_texturemode_changed( cvar_t *self ) { } } +static void gl_texturemode_g( genctx_t *ctx ) { + int i; + + for( i = 0; i < numFilterModes ; i++ ) { + if( !Prompt_AddMatch( ctx, filterModes[i].name ) ) { + break; + } + } +} + static void gl_anisotropy_changed( cvar_t *self ) { int i; image_t *image; @@ -179,19 +191,25 @@ static void GL_TextureAlphaMode( void ) { int i; for( i = 0; i < numAlphaModes; i++ ) { - if( !Q_stricmp( alphaModes[i].name, gl_texturealphamode->string ) ) - break; + if( !Q_stricmp( alphaModes[i].name, gl_texturealphamode->string ) ) { + gl_tex_alpha_format = alphaModes[i].mode; + return; + } } - if( i == numAlphaModes ) { - Com_Printf( "Bad texture alpha mode name %s\n", - gl_texturealphamode->string ); - cvar.Set( "gl_texturealphamode", "default" ); - gl_tex_alpha_format = alphaModes[0].mode; - return; - } + Com_WPrintf( "Bad texture alpha mode: %s\n", gl_texturealphamode->string ); + Cvar_Reset( gl_texturealphamode ); + gl_tex_alpha_format = alphaModes[0].mode; +} - gl_tex_alpha_format = alphaModes[i].mode; +static void gl_texturealphamode_g( genctx_t *ctx ) { + int i; + + for( i = 0; i < numAlphaModes; i++ ) { + if( !Prompt_AddMatch( ctx, alphaModes[i].name ) ) { + break; + } + } } /* @@ -203,19 +221,25 @@ static void GL_TextureSolidMode( void ) { int i; for( i = 0; i < numSolidModes; i++ ) { - if( !Q_stricmp( solidModes[i].name, gl_texturesolidmode->string ) ) - break; + if( !Q_stricmp( solidModes[i].name, gl_texturesolidmode->string ) ) { + gl_tex_solid_format = solidModes[i].mode; + return; + } } - if( i == numSolidModes ) { - Com_Printf( "Bad texture texture mode name %s\n", - gl_texturesolidmode->string ); - cvar.Set( "gl_texturesolidmode", "default" ); - gl_tex_solid_format = solidModes[0].mode; - return; - } + Com_WPrintf( "Bad texture solid mode: %s\n", gl_texturesolidmode->string ); + Cvar_Reset( gl_texturesolidmode ); + gl_tex_solid_format = solidModes[0].mode; +} - gl_tex_solid_format = solidModes[i].mode; +static void gl_texturesolidmode_g( genctx_t *ctx ) { + int i; + + for( i = 0; i < numSolidModes; i++ ) { + if( !Prompt_AddMatch( ctx, solidModes[i].name ) ) { + break; + } + } } /* @@ -467,6 +491,56 @@ static void GL_InvertTexture( byte *in, int inwidth, int inheight ) { /* ================ +GL_ResampleTexture +================ +*/ +static void GL_ResampleTexture( const byte *in, int inwidth, int inheight, byte *out, int outwidth, int outheight ) { + int i, j; + const byte *inrow1, *inrow2; + unsigned frac, fracstep; + unsigned p1[MAX_TEXTURE_SIZE], p2[MAX_TEXTURE_SIZE]; + const byte *pix1, *pix2, *pix3, *pix4; + float heightScale; + + if( outwidth > MAX_TEXTURE_SIZE ) { + Com_Error( ERR_FATAL, "%s: outwidth > %d", __func__, MAX_TEXTURE_SIZE ); + } + + fracstep = inwidth * 0x10000 / outwidth; + + frac = fracstep >> 2; + for( i = 0; i < outwidth; i++ ) { + p1[i] = 4 * ( frac >> 16 ); + frac += fracstep; + } + frac = 3 * ( fracstep >> 2 ); + for( i = 0; i < outwidth; i++ ) { + p2[i] = 4 * ( frac >> 16 ); + frac += fracstep; + } + + heightScale = ( float )inheight / outheight; + inwidth <<= 2; + for( i = 0; i < outheight; i++ ) { + inrow1 = in + inwidth * ( int )( ( i + 0.25f ) * heightScale ); + inrow2 = in + inwidth * ( int )( ( i + 0.75f ) * heightScale ); + for( j = 0; j < outwidth; j++ ) { + pix1 = inrow1 + p1[j]; + pix2 = inrow1 + p2[j]; + pix3 = inrow2 + p1[j]; + pix4 = inrow2 + p2[j]; + out[0] = ( pix1[0] + pix2[0] + pix3[0] + pix4[0] ) >> 2; + out[1] = ( pix1[1] + pix2[1] + pix3[1] + pix4[1] ) >> 2; + out[2] = ( pix1[2] + pix2[2] + pix3[2] + pix4[2] ) >> 2; + out[3] = ( pix1[3] + pix2[3] + pix3[3] + pix4[3] ) >> 2; + out += 4; + } + } +} + + +/* +================ GL_MipMap Operates in place, quartering the size of the texture @@ -494,7 +568,7 @@ static void GL_MipMap( byte *in, int width, int height ) { GL_Upload32 =============== */ -qboolean GL_Upload32( byte *data, int width, int height, qboolean mipmap ) { +static qboolean GL_Upload32( byte *data, int width, int height, qboolean mipmap ) { byte *scaled; int scaled_width, scaled_height; int i, c; @@ -540,7 +614,7 @@ qboolean GL_Upload32( byte *data, int width, int height, qboolean mipmap ) { if( upload_image->type == it_wall && gl_saturation->value != 1 && ( !upload_texinfo || - !( upload_texinfo->flags & (SURF_SKY|SURF_WARP) ) ) ) + !( upload_texinfo->c.flags & (SURF_SKY|SURF_WARP) ) ) ) { GL_Saturation( data, width, height ); if( gl_saturation->value == 0 ) { @@ -557,7 +631,7 @@ qboolean GL_Upload32( byte *data, int width, int height, qboolean mipmap ) { if( upload_image->type == it_wall && gl_invert->integer && ( !upload_texinfo || - !( upload_texinfo->flags & (SURF_SKY|SURF_WARP) ) ) ) + !( upload_texinfo->c.flags & (SURF_SKY|SURF_WARP) ) ) ) { GL_InvertTexture( data, width, height ); } @@ -578,8 +652,8 @@ qboolean GL_Upload32( byte *data, int width, int height, qboolean mipmap ) { /* optimized case, do not reallocate */ scaled = data; } else { - scaled = fs.AllocTempMem( scaled_width * scaled_height * 4 ); - R_ResampleTexture( data, width, height, scaled, + scaled = FS_AllocTempMem( scaled_width * scaled_height * 4 ); + GL_ResampleTexture( data, width, height, scaled, scaled_width, scaled_height ); } @@ -622,7 +696,7 @@ qboolean GL_Upload32( byte *data, int width, int height, qboolean mipmap ) { if( scaled != data ) { - fs.FreeFile( scaled ); + FS_FreeFile( scaled ); } return isalpha; @@ -635,15 +709,15 @@ GL_Upload8 Returns has_alpha =============== */ -qboolean GL_Upload8( byte *data, int width, int height, qboolean mipmap ) { +static qboolean GL_Upload8( byte *data, int width, int height, qboolean mipmap ) { byte buffer[512*256*4]; - byte *dest; - int i, s; - int p; + byte *dest; + int i, s; + int p; s = width * height; if( s > 512*256 ) { - Com_Error( ERR_FATAL, "GL_Upload8: %s is too large: width=%d height=%d", + Com_Error( ERR_FATAL, "GL_Upload8: %s is too large: %dx%d", upload_image->name, width, height ); } @@ -679,70 +753,48 @@ qboolean GL_Upload8( byte *data, int width, int height, qboolean mipmap ) { } -/* -=============== -R_ImageForHandle -=============== -*/ -image_t *R_ImageForHandle( qhandle_t hPic ) { - if( hPic < 0 || hPic >= r_numImages ) { - *( int * )0 = 1; - Com_Error( ERR_FATAL, "R_ImageForHandle: %d out of range", hPic ); - } - - return &r_images[hPic]; -} - -/* -=============== -R_RegisterSkin -=============== -*/ -qhandle_t R_RegisterSkin( const char *name ) { - image_t *image; - - image = R_FindImage( name, it_skin ); - if( !image ) { - return 0; - } - - return ( image - r_images ); -} - -/* -================ -R_RegisterPic -================ -*/ -qhandle_t R_RegisterPic( const char *name ) { - image_t *image; - char fullname[MAX_QPATH]; - - if( name[0] == '*' ) { - image = R_FindImage( name + 1, it_tmp ); - } else if( name[0] == '/' || name[0] == '\\' ) { - image = R_FindImage( name + 1, it_pic ); - } else { - Q_concat( fullname, sizeof( fullname ), "pics/", name, NULL ); - COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) ); - image = R_FindImage( fullname, it_pic ); - } - - if( !image ) { - return 0; - } - - return ( image - r_images ); +static void GL_GetDimensions( image_t *image, imageflags_t flags ) { + char buffer[MAX_QPATH]; + size_t length; + miptex_t mt; + dpcx_t pcx; + fileHandle_t f; + + length = strlen( image->name ); + if( length > 4 && image->name[ length - 4 ] == '.' ) { + strncpy( buffer, image->name, length - 4 ); + if( flags & if_replace_wal ) { + strcpy( buffer + length - 4, ".wal" ); + FS_FOpenFile( buffer, &f, FS_MODE_READ ); + if( f ) { + length = FS_Read( &mt, sizeof( mt ), f ); + if( length == sizeof( mt ) ) { + image->width = LittleLong( mt.width ); + image->height = LittleLong( mt.height ); + } + FS_FCloseFile( f ); + } + } else { + strcpy( buffer + length - 4, ".pcx" ); + FS_FOpenFile( buffer, &f, FS_MODE_READ ); + if( f ) { + length = FS_Read( &pcx, sizeof( pcx ), f ); + if( length == sizeof( pcx ) ) { + image->width = LittleShort( pcx.xmax ) + 1; + image->height = LittleShort( pcx.ymax ) + 1; + } + FS_FCloseFile( f ); + } + } + } } - - /* ================ -R_LoadImage +IMG_Load ================ */ -void R_LoadImage( image_t *image, byte *pic, int width, int height, +void IMG_Load( image_t *image, byte *pic, int width, int height, imagetype_t type, imageflags_t flags ) { qboolean mipmap, transparent; @@ -756,41 +808,10 @@ void R_LoadImage( image_t *image, byte *pic, int width, int height, // HACK: get dimensions from 8-bit texture if( flags & (if_replace_wal|if_replace_pcx) ) { - char buffer[MAX_QPATH]; - size_t length; - miptex_t mt; - pcx_t pcx; - fileHandle_t f; - - length = strlen( image->name ); - if( length > 4 && image->name[ length - 4 ] == '.' ) { - strncpy( buffer, image->name, length - 4 ); - if( flags & if_replace_wal ) { - strcpy( buffer + length - 4, ".wal" ); - fs.FOpenFile( buffer, &f, FS_MODE_READ ); - if( f ) { - length = fs.Read( &mt, sizeof( mt ), f ); - if( length == sizeof( mt ) ) { - image->width = LittleLong( mt.width ); - image->height = LittleLong( mt.height ); - } - fs.FCloseFile( f ); - } - } else { - strcpy( buffer + length - 4, ".pcx" ); - fs.FOpenFile( buffer, &f, FS_MODE_READ ); - if( f ) { - length = fs.Read( &pcx, sizeof( pcx ), f ); - if( length == sizeof( pcx ) ) { - image->width = LittleShort( pcx.xmax ); - image->height = LittleShort( pcx.ymax ); - } - fs.FCloseFile( f ); - } - } - } + GL_GetDimensions( image, flags ); } - + + // load small 8-bit pics onto the scrap if( type == it_pic && ( flags & if_paletted ) && width < 64 && height < 64 && !gl_noscrap->integer ) { @@ -821,7 +842,7 @@ void R_LoadImage( image_t *image, byte *pic, int width, int height, Scrap_Upload(); } - fs.FreeFile( pic ); + FS_FreeFile( pic ); return; } @@ -830,10 +851,7 @@ void R_LoadImage( image_t *image, byte *pic, int width, int height, if( type == it_skin && ( flags & if_paletted ) ) R_FloodFillSkin( pic, width, height ); - mipmap = qfalse; - if( type == it_wall || type == it_skin ) { - mipmap = qtrue; - } + mipmap = ( type == it_wall || type == it_skin ) ? qtrue : qfalse; image->texnum = ( image - r_images ) + 1; GL_BindTexture( image->texnum ); if( flags & if_paletted ) { @@ -859,33 +877,38 @@ void R_LoadImage( image_t *image, byte *pic, int width, int height, } #endif - /* don't free autogenerated images */ + // don't free autogenerated images if( flags & if_auto ) { return; } - /* don't free *.wal textures */ + // don't free *.wal textures if( type == it_wall && ( flags & if_paletted ) ) { return; } - fs.FreeFile( pic ); + FS_FreeFile( pic ); } +void IMG_Unload( image_t *image ) { + if( !( image->flags & if_scrap ) ) { + qglDeleteTextures( 1, &image->texnum ); + } +} /* ================ -R_LoadWal +IMG_LoadWAL ================ */ -image_t *R_LoadWal( const char *name ) { +image_t *IMG_LoadWAL( const char *name ) { miptex_t *mt; size_t width, height, offset, length, endpos; image_t *image; - length = fs.LoadFile( name, ( void ** )&mt ); + length = FS_LoadFile( name, ( void ** )&mt ); if( !mt ) { - return r_notexture; + return NULL; } width = LittleLong( mt->width ); @@ -902,22 +925,16 @@ image_t *R_LoadWal( const char *name ) { goto fail; } - image = R_CreateImage( name, ( byte * )mt + offset, width, height, it_wall, if_paletted ); + image = IMG_Create( name, ( byte * )mt + offset, width, height, it_wall, if_paletted ); - fs.FreeFile( mt ); + FS_FreeFile( mt ); return image; fail: - fs.FreeFile( mt ); + FS_FreeFile( mt ); return NULL; } -void R_FreeImage( image_t *image ) { - if( !( image->flags & if_scrap ) ) { - qglDeleteTextures( 1, &image->texnum ); - } -} - static void GL_BuildGammaTables( void ) { int i; float inf, g = gl_gamma->value; @@ -941,7 +958,7 @@ static void GL_BuildGammaTables( void ) { static void gl_gamma_changed( cvar_t *self ) { GL_BuildGammaTables(); - video.UpdateGamma( gammatable ); + VID_UpdateGamma( gammatable ); } static const byte dottexture[8][8] = { @@ -971,7 +988,7 @@ static void GL_InitDefaultTexture( void ) { } } - r_notexture = R_CreateImage( "*notexture", pixels, 8, 8, it_wall, if_auto ); + r_notexture = IMG_Create( "*notexture", pixels, 8, 8, it_wall, if_auto ); } #define DLIGHT_TEXTURE_SIZE 16 @@ -999,7 +1016,7 @@ static void GL_InitParticleTexture( void ) { } } - r_particletexture = R_CreateImage( "*particleTexture", pixels, + r_particletexture = IMG_Create( "*particleTexture", pixels, DLIGHT_TEXTURE_SIZE, DLIGHT_TEXTURE_SIZE, it_pic, if_auto ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); @@ -1009,13 +1026,13 @@ static void GL_InitWhiteImage( void ) { uint32_t pixel; pixel = MakeColor( 0xff, 0xff, 0xff, 0xff ); - r_whiteimage = R_CreateImage( "*whiteimage", ( byte * )&pixel, 1, 1, + r_whiteimage = IMG_Create( "*whiteimage", ( byte * )&pixel, 1, 1, it_pic, if_auto ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); pixel = MakeColor( 0, 0, 0, 0xff ); - r_blackimage = R_CreateImage( "*blackimage", ( byte * )&pixel, 1, 1, + r_blackimage = IMG_Create( "*blackimage", ( byte * )&pixel, 1, 1, it_pic, if_auto ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); @@ -1042,7 +1059,7 @@ static void GL_InitBeamTexture( void ) { } } - r_beamtexture = R_CreateImage( "*beamTexture", pixels, 16, 16, + r_beamtexture = IMG_Create( "*beamTexture", pixels, 16, 16, it_pic, if_auto ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); @@ -1064,7 +1081,7 @@ static void GL_InitWarpTexture( void ) { } } - r_warptexture = R_CreateImage( "*warpTexture", pixels, 8, 8, + r_warptexture = IMG_Create( "*warpTexture", pixels, 8, 8, it_pic, if_auto ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); @@ -1079,44 +1096,40 @@ void GL_InitImages( void ) { int i, j; float f; - registration_sequence = 1; - - if( r_numImages ) { - Com_Error( ERR_FATAL, "GL_InitImages: %d images still not freed", - r_numImages ); - } - - gl_bilerp_chars = cvar.Get( "gl_bilerp_chars", "0", 0 ); + gl_bilerp_chars = Cvar_Get( "gl_bilerp_chars", "0", 0 ); gl_bilerp_chars->changed = gl_bilerp_chars_changed; - gl_texturemode = cvar.Get( "gl_texturemode", + gl_texturemode = Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE ); gl_texturemode->changed = gl_texturemode_changed; - gl_anisotropy = cvar.Get( "gl_anisotropy", "1", CVAR_ARCHIVE ); + gl_texturemode->generator = gl_texturemode_g; + gl_anisotropy = Cvar_Get( "gl_anisotropy", "1", CVAR_ARCHIVE ); gl_anisotropy->changed = gl_anisotropy_changed; - gl_noscrap = cvar.Get( "gl_noscrap", "0", CVAR_FILES ); - gl_round_down = cvar.Get( "gl_round_down", "0", CVAR_FILES ); - gl_picmip = cvar.Get( "gl_picmip", "0", CVAR_FILES ); - gl_gamma_scale_pics = cvar.Get( "gl_gamma_scale_pics", "0", CVAR_FILES ); - gl_texturealphamode = cvar.Get( "gl_texturealphamode", + gl_noscrap = Cvar_Get( "gl_noscrap", "0", CVAR_FILES ); + gl_round_down = Cvar_Get( "gl_round_down", "0", CVAR_FILES ); + gl_picmip = Cvar_Get( "gl_picmip", "0", CVAR_FILES ); + gl_gamma_scale_pics = Cvar_Get( "gl_gamma_scale_pics", "0", CVAR_FILES ); + gl_texturealphamode = Cvar_Get( "gl_texturealphamode", "default", CVAR_ARCHIVE|CVAR_FILES ); - gl_texturesolidmode = cvar.Get( "gl_texturesolidmode", + gl_texturealphamode->generator = gl_texturealphamode_g; + gl_texturesolidmode = Cvar_Get( "gl_texturesolidmode", "default", CVAR_ARCHIVE|CVAR_FILES ); - gl_saturation = cvar.Get( "gl_saturation", "1", CVAR_ARCHIVE|CVAR_FILES ); - gl_intensity = cvar.Get( "intensity", "1", CVAR_ARCHIVE|CVAR_FILES ); - gl_invert = cvar.Get( "gl_invert", "0", CVAR_ARCHIVE|CVAR_FILES ); + gl_texturesolidmode->generator = gl_texturesolidmode_g; + gl_saturation = Cvar_Get( "gl_saturation", "1", CVAR_ARCHIVE|CVAR_FILES ); + gl_intensity = Cvar_Get( "intensity", "1", CVAR_ARCHIVE|CVAR_FILES ); + gl_invert = Cvar_Get( "gl_invert", "0", CVAR_ARCHIVE|CVAR_FILES ); if( gl_hwgamma->integer ) { - gl_gamma = cvar.Get( "vid_gamma", "1", CVAR_ARCHIVE ); + gl_gamma = Cvar_Get( "vid_gamma", "1", CVAR_ARCHIVE ); gl_gamma->changed = gl_gamma_changed; } else { - gl_gamma = cvar.Get( "vid_gamma", "1", CVAR_ARCHIVE|CVAR_FILES ); + gl_gamma = Cvar_Get( "vid_gamma", "1", CVAR_ARCHIVE|CVAR_FILES ); } - R_InitImageManager(); + IMG_Init(); - R_GetPalette( NULL ); + IMG_GetPalette( NULL ); if( gl_intensity->value < 1 ) { - cvar.Set( "intensity", "1" ); + Cvar_Set( "intensity", "1" ); } f = gl_intensity->value; for( i = 0; i < 256; i++ ) { @@ -1159,6 +1172,9 @@ void GL_ShutdownImages( void ) { gl_bilerp_chars->changed = NULL; gl_texturemode->changed = NULL; + gl_texturemode->generator = NULL; + gl_texturealphamode->generator = NULL; + gl_texturesolidmode->generator = NULL; gl_anisotropy->changed = NULL; gl_gamma->changed = NULL; @@ -1175,8 +1191,9 @@ void GL_ShutdownImages( void ) { r_whiteimage = NULL; r_blackimage = NULL; - R_FreeAllImages(); - R_ShutdownImageManager(); + IMG_FreeAll(); + IMG_Shutdown(); + Scrap_Shutdown(); } diff --git a/source/gl_local.h b/source/gl_local.h index e1b8c9e..eea8a84 100644 --- a/source/gl_local.h +++ b/source/gl_local.h @@ -18,17 +18,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <config.h> -#include "qgl_local.h" -#include "q_shared.h" -#include "q_files.h" -#include "com_public.h" +#include "com_local.h" +#include "files.h" #include "ref_public.h" #include "in_public.h" #include "vid_public.h" #include "cl_public.h" +#include "sys_public.h" #include "q_list.h" +#include "bsp.h" #include "r_shared.h" +#include "r_models.h" +#include "qgl_local.h" #include "qgl_api.h" /* @@ -42,9 +43,12 @@ typedef struct { int numTextureUnits; int maxTextureSize; qboolean registering; - uint32_t palette[256]; // cinematic palette GLuint prog_warp, prog_light; - vec_t *vertices; + struct { + bsp_t *cache; + mempool_t pool; + vec_t *vertices; + } world; } glStatic_t; typedef struct { @@ -123,69 +127,37 @@ void GL_ShowErrors( const char *func ); * */ -typedef struct tcoord_s { +typedef struct maliastc_s { float st[2]; -} tcoord_t; +} maliastc_t; -typedef struct aliasVert_s { +typedef struct maliasvert_s { short pos[3]; - byte normalIndex; + byte normalindex; byte pad; -} aliasVert_t; +} maliasvert_t; -typedef struct aliasFrame_s { +typedef struct maliasframe_s { vec3_t scale; vec3_t translate; vec3_t bounds[2]; vec_t radius; -} aliasFrame_t; +} maliasframe_t; -typedef struct aliasMesh_s { - int numVerts; - int numTris; - int numIndices; +typedef struct maliasmesh_s { + int numverts; + int numtris; + int numindices; uint32_t *indices; - aliasVert_t *verts; - tcoord_t *tcoords; - image_t *skins[MAX_MD2SKINS]; - int numSkins; -} aliasMesh_t; - -typedef struct spriteFrame_s { - int width, height; - int x, y; - image_t *image; -} spriteFrame_t; - -typedef struct model_s { - modelType_t type; - - char name[MAX_QPATH]; - int registration_sequence; - mempool_t pool; - - /* alias models */ - int numFrames; - int numMeshes; - aliasFrame_t *frames; - aliasMesh_t *meshes; - - /* sprite models */ - spriteFrame_t *sframes; -} model_t; + maliasvert_t *verts; + maliastc_t *tcoords; + image_t *skins[MAX_ALIAS_SKINS]; + int numskins; +} maliasmesh_t; /* xyz[3] + st[2] + lmst[2] */ #define VERTEX_SIZE 7 -void GL_InitModels( void ); -void GL_ShutdownModels( void ); -void GL_GetModelSize( qhandle_t hModel, vec3_t mins, vec3_t maxs ); -qhandle_t GL_RegisterModel( const char *name ); -modelType_t *GL_ModelForHandle( qhandle_t hModel ); - -void Model_FreeUnused( void ); -void Model_FreeAll( void ); - /* * gl_surf.c * @@ -195,9 +167,6 @@ void Model_FreeAll( void ); #define LM_BLOCK_HEIGHT 256 #define LM_TEXNUM ( MAX_RIMAGES + 2 ) -#define NOLIGHT_MASK \ - (SURF_SKY|SURF_WARP|SURF_TRANS33|SURF_TRANS66) - typedef struct { int inuse[LM_BLOCK_WIDTH]; byte buffer[LM_BLOCK_WIDTH * LM_BLOCK_HEIGHT * 4]; @@ -207,9 +176,10 @@ typedef struct { extern lightmapBuilder_t lm; -void GL_PostProcessSurface( bspSurface_t *surf ); -void GL_BeginPostProcessing( void ); -void GL_EndPostProcessing( void ); +void GL_AdjustColor( byte *dst, const byte *src, int what ); + +void GL_LoadWorld( const char *name ); +void GL_FreeWorld( void ); /* * gl_state.c @@ -272,25 +242,6 @@ typedef struct { extern drawStatic_t draw; -qhandle_t GL_RegisterFont( const char *name ); - -void Draw_SetColor( int flags, const color_t color ); -void Draw_SetClipRect( int flags, const clipRect_t *clip ); -void Draw_SetScale( float *scale ); -qboolean Draw_GetPicSize( int *w, int *h, qhandle_t hPic ); -void Draw_StretchPicST( int x, int y, int w, int h, float s1, float t1, - float s2, float t2, qhandle_t hPic ); -void Draw_StretchPic( int x, int y, int w, int h, qhandle_t hPic ); -void Draw_Pic( int x, int y, qhandle_t hPic ); -void Draw_StretchRaw( int x, int y, int w, int h, int cols, - int rows, const byte *data ); -void Draw_TileClear( int x, int y, int w, int h, qhandle_t hPic ); -void Draw_Fill( int x, int y, int w, int h, int c ); -void Draw_FillEx( int x, int y, int w, int h, const color_t color ); -void Draw_FadeScreen( void ); -void Draw_Char( int x, int y, int flags, int ch, qhandle_t hFont ); -int Draw_String( int x, int y, int flags, size_t maxChars, - const char *string, qhandle_t hFont ); void Draw_Stringf( int x, int y, const char *fmt, ... ); void Draw_Stats( void ); @@ -337,26 +288,21 @@ typedef struct { int indices[TESS_MAX_INDICES]; byte colors[4*TESS_MAX_VERTICES]; int texnum[MAX_TMUS]; - int numVertices; - int numIndices; + int numverts; + int numindices; int flags; } tesselator_t; extern tesselator_t tess; -void EndSurface_Multitextured( void ); -void EndSurface_Single( void ); - -void Tess_DrawSurfaceTriangles( int *indices, int numIndices ); - void GL_StretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const byte *color, image_t *image ); void GL_Flush2D( void ); void GL_DrawParticles( void ); void GL_DrawBeams( void ); -void GL_AddFace( bspSurface_t *face ); -void GL_AddSolidFace( bspSurface_t *face ); +void GL_AddFace( mface_t *face ); +void GL_AddSolidFace( mface_t *face ); void GL_DrawAlphaFaces( void ); void GL_DrawSolidFaces( void ); @@ -368,15 +314,15 @@ extern vec3_t modelViewOrigin; void GL_MarkLeaves( void ); void GL_MarkLights( void ); -void GL_DrawBspModel( bspSubmodel_t *model ); +void GL_DrawBspModel( mmodel_t *model ); void GL_DrawWorld( void ); -void GL_LightPoint( vec3_t origin, vec3_t dest ); +qboolean GL_LightPoint( vec3_t origin, vec3_t color ); /* * gl_sky.c * */ -void R_AddSkySurface( bspSurface_t *surf ); +void R_AddSkySurface( mface_t *surf ); void R_ClearSkyBox( void ); void R_DrawSkyBox( void ); void R_SetSky( const char *name, float rotate, vec3_t axis ); diff --git a/source/gl_main.c b/source/gl_main.c index b120f6f..0225877 100644 --- a/source/gl_main.c +++ b/source/gl_main.c @@ -25,14 +25,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "gl_local.h" -/* declare imports for this module */ -cmdAPI_t cmd; -cvarAPI_t cvar; -fsAPI_t fs; -commonAPI_t com; -sysAPI_t sys; -videoAPI_t video; - glRefdef_t glr; glStatic_t gl_static; glconfig_t gl_config; @@ -41,7 +33,7 @@ statCounters_t c; int registration_sequence; cvar_t *gl_partscale; -#if USE_JPEG +#if USE_JPG cvar_t *gl_screenshot_quality; #endif #if USE_PNG @@ -273,12 +265,12 @@ void GL_DrawBox( const vec3_t origin, vec3_t bounds[2] ) { static void GL_DrawSpriteModel( model_t *model ) { vec3_t point; entity_t *e = glr.ent; - spriteFrame_t *frame; + mspriteframe_t *frame; image_t *image; int bits; float alpha; - frame = &model->sframes[e->frame % model->numFrames]; + frame = &model->spriteframes[e->frame % model->numframes]; image = frame->image; GL_TexEnv( GL_MODULATE ); @@ -303,23 +295,23 @@ static void GL_DrawSpriteModel( model_t *model ) { qglBegin( GL_QUADS ); qglTexCoord2f( 0, 1 ); - VectorMA( e->origin, -frame->y, glr.viewaxis[2], point ); - VectorMA( point, frame->x, glr.viewaxis[1], point ); + VectorMA( e->origin, -frame->origin_y, glr.viewaxis[2], point ); + VectorMA( point, frame->origin_x, glr.viewaxis[1], point ); qglVertex3fv( point ); qglTexCoord2f( 0, 0 ); - VectorMA( e->origin, frame->height - frame->y, glr.viewaxis[2], point ); - VectorMA( point, frame->x, glr.viewaxis[1], point ); + VectorMA( e->origin, frame->height - frame->origin_y, glr.viewaxis[2], point ); + VectorMA( point, frame->origin_x, glr.viewaxis[1], point ); qglVertex3fv( point ); qglTexCoord2f( 1, 0 ); - VectorMA( e->origin, frame->height - frame->y, glr.viewaxis[2], point ); - VectorMA( point, frame->x - frame->width, glr.viewaxis[1], point ); + VectorMA( e->origin, frame->height - frame->origin_y, glr.viewaxis[2], point ); + VectorMA( point, frame->origin_x - frame->width, glr.viewaxis[1], point ); qglVertex3fv( point ); qglTexCoord2f( 1, 1 ); - VectorMA( e->origin, -frame->y, glr.viewaxis[2], point ); - VectorMA( point, frame->x - frame->width, glr.viewaxis[1], point ); + VectorMA( e->origin, -frame->origin_y, glr.viewaxis[2], point ); + VectorMA( point, frame->origin_x - frame->width, glr.viewaxis[1], point ); qglVertex3fv( point ); qglEnd(); @@ -354,7 +346,7 @@ static void GL_DrawNullModel( void ) { static void GL_DrawEntities( int mask ) { entity_t *ent, *last; - modelType_t *model; + model_t *model; if( !gl_drawentities->integer ) { return; @@ -383,28 +375,37 @@ static void GL_DrawEntities( int mask ) { VectorSet( glr.entaxis[2], 0, 0, 1 ); } - model = GL_ModelForHandle( ent->model ); + // inline BSP model + if( ent->model & 0x80000000 ) { + bsp_t *bsp = gl_static.world.cache; + int index = ~ent->model; + + if( !bsp ) { + Com_Error( ERR_DROP, "%s: inline model without world", + __func__ ); + } + + if( index < 1 || index >= bsp->nummodels ) { + Com_Error( ERR_DROP, "%s: inline model %d out of range", + __func__, index ); + } + + GL_DrawBspModel( &bsp->models[index] ); + continue; + } + + model = MOD_ForHandle( ent->model ); if( !model ) { GL_DrawNullModel(); continue; } - switch( *model ) { - case MODEL_NULL: - GL_DrawNullModel(); - break; - case MODEL_BSP: - GL_DrawBspModel( ( bspSubmodel_t * )model ); - break; - case MODEL_ALIAS: - GL_DrawAliasModel( ( model_t * )model ); - break; - case MODEL_SPRITE: - GL_DrawSpriteModel( ( model_t * )model ); - break; - default: - Com_Error( ERR_FATAL, "GL_DrawEntities: bad model type: %u", *model ); - break; + if( model->frames ) { + GL_DrawAliasModel( model ); + } else if( model->spriteframes ) { + GL_DrawSpriteModel( model ); + } else { + Com_Error( ERR_FATAL, "%s: bad model type", __func__ ); } } } @@ -440,10 +441,10 @@ void GL_ShowErrors( const char *func ) { } } -static void GL_RenderFrame( refdef_t *fd ) { +void R_RenderFrame( refdef_t *fd ) { GL_Flush2D(); - if( !r_world.name[0] && !( fd->rdflags & RDF_NOWORLDMODEL ) ) { + if( !gl_static.world.cache && !( fd->rdflags & RDF_NOWORLDMODEL ) ) { Com_Error( ERR_FATAL, "GL_RenderView: NULL worldmodel" ); } @@ -488,7 +489,7 @@ static void GL_RenderFrame( refdef_t *fd ) { GL_ShowErrors( __func__ ); } -static void GL_BeginFrame( void ) { +void R_BeginFrame( void ) { if( gl_log->integer ) { QGL_LogNewFrame(); } @@ -504,7 +505,7 @@ static void GL_BeginFrame( void ) { GL_ShowErrors( __func__ ); } -static void GL_EndFrame( void ) { +void R_EndFrame( void ) { if( gl_showstats->integer ) { Draw_Stats(); } @@ -517,7 +518,7 @@ static void GL_EndFrame( void ) { GL_ShowErrors( __func__ ); - video.EndFrame(); + VID_EndFrame(); // qglFinish(); } @@ -530,11 +531,12 @@ static void GL_EndFrame( void ) { ============================================================================== */ +#if USE_TGA || USE_JPG || USE_PNG static char *screenshot_path( char *buffer, const char *ext ) { int i; - if( cmd.Argc() > 1 ) { - Com_sprintf( buffer, MAX_OSPATH, SCREENSHOTS_DIRECTORY"/%s", cmd.Argv( 1 ) ); + if( Cmd_Argc() > 1 ) { + Com_sprintf( buffer, MAX_OSPATH, SCREENSHOTS_DIRECTORY"/%s", Cmd_Argv( 1 ) ); COM_AppendExtension( buffer, ext, MAX_OSPATH ); return buffer; } @@ -543,7 +545,7 @@ static char *screenshot_path( char *buffer, const char *ext ) { // for( i = 0; i < 1000; i++ ) { Com_sprintf( buffer, MAX_OSPATH, SCREENSHOTS_DIRECTORY"/quake%03d%s", i, ext ); - if( fs.LoadFileEx( buffer, NULL, FS_PATH_GAME, TAG_FREE ) == INVALID_LENGTH ) { + if( FS_LoadFileEx( buffer, NULL, FS_PATH_GAME, TAG_FREE ) == INVALID_LENGTH ) { return buffer; // file doesn't exist } } @@ -551,6 +553,7 @@ static char *screenshot_path( char *buffer, const char *ext ) { Com_Printf( "All screenshot slots are full.\n" ); return NULL; } +#endif /* @@ -559,12 +562,13 @@ GL_ScreenShot_f ================== */ static void GL_ScreenShot_f( void ) { +#if USE_TGA char buffer[MAX_OSPATH]; byte *bgr; qboolean ret; - if( cmd.Argc() > 2 ) { - Com_Printf( "Usage: %s [name]\n", cmd.Argv( 0 ) ); + if( Cmd_Argc() > 2 ) { + Com_Printf( "Usage: %s [name]\n", Cmd_Argv( 0 ) ); return; } @@ -572,29 +576,32 @@ static void GL_ScreenShot_f( void ) { return; } - bgr = fs.AllocTempMem( gl_config.vidWidth * gl_config.vidHeight * 3 ); + bgr = FS_AllocTempMem( gl_config.vidWidth * gl_config.vidHeight * 3 ); qglReadPixels( 0, 0, gl_config.vidWidth, gl_config.vidHeight, GL_BGR, GL_UNSIGNED_BYTE, bgr ); - ret = Image_WriteTGA( buffer, bgr, gl_config.vidWidth, gl_config.vidHeight ); + ret = IMG_WriteTGA( buffer, bgr, gl_config.vidWidth, gl_config.vidHeight ); - fs.FreeFile( bgr ); + FS_FreeFile( bgr ); if( ret ) { Com_Printf( "Wrote %s\n", buffer ); } +#else + Com_Printf( "Couldn't create screenshot due to no TGA support linked in.\n" ); +#endif } -#if USE_JPEG +#if USE_JPG static void GL_ScreenShotJPG_f( void ) { char buffer[MAX_OSPATH]; byte *rgb; int quality; qboolean ret; - if( cmd.Argc() > 3 ) { - Com_Printf( "Usage: %s [name] [quality]\n", cmd.Argv( 0 ) ); + if( Cmd_Argc() > 3 ) { + Com_Printf( "Usage: %s [name] [quality]\n", Cmd_Argv( 0 ) ); return; } @@ -602,20 +609,20 @@ static void GL_ScreenShotJPG_f( void ) { return; } - rgb = fs.AllocTempMem( gl_config.vidWidth * gl_config.vidHeight * 3 ); + rgb = FS_AllocTempMem( gl_config.vidWidth * gl_config.vidHeight * 3 ); qglReadPixels( 0, 0, gl_config.vidWidth, gl_config.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, rgb ); - if( cmd.Argc() > 2 ) { - quality = atoi( cmd.Argv( 2 ) ); + if( Cmd_Argc() > 2 ) { + quality = atoi( Cmd_Argv( 2 ) ); } else { quality = gl_screenshot_quality->integer; } - ret = Image_WriteJPG( buffer, rgb, gl_config.vidWidth, gl_config.vidHeight, quality ); + ret = IMG_WriteJPG( buffer, rgb, gl_config.vidWidth, gl_config.vidHeight, quality ); - fs.FreeFile( rgb ); + FS_FreeFile( rgb ); if( ret ) { Com_Printf( "Wrote %s\n", buffer ); @@ -630,8 +637,8 @@ static void GL_ScreenShotPNG_f( void ) { int compression; qboolean ret; - if( cmd.Argc() > 3 ) { - Com_Printf( "Usage: %s [name] [compression]\n", cmd.Argv( 0 ) ); + if( Cmd_Argc() > 3 ) { + Com_Printf( "Usage: %s [name] [compression]\n", Cmd_Argv( 0 ) ); return; } @@ -639,20 +646,20 @@ static void GL_ScreenShotPNG_f( void ) { return; } - rgb = fs.AllocTempMem( gl_config.vidWidth * gl_config.vidHeight * 3 ); + rgb = FS_AllocTempMem( gl_config.vidWidth * gl_config.vidHeight * 3 ); qglReadPixels( 0, 0, gl_config.vidWidth, gl_config.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, rgb ); - if( cmd.Argc() > 2 ) { - compression = atoi( cmd.Argv( 2 ) ); + if( Cmd_Argc() > 2 ) { + compression = atoi( Cmd_Argv( 2 ) ); } else { compression = gl_screenshot_compression->integer; } - ret = Image_WritePNG( buffer, rgb, gl_config.vidWidth, gl_config.vidHeight, compression ); + ret = IMG_WritePNG( buffer, rgb, gl_config.vidWidth, gl_config.vidHeight, compression ); - fs.FreeFile( rgb ); + FS_FreeFile( rgb ); if( ret ) { Com_Printf( "Wrote %s\n", buffer ); @@ -669,72 +676,63 @@ static void GL_Strings_f( void ) { // ============================================================================== - -static void GL_ModeChanged( int width, int height, int flags, - int rowbytes, void *pixels ) -{ - gl_config.vidWidth = width & ~7; - gl_config.vidHeight = height & ~1; - gl_config.flags = flags; -} - static void GL_Register( void ) { /* misc */ - gl_partscale = cvar.Get( "gl_partscale", "2", 0 ); -#if USE_JPEG - gl_screenshot_quality = cvar.Get( "gl_screenshot_quality", "100", 0 ); + gl_partscale = Cvar_Get( "gl_partscale", "2", 0 ); +#if USE_JPG + gl_screenshot_quality = Cvar_Get( "gl_screenshot_quality", "100", 0 ); #endif #if USE_PNG - gl_screenshot_compression = cvar.Get( "gl_screenshot_compression", "6", 0 ); + gl_screenshot_compression = Cvar_Get( "gl_screenshot_compression", "6", 0 ); #endif - gl_celshading = cvar.Get( "gl_celshading", "0", 0 ); - gl_modulate = cvar.Get( "gl_modulate", "1", CVAR_ARCHIVE ); - gl_hwgamma = cvar.Get( "vid_hwgamma", "0", CVAR_ARCHIVE|CVAR_REFRESH ); + gl_celshading = Cvar_Get( "gl_celshading", "0", 0 ); + gl_modulate = Cvar_Get( "gl_modulate", "1", CVAR_ARCHIVE ); + gl_hwgamma = Cvar_Get( "vid_hwgamma", "0", CVAR_ARCHIVE|CVAR_REFRESH ); /* development variables */ - gl_znear = cvar.Get( "gl_znear", "2", CVAR_CHEAT ); - gl_zfar = cvar.Get( "gl_zfar", "16384", 0 ); - gl_log = cvar.Get( "gl_log", "0", 0 ); - gl_drawworld = cvar.Get( "gl_drawworld", "1", CVAR_CHEAT ); - gl_drawentities = cvar.Get( "gl_drawentities", "1", CVAR_CHEAT ); - gl_drawsky = cvar.Get( "gl_drawsky", "1", 0 ); - gl_showtris = cvar.Get( "gl_showtris", "0", CVAR_CHEAT ); - gl_showstats = cvar.Get( "gl_showstats", "0", 0 ); - gl_cull_nodes = cvar.Get( "gl_cull_nodes", "1", 0 ); - gl_cull_models = cvar.Get( "gl_cull_models", "1", 0 ); - gl_bind = cvar.Get( "gl_bind", "1", CVAR_CHEAT ); - gl_clear = cvar.Get( "gl_clear", "0", 0 ); - gl_novis = cvar.Get( "gl_novis", "0", 0 ); - gl_lockpvs = cvar.Get( "gl_lockpvs", "0", CVAR_CHEAT ); - gl_lightmap = cvar.Get( "gl_lightmap", "0", CVAR_CHEAT ); + gl_znear = Cvar_Get( "gl_znear", "2", CVAR_CHEAT ); + gl_zfar = Cvar_Get( "gl_zfar", "16384", 0 ); + gl_log = Cvar_Get( "gl_log", "0", 0 ); + gl_drawworld = Cvar_Get( "gl_drawworld", "1", CVAR_CHEAT ); + gl_drawentities = Cvar_Get( "gl_drawentities", "1", CVAR_CHEAT ); + gl_drawsky = Cvar_Get( "gl_drawsky", "1", 0 ); + gl_showtris = Cvar_Get( "gl_showtris", "0", CVAR_CHEAT ); + gl_showstats = Cvar_Get( "gl_showstats", "0", 0 ); + gl_cull_nodes = Cvar_Get( "gl_cull_nodes", "1", 0 ); + gl_cull_models = Cvar_Get( "gl_cull_models", "1", 0 ); + gl_bind = Cvar_Get( "gl_bind", "1", CVAR_CHEAT ); + gl_clear = Cvar_Get( "gl_clear", "0", 0 ); + gl_novis = Cvar_Get( "gl_novis", "0", 0 ); + gl_lockpvs = Cvar_Get( "gl_lockpvs", "0", CVAR_CHEAT ); + gl_lightmap = Cvar_Get( "gl_lightmap", "0", CVAR_CHEAT ); #if USE_DYNAMIC - gl_dynamic = cvar.Get( "gl_dynamic", "2", CVAR_ARCHIVE ); + gl_dynamic = Cvar_Get( "gl_dynamic", "2", CVAR_ARCHIVE ); #endif - gl_polyblend = cvar.Get( "gl_polyblend", "1", 0 ); - gl_fullbright = cvar.Get( "r_fullbright", "0", CVAR_CHEAT ); - gl_showerrors = cvar.Get( "gl_showerrors", "1", 0 ); - gl_fragment_program = cvar.Get( "gl_fragment_program", "0", CVAR_REFRESH ); - gl_vertex_buffer_object = cvar.Get( "gl_vertex_buffer_object", "0", CVAR_REFRESH ); + gl_polyblend = Cvar_Get( "gl_polyblend", "1", 0 ); + gl_fullbright = Cvar_Get( "r_fullbright", "0", CVAR_CHEAT ); + gl_showerrors = Cvar_Get( "gl_showerrors", "1", 0 ); + gl_fragment_program = Cvar_Get( "gl_fragment_program", "0", CVAR_REFRESH ); + gl_vertex_buffer_object = Cvar_Get( "gl_vertex_buffer_object", "0", CVAR_REFRESH ); - cmd.AddCommand( "screenshot", GL_ScreenShot_f ); -#if USE_JPEG - cmd.AddCommand( "screenshotjpg", GL_ScreenShotJPG_f ); + Cmd_AddCommand( "screenshot", GL_ScreenShot_f ); +#if USE_JPG + Cmd_AddCommand( "screenshotjpg", GL_ScreenShotJPG_f ); #else - cmd.AddCommand( "screenshotjpg", GL_ScreenShot_f ); + Cmd_AddCommand( "screenshotjpg", GL_ScreenShot_f ); #endif #if USE_PNG - cmd.AddCommand( "screenshotpng", GL_ScreenShotPNG_f ); + Cmd_AddCommand( "screenshotpng", GL_ScreenShotPNG_f ); #else - cmd.AddCommand( "screenshotpng", GL_ScreenShot_f ); + Cmd_AddCommand( "screenshotpng", GL_ScreenShot_f ); #endif - cmd.AddCommand( "strings", GL_Strings_f ); + Cmd_AddCommand( "strings", GL_Strings_f ); } static void GL_Unregister( void ) { - cmd.RemoveCommand( "screenshot" ); - cmd.RemoveCommand( "screenshotjpg" ); - cmd.RemoveCommand( "screenshotpng" ); - cmd.RemoveCommand( "strings" ); + Cmd_RemoveCommand( "screenshot" ); + Cmd_RemoveCommand( "screenshotjpg" ); + Cmd_RemoveCommand( "screenshotpng" ); + Cmd_RemoveCommand( "strings" ); } #define GPA( x ) do { q ## x = ( void * )qglGetProcAddress( #x ); } while( 0 ) @@ -870,12 +868,21 @@ static void GL_IdentifyRenderer( void ) { } static void GL_PostInit( void ) { + registration_sequence = 1; + GL_InitImages(); - GL_InitModels(); + MOD_Init(); GL_SetDefaultState(); } -static qboolean GL_Init( qboolean total ) { +// ============================================================================== + +/* +=============== +R_Init +=============== +*/ +qboolean R_Init( qboolean total ) { Com_DPrintf( "GL_Init( %i )\n", total ); if( !total ) { @@ -885,15 +892,15 @@ static qboolean GL_Init( qboolean total ) { Com_Printf( "ref_gl " VERSION ", " __DATE__ "\n" ); - /* initialize OS-specific parts of OpenGL */ - /* create the window and set up the context */ - if( !video.Init() ) { + // initialize OS-specific parts of OpenGL + // create the window and set up the context + if( !VID_Init() ) { return qfalse; } GL_Register(); - /* initialize our QGL dynamic bindings */ + // initialize our QGL dynamic bindings QGL_Init(); #define GET_STRING( x ) ( const char * )qglGetString( x ) @@ -914,7 +921,7 @@ static qboolean GL_Init( qboolean total ) { } if( gl_hwgamma->integer && !( gl_config.flags & QVF_GAMMARAMP ) ) { - cvar.Set( "vid_hwgamma", "0" ); + Cvar_Set( "vid_hwgamma", "0" ); Com_Printf( "Hardware gamma is not supported by this video driver\n" ); } @@ -938,33 +945,21 @@ static qboolean GL_Init( qboolean total ) { fail: QGL_Shutdown(); GL_Unregister(); - video.Shutdown(); + VID_Shutdown(); return qfalse; } -static void GL_FreeWorld( void ) { - GLuint buf = 1; - - Bsp_FreeWorld(); - - if( !gl_static.vertices && qglDeleteBuffersARB ) { - qglDeleteBuffersARB( 1, &buf ); - } - - gl_static.vertices = NULL; -} - /* =============== R_Shutdown =============== */ -void GL_Shutdown( qboolean total ) { +void R_Shutdown( qboolean total ) { Com_DPrintf( "GL_Shutdown( %i )\n", total ); GL_FreeWorld(); GL_ShutdownImages(); - GL_ShutdownModels(); + MOD_Shutdown(); if( !total ) { return; @@ -972,14 +967,10 @@ void GL_Shutdown( qboolean total ) { GL_ShutdownPrograms(); - /* - ** shut down OS specific OpenGL stuff like contexts, etc. - */ - video.Shutdown(); + // shut down OS specific OpenGL stuff like contexts, etc. + VID_Shutdown(); - /* - ** shutdown our QGL subsystem - */ + // shutdown our QGL subsystem QGL_Shutdown(); GL_Unregister(); @@ -988,11 +979,13 @@ void GL_Shutdown( qboolean total ) { memset( &gl_config, 0, sizeof( gl_config ) ); } -void GL_BeginRegistration( const char *name ) { +/* +=============== +R_BeginRegistration +=============== +*/ +void R_BeginRegistration( const char *name ) { char fullname[MAX_QPATH]; - bspTexinfo_t *texinfo, *lastexinfo; - bspLeaf_t *leaf, *lastleaf; - bspNode_t *node, *lastnode; gl_static.registering = qtrue; registration_sequence++; @@ -1001,225 +994,38 @@ void GL_BeginRegistration( const char *name ) { glr.viewcluster1 = glr.viewcluster2 = -2; Q_concat( fullname, sizeof( fullname ), "maps/", name, ".bsp", NULL ); - - // check if the required world model was already loaded - if( !strcmp( r_world.name, fullname ) && - !cvar.VariableInteger( "flushmap" ) ) - { - lastexinfo = r_world.texinfos + r_world.numTexinfos; - for( texinfo = r_world.texinfos; texinfo < lastexinfo; texinfo++ ) { - texinfo->image->registration_sequence = registration_sequence; - } - lastleaf = r_world.leafs + r_world.numLeafs; - for( leaf = r_world.leafs; leaf < lastleaf; leaf++ ) { - leaf->visframe = 0; - } - lastnode = r_world.nodes + r_world.numNodes; - for( node = r_world.nodes; node < lastnode; node++ ) { - node->visframe = 0; - } - Com_DPrintf( "%s: reused old world model\n", __func__ ); - return; - } - - // free previous model, if any - GL_FreeWorld(); - - // load fresh world model - Bsp_LoadWorld( fullname ); -} - -void GL_EndRegistration( void ) { - R_FreeUnusedImages(); - Model_FreeUnused(); - Scrap_Upload(); - gl_static.registering = qfalse; + GL_LoadWorld( fullname ); } -void GL_SetPalette( const byte *pal ) { - int i; - - if( pal == NULL ) { - for( i = 0; i < 256; i++ ) { - gl_static.palette[i] = d_8to24table[i]; - } - return; - } - - for( i = 0; i < 256; i++ ) { - gl_static.palette[i] = MakeColor( pal[0], pal[1], pal[2], 255 ); - pal += 3; - } -} - -void GL_GetConfig( glconfig_t *config ) { - *config = gl_config; -} - -#ifndef REF_HARD_LINKED -// this is only here so the functions in q_shared.c can link - -void Com_Printf( const char *fmt, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, fmt ); - Q_vsnprintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - com.Print( PRINT_ALL, text ); -} - -void Com_DPrintf( const char *fmt, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, fmt ); - Q_vsnprintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - com.Print( PRINT_DEVELOPER, text ); -} - -void Com_WPrintf( const char *fmt, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, fmt ); - Q_vsnprintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - com.Print( PRINT_WARNING, text ); -} - -void Com_EPrintf( const char *fmt, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, fmt ); - Q_vsnprintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - com.Print( PRINT_ERROR, text ); -} - -void Com_Error( comErrorType_t type, const char *error, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, error ); - Q_vsnprintf( text, sizeof( text ), error, argptr ); - va_end( argptr ); - - com.Error( type, text ); -} - -#endif /* !REF_HARD_LINKED */ - /* -================= -Ref_FillAPI -================= +=============== +R_EndRegistration +=============== */ -static void Ref_FillAPI( refAPI_t *api ) { - api->BeginRegistration = GL_BeginRegistration; - api->RegisterModel = GL_RegisterModel; - api->RegisterSkin = R_RegisterSkin; - api->RegisterPic = R_RegisterPic; - api->RegisterFont = GL_RegisterFont; - api->SetSky = R_SetSky; - api->EndRegistration = GL_EndRegistration; - api->GetModelSize = GL_GetModelSize; - - api->RenderFrame = GL_RenderFrame; - api->LightPoint = GL_LightPoint; - - api->SetColor = Draw_SetColor; - api->SetClipRect = Draw_SetClipRect; - api->SetScale = Draw_SetScale; - api->DrawString = Draw_String; - api->DrawChar = Draw_Char; - api->DrawGetPicSize = Draw_GetPicSize; - api->DrawPic = Draw_Pic; - api->DrawStretchPicST = Draw_StretchPicST; - api->DrawStretchPic = Draw_StretchPic; - api->DrawTileClear = Draw_TileClear; - api->DrawFill = Draw_Fill; - api->DrawStretchRaw = Draw_StretchRaw; - api->DrawFillEx = Draw_FillEx; - - api->Init = GL_Init; - api->Shutdown = GL_Shutdown; - - api->CinematicSetPalette = GL_SetPalette; - api->BeginFrame = GL_BeginFrame; - api->EndFrame = GL_EndFrame; - api->ModeChanged = GL_ModeChanged; - - api->GetConfig = GL_GetConfig; +void R_EndRegistration( void ) { + IMG_FreeUnused(); + MOD_FreeUnused(); + Scrap_Upload(); + gl_static.registering = qfalse; } /* -================= -Ref_APISetupCallback -================= +=============== +R_ModeChanged +=============== */ -qboolean Ref_APISetupCallback( api_type_t type, void *api ) { - switch( type ) { - case API_REFRESH: - Ref_FillAPI( ( refAPI_t * )api ); - break; - default: - return qfalse; - } - - return qtrue; +void R_ModeChanged( int width, int height, int flags, int rowbytes, void *pixels ) { + gl_config.vidWidth = width & ~7; + gl_config.vidHeight = height & ~1; + gl_config.flags = flags; } -#ifndef REF_HARD_LINKED - /* -@@@@@@@@@@@@@@@@@@@@@ -moduleEntry - -@@@@@@@@@@@@@@@@@@@@@ +=============== +R_GetConfig +=============== */ -EXPORTED void *moduleEntry( int query, void *data ) { - moduleInfo_t *info; - moduleCapability_t caps; - APISetupCallback_t callback; - - switch( query ) { - case MQ_GETINFO: - info = ( moduleInfo_t * )data; - info->api_version = MODULES_APIVERSION; - Q_strncpyz( info->fullname, "OpenGL Refresh Driver", - sizeof( info->fullname ) ); - Q_strncpyz( info->author, "Andrey Nazarov", sizeof( info->author ) ); - return ( void * )qtrue; - - case MQ_GETCAPS: - caps = MCP_REFRESH; - return ( void * )caps; - - case MQ_SETUPAPI: - if( ( callback = ( APISetupCallback_t )data ) == NULL ) { - return NULL; - } - callback( API_CMD, &cmd ); - callback( API_CVAR, &cvar ); - callback( API_FS, &fs ); - callback( API_COMMON, &com ); - callback( API_SYSTEM, &sys ); - callback( API_VIDEO_OPENGL, &video ); - - return ( void * )Ref_APISetupCallback; - - } - - /* quiet compiler warning */ - return NULL; +void R_GetConfig( glconfig_t *config ) { + *config = gl_config; } -#endif /* !REF_HARD_LINKED */ - diff --git a/source/gl_mesh.c b/source/gl_mesh.c index 2fbb7e5..8f07878 100644 --- a/source/gl_mesh.c +++ b/source/gl_mesh.c @@ -28,7 +28,7 @@ static vec3_t oldscale; static vec3_t newscale; static vec3_t translate; -typedef void (*meshTessFunc_t)( aliasMesh_t *, int, int ); +typedef void (*meshTessFunc_t)( maliasmesh_t *, int, int ); #if USE_SHADING @@ -45,8 +45,8 @@ static const vec_t *shadedots; #endif -static void Tess_Mesh( aliasMesh_t *mesh, int oldframe, int newframe ) { - aliasVert_t *src_vert; +static void Tess_Mesh( maliasmesh_t *mesh, int oldframe, int newframe ) { + maliasvert_t *src_vert; vec_t *dst_vert; int i, count; const vec_t *normal; @@ -55,12 +55,12 @@ static void Tess_Mesh( aliasMesh_t *mesh, int oldframe, int newframe ) { vec_t d; #endif - src_vert = &mesh->verts[newframe * mesh->numVerts]; + src_vert = &mesh->verts[newframe * mesh->numverts]; dst_vert = tess.vertices; - count = mesh->numVerts; + count = mesh->numverts; if( glr.ent->flags & RF_SHELL_MASK ) { for( i = 0; i < count; i++ ) { - normal = bytedirs[src_vert->normalIndex]; + normal = bytedirs[src_vert->normalindex]; dst_vert[0] = normal[0] * POWERSUIT_SCALE + src_vert->pos[0] * newscale[0] + translate[0]; @@ -83,7 +83,7 @@ static void Tess_Mesh( aliasMesh_t *mesh, int oldframe, int newframe ) { dst_vert += 4; #if USE_SHADING - d = shadedots[src_vert->normalIndex]; + d = shadedots[src_vert->normalindex]; dst_color[0] = shadelight[0] * d; dst_color[1] = shadelight[1] * d; dst_color[2] = shadelight[2] * d; @@ -98,9 +98,9 @@ static void Tess_Mesh( aliasMesh_t *mesh, int oldframe, int newframe ) { c.trisDrawn += count; } -static void Tess_LerpedMesh( aliasMesh_t *mesh, int oldframe, int newframe ) { - aliasVert_t *src_oldvert; - aliasVert_t *src_newvert; +static void Tess_LerpedMesh( maliasmesh_t *mesh, int oldframe, int newframe ) { + maliasvert_t *src_oldvert; + maliasvert_t *src_newvert; vec_t *dst_vert; int i, count; const vec_t *normal; @@ -109,13 +109,13 @@ static void Tess_LerpedMesh( aliasMesh_t *mesh, int oldframe, int newframe ) { vec_t d; #endif - src_oldvert = &mesh->verts[oldframe * mesh->numVerts]; - src_newvert = &mesh->verts[newframe * mesh->numVerts]; + src_oldvert = &mesh->verts[oldframe * mesh->numverts]; + src_newvert = &mesh->verts[newframe * mesh->numverts]; dst_vert = tess.vertices; - count = mesh->numVerts; + count = mesh->numverts; if( glr.ent->flags & RF_SHELL_MASK ) { for( i = 0; i < count; i++ ) { - normal = bytedirs[src_newvert->normalIndex]; + normal = bytedirs[src_newvert->normalindex]; dst_vert[0] = normal[0] * POWERSUIT_SCALE + src_oldvert->pos[0] * oldscale[0] + @@ -193,7 +193,7 @@ static void GL_SetAliasColor( vec3_t origin, vec_t *color ) { } else if( ent->flags & RF_FULLBRIGHT ) { VectorSet( color, 1, 1, 1 ); } else { - GL_LightPoint( origin, color ); + R_LightPoint( origin, color ); if( ent->flags & RF_MINLIGHT ) { for( i = 0; i < 3; i++ ) { @@ -231,8 +231,8 @@ void GL_DrawAliasModel( model_t *model ) { entity_t *ent = glr.ent; image_t *image; int oldframeIdx, newframeIdx; - aliasFrame_t *newframe, *oldframe; - aliasMesh_t *mesh, *last; + maliasframe_t *newframe, *oldframe; + maliasmesh_t *mesh, *last; meshTessFunc_t tessFunc; float frontlerp, backlerp; vec3_t origin; @@ -272,13 +272,13 @@ void GL_DrawAliasModel( model_t *model ) { #endif newframeIdx = ent->frame; - if( newframeIdx < 0 || newframeIdx >= model->numFrames ) { + if( newframeIdx < 0 || newframeIdx >= model->numframes ) { Com_DPrintf( "GL_DrawAliasModel: no such frame %d\n", newframeIdx ); newframeIdx = 0; } oldframeIdx = ent->oldframe; - if( oldframeIdx < 0 || oldframeIdx >= model->numFrames ) { + if( oldframeIdx < 0 || oldframeIdx >= model->numframes ) { Com_DPrintf( "GL_DrawAliasModel: no such oldframe %d\n", oldframeIdx ); oldframeIdx = 0; } @@ -365,7 +365,7 @@ void GL_DrawAliasModel( model_t *model ) { scale = 0; if( gl_celshading->value > 0 && ( ent->flags & RF_SHELL_MASK ) == 0 ) { if( gl_celshading->value > 5 ) { - cvar.Set( "gl_celshading", "5" ); + Cvar_Set( "gl_celshading", "5" ); } VectorSubtract( origin, glr.fd.vieworg, dir ); scale = VectorLength( dir ); @@ -423,15 +423,15 @@ void GL_DrawAliasModel( model_t *model ) { qglColor4fv( color ); #endif - last = model->meshes + model->numMeshes; + last = model->meshes + model->nummeshes; for( mesh = model->meshes; mesh < last; mesh++ ) { if( ent->flags & RF_SHELL_MASK ) { image = r_whiteimage; } else { if( ent->skin ) { - image = R_ImageForHandle( ent->skin ); + image = IMG_ForHandle( ent->skin ); } else { - if( ( unsigned )ent->skinnum >= MAX_MD2SKINS ) { + if( ( unsigned )ent->skinnum >= MAX_ALIAS_SKINS ) { Com_DPrintf( "GL_DrawAliasModel: no such skin: %d\n", ent->skinnum ); image = mesh->skins[0]; @@ -458,9 +458,9 @@ void GL_DrawAliasModel( model_t *model ) { qglTexCoordPointer( 2, GL_FLOAT, 0, mesh->tcoords ); if( qglLockArraysEXT ) { - qglLockArraysEXT( 0, mesh->numVerts ); + qglLockArraysEXT( 0, mesh->numverts ); } - qglDrawElements( GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT, + qglDrawElements( GL_TRIANGLES, mesh->numindices, GL_UNSIGNED_INT, mesh->indices ); #if USE_CELSHADING @@ -471,7 +471,7 @@ void GL_DrawAliasModel( model_t *model ) { qglLineWidth( gl_celshading->value*scale ); GL_Bits( bits | GLS_BLEND_BLEND ); qglColor4f( 0, 0, 0, scale ); - qglDrawElements( GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT, + qglDrawElements( GL_TRIANGLES, mesh->numindices, GL_UNSIGNED_INT, mesh->indices ); qglCullFace( back ); qglPolygonMode( back, GL_FILL ); @@ -482,7 +482,7 @@ void GL_DrawAliasModel( model_t *model ) { if( gl_showtris->integer ) { GL_EnableOutlines(); - qglDrawElements( GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT, + qglDrawElements( GL_TRIANGLES, mesh->numindices, GL_UNSIGNED_INT, mesh->indices ); GL_DisableOutlines(); } diff --git a/source/gl_models.c b/source/gl_models.c index 7937512..b2ff3d5 100644 --- a/source/gl_models.c +++ b/source/gl_models.c @@ -19,255 +19,59 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "gl_local.h" - -#define Model_Malloc( size ) sys.HunkAlloc( &model->pool, size ) - -static model_t r_models[MAX_MODELS]; -static int r_numModels; - -static byte ll2byte[256][256]; - -static cvar_t *gl_override_models; - -static model_t *Model_Alloc( const char *name ) { - model_t *model; - int i; - - for( i = 0, model = r_models; i < r_numModels; i++, model++ ) { - if( !model->name[0] ) { - break; - } - } - - if( i == r_numModels ) { - if( r_numModels == MAX_MODELS ) { - Com_Error( ERR_DROP, "Model_Alloc: MAX_MODELS" ); - } - r_numModels++; - } - - strcpy( model->name, name ); - model->registration_sequence = registration_sequence; - model->type = MODEL_NULL; - - return model; -} - -static model_t *Model_Find( const char *name ) { - model_t *model; - aliasMesh_t *mesh; - int i, j; - - for( i = 0, model = r_models; i < r_numModels; i++, model++ ) { - if( !model->name[0] ) { - continue; - } - if( !Q_stricmp( model->name, name ) ) { - break; - } - } - - if( i == r_numModels ) { - return NULL; - } - - switch( model->type ) { - case MODEL_ALIAS: - for( i = 0; i < model->numMeshes; i++ ) { - mesh = &model->meshes[i]; - for( j = 0; j < mesh->numSkins; j++ ) { - mesh->skins[j]->registration_sequence = registration_sequence; - } - } - break; - case MODEL_SPRITE: - for( i = 0; i < model->numFrames; i++ ) { - model->sframes[i].image->registration_sequence = registration_sequence; - } - break; - default: - Com_Error( ERR_DROP, "Model_Find: bad model type: %d", model->type ); - break; - } - - model->registration_sequence = registration_sequence; - return model; -} - -static void Model_List_f( void ) { - int i; - model_t *model; - int bytes; - - Com_Printf( "------------------\n"); - bytes = 0; - - for( i = 0, model = r_models; i < r_numModels; i++, model++ ) { - if( !model->name[0] ) { - continue; - } - - Com_Printf( "%8"PRIz" : %s\n", model->pool.cursize, model->name ); - bytes += model->pool.cursize; - } - Com_Printf( "Total resident: %i\n", bytes ); -} - -void Model_FreeUnused( void ) { - model_t *model; - int i; - - for( i = 0, model = r_models; i < r_numModels; i++, model++ ) { - if( !model->name[0] ) { - continue; - } - if( model->registration_sequence != registration_sequence ) { - sys.HunkFree( &model->pool ); - model->name[0] = 0; - } - } -} - -void Model_FreeAll( void ) { - model_t *model; - int i; - - for( i = 0, model = r_models; i < r_numModels; i++, model++ ) { - if( !model->name[0] ) { - continue; - } - - sys.HunkFree( &model->pool ); - model->name[0] = 0; - } - - r_numModels = 0; -} - -static qboolean Model_LoadMd2( model_t *model, const byte *rawdata, int length ) { - dmdl_t header; - daliasframe_t *src_frame; - dtrivertx_t *src_vert; - dtriangle_t *src_tri; - dstvert_t *src_tc; - aliasFrame_t *dst_frame; - aliasVert_t *dst_vert; - aliasMesh_t *dst_mesh; +#include "d_md2.h" +#include "d_md3.h" +#include "d_sp2.h" + +qboolean MOD_LoadMD2( model_t *model, const void *rawdata, size_t length ) { + dmd2header_t header; + dmd2frame_t *src_frame; + dmd2trivertx_t *src_vert; + dmd2triangle_t *src_tri; + dmd2stvert_t *src_tc; + maliasframe_t *dst_frame; + maliasvert_t *dst_vert; + maliasmesh_t *dst_mesh; uint32_t *finalIndices; - tcoord_t *dst_tc; + maliastc_t *dst_tc; int i, j, k; - uint16_t remap[MAX_TRIANGLES*3]; - uint16_t vertIndices[MAX_TRIANGLES*3]; - uint16_t tcIndices[MAX_TRIANGLES*3]; - int numVerts, numIndices; + uint16_t remap[MD2_MAX_TRIANGLES*3]; + uint16_t vertIndices[MD2_MAX_TRIANGLES*3]; + uint16_t tcIndices[MD2_MAX_TRIANGLES*3]; + int numverts, numindices; char skinname[MAX_QPATH]; char *src_skin; image_t *skin; vec_t scaleS, scaleT; int val; vec3_t mins, maxs; - const byte *rawend; - -#define ERR( x ) \ - Com_WPrintf( "LoadMD2: %s: " x "\n", model->name ) if( length < sizeof( header ) ) { - ERR( "file too short" ); + Com_WPrintf( "%s is too short\n", model->name ); return qfalse; } /* byte swap the header */ - header = *( dmdl_t * )rawdata; + header = *( dmd2header_t * )rawdata; for( i = 0; i < sizeof( header )/4; i++ ) { (( uint32_t * )&header)[i] = LittleLong( (( uint32_t * )&header)[i] ); } - // check ident and version - if( header.ident != IDALIASHEADER ) { - ERR( "not an MD2 file" ); - return qfalse; - } - if( header.version != ALIAS_VERSION ) { - ERR( "bad version" ); - return qfalse; - } - - // check triangles - if( header.num_tris < 1 || header.num_tris > MAX_TRIANGLES ) { - ERR( "bad number of triangles" ); - return qfalse; - } - if( header.ofs_tris < sizeof( header ) || - header.ofs_tris + sizeof( dtriangle_t ) * header.num_tris > length ) - { - ERR( "bad triangles offset" ); - return qfalse; - } - - // check st - if( header.num_st < 3 || header.num_st > MAX_VERTS ) { - ERR( "bad number of st" ); - return qfalse; - } - if( header.ofs_st < sizeof( header ) || - header.ofs_st + sizeof( dstvert_t ) * header.num_st > length ) - { - ERR( "bad st offset" ); - return qfalse; - } - - // check xyz and frames - if( header.num_xyz < 3 || header.num_xyz > MAX_VERTS ) { - ERR( "bad number of xyz" ); - return qfalse; - } - if( header.num_frames < 1 || header.num_frames > MAX_FRAMES ) { - ERR( "bad number of frames" ); - return qfalse; - } - if( header.framesize < sizeof( daliasframe_t ) + ( header.num_xyz - 1 ) * sizeof( dtrivertx_t ) || - header.framesize > MAX_FRAMESIZE ) - { - ERR( "bad frame size" ); - return qfalse; - } - if( header.ofs_frames < sizeof( header ) || - header.ofs_frames + header.framesize * header.num_frames > length ) - { - ERR( "bad frames offset" ); - return qfalse; + if( !MOD_ValidateMD2( model, &header, length ) ) { + return qfalse; } - // check skins - if( header.num_skins < 0 || header.num_skins > MAX_MD2SKINS ) { - ERR( "bad number of skins" ); - return qfalse; - } - if( header.num_skins && ( header.ofs_skins < sizeof( header ) || - header.ofs_skins + MAX_SKINNAME * header.num_skins > length ) ) - { - ERR( "bad skins offset" ); - return qfalse; - } - if( header.skinwidth <= 0 || header.skinheight <= 0 ) { - ERR( "bad skin dimensions" ); - return qfalse; - } - - rawend = rawdata + length; - - model->type = MODEL_ALIAS; - sys.HunkBegin( &model->pool, 0x400000 ); + Hunk_Begin( &model->pool, 0x400000 ); /* load all triangle indices */ - src_tri = ( dtriangle_t * )( ( byte * )rawdata + header.ofs_tris ); + src_tri = ( dmd2triangle_t * )( ( byte * )rawdata + header.ofs_tris ); for( i = 0; i < header.num_tris; i++ ) { for( j = 0; j < 3; j++ ) { uint16_t idx_xyz = LittleShort( src_tri->index_xyz[j] ); uint16_t idx_st = LittleShort( src_tri->index_st[j] ); - if( idx_xyz > header.num_xyz || idx_st > header.num_st ) { - ERR( "bad indices" ); + if( idx_xyz >= header.num_xyz || idx_st >= header.num_st ) { + Com_WPrintf( "%s has bad triangle indices\n", model->name ); goto fail; } @@ -277,68 +81,68 @@ static qboolean Model_LoadMd2( model_t *model, const byte *rawdata, int length ) src_tri++; } - numIndices = header.num_tris * 3; + numindices = header.num_tris * 3; - model->meshes = Model_Malloc( sizeof( aliasMesh_t ) ); - model->numMeshes = 1; + model->meshes = Model_Malloc( sizeof( maliasmesh_t ) ); + model->nummeshes = 1; dst_mesh = model->meshes; - dst_mesh->indices = Model_Malloc( numIndices * sizeof( uint32_t ) ); - dst_mesh->numTris = header.num_tris; - dst_mesh->numIndices = numIndices; + dst_mesh->indices = Model_Malloc( numindices * sizeof( uint32_t ) ); + dst_mesh->numtris = header.num_tris; + dst_mesh->numindices = numindices; - for( i = 0; i < numIndices; i++ ) { + for( i = 0; i < numindices; i++ ) { remap[i] = 0xFFFF; } - numVerts = 0; - src_tc = ( dstvert_t * )( ( byte * )rawdata + header.ofs_st ); + numverts = 0; + src_tc = ( dmd2stvert_t * )( ( byte * )rawdata + header.ofs_st ); finalIndices = dst_mesh->indices; - for( i = 0; i < numIndices; i++ ) { + for( i = 0; i < numindices; i++ ) { if( remap[i] != 0xFFFF ) { continue; /* already remapped */ } - for( j = i + 1; j < numIndices; j++ ) { + for( j = i + 1; j < numindices; j++ ) { if( vertIndices[i] == vertIndices[j] && ( src_tc[tcIndices[i]].s == src_tc[tcIndices[j]].s && src_tc[tcIndices[i]].t == src_tc[tcIndices[j]].t ) ) { /* duplicate vertex */ remap[j] = i; - finalIndices[j] = numVerts; + finalIndices[j] = numverts; } } /* new vertex */ remap[i] = i; - finalIndices[i] = numVerts++; + finalIndices[i] = numverts++; } - dst_mesh->verts = Model_Malloc( numVerts * header.num_frames * sizeof( aliasVert_t ) ); - dst_mesh->tcoords = Model_Malloc( numVerts * sizeof( tcoord_t ) ); - dst_mesh->numVerts = numVerts; + dst_mesh->verts = Model_Malloc( numverts * header.num_frames * sizeof( maliasvert_t ) ); + dst_mesh->tcoords = Model_Malloc( numverts * sizeof( maliastc_t ) ); + dst_mesh->numverts = numverts; /* load all skins */ src_skin = ( char * )rawdata + header.ofs_skins; for( i = 0; i < header.num_skins; i++ ) { Q_strncpyz( skinname, src_skin, sizeof( skinname ) ); - skin = R_FindImage( skinname, it_skin ); + skin = IMG_Find( skinname, it_skin ); if( !skin ) { skin = r_notexture; } dst_mesh->skins[i] = skin; - src_skin += MAX_SKINNAME; + src_skin += MD2_MAX_SKINNAME; } - dst_mesh->numSkins = header.num_skins; + dst_mesh->numskins = header.num_skins; /* load all tcoords */ - src_tc = ( dstvert_t * )( ( byte * )rawdata + header.ofs_st ); + src_tc = ( dmd2stvert_t * )( ( byte * )rawdata + header.ofs_st ); dst_tc = dst_mesh->tcoords; skin = dst_mesh->skins[0]; scaleS = 1.0f / header.skinwidth; scaleT = 1.0f / header.skinheight; - for( i = 0; i < numIndices; i++ ) { + for( i = 0; i < numindices; i++ ) { if( remap[i] == i ) { float s = ( signed short )LittleShort( src_tc[ tcIndices[i] ].s ); float t = ( signed short )LittleShort( src_tc[ tcIndices[i] ].t ); @@ -349,10 +153,10 @@ static qboolean Model_LoadMd2( model_t *model, const byte *rawdata, int length ) } /* load all frames */ - model->frames = Model_Malloc( header.num_frames * sizeof( aliasFrame_t ) ); - model->numFrames = header.num_frames; + model->frames = Model_Malloc( header.num_frames * sizeof( maliasframe_t ) ); + model->numframes = header.num_frames; - src_frame = ( daliasframe_t * )( ( byte * )rawdata + header.ofs_frames ); + src_frame = ( dmd2frame_t * )( ( byte * )rawdata + header.ofs_frames ); dst_frame = model->frames; for( j = 0; j < header.num_frames; j++ ) { LittleVector( src_frame->scale, dst_frame->scale ); @@ -360,20 +164,20 @@ static qboolean Model_LoadMd2( model_t *model, const byte *rawdata, int length ) /* load frame vertices */ ClearBounds( mins, maxs ); - for( i = 0; i < numIndices; i++ ) { + for( i = 0; i < numindices; i++ ) { if( remap[i] == i ) { src_vert = &src_frame->verts[ vertIndices[i] ]; - dst_vert = &dst_mesh->verts[ j * numVerts + finalIndices[i] ]; + dst_vert = &dst_mesh->verts[ j * numverts + finalIndices[i] ]; dst_vert->pos[0] = src_vert->v[0]; dst_vert->pos[1] = src_vert->v[1]; dst_vert->pos[2] = src_vert->v[2]; k = src_vert->lightnormalindex; if( k >= NUMVERTEXNORMALS ) { - ERR( "bad normal index" ); + Com_WPrintf( "%s has bad normal indices\n", model->name ); goto fail; } - dst_vert->normalIndex = k; + dst_vert->normalindex = k; for ( k = 0; k < 3; k++ ) { val = dst_vert->pos[k]; @@ -393,21 +197,42 @@ static qboolean Model_LoadMd2( model_t *model, const byte *rawdata, int length ) VectorAdd( mins, dst_frame->translate, dst_frame->bounds[0] ); VectorAdd( maxs, dst_frame->translate, dst_frame->bounds[1] ); - src_frame = ( daliasframe_t * )( ( byte * )src_frame + header.framesize ); + src_frame = ( dmd2frame_t * )( ( byte * )src_frame + header.framesize ); dst_frame++; } - sys.HunkEnd( &model->pool ); + Hunk_End( &model->pool ); return qtrue; fail: - sys.HunkFree( &model->pool ); + Hunk_Free( &model->pool ); return qfalse; +} -#undef ERR +#if USE_MD3 +static byte ll2byte[256][256]; +static qboolean ll2byte_inited; + +static void ll2byte_init( void ) { + float s[2], c[2]; + vec3_t normal; + int i, j; + + for( i = 0; i < 256; i++ ) { + for( j = 0; j < 256; j++ ) { + s[0] = sin( i / 255.0f ); + c[0] = cos( i / 255.0f ); + + s[1] = sin( j / 255.0f ); + c[1] = cos( j / 255.0f ); + + VectorSet( normal, s[0] * c[1], s[0] * s[1], c[0] ); + ll2byte[i][j] = DirToByte( normal ); + } + } } -static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) { +qboolean MOD_LoadMD3( model_t *model, const void *rawdata, size_t length ) { dmd3header_t header; uint32_t offset; dmd3frame_t *src_frame; @@ -416,12 +241,12 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) dmd3coord_t *src_tc; dmd3skin_t *src_skin; uint32_t *src_idx; - aliasFrame_t *dst_frame; - aliasMesh_t *dst_mesh; - aliasVert_t *dst_vert; - tcoord_t *dst_tc; + maliasframe_t *dst_frame; + maliasmesh_t *dst_mesh; + maliasvert_t *dst_vert; + maliastc_t *dst_tc; uint32_t *dst_idx; - uint32_t numVerts, numTris, numSkins; + uint32_t numverts, numtris, numskins; uint32_t totalVerts; char skinname[MAX_QPATH]; image_t *skin; @@ -429,7 +254,7 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) int i, j; if( length < sizeof( header ) ) { - Com_WPrintf( "%s has length < header length\n", model->name ); + Com_WPrintf( "%s is too small to hold MD3 header\n", model->name ); return qfalse; } @@ -443,40 +268,30 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) Com_WPrintf( "%s is not an MD3 file\n", model->name ); return qfalse; } - if( header.version != MD3_VERSION ) { - Com_WPrintf( "%s has bad version: %d != %d\n", + Com_WPrintf( "%s has bad version: %d instead of %d\n", model->name, header.version, MD3_VERSION ); return qfalse; } - - if( header.num_frames < 1 ) { - Com_WPrintf( "%s has bad number of frames: %d\n", - model->name, header.num_frames ); - return qfalse; - } - if( header.num_frames > MD3_MAX_FRAMES ) { - Com_WPrintf( "%s has too many frames: %d > %d\n", - model->name, header.num_frames, MD3_MAX_FRAMES ); + if( header.num_frames < 1 || header.num_frames > MD3_MAX_FRAMES ) { + Com_WPrintf( "%s has bad number of frames\n", model->name ); return qfalse; } - - if( header.num_meshes < 1 || header.num_meshes > MD3_MAX_SURFACES ) { + if( header.num_meshes < 1 || header.num_meshes > MD3_MAX_MESHES ) { Com_WPrintf( "%s has bad number of meshes\n", model->name ); return qfalse; } - model->type = MODEL_ALIAS; - sys.HunkBegin( &model->pool, 0x400000 ); - model->numFrames = header.num_frames; - model->numMeshes = header.num_meshes; - model->meshes = Model_Malloc( sizeof( aliasMesh_t ) * header.num_meshes ); - model->frames = Model_Malloc( sizeof( aliasFrame_t ) * header.num_frames ); - - rawend = rawdata + length; + Hunk_Begin( &model->pool, 0x400000 ); + model->numframes = header.num_frames; + model->nummeshes = header.num_meshes; + model->meshes = Model_Malloc( sizeof( maliasmesh_t ) * header.num_meshes ); + model->frames = Model_Malloc( sizeof( maliasframe_t ) * header.num_frames ); + + rawend = ( byte * )rawdata + length; /* load all frames */ - src_frame = ( dmd3frame_t * )( rawdata + header.ofs_frames ); + src_frame = ( dmd3frame_t * )( ( byte * )rawdata + header.ofs_frames ); if( ( byte * )( src_frame + header.num_frames ) > rawend ) { Com_WPrintf( "%s has bad frames offset\n", model->name ); goto fail; @@ -494,7 +309,7 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) } /* load all meshes */ - src_mesh = ( dmd3mesh_t * )( rawdata + header.ofs_meshes ); + src_mesh = ( dmd3mesh_t * )( ( byte * )rawdata + header.ofs_meshes ); dst_mesh = model->meshes; for( i = 0; i < header.num_meshes; i++ ) { if( ( byte * )( src_mesh + 1 ) > rawend ) { @@ -502,49 +317,49 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) goto fail; } - numVerts = LittleLong( src_mesh->num_verts ); - numTris = LittleLong( src_mesh->num_tris ); + numverts = LittleLong( src_mesh->num_verts ); + numtris = LittleLong( src_mesh->num_tris ); - if( numVerts < 3 || numVerts > TESS_MAX_VERTICES ) { + if( numverts < 3 || numverts > TESS_MAX_VERTICES ) { Com_WPrintf( "%s has bad number of vertices for mesh %d\n", model->name, i ); goto fail; } - if( numTris < 1 || numTris > TESS_MAX_INDICES / 3 ) { + if( numtris < 1 || numtris > TESS_MAX_INDICES / 3 ) { Com_WPrintf( "%s has bad number of faces for mesh %d\n", model->name, i ); goto fail; } - dst_mesh->numTris = numTris; - dst_mesh->numIndices = numTris * 3; - dst_mesh->numVerts = numVerts; - dst_mesh->verts = Model_Malloc( sizeof( aliasVert_t ) * numVerts * header.num_frames ); - dst_mesh->tcoords = Model_Malloc( sizeof( tcoord_t ) * numVerts ); - dst_mesh->indices = Model_Malloc( sizeof( uint32_t ) * numTris * 3 ); + dst_mesh->numtris = numtris; + dst_mesh->numindices = numtris * 3; + dst_mesh->numverts = numverts; + dst_mesh->verts = Model_Malloc( sizeof( maliasvert_t ) * numverts * header.num_frames ); + dst_mesh->tcoords = Model_Malloc( sizeof( maliastc_t ) * numverts ); + dst_mesh->indices = Model_Malloc( sizeof( uint32_t ) * numtris * 3 ); /* load all skins */ - numSkins = LittleLong( src_mesh->num_skins ); - if( numSkins > MAX_MD2SKINS ) { + numskins = LittleLong( src_mesh->num_skins ); + if( numskins > MAX_ALIAS_SKINS ) { Com_WPrintf( "%s has bad number of skins for mesh %d\n", model->name, i ); goto fail; } offset = LittleLong( src_mesh->ofs_skins ); src_skin = ( dmd3skin_t * )( ( byte * )src_mesh + offset ); - if( ( byte * )( src_skin + numSkins ) > rawend ) { + if( ( byte * )( src_skin + numskins ) > rawend ) { Com_WPrintf( "%s has bad skins offset for mesh %d\n", model->name, i ); goto fail; } - for( j = 0; j < numSkins; j++ ) { + for( j = 0; j < numskins; j++ ) { Q_strncpyz( skinname, src_skin->name, sizeof( skinname ) ); - skin = R_FindImage( skinname, it_skin ); + skin = IMG_Find( skinname, it_skin ); if( !skin ) { skin = r_notexture; } dst_mesh->skins[j] = skin; } - dst_mesh->numSkins = numSkins; + dst_mesh->numskins = numskins; /* load all vertices */ - totalVerts = numVerts * header.num_frames; + totalVerts = numverts * header.num_frames; offset = LittleLong( src_mesh->ofs_verts ); src_vert = ( dmd3vertex_t * )( ( byte * )src_mesh + offset ); if( ( byte * )( src_vert + totalVerts ) > rawend ) { @@ -557,7 +372,11 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) dst_vert->pos[1] = ( signed short )LittleShort( src_vert->point[1] ); dst_vert->pos[2] = ( signed short )LittleShort( src_vert->point[2] ); - dst_vert->normalIndex = ll2byte[src_vert->norm[0]] + if( !ll2byte_inited ) { + ll2byte_init(); + ll2byte_inited = qtrue; + } + dst_vert->normalindex = ll2byte[src_vert->norm[0]] [src_vert->norm[1]]; src_vert++; dst_vert++; @@ -566,12 +385,12 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) /* load all texture coords */ offset = LittleLong( src_mesh->ofs_tcs ); src_tc = ( dmd3coord_t * )( ( byte * )src_mesh + offset ); - if( ( byte * )( src_tc + numVerts ) > rawend ) { + if( ( byte * )( src_tc + numverts ) > rawend ) { Com_WPrintf( "%s has bad tcoords offset for mesh %d\n", model->name, i ); goto fail; } dst_tc = dst_mesh->tcoords; - for( j = 0; j < numVerts; j++ ) { + for( j = 0; j < numverts; j++ ) { dst_tc->st[0] = LittleFloat( src_tc->st[0] ); dst_tc->st[1] = LittleFloat( src_tc->st[1] ); src_tc++; dst_tc++; @@ -580,16 +399,16 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) /* load all triangle indices */ offset = LittleLong( src_mesh->ofs_indexes ); src_idx = ( uint32_t * )( ( byte * )src_mesh + offset ); - if( ( byte * )( src_idx + numTris * 3 ) > rawend ) { + if( ( byte * )( src_idx + numtris * 3 ) > rawend ) { Com_WPrintf( "%s has bad indices offset for mesh %d\n", model->name, i ); goto fail; } dst_idx = dst_mesh->indices; - for( j = 0; j < numTris; j++ ) { + for( j = 0; j < numtris; j++ ) { dst_idx[0] = LittleLong( src_idx[0] ); dst_idx[1] = LittleLong( src_idx[1] ); dst_idx[2] = LittleLong( src_idx[2] ); - if( dst_idx[0] >= numVerts || dst_idx[1] >= numVerts || dst_idx[2] >= numVerts ) { + if( dst_idx[0] >= numverts || dst_idx[1] >= numverts || dst_idx[2] >= numverts ) { Com_WPrintf( "%s has bad indices for triangle %d in mesh %d\n", model->name, j, i ); goto fail; } @@ -601,398 +420,33 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) dst_mesh++; } - sys.HunkEnd( &model->pool ); + Hunk_End( &model->pool ); return qtrue; fail: - sys.HunkFree( &model->pool ); + Hunk_Free( &model->pool ); return qfalse; } +#endif -#define Model_TempAlloc( ptr, size ) \ - do { ptr = ( void * )data; data += size; offset += size; } while( 0 ) - -static qboolean Model_WriteMd3( model_t *model, fileHandle_t f ) { - dmd3header_t *header; - uint32_t offset, length; - byte *data; - dmd3frame_t *dst_frame; - dmd3mesh_t *dst_mesh; - dmd3vertex_t *dst_vert; - dmd3coord_t *dst_tc; - dmd3skin_t *dst_skin; - uint32_t *dst_idx; - aliasFrame_t *src_frame; - aliasMesh_t *src_mesh; - aliasVert_t *src_vert; - tcoord_t *src_tc; - uint32_t *src_idx; - uint32_t totalVerts; - int i, j; - qboolean ret; - short pos[3]; - - // precalculate total length - length = sizeof( dmd3header_t ) + - model->numFrames * sizeof( dmd3frame_t ); - src_mesh = model->meshes; - for( i = 0; i < model->numMeshes; i++ ) { - length += sizeof( dmd3mesh_t ) + - src_mesh->numSkins * sizeof( dmd3skin_t ) + - src_mesh->numVerts * model->numFrames * sizeof( dmd3vertex_t ) + - src_mesh->numVerts * sizeof( dmd3coord_t ) + - src_mesh->numIndices * sizeof( uint32_t ); - src_mesh++; - } - - data = fs.AllocTempMem( length ); - offset = 0; - - // write header - Model_TempAlloc( header, sizeof( dmd3header_t ) ); - header->ident = LittleLong( MD3_IDENT ); - header->version = LittleLong( MD3_VERSION ); - memset( header->filename, 0, sizeof( header->filename ) ); - header->flags = 0; - header->num_frames = LittleLong( model->numFrames ); - header->num_tags = 0; - header->num_meshes = LittleLong( model->numMeshes ); - header->num_skins = 0; - - // write all frames - header->ofs_frames = LittleLong( offset ); - src_frame = model->frames; - Model_TempAlloc( dst_frame, model->numFrames * sizeof( dmd3frame_t ) ); - for( i = 0; i < model->numFrames; i++ ) { - LittleVector( src_frame->translate, dst_frame->translate ); - - LittleVector( src_frame->bounds[0], dst_frame->mins ); - LittleVector( src_frame->bounds[1], dst_frame->maxs ); - dst_frame->radius = LittleFloat( src_frame->radius ); - - memset( dst_frame->creator, 0, sizeof( dst_frame->creator ) ); - - src_frame++; dst_frame++; - } - - // write all meshes - header->ofs_meshes = LittleLong( offset ); - src_mesh = model->meshes; - for( i = 0; i < model->numMeshes; i++ ) { - offset = 0; - Model_TempAlloc( dst_mesh, sizeof( dmd3mesh_t ) ); - dst_mesh->ident = LittleLong( MD3_IDENT ); - memset( dst_mesh->name, 0, sizeof( dst_mesh->name ) ); - dst_mesh->flags = 0; - dst_mesh->num_frames = LittleLong( model->numFrames ); - dst_mesh->num_skins = LittleLong( src_mesh->numSkins ); - dst_mesh->num_tris = LittleLong( src_mesh->numTris ); - dst_mesh->num_verts = LittleLong( src_mesh->numVerts ); - - // write all skins - dst_mesh->ofs_skins = LittleLong( offset ); - Model_TempAlloc( dst_skin, sizeof( dmd3skin_t ) * src_mesh->numSkins ); - for( j = 0; j < src_mesh->numSkins; j++ ) { - memcpy( dst_skin->name, src_mesh->skins[j]->name, MAX_QPATH ); - dst_skin->unused = 0; - dst_skin++; - } - - // write all vertices - dst_mesh->ofs_verts = LittleLong( offset ); - totalVerts = src_mesh->numVerts * model->numFrames; - src_vert = src_mesh->verts; - src_frame = model->frames; - Model_TempAlloc( dst_vert, sizeof( dmd3vertex_t ) * totalVerts ); - for( j = 0; j < totalVerts; j++ ) { - pos[0] = src_vert->pos[0] * src_frame->scale[0] / MD3_XYZ_SCALE; - pos[1] = src_vert->pos[1] * src_frame->scale[1] / MD3_XYZ_SCALE; - pos[2] = src_vert->pos[2] * src_frame->scale[2] / MD3_XYZ_SCALE; - - dst_vert->point[0] = ( signed short )LittleShort( pos[0] ); - dst_vert->point[1] = ( signed short )LittleShort( pos[1] ); - dst_vert->point[2] = ( signed short )LittleShort( pos[2] ); - - // TODO: calc normal - - src_vert++; dst_vert++; - } - - // write all texture coords - dst_mesh->ofs_tcs = LittleLong( offset ); - src_tc = src_mesh->tcoords; - Model_TempAlloc( dst_tc, sizeof( dmd3coord_t ) * src_mesh->numVerts ); - for( j = 0; j < src_mesh->numVerts; j++ ) { - dst_tc->st[0] = LittleFloat( src_tc->st[0] ); - dst_tc->st[1] = LittleFloat( src_tc->st[1] ); - src_tc++; dst_tc++; - } - - // write all triangle indices - dst_mesh->ofs_indexes = LittleLong( offset ); - src_idx = src_mesh->indices; - Model_TempAlloc( dst_idx, sizeof( uint32_t ) * src_mesh->numIndices ); - for( j = 0; j < src_mesh->numTris; j++ ) { - dst_idx[0] = LittleLong( src_idx[0] ); - dst_idx[1] = LittleLong( src_idx[1] ); - dst_idx[2] = LittleLong( src_idx[2] ); - src_idx += 3; dst_idx += 3; - } - - dst_mesh->meshsize = LittleLong( offset ); - } - - header->ofs_tags = 0; - header->ofs_end = length; - - // write model to disk - ret = qtrue; - if( fs.Write( header, length, f ) != length ) { - ret = qfalse; - } - - fs.FreeFile( header ); - - return ret; -} - -static qboolean Model_LoadSp2( model_t *model, const byte *rawdata, int length ) { - dsprite_t *header; - dsprframe_t *src_frame; - spriteFrame_t *dst_frame; - unsigned ident, version, numframes, width, height; - char buffer[MAX_SKINNAME]; - image_t *image; - int i; - - if( length < sizeof( *header ) ) { - Com_EPrintf( "%s has length < header length\n", model->name ); - return qfalse; - } - - /* byte swap the header */ - header = ( dsprite_t * )rawdata; - for( i = 0; i < sizeof( header )/4; i++ ) { - (( uint32_t * )&header)[i] = LittleLong( (( uint32_t * )&header)[i] ); - } - - ident = LittleLong( header->ident ); - version = LittleLong( header->version ); - numframes = LittleLong( header->numframes ); - - if( ident != IDSPRITEHEADER ) { - Com_EPrintf( "%s is not an sp2 file\n", model->name ); - return qfalse; - } - if( version != SPRITE_VERSION ) { - Com_EPrintf( "%s has bad version: %d != %d\n", - model->name, version, ALIAS_VERSION ); - return qfalse; - } - if( numframes < 1 || numframes > MAX_MD2SKINS ) { - Com_EPrintf( "%s has bad number of frames: %d\n", - model->name, numframes ); - return qfalse; - } - - model->type = MODEL_SPRITE; - sys.HunkBegin( &model->pool, 0x10000 ); - - model->sframes = Model_Malloc( sizeof( spriteFrame_t ) * numframes ); - model->numFrames = numframes; - - src_frame = header->frames; - dst_frame = model->sframes; - for( i = 0; i < numframes; i++ ) { - width = LittleLong( src_frame->width ); - height = LittleLong( src_frame->height ); - if( width < 1 || height < 1 || width > MAX_TEXTURE_SIZE || height > MAX_TEXTURE_SIZE ) { - Com_WPrintf( "%s has bad image dimensions for frame #%d: %ux%u\n", - model->name, width, height, i ); - width = 1; - height = 1; - } - dst_frame->width = width; - dst_frame->height = height; - dst_frame->x = LittleLong( src_frame->origin_x ); - dst_frame->y = LittleLong( src_frame->origin_y ); - - Q_strncpyz( buffer, src_frame->name, sizeof( buffer ) ); - image = R_FindImage( buffer, it_sprite ); - if( !image ) { - Com_DPrintf( "Couldn't find image '%s' for frame #%d for sprite '%s'\n", - buffer, i, model->name ); - image = r_notexture; - } - dst_frame->image = image; - - dst_frame++; src_frame++; - } - - sys.HunkEnd( &model->pool ); - - return qtrue; -} - -void GL_GetModelSize( qhandle_t hModel, vec3_t mins, vec3_t maxs ) { - VectorClear( mins ); - VectorClear( maxs ); -} +void MOD_Reference( model_t *model ) { + int i, j; -qhandle_t GL_RegisterModel( const char *name ) { - int index, length = 0; - size_t namelen; - model_t *model; - byte *rawdata; - uint32_t ident; - qboolean success; - char buffer[MAX_QPATH]; - - if( name[0] == '*' ) { - /* inline bsp model */ - index = atoi( name + 1 ); - if( index < 1 || index >= r_world.numSubmodels ) { - Com_Error( ERR_DROP, "%s: bad inline model index: %d", __func__, index ); + if( model->frames ) { + for( i = 0; i < model->nummeshes; i++ ) { + maliasmesh_t *mesh = &model->meshes[i]; + for( j = 0; j < mesh->numskins; j++ ) { + mesh->skins[j]->registration_sequence = registration_sequence; + } } - return ~index; - } - - if( !strcmp( r_world.name, name ) ) { - /* TODO: change client code and remove this hack */ - return 0; - } - - namelen = strlen( name ); - if( namelen > MAX_QPATH - 1 ) { - Com_Error( ERR_DROP, "%s: oversize name", __func__ ); - } - - model = Model_Find( name ); - if( model ) { - goto finish; - } - - rawdata = NULL; - buffer[0] = 0; - if( gl_override_models->integer ) { - if( namelen > 4 && !strcmp( name + namelen - 4, ".md2" ) ) { - strcpy( buffer, name ); - buffer[namelen - 1] = '3'; - length = fs.LoadFile( buffer, ( void ** )&rawdata ); - } - } - if( !rawdata ) { - length = fs.LoadFile( name, ( void ** )&rawdata ); - if( !rawdata ) { - Com_DPrintf( "Couldn't load %s\n", name ); - return 0; + } else if( model->spriteframes ) { + for( i = 0; i < model->numframes; i++ ) { + model->spriteframes[i].image->registration_sequence = registration_sequence; } + } else { + Com_Error( ERR_FATAL, "%s: bad model type", __func__ ); } - if( length < 4 ) { - Com_WPrintf( "LoadXXX: %s: file too short\n", name ); - return 0; - } - - model = Model_Alloc( name ); - - ident = LittleLong( *( uint32_t * )rawdata ); - switch( ident ) { - case IDALIASHEADER: - success = Model_LoadMd2( model, rawdata, length ); - if( success && gl_override_models->integer > 1 ) { - fileHandle_t f; - - fs.FOpenFile( buffer, &f, FS_MODE_WRITE ); - if( f ) { - Model_WriteMd3( model, f ); - fs.FCloseFile( f ); - } - } - break; - case MD3_IDENT: - success = Model_LoadMd3( model, rawdata, length ); - break; - case IDSPRITEHEADER: - success = Model_LoadSp2( model, rawdata, length ); - break; - case IDBSPHEADER: - Com_WPrintf( "LoadXXX: %s: loaded BSP model after the world\n", name ); - success = qfalse; - break; - default: - Com_WPrintf( "LoadXXX: %s: unknown ident: %x\n", name, ident ); - success = qfalse; - break; - } - - fs.FreeFile( rawdata ); - - if( !success ) { - model->name[0] = 0; - return 0; - } - -finish: - index = ( model - r_models ) + 1; - return index; -} - -modelType_t *GL_ModelForHandle( qhandle_t hModel ) { - model_t *model; - bspSubmodel_t *submodel; - - if( !hModel ) { - return NULL; - } - - if( hModel & 0x80000000 ) { - hModel = ~hModel; - - if( hModel < 1 || hModel >= r_world.numSubmodels ) { - Com_Error( ERR_DROP, "GL_ModelForHandle: submodel %d out of range", hModel ); - } - - submodel = &r_world.submodels[hModel]; - return &submodel->type; - } - - if( hModel > r_numModels ) { - Com_Error( ERR_DROP, "GL_ModelForHandle: %d out of range", hModel ); - } - model = &r_models[ hModel - 1 ]; - if( !model->name[0] ) { - return NULL; - } - return &model->type; - -} - -void GL_InitModels( void ) { - float s[2], c[2]; - vec3_t normal; - int i, j; - - for( i = 0; i < 256; i++ ) { - for( j = 0; j < 256; j++ ) { - s[0] = sin( i / 255.0f ); - c[0] = cos( i / 255.0f ); - - s[1] = sin( j / 255.0f ); - c[1] = cos( j / 255.0f ); - - VectorSet( normal, s[0] * c[1], s[0] * s[1], c[0] ); - ll2byte[i][j] = DirToByte( normal ); - } - } - - gl_override_models = cvar.Get( "r_override_models", "0", - CVAR_ARCHIVE|CVAR_FILES ); - - cmd.AddCommand( "modellist", Model_List_f ); + model->registration_sequence = registration_sequence; } -void GL_ShutdownModels( void ) { - Model_FreeAll(); - cmd.RemoveCommand( "modellist" ); -} diff --git a/source/gl_sky.c b/source/gl_sky.c index 075cbaf..90519de 100644 --- a/source/gl_sky.c +++ b/source/gl_sky.c @@ -236,22 +236,25 @@ static void ClipSkyPolygon (int nump, vec3_t vecs, int stage) R_AddSkySurface ================= */ -void R_AddSkySurface( bspSurface_t *fa ) { +void R_AddSkySurface( mface_t *fa ) { int i; vec3_t verts[MAX_CLIP_VERTS]; - vec_t *vert; + msurfedge_t *surfedge; + mvertex_t *vert; + medge_t *edge; - if( fa->numVerts > MAX_CLIP_VERTS ) { + if( fa->numsurfedges > MAX_CLIP_VERTS ) { Com_Error( ERR_DROP, "%s: too many verts", __func__ ); } // calculate vertex values for sky box - vert = fa->vertices; - for (i=0 ; i<fa->numVerts ; i++) { - VectorSubtract (vert, modelViewOrigin, verts[i]); - vert += 3; + surfedge = fa->firstsurfedge; + for( i = 0; i < fa->numsurfedges; i++, surfedge++ ) { + edge = surfedge->edge; + vert = edge->v[surfedge->vert]; + VectorSubtract (vert->point, modelViewOrigin, verts[i]); } - ClipSkyPolygon (fa->numVerts, verts[0], 0); + ClipSkyPolygon (fa->numsurfedges, verts[0], 0); } @@ -391,7 +394,7 @@ void R_SetSky( const char *name, float rotate, vec3_t axis ) { for( i = 0; i < 6; i++ ) { Q_concat( pathname, sizeof( pathname ), "env/", name, suf[i], ".tga", NULL ); - sky_images[i] = R_FindImage( pathname, it_sky ); + sky_images[i] = IMG_Find( pathname, it_sky ); if( !sky_images[i] ) { R_UnsetSky(); return; diff --git a/source/gl_surf.c b/source/gl_surf.c index 488093c..29dafaa 100644 --- a/source/gl_surf.c +++ b/source/gl_surf.c @@ -28,18 +28,74 @@ lightmapBuilder_t lm; static cvar_t *gl_coloredlightmaps; static cvar_t *gl_brightness; +static cvar_t *gl_modulate_mask; -cvar_t *gl_modulate_hack; +static float colorScale, colorAdj; /* ============================================================================= -LIGHTMAPS BUILDING +LIGHTMAP COLOR ADJUSTING ============================================================================= */ -static float colorScale, brightness; +void GL_AdjustColor( byte *dst, const byte *src, int what ) { + float r, g, b, min, max, mid; + + r = src[0]; + g = src[1]; + b = src[2]; + + if( colorScale != 1.0f ) { + min = max = r; + if ( g < min ) min = g; + if ( b < min ) min = b; + if ( g > max ) max = g; + if ( b > max ) max = b; + mid = 0.5 * ( min + max ); + r = mid + ( r - mid ) * colorScale; + g = mid + ( g - mid ) * colorScale; + b = mid + ( b - mid ) * colorScale; + } + + if( gl_modulate_mask->integer & what ) { + r *= gl_modulate->value; + g *= gl_modulate->value; + b *= gl_modulate->value; + } + + max = g; + if( r > max ) { + max = r; + } + if( b > max ) { + max = b; + } + + if( max > 255 ) { + r *= 255.0f / max; + g *= 255.0f / max; + b *= 255.0f / max; + } + + // atu brightness adjustments + r += colorAdj; + g += colorAdj; + b += colorAdj; + + dst[0] = clamp( r, 0, 255 ); + dst[1] = clamp( g, 0, 255 ); + dst[2] = clamp( b, 0, 255 ); +} + +/* +============================================================================= + +LIGHTMAPS BUILDING + +============================================================================= +*/ static qboolean LM_AllocBlock( int w, int h, int *s, int *t ) { int i, j; @@ -100,7 +156,7 @@ static void LM_UploadBlock( void ) { } } -static void LM_BuildSurfaceLightmap( bspSurface_t *surf, vec_t *vbo ) { +static void LM_BuildSurfaceLightmap( mface_t *surf, vec_t *vbo ) { byte *ptr, *dst, *src; int i, j; int smax, tmax, s, t; @@ -126,63 +182,7 @@ static void LM_BuildSurfaceLightmap( bspSurface_t *surf, vec_t *vbo ) { for( i = 0; i < tmax; i++ ) { ptr = dst; for( j = 0; j < smax; j++ ) { - float r, g, b, min, max, mid; - - r = src[0]; - g = src[1]; - b = src[2]; - - if( colorScale != 1.0f ) { - min = max = r; - if ( g < min ) min = g; - if ( b < min ) min = b; - if ( g > max ) max = g; - if ( b > max ) max = b; - mid = 0.5 * ( min + max ); - r = mid + ( r - mid ) * colorScale; - g = mid + ( g - mid ) * colorScale; - b = mid + ( b - mid ) * colorScale; - } - - if( !gl_modulate_hack->integer ) { - r *= gl_modulate->value; - g *= gl_modulate->value; - b *= gl_modulate->value; - } - - max = g; - if( r > max ) { - max = r; - } - if( b > max ) { - max = b; - } - - if( max > 255 ) { - r *= 255.0f / max; - g *= 255.0f / max; - b *= 255.0f / max; - } - - //atu brightness adjustments - brightness = 255.0f * gl_brightness->value; - r += brightness; - g += brightness; - b += brightness; - if ( r > 255.0f ) r = 255.0f; - else if ( r < 0.0f ) r = 0.0f; - if ( g > 255.0f ) g = 255.0f; - else if ( g < 0.0f ) g = 0.0f; - if ( b > 255.0f ) b = 255.0f; - else if ( b < 0.0f ) b = 0.0f; - - src[0] = r; - src[1] = g; - src[2] = b; - - ptr[0] = src[0]; - ptr[1] = src[1]; - ptr[2] = src[2]; + GL_AdjustColor( ptr, src, 1 ); ptr[3] = 255; src += 3; ptr += 4; @@ -198,7 +198,7 @@ static void LM_BuildSurfaceLightmap( bspSurface_t *surf, vec_t *vbo ) { s -= surf->texturemins[0]; t -= surf->texturemins[1]; - for( i = 0; i < surf->numVerts; i++ ) { + for( i = 0; i < surf->numsurfedges; i++ ) { vbo[5] += s; vbo[6] += t; vbo[5] /= LM_BLOCK_WIDTH * 16; @@ -215,38 +215,23 @@ POLYGONS BUILDING ============================================================================= */ -static void GL_BuildSurfacePoly( bspSurface_t *surf, vec_t *vbo ) { - int *src_surfedge; - dvertex_t *src_vert; - dedge_t *src_edge; - bspTexinfo_t *texinfo = surf->texinfo; - int index, vertIndex; - int i, numEdges = surf->numSurfEdges; +static void GL_BuildSurfacePoly( bsp_t *bsp, mface_t *surf, vec_t *vbo ) { + msurfedge_t *src_surfedge; + mvertex_t *src_vert; + medge_t *src_edge; + mtexinfo_t *texinfo = surf->texinfo; + int i; vec2_t scale, tc, mins, maxs; int bmins[2], bmaxs[2]; - surf->numVerts = numEdges; - surf->numIndices = ( numEdges - 2 ) * 3; surf->texnum[0] = texinfo->image->texnum; - surf->texflags = texinfo->flags; - - if( texinfo->flags & SURF_WARP ) { - if( qglProgramStringARB ) { - surf->type = DSURF_WARP; - surf->texnum[1] = r_warptexture->texnum; - } else { - surf->type = DSURF_NOLM; - } - } else if( !surf->lightmap || gl_fullbright->integer || ( texinfo->flags & NOLIGHT_MASK ) ) { - surf->type = DSURF_NOLM; - } else { - surf->type = DSURF_POLY; - } // normalize texture coordinates scale[0] = 1.0f / texinfo->image->width; scale[1] = 1.0f / texinfo->image->height; - if( surf->type == DSURF_WARP ) { + + if( ( texinfo->c.flags & SURF_WARP ) && qglProgramStringARB ) { + surf->texnum[1] = r_warptexture->texnum; scale[0] *= 0.5f; scale[1] *= 0.5f; } @@ -254,22 +239,11 @@ static void GL_BuildSurfacePoly( bspSurface_t *surf, vec_t *vbo ) { mins[0] = mins[1] = 99999; maxs[0] = maxs[1] = -99999; - src_surfedge = surf->firstSurfEdge; - for( i = 0; i < numEdges; i++ ) { - index = *src_surfedge++; - - vertIndex = 0; - if( index < 0 ) { - index = -index; - vertIndex = 1; - } - - if( index >= r_world.numEdges ) { - Com_Error( ERR_DROP, "%s: bad edge index", __func__ ); - } - - src_edge = r_world.edges + index; - src_vert = r_world.vertices + src_edge->v[vertIndex]; + src_surfedge = surf->firstsurfedge; + for( i = 0; i < surf->numsurfedges; i++ ) { + src_edge = src_surfedge->edge; + src_vert = src_edge->v[src_surfedge->vert]; + src_surfedge++; // vertex coordinates VectorCopy( src_vert->point, vbo ); @@ -288,7 +262,7 @@ static void GL_BuildSurfacePoly( bspSurface_t *surf, vec_t *vbo ) { vbo[4] = tc[1] * scale[1]; // texture1 coordinates - if( surf->type == DSURF_WARP ) { + if( ( texinfo->c.flags & SURF_WARP ) && qglProgramStringARB ) { vbo[5] = vbo[3]; vbo[6] = vbo[4]; } else { @@ -312,84 +286,84 @@ static void GL_BuildSurfacePoly( bspSurface_t *surf, vec_t *vbo ) { surf->extents[1] = ( bmaxs[1] - bmins[1] ) << 4; } -static void GL_BuildSkyPoly( bspSurface_t *surf ) { - int *src_surfedge; - dvertex_t *src_vert; - dedge_t *src_edge; - bspTexinfo_t *texinfo = surf->texinfo; - int index, vertIndex; - int i, numEdges = surf->numSurfEdges; - vec_t *dst_vert; - - surf->numVerts = numEdges; - surf->numIndices = ( numEdges - 2 ) * 3; - surf->texnum[0] = texinfo->image->texnum; - surf->texflags = texinfo->flags; - surf->type = DSURF_SKY; +void GL_FreeWorld( void ) { + if( !gl_static.world.cache ) { + return; + } - surf->vertices = sys.HunkAlloc( &r_world.pool, - numEdges * 3 * sizeof( vec_t ) ); + BSP_Free( gl_static.world.cache ); - src_surfedge = surf->firstSurfEdge; - dst_vert = surf->vertices; - for( i = 0; i < numEdges; i++ ) { - index = *src_surfedge++; - - vertIndex = 0; - if( index < 0 ) { - index = -index; - vertIndex = 1; - } + if( gl_static.world.vertices ) { + Hunk_Free( &gl_static.world.pool ); + } else if( qglDeleteBuffersARB ) { + GLuint buf = 1; - if( index >= r_world.numEdges ) { - Com_Error( ERR_DROP, "%s: bad edge index", __func__ ); - } + qglDeleteBuffersARB( 1, &buf ); + } - src_edge = r_world.edges + index; - src_vert = r_world.vertices + src_edge->v[vertIndex]; + lm.numMaps = 0; + LM_InitBlock(); + + memset( &gl_static.world, 0, sizeof( gl_static.world ) ); +} + +void GL_LoadWorld( const char *name ) { + char buffer[MAX_QPATH]; + mface_t *surf; + int i, size, count; + vec_t *vbo; + bsp_t *bsp; + mtexinfo_t *info; + image_t *image; + + if( !( bsp = BSP_Load( name ) ) ) { + Com_Error( ERR_DROP, "%s: couldn't load %s: %s", + __func__, name, BSP_GetError() ); + } - VectorCopy( src_vert->point, dst_vert ); + // check if the required world model was already loaded + if( gl_static.world.cache == bsp ) { + for( i = 0; i < bsp->numtexinfo; i++ ) { + bsp->texinfo[i].image->registration_sequence = registration_sequence; + } + for( i = 0; i < bsp->numnodes; i++ ) { + bsp->nodes[i].visframe = 0; + } + for( i = 0; i < bsp->numleafs; i++ ) { + bsp->leafs[i].visframe = 0; + } + Com_DPrintf( "%s: reused old world model\n", __func__ ); + bsp->refcount--; + return; + } - dst_vert += 3; - } -} + gl_coloredlightmaps = Cvar_Get( "gl_coloredlightmaps", "1", CVAR_ARCHIVE|CVAR_FILES ); + gl_brightness = Cvar_Get( "gl_brightness", "0", CVAR_ARCHIVE|CVAR_FILES ); + gl_modulate_mask = Cvar_Get( "gl_modulate_mask", "3", CVAR_FILES ); -void GL_BeginPostProcessing( void ) { - lm.numMaps = 0; - LM_InitBlock(); + colorScale = Cvar_ClampValue( gl_coloredlightmaps, 0, 1 ); + colorAdj = 255 * Cvar_ClampValue( gl_brightness, -1, 1 ); - gl_coloredlightmaps = cvar.Get( "gl_coloredlightmaps", "1", CVAR_ARCHIVE|CVAR_FILES ); - gl_brightness = cvar.Get( "gl_brightness", "0", CVAR_ARCHIVE|CVAR_FILES ); - gl_modulate_hack = cvar.Get( "gl_modulate_hack", "0", CVAR_FILES ); + // free previous model, if any + GL_FreeWorld(); - if( gl_coloredlightmaps->value < 0 ) { - cvar.Set( "gl_coloredlightmaps", "0" ); - } else if( gl_coloredlightmaps->value > 1 ) { - cvar.Set( "gl_coloredlightmaps", "1" ); - } + gl_static.world.cache = bsp; - if( gl_brightness->value < -1 ) { - cvar.Set( "gl_brightness", "-1" ); - } else if( gl_brightness->value > 1 ) { - cvar.Set( "gl_brightness", "1" ); - } + // registers all texinfo + for( i = 0, info = bsp->texinfo; i < bsp->numtexinfo; i++, info++ ) { + Q_concat( buffer, sizeof( buffer ), "textures/", info->name, ".wal", NULL ); + image = IMG_Find( buffer, it_wall ); + info->image = image ? image : r_notexture; + } - brightness = gl_brightness->value; - colorScale = gl_coloredlightmaps->value; -} - -void GL_EndPostProcessing( void ) { - bspSurface_t *surf; - int i, size, count; - vec_t *vbo = NULL; - // calculate vertex buffer size in bytes count = 0; - for( i = 0, surf = r_world.surfaces; i < r_world.numSurfaces; i++, surf++ ) { - count += surf->numSurfEdges; + for( i = 0, surf = bsp->faces; i < bsp->numfaces; i++, surf++ ) { + count += surf->numsurfedges; } size = count * VERTEX_SIZE * 4; + vbo = NULL; if( qglBindBufferARB ) { qglBindBufferARB( GL_ARRAY_BUFFER_ARB, 1 ); @@ -399,7 +373,7 @@ void GL_EndPostProcessing( void ) { vbo = qglMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_READ_WRITE_ARB ); if( vbo ) { - gl_static.vertices = NULL; + gl_static.world.vertices = NULL; Com_DPrintf( "%s: %d bytes of vertex data as VBO\n", __func__, size ); } else { Com_EPrintf( "Failed to map VBO data in client memory\n" ); @@ -408,29 +382,34 @@ void GL_EndPostProcessing( void ) { } if( !vbo ) { - gl_static.vertices = vbo = sys.HunkAlloc( &r_world.pool, size ); + Hunk_Begin( &gl_static.world.pool, size ); + vbo = Hunk_Alloc( &gl_static.world.pool, size ); + Hunk_End( &gl_static.world.pool ); + Com_DPrintf( "%s: %d bytes of vertex data on hunk\n", __func__, size ); + gl_static.world.vertices = vbo; } // post process all surfaces count = 0; - for( i = 0, surf = r_world.surfaces; i < r_world.numSurfaces; i++, surf++ ) { - if( surf->texinfo->flags & SURF_SKY ) { - GL_BuildSkyPoly( surf ); + for( i = 0, surf = bsp->faces; i < bsp->numfaces; i++, surf++ ) { + if( surf->texinfo->c.flags & SURF_SKY ) { continue; } - surf->firstVert = count; - GL_BuildSurfacePoly( surf, vbo ); + surf->firstvert = count; + GL_BuildSurfacePoly( bsp, surf, vbo ); - if( surf->type == DSURF_POLY ) { + if( surf->lightmap && !gl_fullbright->integer && + !( surf->texinfo->c.flags & SURF_NOLM_MASK ) ) + { LM_BuildSurfaceLightmap( surf, vbo ); } - count += surf->numVerts; - vbo += surf->numVerts * VERTEX_SIZE; + count += surf->numsurfedges; + vbo += surf->numsurfedges * VERTEX_SIZE; } - if( qglBindBufferARB && !gl_static.vertices ) { + if( qglBindBufferARB && !gl_static.world.vertices ) { qglBindBufferARB( GL_ARRAY_BUFFER_ARB, 1 ); if( !qglUnmapBufferARB( GL_ARRAY_BUFFER_ARB ) ) { Com_Error( ERR_DROP, "Failed to unmap VBO data" ); diff --git a/source/gl_tess.c b/source/gl_tess.c index caa00f1..3a99769 100644 --- a/source/gl_tess.c +++ b/source/gl_tess.c @@ -25,13 +25,13 @@ tesselator_t tess; #define FACE_HASH_SIZE 32 #define FACE_HASH_MASK ( FACE_HASH_SIZE - 1 ) -static bspSurface_t *faces_alpha, *faces_warp, *faces_alpha_warp, *faces_sky; -static bspSurface_t *faces_hash[FACE_HASH_SIZE]; +static mface_t *faces_alpha, *faces_warp, *faces_alpha_warp; +static mface_t *faces_hash[FACE_HASH_SIZE]; void GL_Flush2D( void ) { glStateBits_t bits; - if( !tess.numVertices ) { + if( !tess.numverts ) { return; } @@ -53,14 +53,14 @@ void GL_Flush2D( void ) { qglVertexPointer( 2, GL_FLOAT, 16, tess.vertices ); if( qglLockArraysEXT ) { - qglLockArraysEXT( 0, tess.numVertices ); + qglLockArraysEXT( 0, tess.numverts ); } - qglDrawArrays( GL_QUADS, 0, tess.numVertices ); + qglDrawArrays( GL_QUADS, 0, tess.numverts ); if( gl_showtris->integer ) { GL_EnableOutlines(); - qglDrawArrays( GL_QUADS, 0, tess.numVertices ); + qglDrawArrays( GL_QUADS, 0, tess.numverts ); GL_DisableOutlines(); } @@ -70,7 +70,7 @@ void GL_Flush2D( void ) { qglDisableClientState( GL_COLOR_ARRAY ); - tess.numVertices = 0; + tess.numverts = 0; tess.texnum[0] = 0; tess.flags = 0; } @@ -82,21 +82,21 @@ void GL_StretchPic( float x, float y, float w, float h, vec_t *dst_vert; uint32_t *dst_color; - if( tess.numVertices + 4 > TESS_MAX_VERTICES || - ( tess.numVertices && tess.texnum[0] != image->texnum ) ) + if( tess.numverts + 4 > TESS_MAX_VERTICES || + ( tess.numverts && tess.texnum[0] != image->texnum ) ) { GL_Flush2D(); } tess.texnum[0] = image->texnum; - dst_vert = tess.vertices + tess.numVertices * 4; + dst_vert = tess.vertices + tess.numverts * 4; Vector4Set( dst_vert, x, y, s1, t1 ); Vector4Set( dst_vert + 4, x + w, y, s2, t1 ); Vector4Set( dst_vert + 8, x + w, y + h, s2, t2 ); Vector4Set( dst_vert + 12, x, y + h, s1, t2 ); - dst_color = ( uint32_t * )tess.colors + tess.numVertices; + dst_color = ( uint32_t * )tess.colors + tess.numverts; dst_color[0] = *( const uint32_t * )color; dst_color[1] = *( const uint32_t * )color; dst_color[2] = *( const uint32_t * )color; @@ -113,7 +113,7 @@ void GL_StretchPic( float x, float y, float w, float h, tess.flags |= 2; } - tess.numVertices += 4; + tess.numverts += 4; } void GL_DrawParticles( void ) { @@ -122,7 +122,7 @@ void GL_DrawParticles( void ) { vec3_t transformed; vec_t scale, dist; color_t color; - int numVertices; + int numverts; vec_t *dst_vert; uint32_t *dst_color; @@ -139,7 +139,7 @@ void GL_DrawParticles( void ) { qglTexCoordPointer( 2, GL_FLOAT, 20, tess.vertices + 3 ); qglVertexPointer( 3, GL_FLOAT, 20, tess.vertices ); - numVertices = 0; + numverts = 0; for( i = 0, p = glr.fd.particles; i < glr.fd.num_particles; i++, p++ ) { VectorSubtract( p->origin, glr.fd.vieworg, transformed ); dist = DotProduct( transformed, glr.viewaxis[0] ); @@ -156,12 +156,12 @@ void GL_DrawParticles( void ) { } color[3] = p->alpha * 255; - if( numVertices + 3 > TESS_MAX_VERTICES ) { - qglDrawArrays( GL_TRIANGLES, 0, numVertices ); - numVertices = 0; + if( numverts + 3 > TESS_MAX_VERTICES ) { + qglDrawArrays( GL_TRIANGLES, 0, numverts ); + numverts = 0; } - dst_vert = tess.vertices + numVertices * 5; + dst_vert = tess.vertices + numverts * 5; // VectorMA( p->origin, -scale*0.5f, glr.viewaxis[2], dst_vert ); VectorMA( p->origin, scale*0.5f, glr.viewaxis[1], dst_vert ); VectorMA( dst_vert, scale, glr.viewaxis[2], dst_vert + 5 ); @@ -171,15 +171,15 @@ void GL_DrawParticles( void ) { dst_vert[8] = 2; dst_vert[9] = 0; dst_vert[13] = 0; dst_vert[14] = 2; - dst_color = ( uint32_t * )tess.colors + numVertices; + dst_color = ( uint32_t * )tess.colors + numverts; dst_color[0] = *( uint32_t * )color; dst_color[1] = *( uint32_t * )color; dst_color[2] = *( uint32_t * )color; - numVertices += 3; + numverts += 3; } - qglDrawArrays( GL_TRIANGLES, 0, numVertices ); + qglDrawArrays( GL_TRIANGLES, 0, numverts ); qglDisableClientState( GL_COLOR_ARRAY ); } @@ -191,7 +191,7 @@ void GL_DrawBeams( void ) { vec_t *dst_vert; uint32_t *dst_color; vec_t length; - int numVertices; + int numverts; entity_t *ent; int i; @@ -207,7 +207,7 @@ void GL_DrawBeams( void ) { qglTexCoordPointer( 2, GL_FLOAT, 20, tess.vertices + 3 ); qglVertexPointer( 3, GL_FLOAT, 20, tess.vertices ); - numVertices = 0; + numverts = 0; for( i = 0, ent = glr.fd.entities; i < glr.fd.num_entities; i++, ent++ ) { if( !( ent->flags & RF_BEAM ) ) { continue; @@ -230,12 +230,12 @@ void GL_DrawBeams( void ) { } color[3] = 255 * ent->alpha; - if( numVertices + 4 > TESS_MAX_VERTICES ) { - qglDrawArrays( GL_QUADS, 0, numVertices ); - numVertices = 0; + if( numverts + 4 > TESS_MAX_VERTICES ) { + qglDrawArrays( GL_QUADS, 0, numverts ); + numverts = 0; } - dst_vert = tess.vertices + numVertices * 5; + dst_vert = tess.vertices + numverts * 5; VectorAdd( start, d3, dst_vert ); VectorSubtract( start, d3, dst_vert + 5 ); VectorSubtract( end, d3, dst_vert + 10 ); @@ -246,23 +246,23 @@ void GL_DrawBeams( void ) { dst_vert[13] = 1; dst_vert[14] = length; dst_vert[18] = 0; dst_vert[19] = length; - dst_color = ( uint32_t * )tess.colors + numVertices; + dst_color = ( uint32_t * )tess.colors + numverts; dst_color[0] = *( uint32_t * )color; dst_color[1] = *( uint32_t * )color; dst_color[2] = *( uint32_t * )color; dst_color[3] = *( uint32_t * )color; - numVertices += 4; + numverts += 4; } - qglDrawArrays( GL_QUADS, 0, numVertices ); + qglDrawArrays( GL_QUADS, 0, numverts ); qglDisableClientState( GL_COLOR_ARRAY ); } static void GL_BindArrays( void ) { vec_t *ptr; - if( gl_static.vertices ) { + if( gl_static.world.vertices ) { ptr = tess.vertices; } else { ptr = NULL; @@ -279,7 +279,7 @@ static void GL_BindArrays( void ) { } static void GL_UnbindArrays( void ) { - if( !gl_static.vertices ) { + if( !gl_static.world.vertices ) { qglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); } qglClientActiveTextureARB( GL_TEXTURE1_ARB ); @@ -288,7 +288,7 @@ static void GL_UnbindArrays( void ) { } static void GL_Flush3D( void ) { - if( !tess.numIndices ) { + if( !tess.numindices ) { return; } @@ -309,11 +309,11 @@ static void GL_Flush3D( void ) { GL_BindTexture( tess.texnum[1] ); } - if( gl_static.vertices && qglLockArraysEXT ) { - qglLockArraysEXT( 0, tess.numVertices ); + if( gl_static.world.vertices && qglLockArraysEXT ) { + qglLockArraysEXT( 0, tess.numverts ); } - qglDrawElements( GL_TRIANGLES, tess.numIndices, GL_UNSIGNED_INT, tess.indices ); + qglDrawElements( GL_TRIANGLES, tess.numindices, GL_UNSIGNED_INT, tess.indices ); if( tess.texnum[1] ) { qglDisable( GL_TEXTURE_2D ); @@ -322,80 +322,95 @@ static void GL_Flush3D( void ) { if( gl_showtris->integer ) { GL_EnableOutlines(); - qglDrawElements( GL_TRIANGLES, tess.numIndices, GL_UNSIGNED_INT, tess.indices ); + qglDrawElements( GL_TRIANGLES, tess.numindices, GL_UNSIGNED_INT, tess.indices ); GL_DisableOutlines(); } - if( gl_static.vertices && qglUnlockArraysEXT ) { + if( gl_static.world.vertices && qglUnlockArraysEXT ) { qglUnlockArraysEXT(); } c.batchesDrawn++; tess.texnum[0] = tess.texnum[1] = 0; - tess.numIndices = 0; - tess.numVertices = 0; + tess.numindices = 0; + tess.numverts = 0; tess.flags = 0; } -static void GL_CopyVerts( bspSurface_t *surf ) { - uint32_t *src_vert, *dst_vert; - int i, j; +static void GL_CopyVerts( mface_t *surf ) { + void *src, *dst; - if( tess.numVertices + surf->numVerts > TESS_MAX_VERTICES ) { + if( tess.numverts + surf->numsurfedges > TESS_MAX_VERTICES ) { GL_Flush3D(); } - src_vert = ( uint32_t * )gl_static.vertices + surf->firstVert * VERTEX_SIZE; - dst_vert = ( uint32_t * )tess.vertices + tess.numVertices * VERTEX_SIZE; - for( i = 0; i < surf->numVerts; i++ ) { - for( j = 0; j < VERTEX_SIZE; j++ ) { - *dst_vert++ = *src_vert++; - } - } - tess.numVertices += surf->numVerts; + src = gl_static.world.vertices + surf->firstvert * VERTEX_SIZE; + dst = tess.vertices + tess.numverts * VERTEX_SIZE; + memcpy( dst, src, surf->numsurfedges * VERTEX_SIZE * sizeof( vec_t ) ); + + tess.numverts += surf->numsurfedges; +} + +static int GL_TextureAnimation( mtexinfo_t *tex ) { + int frame, c; + + if( !tex->next ) + return tex->image->texnum; + + frame = ( int )( glr.fd.time * 2 ); + c = frame % tex->numframes; + while( c ) { + tex = tex->next; + c--; + } + + return tex->image->texnum; } -static void GL_DrawFace( bspSurface_t *surf ) { +static void GL_DrawFace( mface_t *surf ) { + int numindices = ( surf->numsurfedges - 2 ) * 3; + int diff = surf->texinfo->c.flags ^ tess.flags; + int texnum = GL_TextureAnimation( surf->texinfo ); int *dst_indices; int i, j; - if( tess.texnum[0] != surf->texnum[0] || + if( tess.texnum[0] != texnum || tess.texnum[1] != surf->texnum[1] || - ( ( surf->texflags ^ tess.flags ) & ( SURF_TRANS33 | SURF_TRANS66 | SURF_SKY ) ) || - tess.numIndices + surf->numIndices > TESS_MAX_INDICES ) + ( diff & (SURF_TRANS33|SURF_TRANS66|SURF_SKY) ) || + tess.numindices + numindices > TESS_MAX_INDICES ) { GL_Flush3D(); } - if( gl_static.vertices ) { - j = tess.numVertices; + if( gl_static.world.vertices ) { + j = tess.numverts; GL_CopyVerts( surf ); } else { - j = surf->firstVert; + j = surf->firstvert; } if( gl_lightmap->integer ) { - tess.texnum[0] = surf->texnum[1] ? surf->texnum[1] : surf->texnum[0]; + tess.texnum[0] = surf->texnum[1] ? surf->texnum[1] : texnum; tess.texnum[1] = 0; } else { - tess.texnum[0] = surf->texnum[0]; + tess.texnum[0] = texnum; tess.texnum[1] = surf->texnum[1]; } - tess.flags = surf->texflags; - dst_indices = tess.indices + tess.numIndices; - for( i = 0; i < surf->numVerts - 2; i++ ) { + tess.flags = surf->texinfo->c.flags; + dst_indices = tess.indices + tess.numindices; + for( i = 0; i < surf->numsurfedges - 2; i++ ) { dst_indices[0] = j; dst_indices[1] = j + ( i + 1 ); dst_indices[2] = j + ( i + 2 ); dst_indices += 3; } - tess.numIndices += surf->numIndices; - c.trisDrawn += surf->numVerts - 2; + tess.numindices += numindices; + c.trisDrawn += surf->numsurfedges - 2; } -static inline void GL_DrawChain( bspSurface_t **head ) { - bspSurface_t *face; +static inline void GL_DrawChain( mface_t **head ) { + mface_t *face; for( face = *head; face; face = face->next ) { GL_DrawFace( face ); @@ -419,13 +434,6 @@ void GL_DrawSolidFaces( void ) { GL_DisableWarp(); } - if( faces_sky ) { - qglDisable( GL_TEXTURE_2D ); - GL_DrawChain( &faces_sky ); - GL_Flush3D(); - qglEnable( GL_TEXTURE_2D ); - } - for( i = 0; i < FACE_HASH_SIZE; i++ ) { GL_DrawChain( &faces_hash[i] ); } @@ -454,8 +462,8 @@ void GL_DrawAlphaFaces( void ) { GL_UnbindArrays(); } -void GL_AddSolidFace( bspSurface_t *face ) { - if( face->type == DSURF_WARP ) { +void GL_AddSolidFace( mface_t *face ) { + if( ( face->texinfo->c.flags & SURF_WARP ) && qglBindProgramARB ) { face->next = faces_warp; faces_warp = face; } else { @@ -463,30 +471,27 @@ void GL_AddSolidFace( bspSurface_t *face ) { face->next = faces_hash[i]; faces_hash[i] = face; } - + // TODO: SURF_FLOWING support c.facesDrawn++; } -void GL_AddFace( bspSurface_t *face ) { - if( face->type == DSURF_SKY ) { - R_AddSkySurface( face ); - return; - } +void GL_AddFace( mface_t *face ) { + int flags = face->texinfo->c.flags; - if( face->texflags & SURF_SKY ) { - face->next = faces_sky; - faces_sky = face; + if( flags & SURF_SKY ) { + R_AddSkySurface( face ); return; } - if( face->texflags & (SURF_TRANS33|SURF_TRANS66) ) { - if( face->type == DSURF_WARP ) { + if( flags & (SURF_TRANS33|SURF_TRANS66) ) { + if( ( flags & SURF_WARP ) && qglBindProgramARB ) { face->next = faces_alpha_warp; faces_alpha_warp = face; } else { face->next = faces_alpha; faces_alpha = face; } + // TODO: SURF_FLOWING support c.facesDrawn++; return; } diff --git a/source/gl_world.c b/source/gl_world.c index a585dc4..7a38d69 100644 --- a/source/gl_world.c +++ b/source/gl_world.c @@ -22,159 +22,63 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. vec3_t modelViewOrigin; // viewer origin in model space -static vec3_t lightcolor; - -static qboolean GL_LightPoint_r( bspNode_t *node, vec3_t start, vec3_t end ) { - vec_t startFrac, endFrac, midFrac; - vec3_t _start, mid; - int side; - qboolean ret; - bspSurface_t *surf; - bspTexinfo_t *texinfo; - int i, pitch; - int s, t; +qboolean GL_LightPoint( vec3_t origin, vec3_t color ) { + bsp_t *bsp = gl_static.world.cache; + mface_t *surf; + int s, t; byte *b1, *b2, *b3, *b4; int fracu, fracv; int w1, w2, w3, w4; - int color[3]; - - VectorCopy( start, _start ); - while( node->plane ) { - // calculate distancies - startFrac = PlaneDiffFast( _start, node->plane ); - endFrac = PlaneDiffFast( end, node->plane ); - side = ( startFrac < 0 ); - - if( ( endFrac < 0 ) == side ) { - // both points are one the same side - node = node->children[side]; - continue; - } - - // find crossing point - midFrac = startFrac / ( startFrac - endFrac ); - LerpVector( _start, end, midFrac, mid ); - - // check near side - ret = GL_LightPoint_r( node->children[side], _start, mid ); - if( ret ) { - return ret; - } - - for( i = 0, surf = node->firstFace; i < node->numFaces; i++, surf++ ) { - texinfo = surf->texinfo; - if( texinfo->flags & (SURF_WARP|SURF_SKY) ) { - continue; - } - if( !surf->lightmap ) { - continue; - } - s = DotProduct( texinfo->axis[0], mid ) + texinfo->offset[0]; - t = DotProduct( texinfo->axis[1], mid ) + texinfo->offset[1]; + byte temp[3]; + int pitch; + vec3_t point; - s -= surf->texturemins[0]; - t -= surf->texturemins[1]; - if( s < 0 || t < 0 ) { - continue; - } - if( s > surf->extents[0] || t > surf->extents[1] ) { - continue; - } - - fracu = s & 15; - fracv = t & 15; - - s >>= 4; - t >>= 4; - - pitch = ( surf->extents[0] >> 4 ) + 1; - b1 = &surf->lightmap[3 * ( ( t + 0 ) * pitch + ( s + 0 ) )]; - b2 = &surf->lightmap[3 * ( ( t + 0 ) * pitch + ( s + 1 ) )]; - b3 = &surf->lightmap[3 * ( ( t + 1 ) * pitch + ( s + 1 ) )]; - b4 = &surf->lightmap[3 * ( ( t + 1 ) * pitch + ( s + 0 ) )]; - - w1 = ( 16 - fracu ) * ( 16 - fracv ); - w2 = fracu * ( 16 - fracv ); - w3 = fracu * fracv; - w4 = ( 16 - fracu ) * fracv; - - color[0] = ( w1 * b1[0] + w2 * b2[0] + w3 * b3[0] + w4 * b4[0] ) >> 8; - color[1] = ( w1 * b1[1] + w2 * b2[1] + w3 * b3[1] + w4 * b4[1] ) >> 8; - color[2] = ( w1 * b1[2] + w2 * b2[2] + w3 * b3[2] + w4 * b4[2] ) >> 8; - - VectorMA( lightcolor, 1.0f / 255, color, lightcolor ); - - return qtrue; - } - - // check far side - VectorCopy( mid, _start ); - node = node->children[side^1]; + if( !bsp || !bsp->lightmap ) { + return qfalse; } - return qfalse; -} - -void GL_LightPoint( vec3_t origin, vec3_t dest ) { - extern cvar_t *gl_modulate_hack; - vec3_t point; -#if USE_DYNAMIC - dlight_t *light; - vec3_t dir; - vec_t dist, f; -#endif - int i; - - if( !r_world.name[0] || gl_fullbright->integer ) { - VectorSet( dest, 1, 1, 1 ); - return; - } - point[0] = origin[0]; point[1] = origin[1]; point[2] = origin[2] - 8192; - - VectorClear( lightcolor ); - if( !r_world.lightmap || !GL_LightPoint_r( r_world.nodes, origin, point ) ) { - VectorSet( lightcolor, 1, 1, 1 ); + + surf = BSP_LightPoint( bsp->nodes, origin, point, &s, &t ); + if( !surf ) { + return qfalse; } - if( gl_modulate_hack && gl_modulate_hack->integer ) { - VectorScale( lightcolor, gl_modulate->value, lightcolor ); - } + fracu = s & 15; + fracv = t & 15; -#if USE_DYNAMIC - for( i = 0, light = glr.fd.dlights; i < glr.fd.num_dlights; i++, light++ ) { - VectorSubtract( light->origin, origin, dir ); - dist = VectorLength( dir ); - if( dist > light->intensity ) { - continue; - } - f = 1.0f - dist / light->intensity; - VectorMA( lightcolor, f, light->color, lightcolor ); - } -#endif + s >>= 4; + t >>= 4; - /* apply modulate twice to mimic original ref_gl behavior */ - VectorScale( lightcolor, gl_modulate->value, lightcolor ); + pitch = ( surf->extents[0] >> 4 ) + 1; + b1 = &surf->lightmap[3 * ( ( t + 0 ) * pitch + ( s + 0 ) )]; + b2 = &surf->lightmap[3 * ( ( t + 0 ) * pitch + ( s + 1 ) )]; + b3 = &surf->lightmap[3 * ( ( t + 1 ) * pitch + ( s + 1 ) )]; + b4 = &surf->lightmap[3 * ( ( t + 1 ) * pitch + ( s + 0 ) )]; + + w1 = ( 16 - fracu ) * ( 16 - fracv ); + w2 = fracu * ( 16 - fracv ); + w3 = fracu * fracv; + w4 = ( 16 - fracu ) * fracv; - for( i = 0; i < 3; i++ ) { - if( lightcolor[i] > 1 ) { - lightcolor[i] = 1; - } else if( lightcolor[i] < 0 ) { - lightcolor[i] = 0; - } - } + temp[0] = ( w1 * b1[0] + w2 * b2[0] + w3 * b3[0] + w4 * b4[0] ) >> 8; + temp[1] = ( w1 * b1[1] + w2 * b2[1] + w3 * b3[1] + w4 * b4[1] ) >> 8; + temp[2] = ( w1 * b1[2] + w2 * b2[2] + w3 * b3[2] + w4 * b4[2] ) >> 8; + + GL_AdjustColor( temp, temp, 2 ); - VectorCopy( lightcolor, dest ); + VectorScale( temp, 1.0f / 255, color ); + return qtrue; } #if USE_DYNAMIC -static void GL_MarkLights_r( bspNode_t *node, dlight_t *light ) { +static void GL_MarkLights_r( mnode_t *node, dlight_t *light ) { vec_t dot; int count; - bspSurface_t *face; + mface_t *face; int lightbit = 1 << light->index; while( node->plane ) { @@ -215,19 +119,16 @@ void GL_MarkLights( void ) { for( i = 0, light = glr.fd.dlights; i < glr.fd.num_dlights; i++, light++ ) { light->index = i; VectorCopy( light->origin, light->transformed ); - GL_MarkLights_r( r_world.nodes, light ); + GL_MarkLights_r( gl_static.world.cache->nodes, light ); } } -static void GL_TransformLights( bspSubmodel_t *model ) { +static void GL_TransformLights( mmodel_t *model ) { int i; dlight_t *light; vec3_t temp; if( !model->headnode ) { - // this happens on some maps - // could lead to a crash of the original ref_gl - //Com_WPrintf( "GL_TransformLights: NULL headnode\n" ); return; } @@ -239,22 +140,68 @@ static void GL_TransformLights( bspSubmodel_t *model ) { light->transformed[2] = DotProduct( temp, glr.entaxis[2] ); GL_MarkLights_r( model->headnode, light ); - } } + +void GL_AddLights( vec3_t origin, vec3_t color ) { + dlight_t *light; + vec3_t dir; + vec_t dist, f; + int i; + + for( i = 0, light = glr.fd.dlights; i < glr.fd.num_dlights; i++, light++ ) { + VectorSubtract( light->origin, origin, dir ); + dist = VectorLength( dir ); + if( dist > light->intensity ) { + continue; + } + f = 1.0f - dist / light->intensity; + VectorMA( color, f, light->color, color ); + } +} +#endif + +void R_LightPoint( vec3_t origin, vec3_t color ) { + int i; + + if( gl_fullbright->integer ) { + VectorSet( color, 1, 1, 1 ); + return; + } + + // get lighting from world + if( !GL_LightPoint( origin, color ) ) { + VectorSet( color, 1, 1, 1 ); + } + +#if USE_DYNAMIC + if( gl_dynamic->integer ) { + // add dynamic lights + GL_AddLights( origin, color ); + } #endif + // apply modulate twice to mimic original ref_gl behavior + VectorScale( color, gl_modulate->value, color ); + + for( i = 0; i < 3; i++ ) { + clamp( color[i], 0, 1 ); + } +} + void GL_MarkLeaves( void ) { - byte fatvis[MAX_MAP_LEAFS/8]; - bspLeaf_t *leaf, *lastleaf; - bspNode_t *node, *lastnode; - byte *vis1, *vis2; - uint32_t *dst, *src1, *src2; + static int lastNodesVisible; + byte vis1[MAX_MAP_VIS]; + byte vis2[MAX_MAP_VIS]; + mleaf_t *leaf; + mnode_t *node; + uint32_t *src1, *src2; int cluster1, cluster2, longs; vec3_t tmp; - static int lastNodesVisible; + int i; + bsp_t *bsp = gl_static.world.cache; - leaf = Bsp_FindLeaf( glr.fd.vieworg ); + leaf = BSP_PointLeaf( bsp->nodes, glr.fd.vieworg ); cluster1 = cluster2 = leaf->cluster; VectorCopy( glr.fd.vieworg, tmp ); if( !leaf->contents ) { @@ -262,7 +209,7 @@ void GL_MarkLeaves( void ) { } else { tmp[2] += 16; } - leaf = Bsp_FindLeaf( tmp ); + leaf = BSP_PointLeaf( bsp->nodes, tmp ); if( !( leaf->contents & CONTENTS_SOLID ) ) { cluster2 = leaf->cluster; } @@ -275,55 +222,43 @@ void GL_MarkLeaves( void ) { goto finish; } - vis1 = vis2 = Bsp_ClusterPVS( cluster1 ); - if( cluster1 != cluster2 ) { - vis2 = Bsp_ClusterPVS( cluster2 ); - if( !vis1 ) { - vis1 = vis2; - } else if( !vis2 ) { - vis2 = vis1; - } - } glr.visframe++; - lastNodesVisible = 0; glr.viewcluster1 = cluster1; glr.viewcluster2 = cluster2; - if( !vis1 || gl_novis->integer ) { - /* mark everything visible */ - lastleaf = r_world.leafs + r_world.numLeafs; - for( leaf = r_world.leafs; leaf != lastleaf; leaf++ ) { - leaf->visframe = glr.visframe; + if( !bsp->vis || gl_novis->integer || cluster1 == -1 ) { + // mark everything visible + for( i = 0; i < bsp->numnodes; i++ ) { + bsp->nodes[i].visframe = glr.visframe; } - lastnode = r_world.nodes + r_world.numNodes; - for( node = r_world.nodes; node != lastnode; node++ ) { - node->visframe = glr.visframe; + for( i = 0; i < bsp->numleafs; i++ ) { + bsp->leafs[i].visframe = glr.visframe; } - lastNodesVisible = r_world.numNodes; + lastNodesVisible = bsp->numnodes; goto finish; } - if( vis1 != vis2 ) { - longs = ( r_world.numClusters + 31 ) >> 5; + BSP_ClusterVis( bsp, vis1, cluster1, DVIS_PVS ); + if( cluster1 != cluster2 ) { + BSP_ClusterVis( bsp, vis2, cluster2, DVIS_PVS ); + longs = ( bsp->visrowsize + 31 ) >> 5; src1 = ( uint32_t * )vis1; src2 = ( uint32_t * )vis2; - dst = ( uint32_t * )fatvis; while( longs-- ) { - *dst++ = *src1++ | *src2++; + *src1++ |= *src2++; } - vis1 = fatvis; } - - lastleaf = r_world.leafs + r_world.numLeafs; - for( leaf = r_world.leafs; leaf != lastleaf; leaf++ ) { + + lastNodesVisible = 0; + for( i = 0, leaf = bsp->leafs; i < bsp->numleafs; i++, leaf++ ) { cluster1 = leaf->cluster; if( cluster1 == -1 ) { continue; } if( Q_IsBitSet( vis1, cluster1 ) ) { - node = ( bspNode_t * )leaf; + node = ( mnode_t * )leaf; - /* mark parent nodes visible */ + // mark parent nodes visible do { if( node->visframe == glr.visframe ) { break; @@ -340,40 +275,16 @@ finish: } -#define NODE_CLIPPED 0 -#define NODE_UNCLIPPED 15 - -static inline qboolean GL_ClipNodeToFrustum( bspNode_t *node, int *clipflags ) { - int flags = *clipflags; - int i, bits, mask; - - for( i = 0, mask = 1; i < 4; i++, mask <<= 1 ) { - if( flags & mask ) { - continue; - } - bits = BoxOnPlaneSide( node->mins, node->maxs, - &glr.frustumPlanes[i] ); - if( bits == BOX_BEHIND ) { - return qfalse; - } - if( bits == BOX_INFRONT ) { - flags |= mask; - } - } - - *clipflags = flags; - - return qtrue; -} #define BACKFACE_EPSILON 0.001f -#define SIDE_FRONT 0 -#define SIDE_BACK 1 +#define BSP_CullFace( face, dot ) \ + ( ( (dot) < -BACKFACE_EPSILON && !( (face)->drawflags & DSURF_PLANEBACK ) ) || \ + ( (dot) > BACKFACE_EPSILON && ( (face)->drawflags & DSURF_PLANEBACK ) ) ) -void GL_DrawBspModel( bspSubmodel_t *model ) { - bspSurface_t *face; +void GL_DrawBspModel( mmodel_t *model ) { + mface_t *face; int count; vec3_t bounds[2]; vec_t dot; @@ -429,13 +340,11 @@ void GL_DrawBspModel( bspSubmodel_t *model ) { /* draw visible faces */ /* FIXME: go by headnode instead? */ - face = model->firstFace; - count = model->numFaces; + face = model->firstface; + count = model->numfaces; while( count-- ) { dot = PlaneDiffFast( modelViewOrigin, face->plane ); - if( ( dot < -BACKFACE_EPSILON && face->side == SIDE_FRONT ) || - ( dot > BACKFACE_EPSILON && face->side == SIDE_BACK ) ) - { + if( BSP_CullFace( face, dot ) ) { c.facesCulled++; } else { /* FIXME: trans surfaces are not supported on inline models */ @@ -449,61 +358,95 @@ void GL_DrawBspModel( bspSubmodel_t *model ) { qglPopMatrix(); } -static void GL_WorldNode_r( bspNode_t *node, int clipflags ) { - bspLeaf_t *leaf; - bspSurface_t **leafFace, *face; - int count, side, area; +#define NODE_CLIPPED 0 +#define NODE_UNCLIPPED 15 + +static inline qboolean GL_ClipNode( mnode_t *node, int *clipflags ) { + int flags = *clipflags; + int i, bits, mask; + + if( flags == NODE_UNCLIPPED ) { + return qtrue; + } + for( i = 0, mask = 1; i < 4; i++, mask <<= 1 ) { + if( flags & mask ) { + continue; + } + bits = BoxOnPlaneSide( node->mins, node->maxs, + &glr.frustumPlanes[i] ); + if( bits == BOX_BEHIND ) { + return qfalse; + } + if( bits == BOX_INFRONT ) { + flags |= mask; + } + } + + *clipflags = flags; + + return qtrue; +} + +static inline void GL_DrawLeaf( mleaf_t *leaf ) { + mface_t **face, **last; + + if( leaf->contents == CONTENTS_SOLID ) { + return; // solid leaf + } + if( glr.fd.areabits && !Q_IsBitSet( glr.fd.areabits, leaf->area ) ) { + return; // door blocks sight + } + last = leaf->firstleafface + leaf->numleaffaces; + for( face = leaf->firstleafface; face < last; face++ ) { + (*face)->drawframe = glr.drawframe; + } +} + +static inline void GL_DrawNode( mnode_t *node, vec_t dot ) { + mface_t *face, *last = node->firstface + node->numfaces; + + for( face = node->firstface; face < last; face++ ) { + if( face->drawframe != glr.drawframe ) { + continue; + } + if( BSP_CullFace( face, dot ) ) { + c.facesCulled++; + } else { + GL_AddFace( face ); + } + } + + c.nodesDrawn++; +} + +static void GL_WorldNode_r( mnode_t *node, int clipflags ) { + int side; vec_t dot; - + while( node->visframe == glr.visframe ) { - if( gl_cull_nodes->integer && clipflags != NODE_UNCLIPPED && - GL_ClipNodeToFrustum( node, &clipflags ) == qfalse ) - { + if( !GL_ClipNode( node, &clipflags ) ) { c.nodesCulled++; break; } if( !node->plane ) { - /* found a leaf */ - leaf = ( bspLeaf_t * )node; - if( leaf->contents == CONTENTS_SOLID ) { - break; - } - area = leaf->area; - if( !glr.fd.areabits || Q_IsBitSet( glr.fd.areabits, area ) ) { - leafFace = leaf->firstLeafFace; - count = leaf->numLeafFaces; - while( count-- ) { - face = *leafFace++; - face->drawframe = glr.drawframe; - } - } + GL_DrawLeaf( ( mleaf_t * )node ); break; } dot = PlaneDiffFast( modelViewOrigin, node->plane ); - side = ( dot < 0 ); + if( dot < 0 ) { + side = 1; + } else { + side = 0; + } GL_WorldNode_r( node->children[side], clipflags ); - face = node->firstFace; - count = node->numFaces; - while( count-- ) { - if( face->drawframe == glr.drawframe ) { - if( face->side == side ) { - GL_AddFace( face ); - } else { - c.facesCulled++; - } - } - face++; - } - - c.nodesDrawn++; + GL_DrawNode( node, dot ); node = node->children[ side ^ 1 ]; } - } void GL_DrawWorld( void ) { @@ -519,7 +462,8 @@ void GL_DrawWorld( void ) { VectorCopy( glr.fd.vieworg, modelViewOrigin ); - GL_WorldNode_r( r_world.nodes, NODE_CLIPPED ); + GL_WorldNode_r( gl_static.world.cache->nodes, + gl_cull_nodes->integer ? NODE_CLIPPED : NODE_UNCLIPPED ); GL_DrawSolidFaces(); diff --git a/source/mvd_game.c b/source/mvd_game.c index c96c23f..346421d 100644 --- a/source/mvd_game.c +++ b/source/mvd_game.c @@ -815,7 +815,6 @@ follow: static void MVD_Invuse_f( udpClient_t *client ) { mvd_t *mvd; - int cursor = 0; int uf = client->uf; if( client->layout_type == LAYOUT_MENU ) { @@ -864,19 +863,12 @@ static void MVD_Invuse_f( udpClient_t *client ) { return; } - if( client->layout_type != LAYOUT_CHANNELS ) { - return; - } - - LIST_FOR_EACH( mvd_t, mvd, &mvd_channels, entry ) { - if( !mvd->framenum ) { - continue; - } - if( cursor == client->layout_cursor ) { + if( client->layout_type == LAYOUT_CHANNELS ) { + mvd = LIST_INDEX( mvd_t, client->layout_cursor, &mvd_ready, entry ); + if( mvd ) { MVD_TrySwitchChannel( client, mvd ); - return; } - cursor++; + return; } } @@ -1011,7 +1003,7 @@ static void MVD_GameInit( void ) { cvar_t *mvd_default_map; char buffer[MAX_QPATH]; unsigned checksum; - const char *error; + //const char *error; int i; Com_Printf( "----- MVD_GameInit -----\n" ); @@ -1029,7 +1021,7 @@ static void MVD_GameInit( void ) { Z_TagReserve( ( sizeof( edict_t ) + sizeof( udpClient_t ) ) * sv_maxclients->integer + - sizeof( edict_t ), TAG_GAME ); + sizeof( edict_t ), TAG_MVD ); mvd_clients = Z_ReservedAllocz( sizeof( udpClient_t ) * sv_maxclients->integer ); edicts = Z_ReservedAllocz( sizeof( edict_t ) * @@ -1048,20 +1040,20 @@ static void MVD_GameInit( void ) { Com_sprintf( buffer, sizeof( buffer ), "maps/%s.bsp", mvd_default_map->string ); - error = CM_LoadMapEx( &mvd->cm, buffer, - CM_LOAD_CLIENT|CM_LOAD_ENTONLY, &checksum ); - if( error ) { - Com_WPrintf( "Couldn't load %s for the Waiting Room: %s\n", buffer, error ); + // error = CM_LoadMapEx( &mvd->cm, buffer, + // CM_LOAD_CLIENT|CM_LOAD_ENTONLY, &checksum ); + //if( error ) { + //Com_WPrintf( "Couldn't load %s for the Waiting Room: %s\n", buffer, error ); Cvar_Reset( mvd_default_map ); strcpy( buffer, "maps/q2dm1.bsp" ); checksum = 80717714; VectorSet( mvd->spawnOrigin, 984, 192, 784 ); VectorSet( mvd->spawnAngles, 25, 72, 0 ); - } else { + //} else { // get the spectator spawn point - MVD_ParseEntityString( mvd ); - CM_FreeMap( &mvd->cm ); - } + // MVD_ParseEntityString( mvd ); + //CM_FreeMap( &mvd->cm ); + //} strcpy( mvd->name, "Waiting Room" ); Cvar_VariableStringBuffer( "game", mvd->gamedir, sizeof( mvd->gamedir ) ); diff --git a/source/mvd_parse.c b/source/mvd_parse.c index e357964..adfd78f 100644 --- a/source/mvd_parse.c +++ b/source/mvd_parse.c @@ -68,9 +68,9 @@ const char *MVD_ServerCommandString( int cmd ) { static void MVD_LinkEdict( mvd_t *mvd, edict_t *ent ) { int index; - cmodel_t *cm; + mmodel_t *cm; int x, zd, zu; - cmcache_t *cache = mvd->cm.cache; + bsp_t *cache = mvd->cm.cache; if( !cache ) { return; @@ -78,12 +78,12 @@ static void MVD_LinkEdict( mvd_t *mvd, edict_t *ent ) { if( ent->s.solid == 31 ) { index = ent->s.modelindex; - if( index < 1 || index > cache->numcmodels ) { + if( index < 1 || index > cache->nummodels ) { Com_WPrintf( "%s: entity %d: bad inline model index: %d\n", __func__, ent->s.number, index ); return; } - cm = &cache->cmodels[ index - 1 ]; + cm = &cache->models[ index - 1 ]; VectorCopy( cm->mins, ent->mins ); VectorCopy( cm->maxs, ent->maxs ); ent->solid = SOLID_BSP; @@ -205,10 +205,8 @@ void MVD_ParseEntityString( mvd_t *mvd ) { static void MVD_ParseMulticast( mvd_t *mvd, mvd_ops_t op, int extrabits ) { udpClient_t *client; client_t *cl; - byte *mask; - cleaf_t *leaf; - int cluster; - int area1, area2; + byte mask[MAX_MAP_VIS]; + mleaf_t *leaf1, *leaf2; vec3_t org; qboolean reliable = qfalse; player_state_t *ps; @@ -220,33 +218,27 @@ static void MVD_ParseMulticast( mvd_t *mvd, mvd_ops_t op, int extrabits ) { switch( op ) { case mvd_multicast_all_r: - reliable = qtrue; // intentional fallthrough + reliable = qtrue; + // intentional fallthrough case mvd_multicast_all: - area1 = 0; - cluster = 0; - mask = NULL; + leaf1 = NULL; break; - case mvd_multicast_phs_r: - reliable = qtrue; // intentional fallthrough + reliable = qtrue; + // intentional fallthrough case mvd_multicast_phs: leafnum = MSG_ReadShort(); - leaf = CM_LeafNum( &mvd->cm, leafnum ); - area1 = CM_LeafArea( leaf ); - cluster = CM_LeafCluster( leaf ); - mask = CM_ClusterPHS( &mvd->cm, cluster ); + leaf1 = CM_LeafNum( &mvd->cm, leafnum ); + BSP_ClusterVis( mvd->cm.cache, mask, leaf1->cluster, DVIS_PHS ); break; - case mvd_multicast_pvs_r: - reliable = qtrue; // intentional fallthrough + reliable = qtrue; + // intentional fallthrough case mvd_multicast_pvs: leafnum = MSG_ReadShort(); - leaf = CM_LeafNum( &mvd->cm, leafnum ); - area1 = CM_LeafArea( leaf ); - cluster = CM_LeafCluster( leaf ); - mask = CM_ClusterPVS( &mvd->cm, cluster ); + leaf1 = CM_LeafNum( &mvd->cm, leafnum ); + BSP_ClusterVis( mvd->cm.cache, mask, leaf1->cluster, DVIS_PVS ); break; - default: MVD_Destroyf( mvd, "bad op" ); } @@ -270,16 +262,14 @@ static void MVD_ParseMulticast( mvd_t *mvd, mvd_ops_t op, int extrabits ) { continue; } - if( mask ) { + if( leaf1 ) { // find the client's PVS ps = &client->ps; VectorMA( ps->viewoffset, 0.125f, ps->pmove.origin, org ); - leaf = CM_PointLeaf( &mvd->cm, org ); - area2 = CM_LeafArea( leaf ); - if( !CM_AreasConnected( &mvd->cm, area1, area2 ) ) + leaf2 = CM_PointLeaf( &mvd->cm, org ); + if( !CM_AreasConnected( &mvd->cm, leaf1->area, leaf2->area ) ) continue; - cluster = CM_LeafCluster( leaf ); - if( !Q_IsBitSet( mask, cluster ) ) { + if( !Q_IsBitSet( mask, leaf2->cluster ) ) { continue; } } @@ -511,9 +501,9 @@ static void MVD_ParseSound( mvd_t *mvd, int extrabits ) { vec3_t origin; udpClient_t *client; client_t *cl; - byte *mask; - cleaf_t *leaf; - int area, cluster; + byte mask[MAX_MAP_VIS]; + mleaf_t *leaf; + int area; player_state_t *ps; sound_packet_t *msg; edict_t *entity; @@ -560,8 +550,7 @@ static void MVD_ParseSound( mvd_t *mvd, int extrabits ) { continue; // blocked by a door } } - cluster = CM_LeafCluster( leaf ); - mask = CM_ClusterPHS( &mvd->cm, cluster ); + BSP_ClusterVis( mvd->cm.cache, mask, leaf->cluster, DVIS_PHS ); if( !SV_EdictPV( &mvd->cm, entity, mask ) ) { continue; // not in PHS } @@ -777,6 +766,11 @@ static void MVD_ParsePacketEntities( mvd_t *mvd ) { MSG_ParseDeltaEntity( &ent->s, &ent->s, number, bits ); + // lazily relink even if removed + if( number > mvd->maxclients && ( bits & RELINK_MASK ) ) { + MVD_LinkEdict( mvd, ent ); + } + if( bits & U_REMOVE ) { if( mvd_shownet->integer > 2 ) { Com_Printf( " remove: %d\n", number ); @@ -789,10 +783,6 @@ static void MVD_ParsePacketEntities( mvd_t *mvd ) { if( number >= mvd->pool.num_edicts ) { mvd->pool.num_edicts = number + 1; } - - if( number > mvd->maxclients && ( bits & RELINK_MASK ) ) { - MVD_LinkEdict( mvd, ent ); - } } } @@ -894,8 +884,6 @@ static void MVD_ParseServerData( mvd_t *mvd ) { int protocol; size_t length; char *gamedir, *string, *p; - const char *error; - uint32_t checksum; int i, index; mvd_player_t *player; @@ -984,13 +972,12 @@ static void MVD_ParseServerData( mvd_t *mvd ) { // load the world model (we are only interesed in // visibility info, do not load brushes and such) Com_Printf( "[%s] Loading %s...\n", mvd->name, string ); - error = CM_LoadMapEx( &mvd->cm, string, CM_LOAD_VISONLY, &checksum ); - if( error ) { - MVD_Destroyf( mvd, "Couldn't load %s: %s", string, error ); + if( !CM_LoadMap( &mvd->cm, string ) ) { + MVD_Destroyf( mvd, "Couldn't load %s: %s", string, BSP_GetError() ); } #if USE_MAPCHECKSUM - if( checksum != atoi( mvd->configstrings[CS_MAPCHECKSUM] ) ) { + if( mvd->cm.cache->checksum != atoi( mvd->configstrings[CS_MAPCHECKSUM] ) ) { MVD_Destroyf( mvd, "Local map version differs from server" ); } #endif diff --git a/source/net_chan.c b/source/net_chan.c index c1be960..62ce131 100644 --- a/source/net_chan.c +++ b/source/net_chan.c @@ -19,7 +19,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "com_local.h" +#include "protocol.h" +#include "q_msg.h" +#include "net_sock.h" #include "net_chan.h" +#include "files.h" +#include "sys_public.h" /* diff --git a/source/net_chan.h b/source/net_chan.h index 64d57fa..05bde3e 100644 --- a/source/net_chan.h +++ b/source/net_chan.h @@ -19,6 +19,62 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // net_chan.h +typedef enum netchan_type_e { + NETCHAN_OLD, + NETCHAN_NEW +} netchan_type_t; + +typedef struct netchan_s { + netchan_type_t type; + int protocol; + size_t maxpacketlen; + + qboolean fatal_error; + + netsrc_t sock; + + int dropped; // between last packet and previous + + unsigned last_received; // for timeouts + unsigned last_sent; // for retransmits + + netadr_t remote_address; + int qport; // qport value to write when transmitting + + sizebuf_t message; // writing buffer for reliable data + + size_t reliable_length; + + qboolean reliable_ack_pending; // set to qtrue each time reliable is received + qboolean fragment_pending; + + // sequencing variables + int incoming_sequence; + int incoming_acknowledged; + int outgoing_sequence; + + size_t (*Transmit)( struct netchan_s *, size_t, const void * ); + size_t (*TransmitNextFragment)( struct netchan_s * ); + qboolean (*Process)( struct netchan_s * ); + qboolean (*ShouldUpdate)( struct netchan_s * ); +} netchan_t; + +extern cvar_t *net_qport; +extern cvar_t *net_maxmsglen; +extern cvar_t *net_chantype; + +void Netchan_Init( void ); +neterr_t Netchan_OutOfBandPrint( netsrc_t sock, const netadr_t *adr, + const char *format, ... ); +netchan_t *Netchan_Setup( netsrc_t sock, netchan_type_t type, + const netadr_t *adr, int qport, size_t maxpacketlen, int protocol ); +void Netchan_Close( netchan_t *netchan ); + +#define OOB_PRINT( sock, addr, string ) \ + NET_SendPacket( sock, addr, sizeof( "\xff\xff\xff\xff" string ) - 1, "\xff\xff\xff\xff" string ) + +//============================================================================ + typedef struct netchan_old_s { netchan_t pub; diff --git a/source/net_common.c b/source/net_common.c index 492df9c..0bbb94f 100644 --- a/source/net_common.c +++ b/source/net_common.c @@ -23,6 +23,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #include "com_local.h" +#include "files.h" +#include "protocol.h" +#include "q_msg.h" +#include "q_fifo.h" +#include "net_sock.h" +#include "net_stream.h" +#include "sys_public.h" #if defined( _WIN32 ) #define WIN32_LEAN_AND_MEAN diff --git a/source/net_sock.h b/source/net_sock.h new file mode 100644 index 0000000..e959a81 --- /dev/null +++ b/source/net_sock.h @@ -0,0 +1,154 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// net.h -- quake's interface to the networking layer + +#define PORT_ANY -1 + +#define MAX_PACKETLEN 4096 // max length of a single packet +#define PACKET_HEADER 10 // two ints and a short (worst case) +#define MAX_PACKETLEN_DEFAULT 1400 // default quake2 limit +#define MAX_PACKETLEN_WRITABLE ( MAX_PACKETLEN - PACKET_HEADER ) +#define MAX_PACKETLEN_WRITABLE_DEFAULT ( MAX_PACKETLEN_DEFAULT - PACKET_HEADER ) + +typedef enum netadrtype_e { + NA_BAD, + NA_LOOPBACK, + NA_BROADCAST, + NA_IP +} netadrtype_t; + +typedef enum netsrc_e { + NS_CLIENT, + NS_SERVER, + NS_COUNT +} netsrc_t; + +typedef enum netflag_e { + NET_NONE = 0, + NET_CLIENT = ( 1 << 0 ), + NET_SERVER = ( 1 << 1 ) +} netflag_t; + +typedef enum netstat_e { + NET_OK, + NET_AGAIN, + NET_CLOSED, + NET_ERROR, +} neterr_t; + +typedef struct netadr_s { + netadrtype_t type; + uint8_t ip[4]; + uint16_t port; +} netadr_t; + +static inline qboolean NET_IsEqualAdr( const netadr_t *a, const netadr_t *b ) { + if( a->type != b->type ) { + return qfalse; + } + + switch( a->type ) { + case NA_LOOPBACK: + return qtrue; + case NA_IP: + case NA_BROADCAST: + if( *( uint32_t * )a->ip == *( uint32_t * )b->ip && a->port == b->port ) { + return qtrue; + } + return qfalse; + default: + break; + } + + return qfalse; +} + +static inline qboolean NET_IsEqualBaseAdr( const netadr_t *a, const netadr_t *b ) { + if( a->type != b->type ) { + return qfalse; + } + + switch( a->type ) { + case NA_LOOPBACK: + return qtrue; + case NA_IP: + case NA_BROADCAST: + if( *( uint32_t * )a->ip == *( uint32_t * )b->ip ) { + return qtrue; + } + return qfalse; + default: + break; + } + + return qfalse; +} + +static inline qboolean NET_IsLanAddress( const netadr_t *adr ) { + switch( adr->type ) { + case NA_LOOPBACK: + return qtrue; + case NA_IP: + case NA_BROADCAST: + if( adr->ip[0] == 127 || adr->ip[0] == 10 ) { + return qtrue; + } + if( *( uint16_t * )adr->ip == MakeShort( 192, 168 ) || + *( uint16_t * )adr->ip == MakeShort( 172, 16 ) ) + { + return qtrue; + } + return qfalse; + default: + break; + } + + return qfalse; +} + +void NET_Init( void ); +void NET_Shutdown( void ); + +void NET_Config( netflag_t flag ); +qboolean NET_GetAddress( netsrc_t sock, netadr_t *adr ); + +neterr_t NET_GetPacket( netsrc_t sock ); +neterr_t NET_SendPacket( netsrc_t sock, const netadr_t *to, size_t length, const void *data ); +qboolean NET_GetLoopPacket( netsrc_t sock ); + +char * NET_AdrToString( const netadr_t *a ); +qboolean NET_StringToAdr( const char *s, netadr_t *a, int port ); +void NET_Sleep( int msec ); + +#if USE_CLIENT +#define NET_IsLocalAddress( adr ) ( (adr)->type == NA_LOOPBACK ) +#else +#define NET_IsLocalAddress( adr ) 0 +#endif + +const char *NET_ErrorString( void ); + +extern cvar_t *net_ip; +extern cvar_t *net_port; + +extern netadr_t net_from; + + diff --git a/source/net_stream.h b/source/net_stream.h new file mode 100644 index 0000000..32f5acd --- /dev/null +++ b/source/net_stream.h @@ -0,0 +1,42 @@ +/* +Copyright (C) 2003-2008 Andrey Nazarov + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +typedef enum netstate_e { + NS_DISCONNECTED,// no socket opened + NS_CONNECTING, // connect() not yet completed + NS_CONNECTED, // may transmit data + NS_CLOSED, // peer has preformed orderly shutdown + NS_BROKEN // fatal error has been signaled +} netstate_t; + +typedef struct netstream_s { + int socket; + netadr_t address; + netstate_t state; + fifo_t recv; + fifo_t send; +} netstream_t; + +void NET_Close( netstream_t *s ); +neterr_t NET_Listen( qboolean listen ); +neterr_t NET_Accept( netadr_t *peer, netstream_t *s ); +neterr_t NET_Connect( const netadr_t *peer, netstream_t *s ); +neterr_t NET_Run( netstream_t *s ); + diff --git a/source/pmove.c b/source/pmove.c index bc6b925..546b935 100644 --- a/source/pmove.c +++ b/source/pmove.c @@ -18,10 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <config.h> #include "com_local.h" - - +#include "pmove.h" #define STEPSIZE 18 diff --git a/source/pmove.h b/source/pmove.h new file mode 100644 index 0000000..c47b1c8 --- /dev/null +++ b/source/pmove.h @@ -0,0 +1,50 @@ +/* +Copyright (C) 1997-2001 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. + +*/ + +/* +============================================================== + +PLAYER MOVEMENT CODE + +Common between server and client so prediction matches + +============================================================== +*/ + +typedef struct { + qboolean airaccelerate; + qboolean strafeHack; + qboolean flyfix; + int qwmod; + float speedMultiplier; +// float upspeed; + float maxspeed; + float friction; + float waterfriction; + float flyfriction; +#ifdef PMOVE_HACK + vec3_t origin; + vec3_t velocity; + qboolean highprec; +#endif +} pmoveParams_t; + +void Pmove( pmove_t *pmove, pmoveParams_t *params ); + diff --git a/source/prompt.c b/source/prompt.c index 007b853..0c0b044 100644 --- a/source/prompt.c +++ b/source/prompt.c @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #include "com_local.h" +#include "files.h" #include "q_field.h" #include "prompt.h" @@ -128,7 +129,7 @@ static void Prompt_ShowIndividualMatches( } } -qboolean Prompt_AddMatch( genctx_t *ctx, const char *s ) { +EXPORTED qboolean Prompt_AddMatch( genctx_t *ctx, const char *s ) { int r; if( ctx->count >= ctx->size ) { diff --git a/source/q_field.c b/source/q_field.c index 5f9554c..fdd5708 100644 --- a/source/q_field.c +++ b/source/q_field.c @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "com_local.h" #include "key_public.h" #include "ref_public.h" +#include "vid_public.h" #include "q_field.h" /* @@ -61,7 +62,7 @@ void IF_Replace( inputField_t *field, const char *text ) { field->cursorPos = Q_strncpyz( field->text, text, sizeof( field->text ) ); } -#ifndef DEDICATED_ONLY +#if USE_CLIENT /* ================ @@ -234,14 +235,13 @@ int IF_Draw( inputField_t *field, int x, int y, int flags, qhandle_t font ) { } // draw text - ret = ref.DrawString( x, y, flags, field->visibleChars, - text + offset, font ); + ret = R_DrawString( x, y, flags, field->visibleChars, text + offset, font ); if( flags & UI_DRAWCURSOR ) { // draw blinking cursor if( ( com_localTime >> 8 ) & 1 ) { int c = Key_GetOverstrikeMode() ? 11 : '_'; - ref.DrawChar( x + cursorPos * CHAR_WIDTH, y, flags, c, font ); + R_DrawChar( x + cursorPos * CHAR_WIDTH, y, flags, c, font ); } } diff --git a/source/q_fifo.h b/source/q_fifo.h new file mode 100644 index 0000000..9d70bce --- /dev/null +++ b/source/q_fifo.h @@ -0,0 +1,114 @@ +/* +Copyright (C) 2003-2008 Andrey Nazarov + +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. + +*/ + +// +// q_fifo.h +// + +typedef struct { + byte *data; + size_t size; + size_t ax, ay, bs; +} fifo_t; + +static inline void *FIFO_Reserve( fifo_t *fifo, size_t *reserved ) { + size_t tail; + + if( fifo->bs ) { + *reserved = fifo->ax - fifo->bs; + return fifo->data + fifo->bs; + } + + tail = fifo->size - fifo->ay; + if( fifo->ax < tail ) { + *reserved = tail; + return fifo->data + fifo->ay; + } + + *reserved = fifo->ax; + return fifo->data; +} + +static inline void FIFO_Commit( fifo_t *fifo, size_t len ) { + size_t tail; + + if( fifo->bs ) { + fifo->bs += len; + return; + } + + tail = fifo->size - fifo->ay; + if( fifo->ax < tail ) { + fifo->ay += len; + return; + } + + fifo->bs = len; +} + +static inline void *FIFO_Peek( fifo_t *fifo, size_t *len ) { + *len = fifo->ay - fifo->ax; + return fifo->data + fifo->ax; +} + +static inline void FIFO_Decommit( fifo_t *fifo, size_t len ) { + if( fifo->ax + len < fifo->ay ) { + fifo->ax += len; + return; + } + + fifo->ay = fifo->bs; + fifo->ax = fifo->bs = 0; +} + +static inline size_t FIFO_Usage( fifo_t *fifo ) { + return fifo->ay - fifo->ax + fifo->bs; +} + +static inline int FIFO_Percent( fifo_t *fifo ) { + if( !fifo->size ) { + return 0; + } + return ( int )( FIFO_Usage( fifo ) * 100 / fifo->size ); +} + +static inline void FIFO_Clear( fifo_t *fifo ) { + fifo->ax = fifo->ay = fifo->bs = 0; +} + +size_t FIFO_Read( fifo_t *fifo, void *buffer, size_t len ); +size_t FIFO_Write( fifo_t *fifo, const void *buffer, size_t len ); + +static inline qboolean FIFO_TryRead( fifo_t *fifo, void *buffer, size_t len ) { + if( FIFO_Read( fifo, NULL, len ) < len ) { + return qfalse; + } + FIFO_Read( fifo, buffer, len ); + return qtrue; +} + +static inline qboolean FIFO_TryWrite( fifo_t *fifo, void *buffer, size_t len ) { + if( FIFO_Write( fifo, NULL, len ) < len ) { + return qfalse; + } + FIFO_Write( fifo, buffer, len ); + return qtrue; +} + diff --git a/source/q_files.h b/source/q_files.h deleted file mode 100644 index 6cc84d5..0000000 --- a/source/q_files.h +++ /dev/null @@ -1,539 +0,0 @@ -/* -Copyright (C) 1997-2001 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. - -*/ - -// -// qfiles.h: quake file formats -// This file must be identical in the quake and utils directories -// - -/* -======================================================================== - -The .pak files are just a linear collapse of a directory tree - -======================================================================== -*/ - -#define IDPAKHEADER (('K'<<24)+('C'<<16)+('A'<<8)+'P') - -typedef struct { - char name[56]; - uint32_t filepos, filelen; -} dpackfile_t; - -typedef struct { - uint32_t ident; // == IDPAKHEADER - uint32_t dirofs; - uint32_t dirlen; -} dpackheader_t; - -#define MAX_FILES_IN_PACK 4096 - - -/* -======================================================================== - -PCX files are used for as many images as possible - -======================================================================== -*/ - -typedef struct { - uint8_t manufacturer; - uint8_t version; - uint8_t encoding; - uint8_t bits_per_pixel; - uint16_t xmin,ymin,xmax,ymax; - uint16_t hres,vres; - uint8_t palette[48]; - uint8_t reserved; - uint8_t color_planes; - uint16_t bytes_per_line; - uint16_t palette_type; - uint8_t filler[58]; - uint8_t data[1]; // unbounded -} pcx_t; - - -/* -======================================================================== - -.MD2 triangle model file format - -======================================================================== -*/ - -#define IDALIASHEADER (('2'<<24)+('P'<<16)+('D'<<8)+'I') -#define ALIAS_VERSION 8 - -#define MAX_TRIANGLES 4096 -#define MAX_VERTS 2048 -#define MAX_FRAMES 512 -#define MAX_MD2SKINS 32 -#define MAX_SKINNAME 64 - -typedef struct { - int16_t s; - int16_t t; -} dstvert_t; - -typedef struct { - uint16_t index_xyz[3]; - uint16_t index_st[3]; -} dtriangle_t; - -typedef struct { - uint8_t v[3]; // scaled byte to fit in frame mins/maxs - uint8_t lightnormalindex; -} dtrivertx_t; - -#define DTRIVERTX_V0 0 -#define DTRIVERTX_V1 1 -#define DTRIVERTX_V2 2 -#define DTRIVERTX_LNI 3 -#define DTRIVERTX_SIZE 4 - -typedef struct { - float scale[3]; // multiply byte verts by this - float translate[3]; // then add this - char name[16]; // frame name from grabbing - dtrivertx_t verts[1]; // variable sized -} daliasframe_t; - -#define MAX_FRAMESIZE ( sizeof( daliasframe_t ) + sizeof( dtrivertx_t ) * ( MAX_VERTS - 1 ) ) - - -// the glcmd format: -// a positive integer starts a tristrip command, followed by that many -// vertex structures. -// a negative integer starts a trifan command, followed by -x vertexes -// a zero indicates the end of the command list. -// a vertex consists of a floating point s, a floating point t, -// and an integer vertex index. - - -typedef struct { - uint32_t ident; - uint32_t version; - - uint32_t skinwidth; - uint32_t skinheight; - uint32_t framesize; // byte size of each frame - - uint32_t num_skins; - uint32_t num_xyz; - uint32_t num_st; // greater than num_xyz for seams - uint32_t num_tris; - uint32_t num_glcmds; // dwords in strip/fan command list - uint32_t num_frames; - - uint32_t ofs_skins; // each skin is a MAX_SKINNAME string - uint32_t ofs_st; // byte offset from start for stverts - uint32_t ofs_tris; // offset for dtriangles - uint32_t ofs_frames; // offset for first frame - uint32_t ofs_glcmds; - uint32_t ofs_end; // end of file -} dmdl_t; - -/* - ======================================================================= - - .MD3 triangle model file format - - ======================================================================= - */ - -#define MD3_IDENT (('3'<<24)+('P'<<16)+('D'<<8)+'I') -#define MD3_VERSION 15 - -// limits -#define MD3_MAX_LODS 3 -#define MD3_MAX_TRIANGLES 8192 // per surface -#define MD3_MAX_VERTS 4096 // per surface -#define MD3_MAX_SHADERS 256 // per surface -#define MD3_MAX_FRAMES 1024 // per model -#define MD3_MAX_SURFACES 32 // per model -#define MD3_MAX_TAGS 16 // per frame -#define MD3_MAX_PATH 64 - -// vertex scales -#define MD3_XYZ_SCALE (1.0f/64.0f) - -typedef struct { - float st[2]; -} dmd3coord_t; - -typedef struct { - int16_t point[3]; - uint8_t norm[2]; -} dmd3vertex_t; - -typedef struct { - float mins[3]; - float maxs[3]; - float translate[3]; - float radius; - char creator[16]; -} dmd3frame_t; - -typedef struct { - char name[MD3_MAX_PATH]; // tag name - float origin[3]; - float axis[3][3]; -} dmd3tag_t; - -typedef struct { - char name[MD3_MAX_PATH]; - uint32_t unused; // shader -} dmd3skin_t; - -typedef struct { - uint32_t ident; - - char name[MD3_MAX_PATH]; - uint32_t flags; - - uint32_t num_frames; - uint32_t num_skins; - uint32_t num_verts; - uint32_t num_tris; - - uint32_t ofs_indexes; - uint32_t ofs_skins; - uint32_t ofs_tcs; - uint32_t ofs_verts; - - uint32_t meshsize; -} dmd3mesh_t; - -typedef struct { - uint32_t ident; - uint32_t version; - - char filename[MD3_MAX_PATH]; - - uint32_t flags; - - uint32_t num_frames; - uint32_t num_tags; - uint32_t num_meshes; - uint32_t num_skins; - - uint32_t ofs_frames; - uint32_t ofs_tags; - uint32_t ofs_meshes; - uint32_t ofs_end; -} dmd3header_t; - - -/* - ======================================================================== - - .SP2 sprite file format - - ======================================================================== - */ - -#define IDSPRITEHEADER (('2'<<24)+('S'<<16)+('D'<<8)+'I') -// little-endian "IDS2" -#define SPRITE_VERSION 2 - -typedef struct { - uint32_t width, height; - uint32_t origin_x, origin_y; // raster coordinates inside pic - char name[MAX_SKINNAME]; // name of pcx file -} dsprframe_t; - -typedef struct { - uint32_t ident; - uint32_t version; - uint32_t numframes; - dsprframe_t frames[1]; // variable sized -} dsprite_t; - -/* - ============================================================================== - - .WAL texture file format - - ============================================================================== - */ - -#define MIPLEVELS 4 - -typedef struct { - char name[32]; - uint32_t width, height; - uint32_t offsets[MIPLEVELS]; // four mip maps stored - char animname[32]; // next frame in animation chain - uint32_t flags; - uint32_t contents; - uint32_t value; -} miptex_t; - - - -/* - ============================================================================== - - .BSP file format - - ============================================================================== - */ - -#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') -// little-endian "IBSP" - -#define BSPVERSION 38 - - -// upper design bounds -// leaffaces, leafbrushes, planes, and verts are still bounded by -// 16 bit short limits -#define MAX_MAP_MODELS 1024 -#define MAX_MAP_BRUSHES 8192 -#define MAX_MAP_ENTITIES 2048 -#define MAX_MAP_ENTSTRING 0x40000 -#define MAX_MAP_TEXINFO 8192 - -#define MAX_MAP_AREAS 256 -#define MAX_MAP_AREAPORTALS 1024 -#define MAX_MAP_PLANES 65536 -#define MAX_MAP_NODES 65536 -#define MAX_MAP_BRUSHSIDES 65536 -#define MAX_MAP_LEAFS 65536 -#define MAX_MAP_VERTS 65536 -#define MAX_MAP_FACES 65536 -#define MAX_MAP_LEAFFACES 65536 -#define MAX_MAP_LEAFBRUSHES 65536 -#define MAX_MAP_PORTALS 65536 -#define MAX_MAP_EDGES 128000 -#define MAX_MAP_SURFEDGES 256000 -#define MAX_MAP_LIGHTING 0x200000 -#define MAX_MAP_VISIBILITY 0x100000 - -// key / value pair sizes - -#define MAX_KEY 32 -#define MAX_VALUE 1024 - -//============================================================================= - -typedef struct { - uint32_t fileofs, filelen; -} lump_t; - -#define LUMP_ENTITIES 0 -#define LUMP_PLANES 1 -#define LUMP_VERTEXES 2 -#define LUMP_VISIBILITY 3 -#define LUMP_NODES 4 -#define LUMP_TEXINFO 5 -#define LUMP_FACES 6 -#define LUMP_LIGHTING 7 -#define LUMP_LEAFS 8 -#define LUMP_LEAFFACES 9 -#define LUMP_LEAFBRUSHES 10 -#define LUMP_EDGES 11 -#define LUMP_SURFEDGES 12 -#define LUMP_MODELS 13 -#define LUMP_BRUSHES 14 -#define LUMP_BRUSHSIDES 15 -#define LUMP_POP 16 -#define LUMP_AREAS 17 -#define LUMP_AREAPORTALS 18 -#define HEADER_LUMPS 19 - -typedef struct { - uint32_t ident; - uint32_t version; - lump_t lumps[HEADER_LUMPS]; -} dheader_t; - -typedef struct { - float mins[3], maxs[3]; - float origin[3]; // for sounds or lights - uint32_t headnode; - uint32_t firstface, numfaces; // submodels just draw faces - // without walking the bsp tree -} dmodel_t; - - -typedef struct { - float point[3]; -} dvertex_t; - -typedef struct { - float normal[3]; - float dist; - uint32_t type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate -} dplane_t; - - -// contents flags are seperate bits -// a given brush can contribute multiple content bits -// multiple brushes can be in a single leaf - -// these definitions also need to be in q_shared.h! - -// lower bits are stronger, and will eat weaker brushes completely -#define CONTENTS_SOLID 1 // an eye is never valid in a solid -#define CONTENTS_WINDOW 2 // translucent, but not watery -#define CONTENTS_AUX 4 -#define CONTENTS_LAVA 8 -#define CONTENTS_SLIME 16 -#define CONTENTS_WATER 32 -#define CONTENTS_MIST 64 -#define LAST_VISIBLE_CONTENTS 64 - -// remaining contents are non-visible, and don't eat brushes - -#define CONTENTS_AREAPORTAL 0x8000 - -#define CONTENTS_PLAYERCLIP 0x10000 -#define CONTENTS_MONSTERCLIP 0x20000 - -// currents can be added to any other contents, and may be mixed -#define CONTENTS_CURRENT_0 0x40000 -#define CONTENTS_CURRENT_90 0x80000 -#define CONTENTS_CURRENT_180 0x100000 -#define CONTENTS_CURRENT_270 0x200000 -#define CONTENTS_CURRENT_UP 0x400000 -#define CONTENTS_CURRENT_DOWN 0x800000 - -#define CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity - -#define CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game -#define CONTENTS_DEADMONSTER 0x4000000 -#define CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs -#define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans -#define CONTENTS_LADDER 0x20000000 - - - -#define SURF_LIGHT 0x1 // value will hold the light strength - -#define SURF_SLICK 0x2 // effects game physics - -#define SURF_SKY 0x4 // don't draw, but add to skybox -#define SURF_WARP 0x8 // turbulent water warp -#define SURF_TRANS33 0x10 -#define SURF_TRANS66 0x20 -#define SURF_FLOWING 0x40 // scroll towards angle -#define SURF_NODRAW 0x80 // don't bother referencing the texture - -typedef struct { - uint32_t planenum; - uint32_t children[2]; // negative numbers are -(leafs+1), not nodes - int16_t mins[3]; // for frustom culling - int16_t maxs[3]; - uint16_t firstface; - uint16_t numfaces; // counting both sides -} dnode_t; - - -typedef struct texinfo_s { - float vecs[2][4]; // [s/t][xyz offset] - uint32_t flags; // miptex flags + overrides - int32_t value; // light emission, etc - char texture[32]; // texture name (textures/*.wal) - uint32_t nexttexinfo; // for animations, -1 = end of chain -} texinfo_t; - - -// note that edge 0 is never used, because negative edge nums are used for -// counterclockwise use of the edge in a face -typedef struct { - uint16_t v[2]; // vertex numbers -} dedge_t; - -#define MAXLIGHTMAPS 4 - -typedef struct { - uint16_t planenum; - uint16_t side; - - uint32_t firstedge; // we must support > 64k edges - uint16_t numedges; - uint16_t texinfo; - -// lighting info - uint8_t styles[MAXLIGHTMAPS]; - uint32_t lightofs; // start of [numstyles*surfsize] samples -} dface_t; - -typedef struct { - uint32_t contents; // OR of all brushes (not needed?) - - uint16_t cluster; - uint16_t area; - - int16_t mins[3]; // for frustum culling - int16_t maxs[3]; - - uint16_t firstleafface; - uint16_t numleaffaces; - - uint16_t firstleafbrush; - uint16_t numleafbrushes; -} dleaf_t; - -typedef struct { - uint16_t planenum; // facing out of the leaf - uint16_t texinfo; -} dbrushside_t; - -typedef struct { - uint32_t firstside; - uint32_t numsides; - uint32_t contents; -} dbrush_t; - -#define ANGLE_UP -1 -#define ANGLE_DOWN -2 - - -// the visibility lump consists of a header with a count, then -// byte offsets for the PVS and PHS of each cluster, then the raw -// compressed bit vectors -#define DVIS_PVS 0 -#define DVIS_PHS 1 - -#define DVIS_CLUSTERS 8 - -typedef struct { - uint32_t numclusters; - uint32_t bitofs[DVIS_CLUSTERS][2]; // bitofs[numclusters][2] -} dvis_t; - -// each area has a list of portals that lead into other areas -// when portals are closed, other areas may not be visible or -// hearable even if the vis info says that it should be -typedef struct { - uint32_t portalnum; - uint32_t otherarea; -} dareaportal_t; - -typedef struct { - uint32_t numareaportals; - uint32_t firstareaportal; -} darea_t; - - diff --git a/source/q_msg.c b/source/q_msg.c index f734a35..ecca812 100644 --- a/source/q_msg.c +++ b/source/q_msg.c @@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include <config.h> #include "q_shared.h" -#include "com_public.h" #include "protocol.h" #include "q_msg.h" diff --git a/source/q_shared.c b/source/q_shared.c index 9d1a81c..0f0ff83 100644 --- a/source/q_shared.c +++ b/source/q_shared.c @@ -466,7 +466,7 @@ BoxOnPlaneSide Returns 1, 2, or 1 + 2 ================== */ -#ifndef USE_ASM +#if !USE_ASM int BoxOnPlaneSide( vec3_t emins, vec3_t emaxs, cplane_t *p ) { float dist1, dist2; diff --git a/source/q_shared.h b/source/q_shared.h index 23164fe..aa9dd3f 100644 --- a/source/q_shared.h +++ b/source/q_shared.h @@ -122,7 +122,6 @@ typedef enum comPrintType_e { PRINT_ERROR // print in red color } comPrintType_t; -// FIXME: move these to com_public.h? void Com_Printf( const char *fmt, ... ) q_printf( 1, 2 ); void Com_DPrintf( const char *fmt, ... ) q_printf( 1, 2 ); void Com_WPrintf( const char *fmt, ... ) q_printf( 1, 2 ); diff --git a/source/qgl_api.c b/source/qgl_api.c index 122a45b..5494b83 100644 --- a/source/qgl_api.c +++ b/source/qgl_api.c @@ -28,12 +28,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** QGL_Shutdown() - unloads libraries, NULLs function pointers */ -#include <config.h> -#include "qgl_local.h" -#include "q_shared.h" -#include "com_public.h" +#include "com_local.h" #include "in_public.h" #include "vid_public.h" +#include "qgl_local.h" #include "qgl_api.h" static FILE *log_fp; @@ -416,7 +414,7 @@ PFNGLGETBUFFERPOINTERVPROC qglGetBufferPointervARB; #ifdef _WIN32 PROC ( WINAPI * qglGetProcAddress )( LPCSTR ); #else -void *qglGetProcAddress( const char *symbol ) { return video.GetProcAddr( symbol ); } +void *qglGetProcAddress( const char *symbol ) { return VID_GetProcAddr( symbol ); } #endif // ========================================================== @@ -3021,7 +3019,7 @@ void QGL_Shutdown( void ) { #endif } -#define GPA( a ) video.GetProcAddr( a ) +#define GPA( a ) VID_GetProcAddr( a ) /* @@ -3396,7 +3394,7 @@ void QGL_EnableLogging( qboolean enable ) asctime( newtime ); Com_sprintf( buffer, sizeof( buffer ), "%s/qgl.log", - cvar.VariableString( "basedir" ) ); + Cvar_VariableString( "basedir" ) ); log_fp = fopen( buffer, "w" ); if( !log_fp ) { return; diff --git a/source/r_bsp.c b/source/r_bsp.c deleted file mode 100644 index b1a499b..0000000 --- a/source/r_bsp.c +++ /dev/null @@ -1,664 +0,0 @@ -/* -Copyright (C) 2003-2006 Andrey Nazarov - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -// -// r_bsp.c -- map loading functions common for both renderers -// - -#include <config.h> -#include "q_shared.h" -#include "com_public.h" -#include "q_files.h" -#include "q_list.h" -#include "r_shared.h" - -bspModel_t r_world; - -bspLeaf_t *Bsp_FindLeaf( vec3_t origin ) { - bspNode_t *node; - cplane_t *plane; - vec_t dot; - - node = r_world.nodes; - do { - plane = node->plane; - dot = DotProduct( plane->normal, origin ) - plane->dist; - if( dot >= 0 ) { - node = node->children[0]; - } else { - node = node->children[1]; - } - } while( node->plane ); - - return ( bspLeaf_t * )node; -} - -byte *Bsp_ClusterPVS( int clusterNum ) { - if( !r_world.vis || clusterNum == -1 ) { - return NULL; - } - - return r_world.vis + clusterNum * r_world.rowsize; -} - - -/* ========================================================================= */ - -#define Bsp_Malloc( size ) sys.HunkAlloc( &r_world.pool, size ) - -static byte *loadData; - -static void Bsp_DecompressVis( byte *src, byte *dst, unsigned rowsize ) { - unsigned count; - - do { - if( *src ) { - *dst++ = *src++; - rowsize--; - } else { - src++; count = *src++; - if( count > rowsize ) { - Com_WPrintf( "Bsp_DecompressVis: overrun\n" ); - count = rowsize; - } - rowsize -= count; - while( count-- ) { - *dst++ = 0; - } - } - } while( rowsize ); -} - -static void Bsp_LoadVis( lump_t *lump ) { - dvis_t *src_vis; - byte *dst, *src; - uint32_t numClusters, rowsize; - uint32_t offset; - int i; - - if( !lump->filelen ) { - r_world.vis = NULL; - r_world.numClusters = 0; - return; - } - - src_vis = ( dvis_t * )( loadData + lump->fileofs ); - numClusters = LittleLong( src_vis->numclusters ); - if( !numClusters ) { - r_world.vis = 0; - r_world.numClusters = 0; - return; // it is OK to have a map without vis - } - if( numClusters > MAX_MAP_LEAFS/8 ) { - Com_Error( ERR_DROP, "%s: too many clusters", __func__ ); - } - - rowsize = ( numClusters + 7 ) >> 3; - r_world.numClusters = numClusters; - r_world.rowsize = rowsize; - r_world.vis = Bsp_Malloc( numClusters * rowsize ); - - dst = r_world.vis; - for( i = 0; i < numClusters; i++ ) { - offset = LittleLong( src_vis->bitofs[i][DVIS_PVS] ); - if( offset >= lump->filelen ) { - Com_Error( ERR_DROP, "%s: bad offset", __func__ ); - } - - src = ( byte * )src_vis + offset; - Bsp_DecompressVis( src, dst, rowsize ); - dst += rowsize; - } -} - -static void Bsp_LoadVertices( lump_t *lump ) { - int i, count; - dvertex_t *src, *dst; - - count = lump->filelen / sizeof( *src ); - if( lump->filelen % sizeof( *src ) ) { - Com_Error( ERR_DROP, "%s: bad lump size", __func__ ); - } - - r_world.vertices = Bsp_Malloc( ( count + EXTRA_VERTICES ) * sizeof( *dst ) ); - r_world.numVertices = count; - - src = ( dvertex_t * )( loadData + lump->fileofs ); - dst = r_world.vertices; - for( i = 0; i < count; i++ ) { - dst->point[0] = LittleFloat( src->point[0] ); - dst->point[1] = LittleFloat( src->point[1] ); - dst->point[2] = LittleFloat( src->point[2] ); - - src++; dst++; - } -} - -static void Bsp_LoadEdges( lump_t *lump ) { - int i, count; - dedge_t *src, *dst; - - count = lump->filelen / sizeof( *src ); - if( lump->filelen % sizeof( *src ) ) { - Com_Error( ERR_DROP, "%s: bad lump size", __func__ ); - } - - r_world.edges = Bsp_Malloc( ( count + EXTRA_EDGES ) * sizeof( *dst ) ); - r_world.numEdges = count; - - src = ( dedge_t * )( loadData + lump->fileofs ); - dst = r_world.edges; - for( i = 0; i < count; i++ ) { - dst->v[0] = LittleShort( src->v[0] ); - dst->v[1] = LittleShort( src->v[1] ); - - src++; dst++; - } -} - -static void Bsp_LoadSurfEdges( lump_t *lump ) { - int i, count; - int *src, *dst; - - count = lump->filelen / sizeof( *src ); - if( lump->filelen % sizeof( *src ) ) { - Com_Error( ERR_DROP, "%s: bad lump size", __func__ ); - } - - r_world.surfEdges = Bsp_Malloc( ( count + EXTRA_SURFEDGES ) * sizeof( *dst ) ); - r_world.numSurfEdges = count; - - src = ( int * )( loadData + lump->fileofs ); - dst = r_world.surfEdges; - for( i = 0; i < count; i++ ) { - *dst++ = LittleLong( *src++ ); - } -} - -static void Bsp_LoadTexinfo( lump_t *lump ) { - int i, count; - texinfo_t *src; - bspTexinfo_t *dst, *tex; - image_t *texture; - char path[MAX_QPATH]; - int animNext; - - count = lump->filelen / sizeof( *src ); - if( lump->filelen % sizeof( *src ) ) { - Com_Error( ERR_DROP, "%s: bad lump size", __func__ ); - } - - r_world.numTexinfos = count; - r_world.texinfos = Bsp_Malloc( sizeof( *dst ) * count ); - - src = ( texinfo_t * )( loadData + lump->fileofs ); - dst = r_world.texinfos; - for( i = 0; i < count; i++ ) { - Q_strncpyz( dst->name, src->texture, sizeof( dst->name ) ); - dst->flags = LittleLong( src->flags ); - - dst->axis[0][0] = LittleFloat( src->vecs[0][0] ); - dst->axis[0][1] = LittleFloat( src->vecs[0][1] ); - dst->axis[0][2] = LittleFloat( src->vecs[0][2] ); - - dst->axis[1][0] = LittleFloat( src->vecs[1][0] ); - dst->axis[1][1] = LittleFloat( src->vecs[1][1] ); - dst->axis[1][2] = LittleFloat( src->vecs[1][2] ); - - dst->offset[0] = LittleFloat( src->vecs[0][3] ); - dst->offset[1] = LittleFloat( src->vecs[1][3] ); - -#ifdef OPENGL_RENDERER - upload_texinfo = dst; -#endif - - animNext = LittleLong( src->nexttexinfo ); - if( animNext > 0 ) { - if( animNext >= count ) { - Com_Error( ERR_DROP, "%s: bad anim chain", __func__ ); - } - dst->animNext = r_world.texinfos + animNext; - } else { - dst->animNext = NULL; - } - - Q_concat( path, sizeof( path ), "textures/", dst->name, ".wal", NULL ); - texture = R_FindImage( path, it_wall ); - if( texture ) { - dst->image = texture; - } else { - dst->image = r_notexture; - } - -#ifdef OPENGL_RENDERER - upload_texinfo = NULL; -#endif - - src++; dst++; - } - - dst = r_world.texinfos; - for( i = 0; i < count; i++ ) { - dst->numFrames = 1; - for( tex = dst->animNext; tex && tex != dst; tex = tex->animNext ) { - dst->numFrames++; - } - dst++; - } -} - -static void Bsp_LoadFaces( lump_t *lump ) { - dface_t *src_face; - bspSurface_t *dst_face; - int i, j, count; - uint16_t texinfoNum; - uint32_t lightmapOffset; - uint32_t firstEdge; - uint16_t numEdges; - uint16_t planeNum; - - count = lump->filelen / sizeof( *src_face ); - if( lump->filelen % sizeof( *src_face ) ) { - Com_Error( ERR_DROP, "%s: bad lump size", __func__ ); - } - - r_world.surfaces = Bsp_Malloc( ( count + EXTRA_SURFACES ) * sizeof( *dst_face ) ); - r_world.numSurfaces = count; - - src_face = ( dface_t * )( loadData + lump->fileofs ); - dst_face = r_world.surfaces; - for( i = 0; i < count; i++ ) { - firstEdge = LittleLong( src_face->firstedge ); - numEdges = LittleShort( src_face->numedges ); - if( numEdges < 3 ) { - Com_Error( ERR_DROP, "%s: bad surfedges", __func__ ); - } - if( firstEdge + numEdges > r_world.numSurfEdges ) { - Com_Error( ERR_DROP, "%s: surfedges out of bounds", __func__ ); - } - - planeNum = LittleShort( src_face->planenum ); - if( planeNum >= r_world.numPlanes ) { - Com_Error( ERR_DROP, "%s: bad planenum", __func__ ); - } - - texinfoNum = LittleShort( src_face->texinfo ); - if( texinfoNum >= r_world.numTexinfos ) { - Com_Error( ERR_DROP, "%s: bad texinfo", __func__ ); - } - - lightmapOffset = LittleLong( src_face->lightofs ); - if( lightmapOffset == ( uint32_t )-1 || r_world.lightmapSize == 0 ) { - dst_face->lightmap = NULL; - } else { - if( lightmapOffset >= r_world.lightmapSize ) { - Com_Error( ERR_DROP, "%s: bad lightofs", __func__ ); - } - dst_face->lightmap = r_world.lightmap + lightmapOffset; - } - - dst_face->texinfo = r_world.texinfos + texinfoNum; - j = LittleShort( src_face->side ); - dst_face->side = j & 1; - dst_face->index = i; - dst_face->type = DSURF_POLY; - dst_face->plane = r_world.planes + planeNum; - dst_face->firstSurfEdge = r_world.surfEdges + firstEdge; - dst_face->numSurfEdges = numEdges; - - src_face++; dst_face++; - } -} - -static void Bsp_LoadLeafFaces( lump_t *lump ) { - int i, count; - uint32_t faceNum; - uint16_t *src; - bspSurface_t **dst; - - count = lump->filelen / sizeof( *src ); - if( lump->filelen % sizeof( *src ) ) { - Com_Error( ERR_DROP, "%s: bad lump size", __func__ ); - } - - r_world.numLeafFaces = count; - r_world.leafFaces = Bsp_Malloc( sizeof( *dst ) * count ); - - src = ( uint16_t * )( loadData + lump->fileofs ); - dst = r_world.leafFaces; - for( i = 0; i < count; i++ ) { - faceNum = LittleShort( *src ); - if( faceNum >= r_world.numSurfaces ) { - Com_Error( ERR_DROP, "%s: bad face index\n", __func__ ); - } - *dst = r_world.surfaces + faceNum; - - src++; dst++; - } -} - -static void Bsp_LoadLeafs( lump_t *lump ) { - int i, count; - uint16_t cluster, area; - uint16_t firstLeafFace, numLeafFaces; - dleaf_t *src; - bspLeaf_t *dst; - - count = lump->filelen / sizeof( *src ); - if( lump->filelen % sizeof( *src ) ) { - Com_Error( ERR_DROP, "%s: bad lump size", __func__ ); - } - - r_world.numLeafs = count; - r_world.leafs = Bsp_Malloc( sizeof( *dst ) * count ); - - src = ( dleaf_t * )( loadData + lump->fileofs ); - dst = r_world.leafs; - for( i = 0; i < count; i++ ) { - dst->index = i; - dst->plane = NULL; - dst->parent = NULL; - dst->visframe = -1; - - area = LittleShort( src->area ); - if( area >= MAX_MAP_AREAS ) { - Com_Error( ERR_DROP, "%s: bad area num", __func__ ); - } - dst->area = area; - dst->contents = LittleLong( src->contents ); - - cluster = LittleShort( src->cluster ); - if( cluster == ( uint16_t )-1 || r_world.numClusters == 0 ) { - dst->cluster = -1; - } else { - if( cluster >= r_world.numClusters ) { - Com_Error( ERR_DROP, "%s: bad cluster num", __func__ ); - } - dst->cluster = cluster; - } - - firstLeafFace = LittleShort( src->firstleafface ); - numLeafFaces = LittleShort( src->numleaffaces ); - - if( firstLeafFace + numLeafFaces > r_world.numLeafFaces ) { - Com_Error( ERR_DROP, "%s: bad leafface", __func__ ); - } - - dst->firstLeafFace = r_world.leafFaces + firstLeafFace; - dst->numLeafFaces = numLeafFaces; - - LSV( mins ); - LSV( maxs ); - - src++; dst++; - } -} - -static void Bsp_LoadPlanes( lump_t *lump ) { - int i, count; - dplane_t *src; - cplane_t *dst; - - count = lump->filelen / sizeof( *src ); - if( lump->filelen % sizeof( *src ) ) { - Com_Error( ERR_DROP, "%s: bad lump size", __func__ ); - } - - r_world.numPlanes = count; - r_world.planes = Bsp_Malloc( sizeof( *dst ) * count ); - - src = ( dplane_t * )( loadData + lump->fileofs ); - dst = r_world.planes; - for( i = 0; i < count; i++ ) { - LV( normal ); - LF( dist ); - SetPlaneType( dst ); - SetPlaneSignbits( dst ); - - src++; dst++; - } -} - -static void Bsp_LoadNodes( lump_t *lump ) { - int i, j, count; - uint32_t planenum; - uint32_t child; - dnode_t *src; - bspNode_t *dst; - uint16_t firstFace, numFaces; - - count = lump->filelen / sizeof( *src ); - if( lump->filelen % sizeof( *src ) ) { - Com_Error( ERR_DROP, "%s: bad lump size", __func__ ); - } - - r_world.numNodes = count; - r_world.nodes = Bsp_Malloc( sizeof( *dst ) * count ); - - src = ( dnode_t * )( loadData + lump->fileofs ); - dst = r_world.nodes; - for( i = 0; i < count; i++ ) { - dst->index = i; - dst->parent = NULL; - dst->visframe = -1; - - // load splitting plane index - planenum = LittleLong( src->planenum ); - if( planenum >= r_world.numPlanes ) { - Com_Error( ERR_DROP, "%s: bad planenum for node %d", __func__, i ); - } - dst->plane = r_world.planes + planenum; - - // load children indices - for( j = 0; j < 2; j++ ) { - child = LittleLong( src->children[j] ); - if( child & 0x80000000 ) { - // leaf index - child = ~child; - if( child >= r_world.numLeafs ) { - Com_Error( ERR_DROP, "%s: bad leafnum for node %d", __func__, i ); - } - dst->children[j] = ( bspNode_t * )( r_world.leafs + child ); - } else { - // node index - if( child >= count ) { - Com_Error( ERR_DROP, "%s: bad nodenum for node %d", __func__, i ); - } - dst->children[j] = r_world.nodes + child; - } - } - - firstFace = LittleShort( src->firstface ); - numFaces = LittleShort( src->numfaces ); - - if( firstFace + numFaces > r_world.numSurfaces ) { - Com_Error( ERR_DROP, "%s: bad faces for node %d", __func__, i ); - } - - dst->firstFace = r_world.surfaces + firstFace; - dst->numFaces = numFaces; - - LSV( mins ); - LSV( maxs ); - - src++; dst++; - } -} - -static void Bsp_LoadLightMap( lump_t *lump ) { - if( !lump->filelen ) { - return; - } - - r_world.lightmap = Bsp_Malloc( lump->filelen ); - memcpy( r_world.lightmap, loadData + lump->fileofs, lump->filelen ); - r_world.lightmapSize = lump->filelen; -} - -static void Bsp_LoadSubmodels( lump_t *lump ) { - int i, count; - dmodel_t *src; - bspSubmodel_t *dst; - uint32_t firstFace, numFaces; - uint32_t headnode; - - count = lump->filelen / sizeof( *src ); - if( lump->filelen % sizeof( *src ) ) { - Com_Error( ERR_DROP, "%s: bad lump size", __func__ ); - } - - r_world.numSubmodels = count; - r_world.submodels = Bsp_Malloc( sizeof( *dst ) * count ); - - src = ( dmodel_t * )( loadData + lump->fileofs ); - dst = r_world.submodels; - for( i = 0; i < count; i++ ) { - firstFace = LittleLong( src->firstface ); - numFaces = LittleLong( src->numfaces ); - if( firstFace + numFaces > r_world.numSurfaces ) { - Com_Error( ERR_DROP, "%s: bad faces for model %d", __func__, i ); - } - - headnode = LittleLong( src->headnode ); - if( headnode >= r_world.numNodes ) { - // FIXME: headnode may be garbage for some models - Com_DPrintf( "%s: bad headnode for model %d", __func__, i ); - dst->headnode = NULL; - } else { - dst->headnode = r_world.nodes + headnode; - } - - dst->type = MODEL_BSP; - dst->firstFace = r_world.surfaces + firstFace; - dst->numFaces = numFaces; - - LV( mins ); - LV( maxs ); - LV( origin ); - - dst->radius = RadiusFromBounds( dst->mins, dst->maxs ); - - src++; dst++; - } -} - - -static void Bsp_SetParent( bspNode_t *node ) { - bspNode_t *child; - - while( node->plane ) { - child = node->children[0]; - child->parent = node; - Bsp_SetParent( child ); - - child = node->children[1]; - child->parent = node; - node = child; - } - -} - -void Bsp_FreeWorld( void ) { - if( r_world.name[0] ) { - sys.HunkFree( &r_world.pool ); - memset( &r_world, 0, sizeof( r_world ) ); - } -} - -void Bsp_LoadWorld( const char *path ) { - dheader_t header; - lump_t *lump; - int i; - byte *data; - size_t length, endpos; - - length = fs.LoadFile( path, ( void ** )&data ); - if( !data ) { - Com_Error( ERR_DROP, "%s: couldn't load %s", __func__, path ); - } - - if( length < sizeof( header ) ) { - Com_Error( ERR_DROP, "%s: %s is too small", __func__, path ); - } - - // byte swap and validate the header - header = *( dheader_t * )data; - header.ident = LittleLong( header.ident ); - header.version = LittleLong( header.version ); - if( header.ident != IDBSPHEADER ) { - Com_Error( ERR_DROP, "%s: %s is not an IBSP file", __func__, path ); - } - if( header.version != BSPVERSION ) { - Com_Error( ERR_DROP, "%s: %s has wrong IBSP version", __func__, path ); - } - - // byte swap and validate lumps - for( i = 0, lump = header.lumps; i < HEADER_LUMPS; i++, lump++ ) { - lump->fileofs = LittleLong( lump->fileofs ); - lump->filelen = LittleLong( lump->filelen ); - endpos = lump->fileofs + lump->filelen; - if( endpos < lump->fileofs || endpos > length ) { - Com_Error( ERR_DROP, "%s: %s has lump #%d out of bounds\n", - __func__, path, i ); - } - } - - loadData = data; - - // reserve 16 MB of virtual memory - sys.HunkBegin( &r_world.pool, 0x1000000 ); - -#ifdef OPENGL_RENDERER - GL_BeginPostProcessing(); -#endif - -#define LOAD( Func, Lump ) do { \ - Bsp_Load##Func( &header.lumps[LUMP_##Lump] ); \ - } while( 0 ) - - LOAD( Vis, VISIBILITY ); - LOAD( Vertices, VERTEXES ); - LOAD( Edges, EDGES ); - LOAD( SurfEdges, SURFEDGES ); - LOAD( Texinfo, TEXINFO ); - LOAD( LightMap, LIGHTING ); - LOAD( Planes, PLANES ); - LOAD( Faces, FACES ); - LOAD( LeafFaces, LEAFFACES ); - LOAD( Leafs, LEAFS ); - LOAD( Nodes, NODES ); - LOAD( Submodels, MODELS ); - -#undef LOAD - -#ifdef OPENGL_RENDERER - GL_EndPostProcessing(); -#endif - - fs.FreeFile( data ); - - sys.HunkEnd( &r_world.pool ); - - Bsp_SetParent( r_world.nodes ); - - strcpy( r_world.name, path ); -} - - diff --git a/source/r_images.c b/source/r_images.c index 5b92392..4c873bf 100644 --- a/source/r_images.c +++ b/source/r_images.c @@ -1,5 +1,5 @@ /* -Copyright (C) 2003-2006 Andrey Nazarov +Copyright (C) 2003-2008 Andrey Nazarov Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or @@ -23,13 +23,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // images.c -- image reading and writing functions // -#include "config.h" +#include "com_local.h" #if USE_PNG #include <png.h> #endif -#if USE_JPEG +#if USE_JPG #if !USE_PNG #include <setjmp.h> #endif @@ -37,10 +37,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include <jpeglib.h> #endif -#include "q_shared.h" -#include "com_public.h" -#include "q_files.h" #include "q_list.h" +#include "files.h" +#include "sys_public.h" #include "r_shared.h" /* @@ -51,189 +50,185 @@ PCX LOADING ================================================================= */ -// FIXME: get rid of this -#ifdef SOFTWARE_RENDERER -#define PCX_ALLOC( x ) R_Malloc( x ) -#define PCX_FREE( x ) com.Free( x ) -#else -#define PCX_ALLOC( x ) fs.AllocTempMem( w * h ) -#define PCX_FREE( x ) fs.FreeFile( x ) -#endif +#include "d_pcx.h" /* ============== -Image_LoadPCX +IMG_LoadPCX ============== */ -void Image_LoadPCX( const char *filename, byte **pic, byte *palette, int *width, int *height ) { - byte *raw, *end; - pcx_t *pcx; - size_t len, x, y, w, h; - int dataByte, runLength; - byte *out, *pix; - - if( !filename || !pic ) { - Com_Error( ERR_FATAL, "LoadPCX: NULL" ); - } - - *pic = NULL; +qboolean IMG_LoadPCX( const char *filename, byte **pic, byte *palette, int *width, int *height ) { + byte *raw, *end; + dpcx_t *pcx; + size_t len, x, y, w, h; + int dataByte, runLength; + byte *out, *pix; + + if( !filename ) { + Com_Error( ERR_FATAL, "LoadPCX: NULL" ); + } + if( pic ) { + *pic = NULL; + } - // - // load the file - // - len = fs.LoadFile( filename, (void **)&pcx ); - if( !pcx ) { - return; - } + // + // load the file + // + len = FS_LoadFile( filename, (void **)&pcx ); + if( !pcx ) { + return qfalse; + } if( len < sizeof( *pcx ) ) { - Com_WPrintf( "LoadPCX: %s: file too short\n", filename ); + Com_WPrintf( "LoadPCX: %s: file too short\n", filename ); goto fail2; } - // - // parse the PCX file - // - + // + // parse the PCX file + // w = LittleShort( pcx->xmax ) + 1; h = LittleShort( pcx->ymax ) + 1; - - if( pcx->manufacturer != 0x0a - || pcx->version != 5 - || pcx->encoding != 1 - || pcx->bits_per_pixel != 8 - || w > 640 - || h > 480 ) - { - Com_WPrintf( "LoadPCX: %s: unsupported format\n", filename ); + if( pcx->manufacturer != 0x0a || pcx->version != 5 + || pcx->encoding != 1 || pcx->bits_per_pixel != 8 + || w > 640 || h > 480 ) + { + Com_WPrintf( "LoadPCX: %s: unsupported format\n", filename ); goto fail2; - } - - pix = out = PCX_ALLOC( w * h ); + } - if( palette ) { + // + // get palette + // + if( palette ) { if( len < 768 ) { - Com_WPrintf( "LoadPCX: %s: palette too short\n", filename ); - goto fail1; + Com_WPrintf( "LoadPCX: %s: palette too short\n", filename ); + goto fail2; } - memcpy( palette, ( byte * )pcx + len - 768, 768 ); - } + memcpy( palette, ( byte * )pcx + len - 768, 768 ); + } - raw = pcx->data; - end = ( byte * )pcx + len; + // + // get pixels + // + if( pic ) { + pix = out = IMG_AllocPixels( w * h ); - for( y = 0; y < h; y++, pix += w ) { - for( x = 0; x < w; ) { - if( raw >= end ) { - Com_WPrintf( "LoadPCX: %s: read past end of file\n", filename ); - goto fail1; - } - dataByte = *raw++; + raw = pcx->data; + end = ( byte * )pcx + len; - if( ( dataByte & 0xC0 ) == 0xC0 ) { - runLength = dataByte & 0x3F; - if( x + runLength > w ) { - Com_WPrintf( "LoadPCX: %s: run length overrun\n", filename ); - goto fail1; - } + for( y = 0; y < h; y++, pix += w ) { + for( x = 0; x < w; ) { if( raw >= end ) { - Com_WPrintf( "LoadPCX: %s: read past end of file\n", filename ); + Com_WPrintf( "LoadPCX: %s: read past end of file\n", filename ); goto fail1; } - dataByte = *raw++; - while( runLength-- ) { + dataByte = *raw++; + + if( ( dataByte & 0xC0 ) == 0xC0 ) { + runLength = dataByte & 0x3F; + if( x + runLength > w ) { + Com_WPrintf( "LoadPCX: %s: run length overrun\n", filename ); + goto fail1; + } + if( raw >= end ) { + Com_WPrintf( "LoadPCX: %s: read past end of file\n", filename ); + goto fail1; + } + dataByte = *raw++; + while( runLength-- ) { + pix[x++] = dataByte; + } + } else { pix[x++] = dataByte; } - } else { - pix[x++] = dataByte; - } - - } - - } + } + } - if( width ) - *width = w; - if( height ) - *height = h; + *pic = out; + } - *pic = out; + if( width ) + *width = w; + if( height ) + *height = h; - fs.FreeFile( pcx ); - return; + FS_FreeFile( pcx ); + return qtrue; fail1: - PCX_FREE( out ); + IMG_FreePixels( out ); fail2: - fs.FreeFile( pcx ); + FS_FreeFile( pcx ); + return qfalse; } /* ============== -Image_WritePCX +IMG_WritePCX ============== */ -qboolean Image_WritePCX( const char *filename, const byte *data, int width, +qboolean IMG_WritePCX( const char *filename, const byte *data, int width, int height, int rowbytes, byte *palette ) { - int i, j, length; - pcx_t *pcx; - byte *pack; + int i, j, length; + dpcx_t *pcx; + byte *pack; qboolean ret = qfalse; fileHandle_t f; - pcx = fs.AllocTempMem( width * height * 2 + 1000 ); - pcx->manufacturer = 0x0a; // PCX id - pcx->version = 5; // 256 color - pcx->encoding = 1; // uncompressed - pcx->bits_per_pixel = 8; // 256 color - pcx->xmin = 0; - pcx->ymin = 0; - pcx->xmax = LittleShort( width - 1 ); - pcx->ymax = LittleShort( height - 1 ); - pcx->hres = LittleShort( width ); - pcx->vres = LittleShort( height ); - memset( pcx->palette, 0, sizeof( pcx->palette ) ); - pcx->color_planes = 1; // chunky image - pcx->bytes_per_line = LittleShort( width ); - pcx->palette_type = LittleShort( 2 ); // not a grey scale - memset( pcx->filler, 0, sizeof( pcx->filler ) ); + pcx = FS_AllocTempMem( width * height * 2 + 1000 ); + pcx->manufacturer = 0x0a; // PCX id + pcx->version = 5; // 256 color + pcx->encoding = 1; // uncompressed + pcx->bits_per_pixel = 8; // 256 color + pcx->xmin = 0; + pcx->ymin = 0; + pcx->xmax = LittleShort( width - 1 ); + pcx->ymax = LittleShort( height - 1 ); + pcx->hres = LittleShort( width ); + pcx->vres = LittleShort( height ); + memset( pcx->palette, 0, sizeof( pcx->palette ) ); + pcx->color_planes = 1; // chunky image + pcx->bytes_per_line = LittleShort( width ); + pcx->palette_type = LittleShort( 2 ); // not a grey scale + memset( pcx->filler, 0, sizeof( pcx->filler ) ); // pack the image - pack = pcx->data; - for( i = 0; i < height; i++) { - for( j = 0; j < width; j++) { - if( ( *data & 0xc0 ) == 0xc0 ) { - *pack++ = 0xc1; + pack = pcx->data; + for( i = 0; i < height; i++) { + for( j = 0; j < width; j++) { + if( ( *data & 0xc0 ) == 0xc0 ) { + *pack++ = 0xc1; } - *pack++ = *data++; - } - data += rowbytes - width; - } - + *pack++ = *data++; + } + data += rowbytes - width; + } + // write the palette - *pack++ = 0x0c; // palette ID byte - for( i = 0; i < 768; i++ ) - *pack++ = *palette++; - + *pack++ = 0x0c; // palette ID byte + for( i = 0; i < 768; i++ ) + *pack++ = *palette++; + // write output file - fs.FOpenFile( filename, &f, FS_MODE_WRITE ); - if( !f ) { + FS_FOpenFile( filename, &f, FS_MODE_WRITE ); + if( !f ) { goto fail; - } + } - length = pack - ( byte * )pcx; - if( fs.Write( pcx, length, f ) == length ) { + length = pack - ( byte * )pcx; + if( FS_Write( pcx, length, f ) == length ) { ret = qtrue; } - fs.FCloseFile( f ); + FS_FCloseFile( f ); fail: - fs.FreeFile( pcx ); + FS_FreeFile( pcx ); return ret; } -#ifdef TRUECOLOR_RENDERER +#if USE_TGA /* ========================================================= @@ -243,207 +238,201 @@ TARGA LOADING ========================================================= */ -static qboolean tga_decode_bgr( byte *data, byte *pixels, - int columns, int rows, byte *maxp ) -{ - int col, row; - uint32_t *pixbuf; +#define TGA_DECODE( x ) \ + static qboolean tga_decode_##x( byte *data, byte *pixels, \ + int columns, int rows, byte *maxp ) - for( row = rows - 1; row >= 0; row-- ) { - pixbuf = ( uint32_t * )pixels + row * columns; +typedef qboolean (*tga_decode_t)( byte *, byte *, int, int, byte * ); - for( col = 0; col < columns; col++ ) { - *pixbuf++ = MakeColor( data[2], data[1], data[0], 255 ); - data += 3; - } - } +TGA_DECODE( bgr ) { + int col, row; + uint32_t *pixbuf; - return qtrue; + for( row = rows - 1; row >= 0; row-- ) { + pixbuf = ( uint32_t * )pixels + row * columns; + + for( col = 0; col < columns; col++ ) { + *pixbuf++ = MakeColor( data[2], data[1], data[0], 255 ); + data += 3; + } + } + + return qtrue; } -static qboolean tga_decode_bgra( byte *data, byte *pixels, - int columns, int rows, byte *maxp ) -{ - int col, row; - uint32_t *pixbuf; +TGA_DECODE( bgra ) { + int col, row; + uint32_t *pixbuf; - for( row = rows - 1; row >= 0; row-- ) { - pixbuf = ( uint32_t * )pixels + row * columns; + for( row = rows - 1; row >= 0; row-- ) { + pixbuf = ( uint32_t * )pixels + row * columns; - for( col = 0; col < columns; col++ ) { - *pixbuf++ = MakeColor( data[2], data[1], data[0], data[3] ); - data += 4; - } - } + for( col = 0; col < columns; col++ ) { + *pixbuf++ = MakeColor( data[2], data[1], data[0], data[3] ); + data += 4; + } + } - return qtrue; + return qtrue; } -static qboolean tga_decode_bgr_flip( byte *data, byte *pixels, - int columns, int rows, byte *maxp ) -{ - int count; - uint32_t *pixbuf; +TGA_DECODE( bgr_flip ) { + int count; + uint32_t *pixbuf; - pixbuf = ( uint32_t * )pixels; - count = rows * columns; - do { - *pixbuf++ = MakeColor( data[2], data[1], data[0], 255 ); - data += 3; - } while( --count ); + pixbuf = ( uint32_t * )pixels; + count = rows * columns; + do { + *pixbuf++ = MakeColor( data[2], data[1], data[0], 255 ); + data += 3; + } while( --count ); - return qtrue; + return qtrue; } -static qboolean tga_decode_bgra_flip( byte *data, byte *pixels, - int columns, int rows, byte *maxp ) -{ - int count; - uint32_t *pixbuf; +TGA_DECODE( bgra_flip ) { + int count; + uint32_t *pixbuf; - pixbuf = ( uint32_t * )pixels; - count = rows * columns; - do { - *pixbuf++ = MakeColor( data[2], data[1], data[0], data[3] ); - data += 4; - } while( --count ); + pixbuf = ( uint32_t * )pixels; + count = rows * columns; + do { + *pixbuf++ = MakeColor( data[2], data[1], data[0], data[3] ); + data += 4; + } while( --count ); - return qtrue; + return qtrue; } -static qboolean tga_decode_bgr_rle( byte *data, byte *pixels, - int columns, int rows, byte *maxp ) -{ - int col, row; - uint32_t *pixbuf, color; - byte packetHeader, packetSize; - int j; - - for( row = rows - 1; row >= 0; row-- ) { - pixbuf = ( uint32_t * )pixels + row * columns; - - for( col = 0; col < columns; ) { - packetHeader = *data++; - packetSize = 1 + ( packetHeader & 0x7f ); - - if( packetHeader & 0x80 ) { - /* run-length packet */ - if( data + 3 > maxp ) { - return qfalse; - } - color = MakeColor( data[2], data[1], data[0], 255 ); - data += 3; - for( j = 0; j < packetSize; j++ ) { - *pixbuf++ = color; - - col++; - if( col == columns ) { - /* run spans across rows */ - col = 0; - - if( row > 0 ) - row--; - else - goto breakOut; - - pixbuf = ( uint32_t * )pixels + row * columns; - } - } - } else { - /* non run-length packet */ - if( data + 3 * packetSize > maxp ) { - return qfalse; - } - for( j = 0; j < packetSize; j++ ) { - *pixbuf++ = MakeColor( data[2], data[1], data[0], 255 ); - data += 3; - - col++; - if( col == columns ) { - /* run spans across rows */ - col = 0; - if( row > 0 ) - row--; - else - goto breakOut; - pixbuf = ( uint32_t * )pixels + row * columns; - } - } - } - } +TGA_DECODE( bgr_rle ) { + int col, row; + uint32_t *pixbuf, color; + byte packetHeader, packetSize; + int j; + + for( row = rows - 1; row >= 0; row-- ) { + pixbuf = ( uint32_t * )pixels + row * columns; + + for( col = 0; col < columns; ) { + packetHeader = *data++; + packetSize = 1 + ( packetHeader & 0x7f ); + + if( packetHeader & 0x80 ) { + /* run-length packet */ + if( data + 3 > maxp ) { + return qfalse; + } + color = MakeColor( data[2], data[1], data[0], 255 ); + data += 3; + for( j = 0; j < packetSize; j++ ) { + *pixbuf++ = color; + + col++; + if( col == columns ) { + /* run spans across rows */ + col = 0; + + if( row > 0 ) + row--; + else + goto breakOut; + + pixbuf = ( uint32_t * )pixels + row * columns; + } + } + } else { + /* non run-length packet */ + if( data + 3 * packetSize > maxp ) { + return qfalse; + } + for( j = 0; j < packetSize; j++ ) { + *pixbuf++ = MakeColor( data[2], data[1], data[0], 255 ); + data += 3; + + col++; + if( col == columns ) { + /* run spans across rows */ + col = 0; + if( row > 0 ) + row--; + else + goto breakOut; + pixbuf = ( uint32_t * )pixels + row * columns; + } + } + } + } breakOut: ; - } + } - return qtrue; + return qtrue; } -static qboolean tga_decode_bgra_rle( byte *data, byte *pixels, - int columns, int rows, byte *maxp ) -{ - int col, row; - uint32_t *pixbuf, color; - byte packetHeader, packetSize; - int j; - - for( row = rows - 1; row >= 0; row-- ) { - pixbuf = ( uint32_t * )pixels + row * columns; - - for( col = 0; col < columns; ) { - packetHeader = *data++; - packetSize = 1 + ( packetHeader & 0x7f ); - - if( packetHeader & 0x80 ) { - /* run-length packet */ - if( data + 4 > maxp ) { - return qfalse; - } - color = MakeColor( data[2], data[1], data[0], data[3] ); - data += 4; - for( j = 0; j < packetSize; j++ ) { - *pixbuf++ = color; - - col++; - if( col == columns ) { - /* run spans across rows */ - col = 0; - - if( row > 0 ) - row--; - else - goto breakOut; - - pixbuf = ( uint32_t * )pixels + row * columns; - } - } - } else { - /* non run-length packet */ - if( data + 4 * packetSize > maxp ) { - return qfalse; - } - for( j = 0; j < packetSize; j++ ) { - *pixbuf++ = MakeColor( data[2], data[1], data[0], data[3] ); - data += 4; - - col++; - if( col == columns ) { - /* run spans across rows */ - col = 0; - if( row > 0 ) - row--; - else - goto breakOut; - pixbuf = ( uint32_t * )pixels + row * columns; - } - } - } - } +TGA_DECODE( bgra_rle ) { + int col, row; + uint32_t *pixbuf, color; + byte packetHeader, packetSize; + int j; + + for( row = rows - 1; row >= 0; row-- ) { + pixbuf = ( uint32_t * )pixels + row * columns; + + for( col = 0; col < columns; ) { + packetHeader = *data++; + packetSize = 1 + ( packetHeader & 0x7f ); + + if( packetHeader & 0x80 ) { + /* run-length packet */ + if( data + 4 > maxp ) { + return qfalse; + } + color = MakeColor( data[2], data[1], data[0], data[3] ); + data += 4; + for( j = 0; j < packetSize; j++ ) { + *pixbuf++ = color; + + col++; + if( col == columns ) { + /* run spans across rows */ + col = 0; + + if( row > 0 ) + row--; + else + goto breakOut; + + pixbuf = ( uint32_t * )pixels + row * columns; + } + } + } else { + /* non run-length packet */ + if( data + 4 * packetSize > maxp ) { + return qfalse; + } + for( j = 0; j < packetSize; j++ ) { + *pixbuf++ = MakeColor( data[2], data[1], data[0], data[3] ); + data += 4; + + col++; + if( col == columns ) { + /* run spans across rows */ + col = 0; + if( row > 0 ) + row--; + else + goto breakOut; + pixbuf = ( uint32_t * )pixels + row * columns; + } + } + } + } breakOut: ; - } + } - return qtrue; + return qtrue; } @@ -454,115 +443,110 @@ breakOut: ; LoadTGA ============= */ -void Image_LoadTGA( const char *filename, byte **pic, - int *width, int *height ) -{ - byte *buffer; - size_t length; - byte *pixels; - int offset, w, h; - qboolean (*decode)( byte *, byte *, int, int, byte * ); - int id_length, image_type, pixel_size, attributes, bpp; - - if( !filename || !pic ) { - Com_Error( ERR_FATAL, "LoadTGA: NULL" ); - } +void IMG_LoadTGA( const char *filename, byte **pic, int *width, int *height ) { + byte *buffer; + size_t length; + byte *pixels; + int offset, w, h; + tga_decode_t decode; + int id_length, image_type, pixel_size, attributes, bpp; + + if( !filename || !pic ) { + Com_Error( ERR_FATAL, "LoadTGA: NULL" ); + } - *pic = NULL; + *pic = NULL; - // - // load the file - // - length = fs.LoadFile( filename, ( void ** )&buffer ); - if( !buffer ) { - return; - } + // + // load the file + // + length = FS_LoadFile( filename, ( void ** )&buffer ); + if( !buffer ) { + return; + } - if( length < TARGA_HEADER_SIZE ) { - Com_WPrintf( "LoadTGA: %s: file too small\n", filename ); - goto finish; - } + if( length < TARGA_HEADER_SIZE ) { + Com_WPrintf( "LoadTGA: %s: file too small\n", filename ); + goto finish; + } - id_length = buffer[0]; + id_length = buffer[0]; image_type = buffer[2]; w = MakeShort( buffer[12], buffer[13] ); h = MakeShort( buffer[14], buffer[15] ); - pixel_size = buffer[16]; + pixel_size = buffer[16]; attributes = buffer[17]; - - // skip TARGA image comment - offset = TARGA_HEADER_SIZE + id_length; - if( offset + 4 > length ) { - Com_WPrintf( "LoadTGA: %s: offset out of range\n", filename ); - goto finish; - } + + // skip TARGA image comment + offset = TARGA_HEADER_SIZE + id_length; + if( offset + 4 > length ) { + Com_WPrintf( "LoadTGA: %s: offset out of range\n", filename ); + goto finish; + } - if( pixel_size == 32 ) { - bpp = 4; - } else if( pixel_size == 24 ) { - bpp = 3; - } else { - Com_WPrintf( "LoadTGA: %s: only 32 and 24 bit targa RGB " - "images supported, this one is %d bit\n", + if( pixel_size == 32 ) { + bpp = 4; + } else if( pixel_size == 24 ) { + bpp = 3; + } else { + Com_WPrintf( "LoadTGA: %s: only 32 and 24 bit targa RGB " + "images supported, this one is %d bit\n", filename, pixel_size ); - goto finish; - } - - if( w < 1 || h < 1 || w > MAX_TEXTURE_SIZE || h > MAX_TEXTURE_SIZE ) { - Com_WPrintf( "LoadTGA: %s: bad dimensions: %dx%d\n", - filename, w, h ); - goto finish; - } - - if( image_type == 2 ) { - if( offset + w * h * bpp > length ) { - Com_WPrintf( "LoadTGA: %s: malformed targa image\n", filename ); - goto finish; - } - if( attributes & 32 ) { - if( pixel_size == 32 ) { - decode = tga_decode_bgra_flip; - } else { - decode = tga_decode_bgr_flip; - } - } else { - if( pixel_size == 32 ) { - decode = tga_decode_bgra; - } else { - decode = tga_decode_bgr; - } - } - } else if( image_type == 10 ) { - if( attributes & 32 ) { - Com_WPrintf( "LoadTGA: %s: vertically flipped, RLE encoded " - "images are not supported\n", filename ); - goto finish; - } - if( pixel_size == 32 ) { - decode = tga_decode_bgra_rle; - } else { - decode = tga_decode_bgr_rle; - } - } else { - Com_WPrintf( "LoadTGA: %s: only type 2 and 10 targa RGB " - "images supported, this one is %d\n", - filename, image_type ); - goto finish; - } + goto finish; + } - pixels = fs.AllocTempMem( w * h * 4 ); + if( w < 1 || h < 1 || w > MAX_TEXTURE_SIZE || h > MAX_TEXTURE_SIZE ) { + Com_WPrintf( "LoadTGA: %s: bad dimensions: %dx%d\n", + filename, w, h ); + goto finish; + } - if( (*decode)( buffer + offset, pixels, w, h, buffer + length ) == qfalse ) { - fs.FreeFile( pixels ); - goto finish; - } + if( image_type == 2 ) { + if( offset + w * h * bpp > length ) { + Com_WPrintf( "LoadTGA: %s: malformed targa image\n", filename ); + goto finish; + } + if( attributes & 32 ) { + if( pixel_size == 32 ) { + decode = tga_decode_bgra_flip; + } else { + decode = tga_decode_bgr_flip; + } + } else { + if( pixel_size == 32 ) { + decode = tga_decode_bgra; + } else { + decode = tga_decode_bgr; + } + } + } else if( image_type == 10 ) { + if( attributes & 32 ) { + Com_WPrintf( "LoadTGA: %s: vertically flipped, RLE encoded " + "images are not supported\n", filename ); + goto finish; + } + if( pixel_size == 32 ) { + decode = tga_decode_bgra_rle; + } else { + decode = tga_decode_bgr_rle; + } + } else { + Com_WPrintf( "LoadTGA: %s: only type 2 and 10 targa RGB " + "images supported, this one is %d\n", + filename, image_type ); + goto finish; + } - *pic = pixels; - *width = w; - *height = h; - + pixels = IMG_AllocPixels( w * h * 4 ); + if( decode( buffer + offset, pixels, w, h, buffer + length ) ) { + *pic = pixels; + *width = w; + *height = h; + } else { + IMG_FreePixels( pixels ); + } finish: - fs.FreeFile( buffer ); + FS_FreeFile( buffer ); } /* @@ -575,46 +559,45 @@ TARGA WRITING /* ================= -Image_WriteTGA +IMG_WriteTGA ================= */ -qboolean Image_WriteTGA( const char *filename, const byte *bgr, - int width, int height ) -{ - int length; - fileHandle_t f; - byte header[TARGA_HEADER_SIZE]; +qboolean IMG_WriteTGA( const char *filename, const byte *bgr, int width, int height ) { + int length; + fileHandle_t f; + byte header[TARGA_HEADER_SIZE]; - fs.FOpenFile( filename, &f, FS_MODE_WRITE ); - if( !f ) { - return qfalse; - } + FS_FOpenFile( filename, &f, FS_MODE_WRITE ); + if( !f ) { + return qfalse; + } memset( &header, 0, sizeof( header ) ); - header[ 2] = 2; // uncompressed type - header[12] = width & 255; + header[ 2] = 2; // uncompressed type + header[12] = width & 255; header[13] = width >> 8; - header[14] = height & 255; + header[14] = height & 255; header[15] = height >> 8; - header[16] = 24; // pixel size + header[16] = 24; // pixel size - if( fs.Write( &header, sizeof( header ), f ) != sizeof( header ) ) { + if( FS_Write( &header, sizeof( header ), f ) != sizeof( header ) ) { goto fail; } - length = width * height * 3; - if( fs.Write( bgr, length, f ) != length ) { + length = width * height * 3; + if( FS_Write( bgr, length, f ) != length ) { goto fail; } - fs.FCloseFile( f ); - return qtrue; + FS_FCloseFile( f ); + return qtrue; fail: - fs.FCloseFile( f ); - return qfalse; + FS_FCloseFile( f ); + return qfalse; } +#endif // USE_TGA /* ========================================================= @@ -624,17 +607,17 @@ JPEG LOADING ========================================================= */ -#if USE_JPEG +#if USE_JPG typedef struct my_error_mgr { - struct jpeg_error_mgr pub; - jmp_buf setjmp_buffer; + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; const char *filename; } *my_error_ptr; METHODDEF( void )my_output_message( j_common_ptr cinfo ) { char buffer[JMSG_LENGTH_MAX]; - my_error_ptr myerr = ( my_error_ptr )cinfo->err; + my_error_ptr myerr = ( my_error_ptr )cinfo->err; (*cinfo->err->format_message)( cinfo, buffer ); @@ -642,50 +625,50 @@ METHODDEF( void )my_output_message( j_common_ptr cinfo ) { } METHODDEF( void )my_error_exit( j_common_ptr cinfo ) { - my_error_ptr myerr = ( my_error_ptr )cinfo->err; + my_error_ptr myerr = ( my_error_ptr )cinfo->err; - (*cinfo->err->output_message)( cinfo ); + (*cinfo->err->output_message)( cinfo ); - longjmp( myerr->setjmp_buffer, 1 ); + longjmp( myerr->setjmp_buffer, 1 ); } METHODDEF( void )mem_init_source( j_decompress_ptr cinfo ) { } METHODDEF( boolean )mem_fill_input_buffer( j_decompress_ptr cinfo ) { - my_error_ptr jerr = ( my_error_ptr )cinfo->err; + my_error_ptr jerr = ( my_error_ptr )cinfo->err; - longjmp( jerr->setjmp_buffer, 1 ); - return TRUE; + longjmp( jerr->setjmp_buffer, 1 ); + return TRUE; } METHODDEF( void )mem_skip_input_data( j_decompress_ptr cinfo, long num_bytes ) { - struct jpeg_source_mgr *src = cinfo->src; - my_error_ptr jerr = ( my_error_ptr )cinfo->err; + struct jpeg_source_mgr *src = cinfo->src; + my_error_ptr jerr = ( my_error_ptr )cinfo->err; - if( src->bytes_in_buffer < num_bytes ) { - longjmp( jerr->setjmp_buffer, 1 ); - } - - src->next_input_byte += ( size_t )num_bytes; - src->bytes_in_buffer -= ( size_t )num_bytes; + if( src->bytes_in_buffer < num_bytes ) { + longjmp( jerr->setjmp_buffer, 1 ); + } + + src->next_input_byte += ( size_t )num_bytes; + src->bytes_in_buffer -= ( size_t )num_bytes; } METHODDEF( void )mem_term_source( j_decompress_ptr cinfo ) { } METHODDEF( void )jpeg_mem_src( j_decompress_ptr cinfo, byte *data, size_t size ) { - cinfo->src = ( struct jpeg_source_mgr * )(*cinfo->mem->alloc_small)( + cinfo->src = ( struct jpeg_source_mgr * )(*cinfo->mem->alloc_small)( ( j_common_ptr )cinfo, JPOOL_PERMANENT, sizeof( struct jpeg_source_mgr ) ); - cinfo->src->init_source = mem_init_source; - cinfo->src->fill_input_buffer = mem_fill_input_buffer; - cinfo->src->skip_input_data = mem_skip_input_data; - cinfo->src->resync_to_restart = jpeg_resync_to_restart; - cinfo->src->term_source = mem_term_source; - cinfo->src->bytes_in_buffer = size; - cinfo->src->next_input_byte = data; + cinfo->src->init_source = mem_init_source; + cinfo->src->fill_input_buffer = mem_fill_input_buffer; + cinfo->src->skip_input_data = mem_skip_input_data; + cinfo->src->resync_to_restart = jpeg_resync_to_restart; + cinfo->src->term_source = mem_term_source; + cinfo->src->bytes_in_buffer = size; + cinfo->src->next_input_byte = data; } /* @@ -693,83 +676,82 @@ METHODDEF( void )jpeg_mem_src( j_decompress_ptr cinfo, byte *data, size_t size ) LoadJPG ================= */ -void Image_LoadJPG( const char *filename, byte **pic, int *width, int *height ) { - struct jpeg_decompress_struct cinfo; - struct my_error_mgr jerr; - JSAMPARRAY buffer; - int row_stride; - byte *rawdata; - size_t rawlength; - byte *pixels; - byte *src; +void IMG_LoadJPG( const char *filename, byte **pic, int *width, int *height ) { + struct jpeg_decompress_struct cinfo; + struct my_error_mgr jerr; + JSAMPARRAY buffer; + int row_stride; + byte *rawdata; + size_t rawlength; + byte *pixels; + byte *src; uint32_t *dst; - int i; + int i; - if( !filename || !pic ) { - Com_Error( ERR_FATAL, "LoadJPG: NULL" ); - } + if( !filename || !pic ) { + Com_Error( ERR_FATAL, "LoadJPG: NULL" ); + } - *pic = NULL; - pixels = NULL; + *pic = pixels = NULL; - rawlength = fs.LoadFile( filename, ( void ** )&rawdata ); - if( !rawdata ) { - return; - } + rawlength = FS_LoadFile( filename, ( void ** )&rawdata ); + if( !rawdata ) { + return; + } - cinfo.err = jpeg_std_error( &jerr.pub ); - jerr.pub.error_exit = my_error_exit; - jerr.pub.output_message = my_output_message; + cinfo.err = jpeg_std_error( &jerr.pub ); + jerr.pub.error_exit = my_error_exit; + jerr.pub.output_message = my_output_message; jerr.filename = filename; - jpeg_create_decompress( &cinfo ); - - if( setjmp( jerr.setjmp_buffer ) ) { - jpeg_destroy_decompress( &cinfo ); - if( pixels ) { - fs.FreeFile( pixels ); - } - fs.FreeFile( rawdata ); - return; - } + jpeg_create_decompress( &cinfo ); + + if( setjmp( jerr.setjmp_buffer ) ) { + jpeg_destroy_decompress( &cinfo ); + if( pixels ) { + IMG_FreePixels( pixels ); + } + FS_FreeFile( rawdata ); + return; + } - jpeg_mem_src( &cinfo, rawdata, rawlength ); - jpeg_read_header( &cinfo, TRUE ); - jpeg_start_decompress( &cinfo ); - - if( cinfo.output_components != 3 /*&& cinfo.output_components != 4*/ ) { - Com_WPrintf( "LoadJPG: %s: unsupported number of color components: %i\n", - filename, cinfo.output_components ); - jpeg_destroy_decompress( &cinfo ); - fs.FreeFile( rawdata ); - return; - } + jpeg_mem_src( &cinfo, rawdata, rawlength ); + jpeg_read_header( &cinfo, TRUE ); + jpeg_start_decompress( &cinfo ); + + if( cinfo.output_components != 3 /*&& cinfo.output_components != 4*/ ) { + Com_WPrintf( "LoadJPG: %s: unsupported number of color components: %i\n", + filename, cinfo.output_components ); + jpeg_destroy_decompress( &cinfo ); + FS_FreeFile( rawdata ); + return; + } - *width = cinfo.output_width; - *height = cinfo.output_height; + *width = cinfo.output_width; + *height = cinfo.output_height; - pixels = fs.AllocTempMem( cinfo.output_width * cinfo.output_height * 4 ); + pixels = IMG_AllocPixels( cinfo.output_width * cinfo.output_height * 4 ); - row_stride = cinfo.output_width * cinfo.output_components; + row_stride = cinfo.output_width * cinfo.output_components; - buffer = (*cinfo.mem->alloc_sarray)( ( j_common_ptr )&cinfo, JPOOL_IMAGE, row_stride, 1 ); + buffer = (*cinfo.mem->alloc_sarray)( ( j_common_ptr )&cinfo, JPOOL_IMAGE, row_stride, 1 ); - dst = ( uint32_t * )pixels; - while( cinfo.output_scanline < cinfo.output_height ) { - jpeg_read_scanlines( &cinfo, buffer, 1 ); + dst = ( uint32_t * )pixels; + while( cinfo.output_scanline < cinfo.output_height ) { + jpeg_read_scanlines( &cinfo, buffer, 1 ); - src = ( byte * )buffer[0]; - for( i = 0; i < cinfo.output_width; i++, src += 3 ) { - *dst++ = MakeColor( src[0], src[1], src[2], 255 ); - } - } + src = ( byte * )buffer[0]; + for( i = 0; i < cinfo.output_width; i++, src += 3 ) { + *dst++ = MakeColor( src[0], src[1], src[2], 255 ); + } + } - jpeg_finish_decompress( &cinfo ); - jpeg_destroy_decompress( &cinfo ); + jpeg_finish_decompress( &cinfo ); + jpeg_destroy_decompress( &cinfo ); - fs.FreeFile( rawdata ); + FS_FreeFile( rawdata ); - *pic = pixels; + *pic = pixels; } @@ -781,129 +763,129 @@ JPEG WRITING ========================================================= */ -#define OUTPUT_BUF_SIZE 4096 +#define OUTPUT_BUF_SIZE 4096 typedef struct my_destination_mgr { - struct jpeg_destination_mgr pub; /* public fields */ + struct jpeg_destination_mgr pub; /* public fields */ - fileHandle_t hFile; /* target stream */ - JOCTET *buffer; /* start of buffer */ + fileHandle_t hFile; /* target stream */ + JOCTET *buffer; /* start of buffer */ } *my_dest_ptr; METHODDEF( void ) vfs_init_destination( j_compress_ptr cinfo ) { - my_dest_ptr dest = ( my_dest_ptr )cinfo->dest; + my_dest_ptr dest = ( my_dest_ptr )cinfo->dest; - /* Allocate the output buffer --- it will be released when done with image */ - dest->buffer = ( JOCTET * )(*cinfo->mem->alloc_small)( ( j_common_ptr )cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * sizeof( JOCTET ) ); + /* Allocate the output buffer --- it will be released when done with image */ + dest->buffer = ( JOCTET * )(*cinfo->mem->alloc_small)( ( j_common_ptr )cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * sizeof( JOCTET ) ); - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; } METHODDEF( boolean ) vfs_empty_output_buffer( j_compress_ptr cinfo ) { - my_dest_ptr dest = ( my_dest_ptr )cinfo->dest; - my_error_ptr jerr = ( my_error_ptr )cinfo->err; + my_dest_ptr dest = ( my_dest_ptr )cinfo->dest; + my_error_ptr jerr = ( my_error_ptr )cinfo->err; - if( fs.Write( dest->buffer, OUTPUT_BUF_SIZE, dest->hFile ) != OUTPUT_BUF_SIZE ) { - longjmp( jerr->setjmp_buffer, 1 ); - } + if( FS_Write( dest->buffer, OUTPUT_BUF_SIZE, dest->hFile ) != OUTPUT_BUF_SIZE ) { + longjmp( jerr->setjmp_buffer, 1 ); + } - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; - return TRUE; + return TRUE; } METHODDEF( void ) vfs_term_destination( j_compress_ptr cinfo ) { - my_dest_ptr dest = ( my_dest_ptr )cinfo->dest; - my_error_ptr jerr = ( my_error_ptr )cinfo->err; - int remaining = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; - - /* Write any data remaining in the buffer */ - if( remaining > 0 ) { - if( fs.Write( dest->buffer, remaining, dest->hFile ) != remaining ) { - longjmp( jerr->setjmp_buffer, 1 ); - } - } + my_dest_ptr dest = ( my_dest_ptr )cinfo->dest; + my_error_ptr jerr = ( my_error_ptr )cinfo->err; + int remaining = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + /* Write any data remaining in the buffer */ + if( remaining > 0 ) { + if( FS_Write( dest->buffer, remaining, dest->hFile ) != remaining ) { + longjmp( jerr->setjmp_buffer, 1 ); + } + } } METHODDEF( void ) jpeg_vfs_dst( j_compress_ptr cinfo, fileHandle_t hFile ) { - my_dest_ptr dest; + my_dest_ptr dest; - dest = ( my_dest_ptr )(*cinfo->mem->alloc_small)( ( j_common_ptr )cinfo, JPOOL_PERMANENT, sizeof( struct my_destination_mgr ) ); - cinfo->dest = &dest->pub; + dest = ( my_dest_ptr )(*cinfo->mem->alloc_small)( ( j_common_ptr )cinfo, JPOOL_PERMANENT, sizeof( struct my_destination_mgr ) ); + cinfo->dest = &dest->pub; - dest->pub.init_destination = vfs_init_destination; - dest->pub.empty_output_buffer = vfs_empty_output_buffer; - dest->pub.term_destination = vfs_term_destination; - dest->hFile = hFile; + dest->pub.init_destination = vfs_init_destination; + dest->pub.empty_output_buffer = vfs_empty_output_buffer; + dest->pub.term_destination = vfs_term_destination; + dest->hFile = hFile; } /* ================= -Image_WriteJPG +IMG_WriteJPG ================= */ -qboolean Image_WriteJPG( const char *filename, const byte *rgb, int width, int height, int quality ) { - struct jpeg_compress_struct cinfo; - struct my_error_mgr jerr; - fileHandle_t hFile; - JSAMPROW row_pointer[1]; - int row_stride; - - fs.FOpenFile( filename, &hFile, FS_MODE_WRITE ); - if( !hFile ) { - Com_DPrintf( "WriteJPG: %s: couldn't create file\n", filename ); - return qfalse; - } +qboolean IMG_WriteJPG( const char *filename, const byte *rgb, int width, int height, int quality ) { + struct jpeg_compress_struct cinfo; + struct my_error_mgr jerr; + fileHandle_t hFile; + JSAMPROW row_pointer[1]; + int row_stride; - cinfo.err = jpeg_std_error( &jerr.pub ); - jerr.pub.error_exit = my_error_exit; + FS_FOpenFile( filename, &hFile, FS_MODE_WRITE ); + if( !hFile ) { + Com_DPrintf( "WriteJPG: %s: couldn't create file\n", filename ); + return qfalse; + } - if( setjmp( jerr.setjmp_buffer ) ) { - Com_DPrintf( "WriteJPG: %s: JPEGLIB signaled an error\n", filename ); - jpeg_destroy_compress( &cinfo ); - fs.FCloseFile( hFile ); - return qfalse; - } + cinfo.err = jpeg_std_error( &jerr.pub ); + jerr.pub.error_exit = my_error_exit; - jpeg_create_compress( &cinfo ); + if( setjmp( jerr.setjmp_buffer ) ) { + Com_DPrintf( "WriteJPG: %s: JPEGLIB signaled an error\n", filename ); + jpeg_destroy_compress( &cinfo ); + FS_FCloseFile( hFile ); + return qfalse; + } - jpeg_vfs_dst( &cinfo, hFile ); + jpeg_create_compress( &cinfo ); - cinfo.image_width = width; // image width and height, in pixels - cinfo.image_height = height; - cinfo.input_components = 3; // # of color components per pixel - cinfo.in_color_space = JCS_RGB; // colorspace of input image + jpeg_vfs_dst( &cinfo, hFile ); - clamp( quality, 0, 100 ); + cinfo.image_width = width; // image width and height, in pixels + cinfo.image_height = height; + cinfo.input_components = 3; // # of color components per pixel + cinfo.in_color_space = JCS_RGB; // colorspace of input image - jpeg_set_defaults( &cinfo ); - jpeg_set_quality( &cinfo, quality, TRUE ); + clamp( quality, 0, 100 ); - jpeg_start_compress( &cinfo, TRUE ); + jpeg_set_defaults( &cinfo ); + jpeg_set_quality( &cinfo, quality, TRUE ); - row_stride = width * 3; // JSAMPLEs per row in image_buffer + jpeg_start_compress( &cinfo, TRUE ); - while( cinfo.next_scanline < cinfo.image_height ) { - row_pointer[0] = ( byte * )( &rgb[( cinfo.image_height - cinfo.next_scanline - 1 ) * row_stride] ); - jpeg_write_scanlines( &cinfo, row_pointer, 1 ); - } + row_stride = width * 3; // JSAMPLEs per row in image_buffer - jpeg_finish_compress( &cinfo ); - fs.FCloseFile( hFile ); + while( cinfo.next_scanline < cinfo.image_height ) { + row_pointer[0] = ( byte * )( &rgb[( cinfo.image_height - cinfo.next_scanline - 1 ) * row_stride] ); + jpeg_write_scanlines( &cinfo, row_pointer, 1 ); + } - jpeg_destroy_compress( &cinfo ); + jpeg_finish_compress( &cinfo ); + FS_FCloseFile( hFile ); - return qtrue; + jpeg_destroy_compress( &cinfo ); + + return qtrue; } -#endif /* USE_JPEG */ +#endif /* USE_JPG */ #if USE_PNG @@ -917,32 +899,32 @@ PNG LOADING */ struct pngReadStruct { - byte *data; - byte *maxp; + byte *data; + byte *maxp; }; static void QDECL png_vfs_read_fn( png_structp png_ptr, png_bytep buf, png_size_t size ) { - struct pngReadStruct *r = png_get_io_ptr( png_ptr ); + struct pngReadStruct *r = png_get_io_ptr( png_ptr ); - if( r->data + size > r->maxp ) { + if( r->data + size > r->maxp ) { png_error( png_ptr, "read error" ); - } else { - memcpy( buf, r->data, size ); - r->data += size; + } else { + memcpy( buf, r->data, size ); + r->data += size; } } static void QDECL png_console_error_fn( png_structp png_ptr, png_const_charp error_msg ) { - char *f = png_get_error_ptr( png_ptr ); + char *f = png_get_error_ptr( png_ptr ); - Com_EPrintf( "LoadPNG: %s: %s\n", f, error_msg ); - longjmp( png_jmpbuf( png_ptr ), -1 ); + Com_EPrintf( "LoadPNG: %s: %s\n", f, error_msg ); + longjmp( png_jmpbuf( png_ptr ), -1 ); } static void QDECL png_console_warning_fn( png_structp png_ptr, png_const_charp warning_msg ) { - char *f = png_get_error_ptr( png_ptr ); + char *f = png_get_error_ptr( png_ptr ); - Com_WPrintf( "LoadPNG: %s: %s\n", f, warning_msg ); + Com_WPrintf( "LoadPNG: %s: %s\n", f, warning_msg ); } /* @@ -950,161 +932,160 @@ static void QDECL png_console_warning_fn( png_structp png_ptr, png_const_charp w LoadPNG ================= */ -void Image_LoadPNG( const char *filename, byte **pic, int *width, int *height ) { - byte *rawdata; - size_t rawlength; - byte *pixels; - png_bytep row_pointers[MAX_TEXTURE_SIZE]; - png_uint_32 w, h, rowbytes, row; +void IMG_LoadPNG( const char *filename, byte **pic, int *width, int *height ) { + byte *rawdata; + size_t rawlength; + byte *pixels; + png_bytep row_pointers[MAX_TEXTURE_SIZE]; + png_uint_32 w, h, rowbytes, row; int bitdepth, colortype; - png_structp png_ptr; - png_infop info_ptr; - struct pngReadStruct r; + png_structp png_ptr; + png_infop info_ptr; + struct pngReadStruct r; - if( !filename || !pic ) { - Com_Error( ERR_FATAL, "LoadPNG: NULL" ); - } + if( !filename || !pic ) { + Com_Error( ERR_FATAL, "LoadPNG: NULL" ); + } - *pic = NULL; - pixels = NULL; + *pic = pixels = NULL; - rawlength = fs.LoadFile( filename, ( void ** )&rawdata ); - if( !rawdata ) { - return; - } + rawlength = FS_LoadFile( filename, ( void ** )&rawdata ); + if( !rawdata ) { + return; + } - png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, - ( png_voidp )filename, png_console_error_fn, png_console_warning_fn ); - if( !png_ptr ) { - goto fail; - } + png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, + ( png_voidp )filename, png_console_error_fn, png_console_warning_fn ); + if( !png_ptr ) { + goto fail; + } - info_ptr = png_create_info_struct( png_ptr ); - if( !info_ptr ) { - png_destroy_read_struct( &png_ptr, NULL, NULL ); - goto fail; - } + info_ptr = png_create_info_struct( png_ptr ); + if( !info_ptr ) { + png_destroy_read_struct( &png_ptr, NULL, NULL ); + goto fail; + } - if( setjmp( png_jmpbuf( png_ptr ) ) ) { - png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); + if( setjmp( png_jmpbuf( png_ptr ) ) ) { + png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); if( pixels ) { - fs.FreeFile( pixels ); + IMG_FreePixels( pixels ); } - goto fail; - } + goto fail; + } - r.data = rawdata; - r.maxp = rawdata + rawlength; - png_set_read_fn( png_ptr, ( png_voidp )&r, png_vfs_read_fn ); + r.data = rawdata; + r.maxp = rawdata + rawlength; + png_set_read_fn( png_ptr, ( png_voidp )&r, png_vfs_read_fn ); - png_read_info( png_ptr, info_ptr ); + png_read_info( png_ptr, info_ptr ); - if( !png_get_IHDR( png_ptr, info_ptr, &w, &h, &bitdepth, &colortype, - NULL, NULL, NULL ) ) - { - png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); - goto fail; - } + if( !png_get_IHDR( png_ptr, info_ptr, &w, &h, &bitdepth, &colortype, + NULL, NULL, NULL ) ) + { + png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); + goto fail; + } - if( w > MAX_TEXTURE_SIZE || h > MAX_TEXTURE_SIZE ) { - Com_EPrintf( "LoadPNG: %s: oversize image dimensions: %lux%lu\n", - filename, w, h ); - png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); - goto fail; - } + if( w > MAX_TEXTURE_SIZE || h > MAX_TEXTURE_SIZE ) { + Com_EPrintf( "LoadPNG: %s: oversize image dimensions: %lux%lu\n", + filename, w, h ); + png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); + goto fail; + } - switch( colortype ) { - case PNG_COLOR_TYPE_PALETTE: - png_set_palette_to_rgb( png_ptr ); - break; - case PNG_COLOR_TYPE_GRAY: - if( bitdepth < 8 ) { - png_set_gray_1_2_4_to_8( png_ptr ); - } - // fall through - case PNG_COLOR_TYPE_GRAY_ALPHA: - png_set_gray_to_rgb( png_ptr ); - break; - } + switch( colortype ) { + case PNG_COLOR_TYPE_PALETTE: + png_set_palette_to_rgb( png_ptr ); + break; + case PNG_COLOR_TYPE_GRAY: + if( bitdepth < 8 ) { + png_set_gray_1_2_4_to_8( png_ptr ); + } + // fall through + case PNG_COLOR_TYPE_GRAY_ALPHA: + png_set_gray_to_rgb( png_ptr ); + break; + } - if( bitdepth < 8 ) { - png_set_packing( png_ptr ); - } else if( bitdepth == 16 ) { - png_set_strip_16( png_ptr ); - } + if( bitdepth < 8 ) { + png_set_packing( png_ptr ); + } else if( bitdepth == 16 ) { + png_set_strip_16( png_ptr ); + } - if( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ) ) { - png_set_tRNS_to_alpha( png_ptr ); - } + if( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ) ) { + png_set_tRNS_to_alpha( png_ptr ); + } - png_set_filler( png_ptr, 0xff, PNG_FILLER_AFTER ); + png_set_filler( png_ptr, 0xff, PNG_FILLER_AFTER ); - png_read_update_info( png_ptr, info_ptr ); + png_read_update_info( png_ptr, info_ptr ); - rowbytes = png_get_rowbytes( png_ptr, info_ptr ); - pixels = fs.AllocTempMem( h * rowbytes ); + rowbytes = png_get_rowbytes( png_ptr, info_ptr ); + pixels = IMG_AllocPixels( h * rowbytes ); - for( row = 0; row < h; row++ ) { - row_pointers[row] = pixels + row * rowbytes; - } + for( row = 0; row < h; row++ ) { + row_pointers[row] = pixels + row * rowbytes; + } - png_read_image( png_ptr, row_pointers ); + png_read_image( png_ptr, row_pointers ); - png_read_end( png_ptr, info_ptr ); + png_read_end( png_ptr, info_ptr ); - png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); + png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); - *pic = pixels; - *width = w; - *height = h; + *pic = pixels; + *width = w; + *height = h; fail: - fs.FreeFile( rawdata ); + FS_FreeFile( rawdata ); } static void QDECL png_vfs_write_fn( png_structp png_ptr, png_bytep buf, png_size_t size ) { - fileHandle_t *f = png_get_io_ptr( png_ptr ); - fs.Write( buf, size, *f ); + fileHandle_t *f = png_get_io_ptr( png_ptr ); + FS_Write( buf, size, *f ); } static void QDECL png_vfs_flush_fn( png_structp png_ptr ) { - //fileHandle_t *f = png_get_io_ptr( png_ptr ); - //fs.Flush( *f ); + //fileHandle_t *f = png_get_io_ptr( png_ptr ); + //FS_Flush( *f ); } -qboolean Image_WritePNG( const char *filename, const byte *rgb, int width, int height, int compression ) { - png_structp png_ptr; - png_infop info_ptr; +qboolean IMG_WritePNG( const char *filename, const byte *rgb, int width, int height, int compression ) { + png_structp png_ptr; + png_infop info_ptr; fileHandle_t f; qboolean ret = qfalse; png_bytepp row_pointers = NULL; int row_stride; int i; - fs.FOpenFile( filename, &f, FS_MODE_WRITE ); - if( !f ) { - Com_DPrintf( "WritePNG: %s: couldn't create file\n", filename ); - return qfalse; - } + FS_FOpenFile( filename, &f, FS_MODE_WRITE ); + if( !f ) { + Com_DPrintf( "WritePNG: %s: couldn't create file\n", filename ); + return qfalse; + } - png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, - ( png_voidp )filename, png_console_error_fn, png_console_warning_fn ); - if( !png_ptr ) { + png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, + ( png_voidp )filename, png_console_error_fn, png_console_warning_fn ); + if( !png_ptr ) { goto fail; - } + } - info_ptr = png_create_info_struct( png_ptr ); - if( !info_ptr ) { - png_destroy_write_struct( &png_ptr, NULL ); - goto fail; - } + info_ptr = png_create_info_struct( png_ptr ); + if( !info_ptr ) { + png_destroy_write_struct( &png_ptr, NULL ); + goto fail; + } - if( setjmp( png_jmpbuf( png_ptr ) ) ) { - png_destroy_write_struct( &png_ptr, &info_ptr ); - goto fail; - } + if( setjmp( png_jmpbuf( png_ptr ) ) ) { + png_destroy_write_struct( &png_ptr, &info_ptr ); + goto fail; + } - png_set_write_fn( png_ptr, ( png_voidp )&f, + png_set_write_fn( png_ptr, ( png_voidp )&f, png_vfs_write_fn, png_vfs_flush_fn ); png_set_IHDR( png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, @@ -1114,7 +1095,7 @@ qboolean Image_WritePNG( const char *filename, const byte *rgb, int width, int h clamp( compression, Z_NO_COMPRESSION, Z_BEST_COMPRESSION ); png_set_compression_level( png_ptr, compression ); - row_pointers = fs.AllocTempMem( sizeof( png_bytep ) * height ); + row_pointers = FS_AllocTempMem( sizeof( png_bytep ) * height ); row_stride = width * 3; for( i = 0; i < height; i++ ) { row_pointers[i] = ( png_bytep )rgb + ( height - i - 1 ) * row_stride; @@ -1124,22 +1105,20 @@ qboolean Image_WritePNG( const char *filename, const byte *rgb, int width, int h png_write_png( png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL ); - png_destroy_write_struct( &png_ptr, &info_ptr ); + png_destroy_write_struct( &png_ptr, &info_ptr ); ret = qtrue; fail: if( row_pointers ) { - fs.FreeFile( row_pointers ); + FS_FreeFile( row_pointers ); } - fs.FCloseFile( f ); + FS_FCloseFile( f ); return ret; } #endif /* USE_PNG */ -#endif /* TRUECOLOR_RENDERER */ - /* ========================================================= @@ -1148,292 +1127,219 @@ IMAGE MANAGER ========================================================= */ -image_t r_images[MAX_RIMAGES]; -list_t r_imageHash[RIMAGES_HASH]; -int r_numImages; +#define RIMAGES_HASH 256 -uint32_t d_8to24table[256]; +image_t r_images[MAX_RIMAGES]; +list_t r_imageHash[RIMAGES_HASH]; +int r_numImages; -#ifdef TRUECOLOR_RENDERER +uint32_t d_8to24table[256]; -static cvar_t *r_override_textures; -static cvar_t *r_texture_formats; +#if USE_PNG || USE_JPG || USE_TGA +static cvar_t *r_override_textures; +static cvar_t *r_texture_formats; +#endif /* -================ -R_ResampleTexture -================ +=============== +IMG_List_f +=============== */ -void R_ResampleTexture( const byte *in, int inwidth, int inheight, byte *out, int outwidth, int outheight ) { - int i, j; - const byte *inrow1, *inrow2; - unsigned frac, fracstep; - unsigned p1[MAX_TEXTURE_SIZE], p2[MAX_TEXTURE_SIZE]; - const byte *pix1, *pix2, *pix3, *pix4; - float heightScale; - - if( outwidth > MAX_TEXTURE_SIZE ) { - Com_Error( ERR_FATAL, "%s: outwidth > %d", __func__, MAX_TEXTURE_SIZE ); - } - - fracstep = inwidth * 0x10000 / outwidth; - - frac = fracstep >> 2; - for( i = 0; i < outwidth; i++ ) { - p1[i] = 4 * ( frac >> 16 ); - frac += fracstep; - } - frac = 3 * ( fracstep >> 2 ); - for( i = 0; i < outwidth; i++ ) { - p2[i] = 4 * ( frac >> 16 ); - frac += fracstep; - } +static void IMG_List_f( void ) { + int i; + image_t *image; + int texels, count; + + Com_Printf( "------------------\n"); + texels = count = 0; + + for( i = 0, image = r_images; i < r_numImages; i++, image++ ) { + if( !image->registration_sequence ) + continue; + texels += image->upload_width * image->upload_height; + switch( image->type ) { + case it_skin: + Com_Printf( "M" ); + break; + case it_sprite: + Com_Printf( "S" ); + break; + case it_wall: + Com_Printf( "W" ); + break; + case it_pic: + Com_Printf( "P" ); + break; + case it_sky: + Com_Printf( "Y" ); + break; + case it_charset: + Com_Printf( "C" ); + break; + default: + Com_Printf( " " ); + break; + } - heightScale = ( float )inheight / outheight; - inwidth <<= 2; - for( i = 0; i < outheight; i++ ) { - inrow1 = in + inwidth * ( int )( ( i + 0.25f ) * heightScale ); - inrow2 = in + inwidth * ( int )( ( i + 0.75f ) * heightScale ); - for( j = 0; j < outwidth; j++ ) { - pix1 = inrow1 + p1[j]; - pix2 = inrow1 + p2[j]; - pix3 = inrow2 + p1[j]; - pix4 = inrow2 + p2[j]; - out[0] = ( pix1[0] + pix2[0] + pix3[0] + pix4[0] ) >> 2; - out[1] = ( pix1[1] + pix2[1] + pix3[1] + pix4[1] ) >> 2; - out[2] = ( pix1[2] + pix2[2] + pix3[2] + pix4[2] ) >> 2; - out[3] = ( pix1[3] + pix2[3] + pix3[3] + pix4[3] ) >> 2; - out += 4; - } - } + Com_Printf( " %4i %4i %s: %s\n", + image->upload_width, + image->upload_height, + ( image->flags & if_paletted ) ? "PAL" : "RGB", + image->name ); + count++; + } + Com_Printf( "Total images: %d (out of %d slots)\n", count, r_numImages ); + Com_Printf( "Total texels: %d (not counting mipmaps)\n", texels ); } -#endif /* TRUECOLOR_RENDERER */ +image_t *IMG_Alloc( const char *name ) { + int i; + image_t *image; -/* -=============== -R_ImageList_f -=============== -*/ -static void R_ImageList_f( void ) { - int i; - image_t *image; - int texels; - - Com_Printf( "------------------\n"); - texels = 0; - - for( i = 0, image = r_images; i < r_numImages; i++, image++ ) { - if( !image->registration_sequence ) - continue; - texels += image->upload_width * image->upload_height; - switch( image->type ) { - case it_skin: - Com_Printf( "M" ); - break; - case it_sprite: - Com_Printf( "S" ); - break; - case it_wall: - Com_Printf( "W" ); - break; - case it_pic: - Com_Printf( "P" ); - break; - case it_sky: - Com_Printf( "Y" ); - break; - case it_charset: - Com_Printf( "C" ); - break; - default: - Com_Printf( " " ); - break; - } - - Com_Printf( " %4i %4i %s: %s\n", image->upload_width, - image->upload_height, ( image->flags & if_paletted ) ? "PAL" : "RGB", - image->name ); - } - Com_Printf( "Total texel count (not counting mipmaps): %i\n", texels ); -} + // find a free image_t slot + for( i = 0, image = r_images; i < r_numImages; i++, image++ ) { + if( !image->registration_sequence ) + break; + } -static image_t *R_AllocImageInternal( const char *name, unsigned hash ) { - int i; - image_t *image; - - // find a free image_t slot - for( i = 0, image = r_images; i < r_numImages; i++, image++ ) { - if( !image->registration_sequence ) - break; - } - - if( i == r_numImages ) { - if( r_numImages == MAX_RIMAGES ) - Com_Error( ERR_FATAL, "R_AllocImage: MAX_IMAGES" ); - r_numImages++; - } + if( i == r_numImages ) { + if( r_numImages == MAX_RIMAGES ) + Com_Error( ERR_FATAL, "%s: MAX_IMAGES exceeded", __func__ ); + r_numImages++; + } - strcpy( image->name, name ); - List_Append( &r_imageHash[hash], &image->entry ); + strcpy( image->name, name ); - image->registration_sequence = registration_sequence; + image->registration_sequence = registration_sequence; - return image; + return image; } /* =============== -R_LookupImage +IMG_Lookup Finds the given image of the given type. Case and extension insensitive. =============== */ -static image_t *R_LookupImage( const char *name, imagetype_t type, - unsigned hash, size_t baselength ) +static image_t *IMG_Lookup( const char *name, imagetype_t type, + unsigned hash, size_t baselength ) { - image_t *image; + image_t *image; - // look for it + // look for it LIST_FOR_EACH( image_t, image, &r_imageHash[hash], entry ) { - if( image->type != type ) { - continue; - } - if( !Q_stricmpn( image->name, name, baselength ) ) { - return image; - } - } - - return NULL; -} - -image_t *R_AllocImage( const char *name ) { - char buffer[MAX_QPATH]; - char *ext; - unsigned hash; - image_t *image; - size_t length; - - if( !name || !name[0] ) { - Com_Error( ERR_FATAL, "R_AllocImage: NULL" ); - } - - length = strlen( name ); - if( length >= MAX_QPATH ) { - Com_Error( ERR_FATAL, "R_AllocImage: oversize name" ); - } - - memcpy( buffer, name, length + 1 ); - - ext = COM_FileExtension( buffer ); - if( *ext == '.' ) { - *ext = 0; - } else { - ext = NULL; - } - hash = Com_HashPath( buffer, RIMAGES_HASH ); - if( ext ) { - *ext = '.'; - } - - image = R_AllocImageInternal( buffer, hash ); + if( image->type != type ) { + continue; + } + // FIXME + if( !FS_pathcmpn( image->name, name, baselength ) ) { + return image; + } + } - return image; + return NULL; } +/* +=============== +IMG_Create -image_t *R_CreateImage( const char *name, byte *pic, int width, int height, - imagetype_t type, imageflags_t flags ) +Allocates and loads image from supplied data. +=============== +*/ +image_t *IMG_Create( const char *name, byte *pic, int width, int height, + imagetype_t type, imageflags_t flags ) { - image_t *image; - - image = R_AllocImage( name ); - R_LoadImage( image, pic, width, height, type, flags ); + image_t *image; - return image; + image = IMG_Alloc( name ); + IMG_Load( image, pic, width, height, type, flags ); + return image; } - -#ifdef TRUECOLOR_RENDERER - /* =============== -R_FindImage +IMG_Find -Finds or loads the given image (8 or 32 bit) +Finds or loads the given image, adding it to the hash table. =============== */ -image_t *R_FindImage( const char *name, imagetype_t type ) { - image_t *image; - byte *pic; - int width, height; - char buffer[MAX_QPATH]; - char *ext, *s; - size_t length; - unsigned hash, extHash; - imageflags_t flags; - - if( !name || !name[0] ) { - Com_Error( ERR_FATAL, "R_FindImage: NULL" ); - } +image_t *IMG_Find( const char *name, imagetype_t type ) { + image_t *image; + byte *pic; + int width, height; + char buffer[MAX_QPATH]; + char *ext; + size_t length; + unsigned hash, extHash; + imageflags_t flags; +#if USE_PNG || USE_JPG || USE_TGA + char *s; +#endif - length = strlen( name ); - if( length >= MAX_QPATH ) { - Com_Error( ERR_FATAL, "R_FindImage: oversize name" ); - } + if( !name ) { + Com_Error( ERR_FATAL, "%s: NULL", __func__ ); + } - if( length <= 4 ) { - return NULL; // must have at least 1 char of base name - } + length = strlen( name ); + if( length >= MAX_QPATH ) { + Com_Error( ERR_FATAL, "%s: oversize name", __func__ ); + } - length -= 4; - if( name[length] != '.' ) { - return NULL; - } - - strcpy( buffer, name ); - buffer[length] = 0; + if( length <= 4 ) { + return NULL; // must have at least 1 char of base name + } - hash = Com_HashPath( buffer, RIMAGES_HASH ); + length -= 4; + if( name[length] != '.' ) { + return NULL; + } + + strcpy( buffer, name ); + buffer[length] = 0; - if( ( image = R_LookupImage( buffer, type, hash, length ) ) != NULL ) { - image->registration_sequence = registration_sequence; - return image; - } + hash = Com_HashPath( buffer, RIMAGES_HASH ); - ext = buffer + length; - Q_strlwr( ext + 1 ); - extHash = MakeLong( '.', ext[1], ext[2], ext[3] ); + if( ( image = IMG_Lookup( buffer, type, hash, length ) ) != NULL ) { + image->registration_sequence = registration_sequence; + return image; + } - // - // load the pic from disk - // - pic = NULL; - image = NULL; - flags = 0; + ext = buffer + length; + Q_strlwr( ext + 1 ); + extHash = MakeLong( '.', ext[1], ext[2], ext[3] ); - if( r_override_textures->integer ) { + // + // create the pic from disk + // + pic = NULL; + flags = 0; + +#if USE_PNG || USE_JPG || USE_TGA + if( r_override_textures->integer ) { for( s = r_texture_formats->string; *s; s++ ) { switch( *s ) { #if USE_PNG case 'p': // try *.png strcpy( ext, ".png" ); - Image_LoadPNG( buffer, &pic, &width, &height ); + IMG_LoadPNG( buffer, &pic, &width, &height ); break; #endif -#if USE_JPEG +#if USE_JPG case 'j': // try *.jpg strcpy( ext, ".jpg" ); - Image_LoadJPG( buffer, &pic, &width, &height ); + IMG_LoadJPG( buffer, &pic, &width, &height ); break; #endif +#if USE_TGA case 't': // try *.tga strcpy( ext, ".tga" ); - Image_LoadTGA( buffer, &pic, &width, &height ); + IMG_LoadTGA( buffer, &pic, &width, &height ); break; } - +#endif if( pic ) { // replacing 8 bit texture with 32 bit texture if( extHash == EXTENSION_WAL ) { @@ -1441,7 +1347,7 @@ image_t *R_FindImage( const char *name, imagetype_t type ) { } else if( extHash == EXTENSION_PCX ) { flags |= if_replace_pcx; } - goto load; + goto create; } } @@ -1450,415 +1356,431 @@ image_t *R_FindImage( const char *name, imagetype_t type ) { case EXTENSION_TGA: case EXTENSION_JPG: case EXTENSION_PCX: - strcpy( ext, ".pcx" ); - Image_LoadPCX( buffer, &pic, NULL, &width, &height ); - if( pic ) { - flags |= if_paletted; - goto load; - } - return NULL; - case EXTENSION_WAL: - strcpy( ext, ".wal" ); - image = R_LoadWal( buffer ); - return image; - } - - return NULL; - } + strcpy( ext, ".pcx" ); + IMG_LoadPCX( buffer, &pic, NULL, &width, &height ); + if( pic ) { + flags |= if_paletted; + goto create; + } + return NULL; + case EXTENSION_WAL: + strcpy( ext, ".wal" ); + if( ( image = IMG_LoadWAL( buffer ) ) != NULL ) { + goto append; + } + } + + return NULL; + } +#endif - switch( extHash ) { - case EXTENSION_PNG: + switch( extHash ) { + case EXTENSION_PNG: #if USE_PNG - // try *.png - strcpy( ext, ".png" ); - Image_LoadPNG( buffer, &pic, &width, &height ); - if( pic ) { - goto load; - } + // try *.png + strcpy( ext, ".png" ); + IMG_LoadPNG( buffer, &pic, &width, &height ); + if( pic ) { + goto create; + } #endif +#if USE_JPG || USE_TGA for( s = r_texture_formats->string; *s; s++ ) { switch( *s ) { -#if USE_JPEG +#if USE_JPG case 'j': // try *.jpg strcpy( ext, ".jpg" ); - Image_LoadJPG( buffer, &pic, &width, &height ); + IMG_LoadJPG( buffer, &pic, &width, &height ); break; #endif +#if USE_TGA case 't': // try *.tga strcpy( ext, ".tga" ); - Image_LoadTGA( buffer, &pic, &width, &height ); + IMG_LoadTGA( buffer, &pic, &width, &height ); break; } +#endif if( pic ) { - goto load; + goto create; } } +#endif + // try *.pcx + strcpy( ext, ".pcx" ); + IMG_LoadPCX( buffer, &pic, NULL, &width, &height ); + if( pic ) { + flags |= if_paletted; + goto create; + } + return NULL; + + case EXTENSION_TGA: +#if USE_TGA + strcpy( ext, ".tga" ); + IMG_LoadTGA( buffer, &pic, &width, &height ); + if( pic ) { + goto create; + } +#endif - // try *.pcx - strcpy( ext, ".pcx" ); - Image_LoadPCX( buffer, &pic, NULL, &width, &height ); - if( pic ) { - flags |= if_paletted; - goto load; - } - return NULL; - - case EXTENSION_TGA: - strcpy( ext, ".tga" ); - Image_LoadTGA( buffer, &pic, &width, &height ); - if( pic ) { - goto load; - } - +#if USE_PNG || USE_JPG for( s = r_texture_formats->string; *s; s++ ) { switch( *s ) { #if USE_PNG case 'p': // try *.png strcpy( ext, ".png" ); - Image_LoadPNG( buffer, &pic, &width, &height ); + IMG_LoadPNG( buffer, &pic, &width, &height ); break; #endif -#if USE_JPEG +#if USE_JPG case 'j': // try *.jpg strcpy( ext, ".jpg" ); - Image_LoadJPG( buffer, &pic, &width, &height ); + IMG_LoadJPG( buffer, &pic, &width, &height ); break; #endif } if( pic ) { - goto load; + goto create; } } - - // try *.pcx - strcpy( ext, ".pcx" ); - Image_LoadPCX( buffer, &pic, NULL, &width, &height ); - if( pic ) { - flags |= if_paletted; - goto load; - } - return NULL; - - case EXTENSION_JPG: -#if USE_JPEG - strcpy( ext, ".jpg" ); - Image_LoadJPG( buffer, &pic, &width, &height ); - if( pic ) { - goto load; - } +#endif + // try *.pcx + strcpy( ext, ".pcx" ); + IMG_LoadPCX( buffer, &pic, NULL, &width, &height ); + if( pic ) { + flags |= if_paletted; + goto create; + } + return NULL; + + case EXTENSION_JPG: +#if USE_JPG + strcpy( ext, ".jpg" ); + IMG_LoadJPG( buffer, &pic, &width, &height ); + if( pic ) { + goto create; + } #endif +#if USE_PNG || USE_TGA for( s = r_texture_formats->string; *s; s++ ) { switch( *s ) { #if USE_PNG case 'p': // try *.png strcpy( ext, ".png" ); - Image_LoadPNG( buffer, &pic, &width, &height ); + IMG_LoadPNG( buffer, &pic, &width, &height ); break; #endif +#if USE_TGA case 't': // try *.tga strcpy( ext, ".tga" ); - Image_LoadTGA( buffer, &pic, &width, &height ); + IMG_LoadTGA( buffer, &pic, &width, &height ); break; } +#endif if( pic ) { - goto load; + goto create; } } +#endif - - // try *.pcx - strcpy( ext, ".pcx" ); - Image_LoadPCX( buffer, &pic, NULL, &width, &height ); - if( pic ) { - flags |= if_paletted; - goto load; - } - return NULL; + // try *.pcx + strcpy( ext, ".pcx" ); + IMG_LoadPCX( buffer, &pic, NULL, &width, &height ); + if( pic ) { + flags |= if_paletted; + goto create; + } + return NULL; - case EXTENSION_PCX: - strcpy( ext, ".pcx" ); - Image_LoadPCX( buffer, &pic, NULL, &width, &height ); - if( pic ) { - flags |= if_paletted; - goto load; - } + case EXTENSION_PCX: + strcpy( ext, ".pcx" ); + IMG_LoadPCX( buffer, &pic, NULL, &width, &height ); + if( pic ) { + flags |= if_paletted; + goto create; + } +#if USE_PNG || USE_JPG || USE_TGA for( s = r_texture_formats->string; *s; s++ ) { switch( *s ) { #if USE_PNG case 'p': // try *.png strcpy( ext, ".png" ); - Image_LoadPNG( buffer, &pic, &width, &height ); + IMG_LoadPNG( buffer, &pic, &width, &height ); break; #endif -#if USE_JPEG +#if USE_JPG case 'j': // try *.jpg strcpy( ext, ".jpg" ); - Image_LoadJPG( buffer, &pic, &width, &height ); + IMG_LoadJPG( buffer, &pic, &width, &height ); break; #endif +#if USE_TGA case 't': // try *.tga strcpy( ext, ".tga" ); - Image_LoadTGA( buffer, &pic, &width, &height ); + IMG_LoadTGA( buffer, &pic, &width, &height ); break; } - +#endif if( pic ) { - goto load; + goto create; } } +#endif + return NULL; - return NULL; - - case EXTENSION_WAL: - strcpy( ext, ".wal" ); - image = R_LoadWal( buffer ); - if( image ) { - return image; - } + case EXTENSION_WAL: + strcpy( ext, ".wal" ); + if( ( image = IMG_LoadWAL( buffer ) ) != NULL ) { + goto append; + } - // FIXME: no way to figure correct texture dimensions here +#if USE_PNG || USE_JPG || USE_TGA + // FIXME: no way to figure correct texture dimensions here for( s = r_texture_formats->string; *s; s++ ) { switch( *s ) { #if USE_PNG case 'p': // try *.png strcpy( ext, ".png" ); - Image_LoadPNG( buffer, &pic, &width, &height ); + IMG_LoadPNG( buffer, &pic, &width, &height ); break; #endif -#if USE_JPEG +#if USE_JPG case 'j': // try *.jpg strcpy( ext, ".jpg" ); - Image_LoadJPG( buffer, &pic, &width, &height ); + IMG_LoadJPG( buffer, &pic, &width, &height ); break; #endif +#if USE_TGA case 't': // try *.tga strcpy( ext, ".tga" ); - Image_LoadTGA( buffer, &pic, &width, &height ); + IMG_LoadTGA( buffer, &pic, &width, &height ); break; } - +#endif if( pic ) { - goto load; + goto create; } } +#endif + return NULL; - return NULL; + default: + return NULL; + } - default: - return NULL; - +create: + image = IMG_Create( buffer, pic, width, height, type, flags ); +append: + List_Append( &r_imageHash[hash], &image->entry ); + return image; +} + +/* +=============== +IMG_ForHandle +=============== +*/ +image_t *IMG_ForHandle( qhandle_t h ) { + if( h < 0 || h >= r_numImages ) { + Com_Error( ERR_FATAL, "%s: %d out of range", __func__, h ); } -load: - image = R_AllocImageInternal( buffer, hash ); - R_LoadImage( image, pic, width, height, type, flags ); - return image; + return &r_images[h]; } -#else /* TRUECOLOR_RENDERER */ - /* =============== -R_FindImage - -Finds or loads the given image (8 bit) +R_RegisterSkin =============== */ -image_t *R_FindImage( const char *name, imagetype_t type ) { +qhandle_t R_RegisterSkin( const char *name ) { image_t *image; - byte *pic; - int width, height; - char buffer[MAX_QPATH]; - char *ext; - int length; - unsigned hash, extHash; - - if( !name || !name[0] ) { - Com_Error( ERR_FATAL, "R_FindImage: NULL" ); - } - length = strlen( name ); - if( length >= MAX_QPATH ) { - Com_Error( ERR_FATAL, "R_FindImage: oversize name: %d chars", length ); + image = IMG_Find( name, it_skin ); + if( !image ) { + return 0; } - if( length <= 4 ) { - /* must have at least 1 char of basename - * and 4 chars of extension part */ - return NULL; - } + return ( image - r_images ); +} - length -= 4; - if( name[length] != '.' ) { - return NULL; - } - - strcpy( buffer, name ); - Q_strlwr( buffer ); - buffer[length] = 0; +/* +================ +R_RegisterPic +================ +*/ +qhandle_t R_RegisterPic( const char *name ) { + image_t *image; + char fullname[MAX_QPATH]; - hash = Com_HashPath( buffer, RIMAGES_HASH ); + if( name[0] == '*' ) { + image = IMG_Find( name + 1, it_tmp ); + } else if( name[0] == '/' || name[0] == '\\' ) { + image = IMG_Find( name + 1, it_pic ); + } else { + Q_concat( fullname, sizeof( fullname ), "pics/", name, NULL ); + COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) ); + image = IMG_Find( fullname, it_pic ); + } - if( ( image = R_LookupImage( buffer, type, hash, length ) ) != NULL ) { - image->registration_sequence = registration_sequence; - return image; + if( !image ) { + return 0; } - ext = buffer + length; - extHash = MakeLong( '.', ext[1], ext[2], ext[3] ); + return ( image - r_images ); +} - *ext = '.'; +/* +================ +R_RegisterFont +================ +*/ +qhandle_t R_RegisterFont( const char *name ) { + image_t *image; + char fullname[MAX_QPATH]; - // - // load the pic from disk - // - if( extHash == EXTENSION_JPG || extHash == EXTENSION_TGA || extHash == EXTENSION_PNG ) { - strcpy( ext, ".pcx" ); - extHash = EXTENSION_PCX; - } - if( extHash == EXTENSION_PCX ) { - Image_LoadPCX( buffer, &pic, NULL, &width, &height ); - if( !pic ) { - return NULL; - } - image = R_AllocImageInternal( buffer, hash ); - R_LoadImage( image, pic, width, height, type, if_paletted ); - return image; + if( name[0] == '/' || name[0] == '\\' ) { + image = IMG_Find( name + 1, it_charset ); + } else { + Q_concat( fullname, sizeof( fullname ), "pics/", name, NULL ); + COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) ); + image = IMG_Find( fullname, it_charset ); } - if( extHash == EXTENSION_WAL ) { - image = R_LoadWal( buffer ); - return image; + if( !image ) { + return 0; } - return NULL; + return ( image - r_images ); } -#endif /* !TRUECOLOR_RENDERER */ - /* ================ -R_FreeUnusedImages +IMG_FreeUnused Any image that was not touched on this registration sequence will be freed. ================ */ -void R_FreeUnusedImages( void ) { - image_t *image, *last; +void IMG_FreeUnused( void ) { + image_t *image, *last; int count = 0; - last = r_images + r_numImages; - for( image = r_images; image != last; image++ ) { - if( image->registration_sequence == registration_sequence ) { -#ifdef SOFTWARE_RENDERER - Com_PageInMemory( image->pixels[0], image->width * image->height * VID_BYTES ); + last = r_images + r_numImages; + for( image = r_images; image < last; image++ ) { + if( image->registration_sequence == registration_sequence ) { +#if SOFTWARE_RENDERER + Com_PageInMemory( image->pixels[0], image->width * image->height * VID_BYTES ); #endif - continue; // used this sequence - } - if( !image->registration_sequence ) - continue; // free image_t slot - if( image->type == it_pic || image->type == it_charset ) - continue; // don't free pics - if( image->flags & if_auto ) { - continue; // don't free auto textures - } - - // delete it from hash table - List_Remove( &image->entry ); - - // free it - R_FreeImage( image ); + continue; // used this sequence + } + if( !image->registration_sequence ) + continue; // free image_t slot + if( image->type == it_pic || image->type == it_charset ) + continue; // don't free pics + if( image->flags & if_auto ) { + continue; // don't free auto textures + } + + // delete it from hash table + List_Remove( &image->entry ); + + // free it + IMG_Unload( image ); memset( image, 0, sizeof( *image ) ); count++; - } + } - Com_DPrintf( "%s: %i images freed\n", __func__, count ); + if( count ) { + Com_DPrintf( "%s: %i images freed\n", __func__, count ); + } } -void R_FreeAllImages( void ) { - image_t *image, *last; +void IMG_FreeAll( void ) { + image_t *image, *last; int i, count = 0; - - last = r_images + r_numImages; - for( image = r_images; image != last; image++ ) { - if( !image->registration_sequence ) - continue; // free image_t slot - // free it - R_FreeImage( image ); - + + last = r_images + r_numImages; + for( image = r_images; image < last; image++ ) { + if( !image->registration_sequence ) + continue; // free image_t slot + // free it + IMG_Unload( image ); + memset( image, 0, sizeof( *image ) ); count++; - } + } - Com_DPrintf( "%s: %i images freed\n", __func__, count ); - - r_numImages = 0; + if( count ) { + Com_DPrintf( "%s: %i images freed\n", __func__, count ); + } + + r_numImages = 0; for( i = 0; i < RIMAGES_HASH; i++ ) { - List_Init( &r_imageHash[i] ); + List_Init( &r_imageHash[i] ); } } /* =============== R_GetPalette + +Reads the palette and (optionally) loads +the colormap for software renderer. =============== */ -void R_GetPalette( byte **dest ) { - int i; - byte *pic, *src; - byte palette[768]; - int width, height; - - /* get the palette */ - Image_LoadPCX( "pics/colormap.pcx", &pic, palette, &width, &height ); - if( !pic ) { - Com_Error( ERR_FATAL, "Couldn't load pics/colormap.pcx" ); - } - - src = palette; - for( i = 0; i < 255; i++ ) { - d_8to24table[i] = MakeColor( src[0], src[1], src[2], 255 ); - src += 3; - } +void IMG_GetPalette( byte **pic ) { + int i; + byte pal[768], *src; + int w, h; - /* 255 is transparent*/ - d_8to24table[i] = MakeColor( src[0], src[1], src[2], 0 ); + // get the palette + if( !IMG_LoadPCX( "pics/colormap.pcx", pic, pal, &w, &h ) ) { + Com_Error( ERR_FATAL, "Couldn't load pics/colormap.pcx" ); + } - if( dest ) { - *dest = R_Malloc( width * height ); - memcpy( *dest, pic, width * height ); - } + for( i = 0, src = pal; i < 255; i++, src += 3 ) { + d_8to24table[i] = MakeColor( src[0], src[1], src[2], 255 ); + } - fs.FreeFile( pic ); + // 255 is transparent + d_8to24table[i] = MakeColor( src[0], src[1], src[2], 0 ); } -void R_InitImageManager( void ) { +void IMG_Init( void ) { int i; -#ifdef TRUECOLOR_RENDERER - r_override_textures = cvar.Get( "r_override_textures", "1", CVAR_ARCHIVE|CVAR_FILES ); - r_texture_formats = cvar.Get( "r_texture_formats", + if( r_numImages ) { + Com_Error( ERR_FATAL, "%s: %d images not freed", __func__, r_numImages ); + } + + +#if USE_PNG || USE_JPG || USE_TGA + r_override_textures = Cvar_Get( "r_override_textures", "1", CVAR_ARCHIVE|CVAR_FILES ); + r_texture_formats = Cvar_Get( "r_texture_formats", #if USE_PNG "p" #endif -#if USE_JPEG +#if USE_JPG "j" #endif - "t", 0 ); +#if USE_TGA + "t", +#endif + 0 ); #endif - cmd.AddCommand( "imagelist", R_ImageList_f ); + Cmd_AddCommand( "imagelist", IMG_List_f ); for( i = 0; i < RIMAGES_HASH; i++ ) { - List_Init( &r_imageHash[i] ); + List_Init( &r_imageHash[i] ); } } -void R_ShutdownImageManager( void ) { - cmd.RemoveCommand( "imagelist" ); +void IMG_Shutdown( void ) { + Cmd_RemoveCommand( "imagelist" ); } diff --git a/source/r_models.c b/source/r_models.c new file mode 100644 index 0000000..795721e --- /dev/null +++ b/source/r_models.c @@ -0,0 +1,418 @@ +/* +Copyright (C) 2008 Andrey Nazarov +Copyright (C) 1997-2001 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 "com_local.h" +#include "files.h" +#include "sys_public.h" +#include "q_list.h" +#include "d_md2.h" +#if USE_MD3 +#include "d_md3.h" +#endif +#include "d_sp2.h" +#include "r_shared.h" +#include "r_models.h" + +static model_t r_models[MAX_MODELS]; +static int r_numModels; + +#if USE_MD3 +static cvar_t *r_override_models; +#endif + +static model_t *MOD_Alloc( const char *name ) { + model_t *model; + int i; + + for( i = 0, model = r_models; i < r_numModels; i++, model++ ) { + if( !model->name[0] ) { + break; + } + } + + if( i == r_numModels ) { + if( r_numModels == MAX_MODELS ) { + Com_Error( ERR_DROP, "Model_Alloc: MAX_MODELS" ); + } + r_numModels++; + } + + strcpy( model->name, name ); + model->registration_sequence = registration_sequence; + + return model; +} + +static model_t *MOD_Find( const char *name ) { + model_t *model; + int i; + + for( i = 0, model = r_models; i < r_numModels; i++, model++ ) { + if( !model->name[0] ) { + continue; + } + if( !FS_pathcmp( model->name, name ) ) { + return model; + } + } + + return NULL; +} + +static void MOD_List_f( void ) { + int i, count; + model_t *model; + size_t bytes; + + Com_Printf( "------------------\n"); + bytes = count = 0; + + for( i = 0, model = r_models; i < r_numModels; i++, model++ ) { + if( !model->name[0] ) { + continue; + } + Com_Printf( "%8"PRIz" : %s\n", model->pool.mapped, model->name ); + bytes += model->pool.mapped; + count++; + } + Com_Printf( "Total models: %d (out of %d slots)\n", count, r_numModels ); + Com_Printf( "Total resident: %"PRIz"\n", bytes ); +} + +void MOD_FreeUnused( void ) { + model_t *model; + int i; + + for( i = 0, model = r_models; i < r_numModels; i++, model++ ) { + if( !model->name[0] ) { + continue; + } + if( model->registration_sequence == registration_sequence ) { + // make sure it is paged in + Com_PageInMemory( model->pool.base, model->pool.cursize ); + } else { + // don't need this model + Hunk_Free( &model->pool ); + memset( model, 0, sizeof( *model ) ); + } + } +} + +void MOD_FreeAll( void ) { + model_t *model; + int i; + + for( i = 0, model = r_models; i < r_numModels; i++, model++ ) { + if( !model->name[0] ) { + continue; + } + + Hunk_Free( &model->pool ); + memset( model, 0, sizeof( *model ) ); + } + + r_numModels = 0; +} + +qboolean MOD_ValidateMD2( model_t *model, dmd2header_t *header, size_t length ) { + size_t end; + + // check ident and version + if( header->ident != MD2_IDENT ) { + Com_WPrintf( "%s is not an MD2 file\n", model->name ); + return qfalse; + } + if( header->version != MD2_VERSION ) { + Com_WPrintf( "%s has bad version: %d instead of %d\n", + model->name, header->version, MD2_VERSION ); + return qfalse; + } + + // check triangles + if( header->num_tris < 1 || header->num_tris > MD2_MAX_TRIANGLES ) { + Com_WPrintf( "%s has bad number of triangles\n", model->name ); + return qfalse; + } + end = header->ofs_tris + sizeof( dmd2triangle_t ) * header->num_tris; + if( header->ofs_tris < sizeof( header ) || end < header->ofs_tris || end > length ) { + Com_WPrintf( "%s has bad triangles offset\n", model->name ); + return qfalse; + } + + // check st + if( header->num_st < 3 || header->num_st > MD2_MAX_VERTS ) { + Com_WPrintf( "%s has bad number of st\n", model->name ); + return qfalse; + } + end = header->ofs_st + sizeof( dmd2stvert_t ) * header->num_st; + if( header->ofs_st < sizeof( header ) || end < header->ofs_st || end > length ) { + Com_WPrintf( "%s has bad st offset\n", model->name ); + return qfalse; + } + + // check xyz and frames + if( header->num_xyz < 3 || header->num_xyz > MD2_MAX_VERTS ) { + Com_WPrintf( "%s has bad number of xyz\n", model->name ); + return qfalse; + } + if( header->num_frames < 1 || header->num_frames > MD2_MAX_FRAMES ) { + Com_WPrintf( "%s has bad number of frames\n", model->name ); + return qfalse; + } + end = sizeof( dmd2frame_t ) + ( header->num_xyz - 1 ) * sizeof( dmd2trivertx_t ); + if( header->framesize < end || header->framesize > MD2_MAX_FRAMESIZE ) { + Com_WPrintf( "%s has bad frame size\n", model->name ); + return qfalse; + } + end = header->ofs_frames + header->framesize * header->num_frames; + if( header->ofs_frames < sizeof( header ) || end < header->ofs_frames || end > length ) { + Com_WPrintf( "%s has bad frames offset\n", model->name ); + return qfalse; + } + + // check skins + if( header->num_skins > MAX_ALIAS_SKINS ) { + Com_WPrintf( "%s has bad number of skins\n", model->name ); + return qfalse; + } + if( header->num_skins ) { + end = header->ofs_skins + MD2_MAX_SKINNAME * header->num_skins; + if( header->ofs_skins < sizeof( header ) || end < header->ofs_skins || end > length ) { + Com_WPrintf( "%s has bad skins offset\n", model->name ); + return qfalse; + } + } + if( header->skinwidth < 1 || header->skinwidth > MD2_MAX_SKINWIDTH ) { + Com_WPrintf( "%s has bad skin width\n", model->name ); + return qfalse; + } + if( header->skinheight < 1 || header->skinheight > MD2_MAX_SKINHEIGHT ) { + Com_WPrintf( "%s has bad skin height\n", model->name ); + return qfalse; + } + return qtrue; +} + +static qboolean MOD_LoadSP2( model_t *model, const void *rawdata, size_t length ) { + dsp2header_t header; + dsp2frame_t *src_frame; + mspriteframe_t *dst_frame; + unsigned w, h, x, y; + char buffer[SP2_MAX_FRAMENAME]; + image_t *image; + int i; + + if( length < sizeof( header ) ) { + Com_EPrintf( "%s is too small\n", model->name ); + return qfalse; + } + + // byte swap the header + header = *( dsp2header_t * )rawdata; + for( i = 0; i < sizeof( header )/4; i++ ) { + (( uint32_t * )&header)[i] = LittleLong( (( uint32_t * )&header)[i] ); + } + + if( header.ident != SP2_IDENT ) { + Com_EPrintf( "%s is not an SP2 file\n", model->name ); + return qfalse; + } + if( header.version != SP2_VERSION ) { + Com_EPrintf( "%s has bad version: %d instead of %d\n", + model->name, header.version, SP2_VERSION ); + return qfalse; + } + if( header.numframes < 1 || header.numframes > SP2_MAX_FRAMES ) { + Com_EPrintf( "%s has bad number of frames: %d\n", + model->name, header.numframes ); + return qfalse; + } + if( sizeof( dsp2header_t ) + sizeof( dsp2frame_t ) * header.numframes > length ) { + Com_EPrintf( "%s has frames out of bounds\n", model->name ); + return qfalse; + } + + Hunk_Begin( &model->pool, 0x10000 ); + + model->spriteframes = Model_Malloc( sizeof( mspriteframe_t ) * header.numframes ); + model->numframes = header.numframes; + + src_frame = ( dsp2frame_t * )( ( byte * )rawdata + sizeof( dsp2header_t ) ); + dst_frame = model->spriteframes; + for( i = 0; i < header.numframes; i++ ) { + w = LittleLong( src_frame->width ); + h = LittleLong( src_frame->height ); + if( w < 1 || h < 1 || w > MAX_TEXTURE_SIZE || h > MAX_TEXTURE_SIZE ) { + Com_WPrintf( "%s has bad frame dimensions\n", model->name ); + w = 1; + h = 1; + } + dst_frame->width = w; + dst_frame->height = h; + + // FIXME: are these signed? + x = LittleLong( src_frame->origin_x ); + y = LittleLong( src_frame->origin_y ); + if( x > 8192 || y > 8192 ) { + Com_WPrintf( "%s has bad frame origin\n", model->name ); + x = y = 0; + } + dst_frame->origin_x = x; + dst_frame->origin_y = y; + + memcpy( buffer, src_frame->name, sizeof( buffer ) ); + buffer[sizeof( buffer ) - 1] = 0; + image = IMG_Find( buffer, it_sprite ); + if( !image ) { + image = r_notexture; + } + dst_frame->image = image; + + src_frame++; + dst_frame++; + } + + Hunk_End( &model->pool ); + + return qtrue; +} + + +qhandle_t R_RegisterModel( const char *name ) { + int index; + size_t namelen, filelen; + model_t *model; + byte *rawdata; + uint32_t ident; + qboolean success; + + if( name[0] == '*' ) { + // inline bsp model + index = atoi( name + 1 ); + return ~index; + } + + namelen = strlen( name ); + if( namelen >= MAX_QPATH ) { + Com_Error( ERR_DROP, "%s: oversize name", __func__ ); + } + + model = MOD_Find( name ); + if( model ) { + MOD_Reference( model ); + goto finish; + } + + filelen = 0; + rawdata = NULL; + +#if USE_MD3 + if( r_override_models->integer ) { + char buffer[MAX_QPATH]; + + if( namelen > 4 && !Q_stricmp( name + namelen - 4, ".md2" ) ) { + memcpy( buffer, name, namelen + 1 ); + buffer[namelen - 1] = '3'; + filelen = FS_LoadFile( buffer, ( void ** )&rawdata ); + } + } + if( !rawdata ) +#endif + { + filelen = FS_LoadFile( name, ( void ** )&rawdata ); + if( !rawdata ) { + Com_DPrintf( "Couldn't load %s\n", name ); + return 0; + } + } + + if( filelen < 4 ) { + Com_WPrintf( "%s: %s: file too short\n", __func__, name ); + return 0; + } + + model = MOD_Alloc( name ); + + ident = LittleLong( *( uint32_t * )rawdata ); + switch( ident ) { + case MD2_IDENT: + success = MOD_LoadMD2( model, rawdata, filelen ); + break; +#if USE_MD3 + case MD3_IDENT: + success = MOD_LoadMD3( model, rawdata, filelen ); + break; +#endif + case SP2_IDENT: + success = MOD_LoadSP2( model, rawdata, filelen ); + break; + default: + Com_WPrintf( "%s: %s: unknown ident: %x\n", __func__, name, ident ); + success = qfalse; + break; + } + + FS_FreeFile( rawdata ); + + if( !success ) { + memset( model, 0, sizeof( *model ) ); + return 0; + } + +finish: + index = ( model - r_models ) + 1; + return index; +} + +model_t *MOD_ForHandle( qhandle_t h ) { + model_t *model; + + if( !h ) { + return NULL; + } + if( h < 0 || h > r_numModels ) { + Com_Error( ERR_DROP, "%s: %d out of range", __func__, h ); + } + model = &r_models[ h - 1 ]; + if( !model->name[0] ) { + return NULL; + } + return model; +} + +void MOD_Init( void ) { + if( r_numModels ) { + Com_Error( ERR_FATAL, "%s: %d models not freed", __func__, r_numModels ); + } + +#if USE_MD3 + r_override_models = Cvar_Get( "r_override_models", "0", + CVAR_ARCHIVE|CVAR_FILES ); +#endif + + Cmd_AddCommand( "modellist", MOD_List_f ); +} + +void MOD_Shutdown( void ) { + MOD_FreeAll(); + Cmd_RemoveCommand( "modellist" ); +} + diff --git a/source/r_models.h b/source/r_models.h new file mode 100644 index 0000000..1dbf739 --- /dev/null +++ b/source/r_models.h @@ -0,0 +1,84 @@ +/* +Copyright (C) 2008 Andrey Nazarov + +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. + +*/ + +/* +============================================================================= + +MODEL MANAGER + +============================================================================= +*/ + +#define Model_Malloc( size ) Hunk_Alloc( &model->pool, size ) + +// FIXME: MD3 has 256 limit +#define MAX_ALIAS_SKINS 32 + +typedef struct mspriteframe_s { + int width, height; + int origin_x, origin_y; + struct image_s *image; +} mspriteframe_t; + +typedef struct model_s { + char name[MAX_QPATH]; + int registration_sequence; + mempool_t pool; + + // alias models + int numframes; + struct maliasframe_s *frames; +#if USE_REF == REF_GL + int nummeshes; + struct maliasmesh_s *meshes; +#else + int numskins; + struct image_s *skins[MAX_ALIAS_SKINS]; + int numtris; + struct maliastri_s *tris; + int numsts; + struct maliasst_s *sts; + int numverts; +#endif + + // sprite models + struct mspriteframe_s *spriteframes; +} model_t; + +extern int registration_sequence; + +// these are implemented in r_models.c +void MOD_FreeUnused( void ); +void MOD_FreeAll( void ); +void MOD_Init( void ); +void MOD_Shutdown( void ); + +model_t *MOD_ForHandle( qhandle_t h ); +qhandle_t R_RegisterModel( const char *name ); + +// these are implemented in [gl,sw]_models.c +struct dmd2header_s; +qboolean MOD_ValidateMD2( model_t *model, struct dmd2header_s *header, size_t length ); +qboolean MOD_LoadMD2( model_t *model, const void *rawdata, size_t length ); +#if USE_MD3 +qboolean MOD_LoadMD3( model_t *model, const void *rawdata, size_t length ); +#endif +void MOD_Reference( model_t *model ); + diff --git a/source/r_shared.h b/source/r_shared.h index 2ec2e2d..59ea32e 100644 --- a/source/r_shared.h +++ b/source/r_shared.h @@ -18,28 +18,38 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef SOFTWARE_RENDERER -#ifdef TRUECOLOR_RENDERER -#define VID_BPP 32 -#define VID_BYTES 4 -#define VID_SHIFT 2 -#define VID_IS32BIT 1 +/* +============================================================================= + +IMAGE MANAGER + +============================================================================= +*/ + +#if USE_BGRA +#define MakeColor( r, g, b, a ) MakeLong( b, g, r, a ) #else -#define VID_BPP 8 -#define VID_BYTES 1 -#define VID_SHIFT 0 -#define VID_IS32BIT 0 -#endif +#define MakeColor( r, g, b, a ) MakeLong( r, g, b, a ) #endif -#ifdef USE_BGRA_FORMAT -#define MakeColor( r, g, b, a ) MakeLong( b, g, r, a ) +#define R_Malloc( size ) Z_TagMalloc( size, TAG_RENDERER ) +#define R_Mallocz( size ) Z_TagMallocz( size, TAG_RENDERER ) + +#if USE_REF == REF_GL +#define IMG_AllocPixels( x ) FS_AllocTempMem( x ) +#define IMG_FreePixels( x ) FS_FreeFile( x ) #else -#define MakeColor( r, g, b, a ) MakeLong( r, g, b, a ) +#define IMG_AllocPixels( x ) R_Malloc( x ) +#define IMG_FreePixels( x ) Z_Free( x ) #endif + // absolute limit for OpenGL renderer -#define MAX_TEXTURE_SIZE 2048 +#if USE_REF == REF_GL +#define MAX_TEXTURE_SIZE 2048 +#else +#define MAX_TEXTURE_SIZE 512 +#endif /* @@ -55,336 +65,100 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ typedef enum { - if_transparent = ( 1 << 0 ), - if_paletted = ( 1 << 1 ), - if_scrap = ( 1 << 2 ), - if_replace_wal = ( 1 << 3 ), - if_replace_pcx = ( 1 << 4 ), - if_auto = ( 1 << 5 ) + if_transparent = ( 1 << 0 ), + if_paletted = ( 1 << 1 ), + if_scrap = ( 1 << 2 ), + if_replace_wal = ( 1 << 3 ), + if_replace_pcx = ( 1 << 4 ), + if_auto = ( 1 << 5 ) } imageflags_t; typedef enum { - it_skin, - it_sprite, - it_wall, - it_pic, - it_sky, - it_charset, + it_skin, + it_sprite, + it_wall, + it_pic, + it_sky, + it_charset, it_tmp } imagetype_t; -#define EXTENSION_PNG MakeLong( '.', 'p', 'n', 'g' ) -#define EXTENSION_TGA MakeLong( '.', 't', 'g', 'a' ) -#define EXTENSION_JPG MakeLong( '.', 'j', 'p', 'g' ) -#define EXTENSION_PCX MakeLong( '.', 'p', 'c', 'x' ) -#define EXTENSION_WAL MakeLong( '.', 'w', 'a', 'l' ) +#define EXTENSION_PNG MakeLong( '.', 'p', 'n', 'g' ) +#define EXTENSION_TGA MakeLong( '.', 't', 'g', 'a' ) +#define EXTENSION_JPG MakeLong( '.', 'j', 'p', 'g' ) +#define EXTENSION_PCX MakeLong( '.', 'p', 'c', 'x' ) +#define EXTENSION_WAL MakeLong( '.', 'w', 'a', 'l' ) typedef struct image_s { - list_t entry; - char name[MAX_QPATH]; // game path, without extension - int baselength; // length of the path without extension - imagetype_t type; - int width, height; // source image - int upload_width, upload_height; // after power of two and picmip - int registration_sequence; // 0 = free -#ifdef OPENGL_RENDERER - unsigned texnum; // gl texture binding - float sl, sh, tl, th; -#elif SOFTWARE_RENDERER - byte *pixels[4]; // mip levels + list_t entry; + char name[MAX_QPATH]; // game path, without extension + int baselength; // length of the path without extension + imagetype_t type; + int width, height; // source image + int upload_width, upload_height; // after power of two and picmip + int registration_sequence; // 0 = free +#if USE_REF == REF_GL + unsigned texnum; // gl texture binding + float sl, sh, tl, th; #else -#error Neither OPENGL_RENDERER nor SOFTWARE_RENDERER defined + byte *pixels[4]; // mip levels #endif - imageflags_t flags; + imageflags_t flags; } image_t; +#define MAX_RIMAGES 1024 -#define MAX_RIMAGES 1024 -#define RIMAGES_HASH 256 - -extern image_t r_images[MAX_RIMAGES]; -extern list_t r_imageHash[RIMAGES_HASH]; -extern int r_numImages; - -extern uint32_t d_8to24table[256]; - -#define R_Malloc( size ) com.TagMalloc( size, TAG_RENDERER ) - -/* these are implemented in r_images.c */ -image_t *R_FindImage( const char *name, imagetype_t type ); -image_t *R_AllocImage( const char *name ); -image_t *R_CreateImage( const char *name, byte *pic, int width, int height, - imagetype_t type, imageflags_t flags ); -void R_FreeUnusedImages( void ); -void R_FreeAllImages( void ); -void R_InitImageManager( void ); -void R_ShutdownImageManager( void ); -void R_ResampleTexture( const byte *in, int inwidth, int inheight, byte *out, - int outwidth, int outheight ); -void R_GetPalette( byte **dest ); - -void Image_LoadPCX( const char *filename, byte **pic, byte *palette, int *width, int *height ); -void Image_LoadTGA( const char *filename, byte **pic, int *width, int *height ); -qboolean Image_WriteTGA( const char *filename, const byte *rgb, int width, int height ); -#if USE_JPEG -void Image_LoadJPG( const char *filename, byte **pic, int *width, int *height ); -qboolean Image_WriteJPG( const char *filename, const byte *rgb, int width, int height, int quality ); -#endif -#if USE_PNG -void Image_LoadPNG( const char *filename, byte **pic, int *width, int *height ); -qboolean Image_WritePNG( const char *filename, const byte *rgb, int width, int height, int compression ); -#endif - -/* these should be implemented by renderer library itself */ -void R_FreeImage( image_t *image ); -void R_LoadImage( image_t *image, byte *pic, int width, int height, imagetype_t type, imageflags_t flags ); -image_t *R_LoadWal( const char *name ); +extern image_t r_images[MAX_RIMAGES]; +extern int r_numImages; extern int registration_sequence; -extern image_t *r_notexture; -// -// BSP MODELS -// - -#ifdef SOFTWARE_RENDERER - -// FIXME: differentiate from texinfo SURF_ flags -#define SURF_PLANEBACK 0x02 -#define SURF_DRAWSKY 0x04 // sky brush face -#define SURF_FLOW 0x08 //PGM -#define SURF_DRAWTURB 0x10 -#define SURF_DRAWBACKGROUND 0x40 -#define SURF_DRAWSKYBOX 0x80 // sky box - -#define EXTRA_SURFACES 6 -#define EXTRA_VERTICES 8 -#define EXTRA_EDGES 12 -#define EXTRA_SURFEDGES 24 - -#else // SOFTWARE_RENDERER - -#define EXTRA_SURFACES 0 -#define EXTRA_VERTICES 0 -#define EXTRA_EDGES 0 -#define EXTRA_SURFEDGES 0 - -#endif // !SOFTWARE_RENDERER - -typedef struct bspTexinfo_s { - char name[MAX_QPATH]; - int contents; - int flags; - vec3_t axis[2]; -#ifdef OPENGL_RENDERER -// vec3_t normalizedAxis[2]; -#endif - vec2_t offset; - int numFrames; - struct bspTexinfo_s *animNext; - image_t *image; -} bspTexinfo_t; - -#ifdef OPENGL_RENDERER -typedef enum { - DSURF_POLY, - DSURF_WARP, - DSURF_NOLM, - DSURF_SKY, +extern image_t *r_notexture; - DSURF_NUM_TYPES -} drawSurfType_t; +extern uint32_t d_8to24table[256]; + +// these are implemented in r_images.c +image_t *IMG_Alloc( const char *name ); +image_t *IMG_Find( const char *name, imagetype_t type ); +image_t *IMG_Create( const char *name, byte *pic, int width, int height, + imagetype_t type, imageflags_t flags ); +void IMG_FreeUnused( void ); +void IMG_FreeAll( void ); +void IMG_Init( void ); +void IMG_Shutdown( void ); +void IMG_GetPalette( byte **dest ); + +image_t *IMG_ForHandle( qhandle_t h ); +qhandle_t R_RegisterSkin( const char *name ); +qhandle_t R_RegisterPic( const char *name ); +qhandle_t R_RegisterFont( const char *name ); + +qboolean IMG_LoadPCX( const char *filename, byte **pic, byte *palette, + int *width, int *height ); + +#if USE_TGA +void IMG_LoadTGA( const char *filename, byte **pic, int *width, int *height ); +qboolean IMG_WriteTGA( const char *filename, const byte *rgb, + int width, int height ); #endif -typedef struct bspSurface_s { -#ifdef OPENGL_RENDERER -/* ======> */ - drawSurfType_t type; -/* <====== */ -#endif - - int index; - - vec3_t origin; - vec3_t mins; - vec3_t maxs; - - bspTexinfo_t *texinfo; - byte *lightmap; - int *firstSurfEdge; - int numSurfEdges; - - cplane_t *plane; - int side; - - int texturemins[2]; - int extents[2]; - -#ifdef OPENGL_RENDERER - int texnum[2]; - int texflags; - - int firstVert; - int numVerts; // FIXME: duplicates numSurfEdges - int numIndices; - - int drawframe; - int dlightframe; - int dlightbits; - - vec_t *vertices; // used for sky surfaces only - - struct bspSurface_s *next; +#if USE_JPG +void IMG_LoadJPG( const char *filename, byte **pic, int *width, int *height ); +qboolean IMG_WriteJPG( const char *filename, const byte *rgb, + int width, int height, int quality ); #endif -} bspSurface_t; - -typedef struct bspNode_s { -/* ======> */ - cplane_t *plane; // never NULL - int index; - - vec3_t mins; - vec3_t maxs; - - int visframe; - - struct bspNode_s *parent; -/* <====== */ - - int numFaces; - bspSurface_t *firstFace; - - struct bspNode_s *children[2]; -} bspNode_t; - -typedef struct bspLeaf_s { -/* ======> */ - cplane_t *plane; // always NULL - int index; - - vec3_t mins; - vec3_t maxs; - - int visframe; - - struct bspNode_s *parent; -/* <====== */ - - int cluster; - int area; - int contents; - - int numLeafFaces; - bspSurface_t **firstLeafFace; -} bspLeaf_t; - -typedef enum { - MODEL_NULL, - MODEL_BSP, - MODEL_ALIAS, - MODEL_SPRITE -} modelType_t; - -typedef struct bspSubmodel_s { - modelType_t type; - vec3_t mins; - vec3_t maxs; - float radius; - - vec3_t origin; - - int numFaces; - bspSurface_t *firstFace; - - bspNode_t *headnode; -} bspSubmodel_t; - -typedef struct bspModel_s { - char name[MAX_QPATH]; - mempool_t pool; - - bspSubmodel_t *submodels; - int numSubmodels; - - bspTexinfo_t *texinfos; - int numTexinfos; - - bspSurface_t *surfaces; - int numSurfaces; - - bspSurface_t **leafFaces; - int numLeafFaces; - - cplane_t *planes; - int numPlanes; - - bspLeaf_t *leafs; - int numLeafs; - - bspNode_t *nodes; - int numNodes; - - byte *vis; - int numClusters; - int rowsize; - - byte *lightmap; - unsigned lightmapSize; - -// char *entityString; - - dvertex_t *vertices; - int numVertices; - - dedge_t *edges; - int numEdges; - - int *surfEdges; - int numSurfEdges; -} bspModel_t; - - -extern bspModel_t r_world; - -void Bsp_FreeWorld( void ); -void Bsp_LoadWorld( const char *path ); -bspLeaf_t *Bsp_FindLeaf( vec3_t origin ); -byte *Bsp_ClusterPVS( int clusterNum ); - -#ifdef OPENGL_RENDERER -extern bspTexinfo_t *upload_texinfo; -void GL_BeginPostProcessing( void ); -void GL_EndPostProcessing( void ); +#if USE_PNG +void IMG_LoadPNG( const char *filename, byte **pic, int *width, int *height ); +qboolean IMG_WritePNG( const char *filename, const byte *rgb, + int width, int height, int compression ); #endif -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define LL(x) ( dst->x = src->x ) -#define LF(x) ( dst->x = src->x ) -#define LV(x) ( dst->x[0] = src->x[0], \ - dst->x[1] = src->x[1], \ - dst->x[2] = src->x[2] ) -#define LLV(x) ( dst->x[0] = src->x[0], \ - dst->x[1] = src->x[1], \ - dst->x[2] = src->x[2] ) -#define LSV(x) ( dst->x[0] = src->x[0], \ - dst->x[1] = src->x[1], \ - dst->x[2] = src->x[2] ) -#elif __BYTE_ORDER == __BIG_ENDIAN -#define LL(x) ( dst->x = LongSwap( src->x ) ) -#define LF(x) ( dst->x = FloatSwap( src->x ) ) -#define LV(x) ( dst->x[0] = FloatSwap( src->x[0] ), \ - dst->x[1] = FloatSwap( src->x[1] ), \ - dst->x[2] = FloatSwap( src->x[2] ) ) -#define LLV(x) ( dst->x[0] = LongSwap( src->x[0] ), \ - dst->x[1] = LongSwap( src->x[1] ), \ - dst->x[2] = LongSwap( src->x[2] ) ) -#define LSV(x) ( dst->x[0] = ( signed short )ShortSwap( src->x[0] ), \ - dst->x[1] = ( signed short )ShortSwap( src->x[1] ), \ - dst->x[2] = ( signed short )ShortSwap( src->x[2] ) ) -#else -#error Unknown byte order -#endif +// these are implemented in [gl,sw]_images.c +void IMG_Unload( image_t *image ); +void IMG_Load( image_t *image, byte *pic, int width, int height, + imagetype_t type, imageflags_t flags ); +image_t *IMG_LoadWAL( const char *name ); diff --git a/source/ref_public.h b/source/ref_public.h index 4bb0b47..f49aa8e 100644 --- a/source/ref_public.h +++ b/source/ref_public.h @@ -177,72 +177,55 @@ typedef struct { int left, right, top, bottom; } clipRect_t; -// -// these are the functions exported by the refresh module -// -typedef struct refAPI_s { - // called when the library is loaded - qboolean (*Init)( qboolean total ); - - // called before the library is unloaded - void (*Shutdown)( qboolean total ); - - // All data that will be used in a level should be - // registered before rendering any frames to prevent disk hits, - // but they can still be registered at a later time - // if necessary. - // - // EndRegistration will free any remaining data that wasn't registered. - // Any model_s or skin_s pointers from before the BeginRegistration - // are no longer valid after EndRegistration. - // - // Skins and images need to be differentiated, because skins - // are flood filled to eliminate mip map edge errors, and pics have - // an implicit "pics/" prepended to the name. (a pic name that starts with a - // slash will not use the "pics/" prefix or the ".pcx" postfix) - void (*BeginRegistration)( const char *map ); - qhandle_t (*RegisterModel)( const char *name ); - qhandle_t (*RegisterSkin)( const char *name ); - qhandle_t (*RegisterPic)( const char *name ); - qhandle_t (*RegisterFont)( const char *name ); - void (*SetSky)( const char *name, float rotate, vec3_t axis ); - void (*EndRegistration)( void ); - void (*GetModelSize)( qhandle_t hModel, vec3_t mins, vec3_t maxs ); - - void (*RenderFrame)( refdef_t *fd ); - void (*LightPoint)( vec3_t origin, vec3_t light ); - - void (*SetColor)( int flags, const color_t color ); - void (*SetClipRect)( int flags, const clipRect_t *clip ); - void (*SetScale)( float *scale ); - void (*DrawChar)( int x, int y, int flags, int ch, qhandle_t hFont ); - int (*DrawString)( int x, int y, int flags, size_t maxChars, - const char *string, qhandle_t hFont ); // returns advanced x coord - // will return 0 0 if not found - qboolean (*DrawGetPicSize)( int *w, int *h, qhandle_t hPic ); // returns transparency bit - void (*DrawPic)( int x, int y, qhandle_t hPic ); - void (*DrawStretchPic)( int x, int y, int w, int h, qhandle_t hPic ); - void (*DrawStretchPicST)( int x, int y, int w, int h, - float s1, float t1, float s2, float t2, qhandle_t hPic ); - void (*DrawTileClear)( int x, int y, int w, int h, qhandle_t hPic ); - void (*DrawFill)( int x, int y, int w, int h, int c ); - void (*DrawFillEx)( int x, int y, int w, int h, const color_t color ); - - // Draw images for cinematic rendering (which can have a different palette). - void (*DrawStretchRaw)( int x, int y, int w, int h, int cols, int rows, const byte *data ); +// called when the library is loaded +qboolean R_Init( qboolean total ); - /* - ** video mode and refresh state management entry points - */ - void (*CinematicSetPalette)( const byte *palette ); // NULL = game palette - void (*BeginFrame)( void ); - void (*EndFrame)( void ); - void (*ModeChanged)( int width, int height, int flags, - int rowbytes, void *pixels ); +// called before the library is unloaded +void R_Shutdown( qboolean total ); - void (*GetConfig)( glconfig_t *dest ); -} refAPI_t; - -extern refAPI_t ref; +// All data that will be used in a level should be +// registered before rendering any frames to prevent disk hits, +// but they can still be registered at a later time +// if necessary. +// +// EndRegistration will free any remaining data that wasn't registered. +// Any model_s or skin_s pointers from before the BeginRegistration +// are no longer valid after EndRegistration. +// +// Skins and images need to be differentiated, because skins +// are flood filled to eliminate mip map edge errors, and pics have +// an implicit "pics/" prepended to the name. (a pic name that starts with a +// slash will not use the "pics/" prefix or the ".pcx" postfix) +void R_BeginRegistration( const char *map ); +qhandle_t R_RegisterModel( const char *name ); +qhandle_t R_RegisterSkin( const char *name ); +qhandle_t R_RegisterPic( const char *name ); +qhandle_t R_RegisterFont( const char *name ); +void R_SetSky( const char *name, float rotate, vec3_t axis ); +void R_EndRegistration( void ); + +void R_RenderFrame( refdef_t *fd ); +void R_LightPoint( vec3_t origin, vec3_t light ); + +void R_SetColor( int flags, const color_t color ); +void R_SetClipRect( int flags, const clipRect_t *clip ); +void R_SetScale( float *scale ); +void R_DrawChar( int x, int y, int flags, int ch, qhandle_t font ); +int R_DrawString( int x, int y, int flags, size_t maxChars, + const char *string, qhandle_t font ); // returns advanced x coord +qboolean R_GetPicSize( int *w, int *h, qhandle_t pic ); // returns transparency bit +void R_DrawPic( int x, int y, qhandle_t pic ); +void R_DrawStretchPic( int x, int y, int w, int h, qhandle_t pic ); +void R_DrawStretchPicST( int x, int y, int w, int h, + float s1, float t1, float s2, float t2, qhandle_t pic ); +void R_TileClear( int x, int y, int w, int h, qhandle_t pic ); +void R_DrawFill( int x, int y, int w, int h, int c ); +void R_DrawFillEx( int x, int y, int w, int h, const color_t color ); + +// video mode and refresh state management entry points +void R_BeginFrame( void ); +void R_EndFrame( void ); +void R_ModeChanged( int width, int height, int flags, int rowbytes, void *pixels ); +void R_GetConfig( glconfig_t *dest ); #endif // __REF_H diff --git a/source/sv_ac.c b/source/sv_ac.c index fae15df..e550238 100644 --- a/source/sv_ac.c +++ b/source/sv_ac.c @@ -1334,7 +1334,7 @@ void AC_Connect( qboolean ismvd ) { return; } -#ifndef DEDICATED_ONLY +#if USE_CLIENT if( !dedicated->integer ) { Com_Printf( "ANTICHEAT: Only supported on dedicated servers, disabling.\n" ); Cvar_SetByVar( ac_required, "0", CVAR_SET_DIRECT ); diff --git a/source/sv_ccmds.c b/source/sv_ccmds.c index bf0abe3..a388e16 100644 --- a/source/sv_ccmds.c +++ b/source/sv_ccmds.c @@ -41,7 +41,7 @@ static void SV_SetMaster_f( void ) { int i, j, slot; char *s; -#ifndef DEDICATED_ONLY +#if USE_CLIENT // only dedicated servers send heartbeats if( !dedicated->integer ) { Com_Printf( "Only dedicated servers use masters.\n" ); @@ -233,7 +233,7 @@ static void SV_Map_c( genctx_t *ctx, int argnum ) { } static void SV_DumpEnts_f( void ) { - cmcache_t *c = sv.cm.cache; + bsp_t *c = sv.cm.cache; fileHandle_t f; char *s, buffer[MAX_QPATH]; @@ -257,7 +257,7 @@ static void SV_DumpEnts_f( void ) { FS_FOpenFile( buffer, &f, FS_MODE_WRITE ); if( f ) { - FS_Write( c->entitystring, c->numEntityChars, f ); + FS_Write( c->entitystring, c->numentitychars, f ); FS_FCloseFile( f ); Com_Printf( "Dumped entity string to %s\n", buffer ); } else { diff --git a/source/sv_ents.c b/source/sv_ents.c index a662fee..7092693 100644 --- a/source/sv_ents.c +++ b/source/sv_ents.c @@ -320,7 +320,7 @@ Build a client frame structure */ qboolean SV_EdictPV( cm_t *cm, edict_t *ent, byte *mask ) { - cnode_t *node; + mnode_t *node; int i, l; if( ent->num_clusters == -1 ) { @@ -357,9 +357,10 @@ void SV_BuildClientFrame( client_t *client ) { player_state_t *ps; int l; int clientarea, clientcluster; - cleaf_t *leaf; - byte *clientphs; - byte *clientpvs; + mleaf_t *leaf; + byte clientphs[MAX_MAP_VIS]; + byte clientpvs[MAX_MAP_VIS]; + extern cvar_t *sv_novis; clent = client->edict; if( !clent->client ) @@ -396,8 +397,8 @@ void SV_BuildClientFrame( client_t *client ) { frame->clientNum = client->number; } - clientpvs = CM_FatPVS( client->cm, org ); - clientphs = CM_ClusterPHS( client->cm, clientcluster ); + CM_FatPVS( client->cm, clientpvs, org ); + BSP_ClusterVis( client->cm->cache, clientphs, clientcluster, DVIS_PHS ); // build up the list of visible entities frame->numEntities = 0; @@ -430,7 +431,7 @@ void SV_BuildClientFrame( client_t *client ) { } // ignore if not touching a PV leaf - if( ent != clent ) { + if( ent != clent && !sv_novis->integer ) { // check area if( !CM_AreasConnected( client->cm, clientarea, ent->areanum ) ) { // doors can legally straddle two areas, so diff --git a/source/sv_game.c b/source/sv_game.c index 5a24858..3ad8cde 100644 --- a/source/sv_game.c +++ b/source/sv_game.c @@ -325,7 +325,7 @@ Also sets mins and maxs for inline bmodels */ static void PF_setmodel (edict_t *ent, const char *name) { int i; - cmodel_t *mod; + mmodel_t *mod; if (!name) Com_Error (ERR_DROP, "PF_setmodel: NULL"); @@ -403,6 +403,28 @@ static void PF_WriteFloat( float f ) { Com_Error( ERR_DROP, "PF_WriteFloat not implemented" ); } +static qboolean PF_inVIS( vec3_t p1, vec3_t p2, int vis ) { + mleaf_t *leaf1, *leaf2; + byte mask[MAX_MAP_VIS]; + bsp_t *bsp = sv.cm.cache; + + if( !bsp ) { + Com_Error( ERR_DROP, "%s: no map loaded", __func__ ); + } + + leaf1 = BSP_PointLeaf( bsp->nodes, p1 ); + BSP_ClusterVis( bsp, mask, leaf1->cluster, vis ); + + leaf2 = BSP_PointLeaf( bsp->nodes, p2 ); + if( !Q_IsBitSet( mask, leaf2->cluster ) ) { + return qfalse; + } + if( !CM_AreasConnected( &sv.cm, leaf1->area, leaf2->area ) ) { + return qfalse; // a door blocks it + } + return qtrue; +} + /* ================= PF_inPVS @@ -410,32 +432,10 @@ PF_inPVS Also checks portalareas so that doors block sight ================= */ -static qboolean PF_inPVS (vec3_t p1, vec3_t p2) { - cleaf_t *leaf; - int cluster; - int area1, area2; - byte *mask; - - if( !sv.cm.cache ) { - Com_Error( ERR_DROP, "PF_inPVS: no map loaded" ); - } - - leaf = CM_PointLeaf (&sv.cm, p1); - cluster = CM_LeafCluster (leaf); - area1 = CM_LeafArea (leaf); - mask = CM_ClusterPVS (&sv.cm, cluster); - - leaf = CM_PointLeaf (&sv.cm, p2); - cluster = CM_LeafCluster (leaf); - area2 = CM_LeafArea (leaf); - if ( !Q_IsBitSet( mask, cluster ) ) - return qfalse; - if (!CM_AreasConnected (&sv.cm, area1, area2)) - return qfalse; // a door blocks sight - return qtrue; +static qboolean PF_inPVS( vec3_t p1, vec3_t p2 ) { + return PF_inVIS( p1, p2, DVIS_PVS ); } - /* ================= PF_inPHS @@ -443,30 +443,8 @@ PF_inPHS Also checks portalareas so that doors block sound ================= */ -static qboolean PF_inPHS (vec3_t p1, vec3_t p2) { - cleaf_t *leaf; - int cluster; - int area1, area2; - byte *mask; - - if( !sv.cm.cache ) { - Com_Error( ERR_DROP, "PF_inPHS: no map loaded" ); - } - - leaf = CM_PointLeaf (&sv.cm, p1); - cluster = CM_LeafCluster (leaf); - area1 = CM_LeafArea (leaf); - mask = CM_ClusterPHS (&sv.cm, cluster); - - leaf = CM_PointLeaf (&sv.cm, p2); - cluster = CM_LeafCluster (leaf); - area2 = CM_LeafArea (leaf); - if( !Q_IsBitSet( mask, cluster ) ) - return qfalse; // more than one bounce away - if (!CM_AreasConnected (&sv.cm, area1, area2)) - return qfalse; // a door blocks hearing - - return qtrue; +static qboolean PF_inPHS( vec3_t p1, vec3_t p2 ) { + return PF_inVIS( p1, p2, DVIS_PHS ); } /* @@ -504,9 +482,9 @@ static void PF_StartSound( edict_t *edict, int channel, int ent; vec3_t origin; client_t *client; - byte *mask; - cleaf_t *leaf; - int area, cluster; + byte mask[MAX_MAP_VIS]; + mleaf_t *leaf; + int area; player_state_t *ps; sound_packet_t *msg; @@ -561,8 +539,7 @@ static void PF_StartSound( edict_t *edict, int channel, continue; // blocked by a door } } - cluster = CM_LeafCluster( leaf ); - mask = CM_ClusterPHS( &sv.cm, cluster ); + BSP_ClusterVis( sv.cm.cache, mask, leaf->cluster, DVIS_PHS ); if( !SV_EdictPV( &sv.cm, edict, mask ) ) { continue; // not in PHS } @@ -742,6 +719,23 @@ static qboolean PF_AreasConnected( int area1, int area2 ) { return CM_AreasConnected( &sv.cm, area1, area2 ); } +static void *PF_TagMalloc( size_t size, unsigned tag ) { + if( tag + TAG_MAX < tag ) { + Com_Error( ERR_FATAL, "%s: bad tag", __func__ ); + } + if( !size ) { + return NULL; + } + return memset( Z_TagMalloc( size, tag + TAG_MAX ), 0, size ); +} + +static void PF_FreeTags( unsigned tag ) { + if( tag + TAG_MAX < tag ) { + Com_Error( ERR_FATAL, "%s: bad tag", __func__ ); + } + Z_FreeTags( tag + TAG_MAX ); +} + //============================================== static void *game_library; @@ -791,23 +785,26 @@ void SV_InitGameProgs ( void ) { if( !entry ) #endif { - // try gamedir first + // try ./game first if( fs_game->string[0] ) { Q_concat( path, sizeof( path ), sys_libdir->string, PATH_SEP_STRING, fs_game->string, PATH_SEP_STRING GAMELIB, NULL ); entry = Sys_LoadLibrary( path, "GetGameAPI", &game_library ); } if( !entry ) { - // then try baseq2 + // then try ./baseq2 Q_concat( path, sizeof( path ), sys_libdir->string, PATH_SEP_STRING BASEGAME PATH_SEP_STRING GAMELIB, NULL ); entry = Sys_LoadLibrary( path, "GetGameAPI", &game_library ); if( !entry ) { - // then try to fall back to refdir - Q_concat( path, sizeof( path ), sys_refdir->string, +#ifdef __unix__ + // then try ./ + Q_concat( path, sizeof( path ), sys_libdir->string, PATH_SEP_STRING GAMELIB, NULL ); entry = Sys_LoadLibrary( path, "GetGameAPI", &game_library ); - if( !entry ) { + if( !entry ) +#endif + { Com_Error( ERR_DROP, "Failed to load game DLL" ); } } @@ -863,9 +860,9 @@ void SV_InitGameProgs ( void ) { import.WriteDir = MSG_WriteDir; import.WriteAngle = MSG_WriteAngle; - import.TagMalloc = Z_TagMallocz; + import.TagMalloc = PF_TagMalloc; import.TagFree = Z_Free; - import.FreeTags = Z_FreeTags; + import.FreeTags = PF_FreeTags; import.cvar = PF_cvar; import.cvar_set = Cvar_UserSet; diff --git a/source/sv_init.c b/source/sv_init.c index b3b062f..c697024 100644 --- a/source/sv_init.c +++ b/source/sv_init.c @@ -96,7 +96,7 @@ static void SV_SpawnServer( cm_t *cm, const char *server, const char *spawnpoint sprintf( sv.configstrings[CS_MAPCHECKSUM], "%d", ( int )cm->cache->checksum ); - for( i = 1; i < sv.cm.cache->numcmodels; i++ ) { + for( i = 1; i < sv.cm.cache->nummodels; i++ ) { sprintf( sv.configstrings[ CS_MODELS + 1 + i ], "*%d", i ); } @@ -114,7 +114,7 @@ static void SV_SpawnServer( cm_t *cm, const char *server, const char *spawnpoint sv.state = ss_loading; // load and spawn all other entities - ge->SpawnEntities ( sv.name, CM_EntityString( &sv.cm ), spawnpoint ); + ge->SpawnEntities ( sv.name, cm->cache->entitystring, spawnpoint ); // run two frames to allow everything to settle ge->RunFrame (); @@ -312,8 +312,6 @@ void SV_Map (const char *levelstring, qboolean restart) { char expanded[MAX_QPATH]; char *ch; cm_t cm; - uint32_t checksum; - const char *error; // skip the end-of-unit flag if necessary if( *levelstring == '*' ) { @@ -342,8 +340,8 @@ void SV_Map (const char *levelstring, qboolean restart) { } Q_concat( expanded, sizeof( expanded ), "maps/", level, ".bsp", NULL ); - if( ( error = CM_LoadMapEx( &cm, expanded, 0, &checksum ) ) != NULL ) { - Com_Printf( "Couldn't load %s: %s\n", expanded, error ); + if( !CM_LoadMap( &cm, expanded ) ) { + Com_Printf( "Couldn't load %s: %s\n", expanded, BSP_GetError() ); return; } diff --git a/source/sv_local.h b/source/sv_local.h index 39c0ecd..1749a00 100644 --- a/source/sv_local.h +++ b/source/sv_local.h @@ -24,7 +24,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "com_local.h" #include "q_list.h" +#include "files.h" +#include "sys_public.h" +#include "bsp.h" +#include "cmodel.h" +#include "pmove.h" +#include "protocol.h" +#include "q_msg.h" +#include "q_fifo.h" +#include "net_sock.h" +#include "net_stream.h" +#include "net_chan.h" #include "g_public.h" +#include "sv_public.h" +#include "cl_public.h" #if USE_ZLIB #include <zlib.h> #endif diff --git a/source/sv_main.c b/source/sv_main.c index 4ece3da..75bd455 100644 --- a/source/sv_main.c +++ b/source/sv_main.c @@ -55,6 +55,7 @@ cvar_t *allow_download_other; cvar_t *sv_airaccelerate; cvar_t *sv_qwmod; // atu QW Physics modificator cvar_t *sv_noreload; // don't reload level state when reentering +cvar_t *sv_novis; cvar_t *sv_http_enable; cvar_t *sv_http_maxclients; @@ -1148,7 +1149,7 @@ static void SV_GiveMsec( void ) { SV_PacketEvent ================= */ -void SV_PacketEvent( neterr_t ret ) { +static void SV_PacketEvent( neterr_t ret ) { client_t *client; netchan_t *netchan; int qport; @@ -1226,6 +1227,32 @@ void SV_PacketEvent( neterr_t ret ) { } } +void SV_ProcessEvents( void ) { + neterr_t ret; + +#if USE_CLIENT + memset( &net_from, 0, sizeof( net_from ) ); + net_from.type = NA_LOOPBACK; + + // process loopback packets + while( NET_GetLoopPacket( NS_SERVER ) ) { + if( sv_running->integer ) { + SV_PacketEvent( NET_OK ); + } + } +#endif + + // process network packets + do { + ret = NET_GetPacket( NS_SERVER ); + if( ret == NET_AGAIN ) { + break; + } + SV_PacketEvent( ret ); + } while( ret == NET_OK ); +} + + /* ================== SV_SendAsyncPackets @@ -1371,7 +1398,7 @@ SV_RunGameFrame ================= */ static void SV_RunGameFrame( void ) { -#ifndef DEDICATED_ONLY +#if USE_CLIENT if( host_speeds->integer ) time_before_game = Sys_Milliseconds(); #endif @@ -1407,7 +1434,7 @@ static void SV_RunGameFrame( void ) { svs.realtime = svs.time; } -#ifndef DEDICATED_ONLY +#if USE_CLIENT if( host_speeds->integer ) time_after_game = Sys_Milliseconds(); #endif @@ -1488,7 +1515,7 @@ SV_Frame void SV_Frame( int msec ) { int mvdconns; -#ifndef DEDICATED_ONLY +#if USE_CLIENT time_before_game = time_after_game = 0; #endif @@ -1504,7 +1531,7 @@ void SV_Frame( int msec ) { return; } -#ifndef DEDICATED_ONLY +#if USE_CLIENT // pause if there is only local client on the server if( !dedicated->integer && cl_paused->integer && List_Count( &svs.udp_client_list ) == 1 && mvdconns == 0 && @@ -1770,6 +1797,7 @@ void SV_Init( void ) { sv_password = Cvar_Get( "sv_password", "", CVAR_PRIVATE ); sv_reserved_password = Cvar_Get( "sv_reserved_password", "", CVAR_PRIVATE ); sv_locked = Cvar_Get( "sv_locked", "0", 0 ); + sv_novis = Cvar_Get ("sv_novis", "0", 0); sv_debug_send = Cvar_Get( "sv_debug_send", "0", 0 ); sv_pad_packets = Cvar_Get( "sv_pad_packets", "0", 0 ); diff --git a/source/sv_public.h b/source/sv_public.h new file mode 100644 index 0000000..06a7c74 --- /dev/null +++ b/source/sv_public.h @@ -0,0 +1,39 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +typedef enum { + ss_dead, // no map loaded + ss_loading, // spawning level edicts + ss_game, // actively running + ss_broadcast +} server_state_t; + +typedef enum { + KILL_RESTART, + KILL_DISCONNECT, + KILL_DROP +} killtype_t; + +void SV_ProcessEvents( void ); +void SV_Init (void); +void SV_Shutdown( const char *finalmsg, killtype_t type ); +void SV_Frame (int msec); +qboolean MVD_GetDemoPercent( int *percent, int *bufferPercent ); + diff --git a/source/sv_send.c b/source/sv_send.c index a591b78..680369f 100644 --- a/source/sv_send.c +++ b/source/sv_send.c @@ -223,11 +223,9 @@ MULTICAST_PHS send to clients potentially hearable from org */ void SV_Multicast( vec3_t origin, multicast_t to ) { client_t *client; - byte *mask; - cleaf_t *leaf; + byte mask[MAX_MAP_VIS]; + mleaf_t *leaf1, *leaf2; int leafnum; - int cluster; - int area1, area2; int flags; vec3_t org; player_state_t *ps; @@ -238,33 +236,30 @@ void SV_Multicast( vec3_t origin, multicast_t to ) { switch( to ) { case MULTICAST_ALL_R: - flags |= MSG_RELIABLE; // intentional fallthrough + flags |= MSG_RELIABLE; buf = &sv.mvd.message; + // intentional fallthrough case MULTICAST_ALL: - area1 = 0; + leaf1 = NULL; leafnum = 0; - cluster = 0; - mask = NULL; break; case MULTICAST_PHS_R: - flags |= MSG_RELIABLE; // intentional fallthrough + flags |= MSG_RELIABLE; buf = &sv.mvd.message; + // intentional fallthrough case MULTICAST_PHS: - leaf = CM_PointLeaf( &sv.cm, origin ); - leafnum = leaf - sv.cm.cache->leafs; - area1 = CM_LeafArea( leaf ); - cluster = CM_LeafCluster( leaf ); - mask = CM_ClusterPHS( &sv.cm, cluster ); + leaf1 = CM_PointLeaf( &sv.cm, origin ); + leafnum = leaf1 - sv.cm.cache->leafs; + BSP_ClusterVis( sv.cm.cache, mask, leaf1->cluster, DVIS_PHS ); break; case MULTICAST_PVS_R: - flags |= MSG_RELIABLE; // intentional fallthrough + flags |= MSG_RELIABLE; buf = &sv.mvd.message; + // intentional fallthrough case MULTICAST_PVS: - leaf = CM_PointLeaf( &sv.cm, origin ); - leafnum = leaf - sv.cm.cache->leafs; - area1 = CM_LeafArea( leaf ); - cluster = CM_LeafCluster( leaf ); - mask = CM_ClusterPVS( &sv.cm, cluster ); + leaf1 = CM_PointLeaf( &sv.cm, origin ); + leafnum = leaf1 - sv.cm.cache->leafs; + BSP_ClusterVis( sv.cm.cache, mask, leaf1->cluster, DVIS_PVS ); break; default: Com_Error( ERR_DROP, "SV_Multicast: bad to: %i", to ); @@ -282,23 +277,20 @@ void SV_Multicast( vec3_t origin, multicast_t to ) { continue; } - if( mask ) { + if( leaf1 ) { // find the client's PVS ps = &client->edict->client->ps; VectorMA( ps->viewoffset, 0.125f, ps->pmove.origin, org ); - leaf = CM_PointLeaf( &sv.cm, org ); - area2 = CM_LeafArea( leaf ); - if( !CM_AreasConnected( &sv.cm, area1, area2 ) ) { + leaf2 = CM_PointLeaf( &sv.cm, org ); + if( !CM_AreasConnected( &sv.cm, leaf1->area, leaf2->area ) ) { continue; } - cluster = CM_LeafCluster( leaf ); - if( !Q_IsBitSet( mask, cluster ) ) { + if( !Q_IsBitSet( mask, leaf2->cluster ) ) { continue; } } SV_ClientAddMessage( client, flags ); - } // add to MVD datagram diff --git a/source/sv_world.c b/source/sv_world.c index 54f5e30..3ad9748 100644 --- a/source/sv_world.c +++ b/source/sv_world.c @@ -101,7 +101,7 @@ SV_ClearWorld =============== */ void SV_ClearWorld( void ) { - cmodel_t *cm; + mmodel_t *cm; edict_t *ent; int i; @@ -109,7 +109,7 @@ void SV_ClearWorld( void ) { sv_numareanodes = 0; if( sv.cm.cache ) { - cm = &sv.cm.cache->cmodels[0]; + cm = &sv.cm.cache->models[0]; SV_CreateAreaNode( 0, cm->mins, cm->maxs ); } @@ -130,12 +130,12 @@ Links entity to PVS leafs. =============== */ void SV_LinkEdict( cm_t *cm, edict_t *ent ) { - cleaf_t *leafs[MAX_TOTAL_ENT_LEAFS]; + mleaf_t *leafs[MAX_TOTAL_ENT_LEAFS]; int clusters[MAX_TOTAL_ENT_LEAFS]; int num_leafs; int i, j; int area; - cnode_t *topnode; + mnode_t *topnode; // set the size VectorSubtract (ent->maxs, ent->mins, ent->size); @@ -431,16 +431,17 @@ Returns a headnode that can be used for testing or clipping an object of mins/maxs size. ================ */ -static cnode_t *SV_HullForEntity( edict_t *ent ) { - cmodel_t *model; +static mnode_t *SV_HullForEntity( edict_t *ent ) { + mmodel_t *model; if( ent->solid == SOLID_BSP ) { // explicit hulls in the BSP model - if( ent->s.modelindex < 2 || ent->s.modelindex > sv.cm.cache->numcmodels ) { - Com_Error( ERR_DROP, "SV_HullForEntity: inline model index %d out of range", ent->s.modelindex ); + if( ent->s.modelindex < 2 || ent->s.modelindex > sv.cm.cache->nummodels ) { + Com_Error( ERR_DROP, "%s: inline model index %d out of range", + __func__, ent->s.modelindex ); } - model = &sv.cm.cache->cmodels[ ent->s.modelindex - 1 ]; + model = &sv.cm.cache->models[ ent->s.modelindex - 1 ]; return model->headnode; } @@ -459,7 +460,7 @@ int SV_PointContents (vec3_t p) edict_t *touch[MAX_EDICTS], *hit; int i, num; int contents, c2; - cnode_t *headnode; + mnode_t *headnode; if( !sv.cm.cache ) { Com_Error( ERR_DROP, "%s: no map loaded", __func__ ); @@ -507,7 +508,7 @@ static void SV_ClipMoveToEntities( moveclip_t *clip ) { int i, num; edict_t *touchlist[MAX_EDICTS], *touch; trace_t trace; - cnode_t *headnode; + mnode_t *headnode; num = SV_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist , MAX_EDICTS, AREA_SOLID); diff --git a/source/sw_alias.c b/source/sw_alias.c index be24ad2..d9bb54c 100644 --- a/source/sw_alias.c +++ b/source/sw_alias.c @@ -44,8 +44,7 @@ int r_aliasblendcolor; float r_shadelight; -daliasframe_t *r_thisframe, *r_lastframe; -dmdl_t *s_pmdl; +maliasframe_t *r_thisframe, *r_lastframe; float aliastransform[3][4]; float aliasworldtransform[3][4]; @@ -54,27 +53,30 @@ float aliasoldworldtransform[3][4]; static float s_ziscale; static vec3_t s_alias_forward, s_alias_right, s_alias_up; -void R_AliasSetUpLerpData( dmdl_t *pmdl, float backlerp ); -void R_AliasSetUpTransform (void); -void R_AliasTransformVector (vec3_t in, vec3_t out, float m[3][4] ); -void R_AliasProjectAndClipTestFinalVert (finalvert_t *fv); - -void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv ); - -void R_AliasLerpFrames( dmdl_t *paliashdr, float backlerp ); - - #define BBOX_TRIVIAL_ACCEPT 0 #define BBOX_MUST_CLIP_XY 1 #define BBOX_MUST_CLIP_Z 2 #define BBOX_TRIVIAL_REJECT 8 /* +================ +R_AliasTransformVector +================ +*/ +void R_AliasTransformVector(vec3_t in, vec3_t out, float xf[3][4] ) +{ + out[0] = DotProduct(in, xf[0]) + xf[0][3]; + out[1] = DotProduct(in, xf[1]) + xf[1][3]; + out[2] = DotProduct(in, xf[2]) + xf[2][3]; +} + + +/* ** R_AliasCheckFrameBBox ** ** Checks a specific alias frame bounding box */ -unsigned long R_AliasCheckFrameBBox( daliasframe_t *frame, float worldxf[3][4] ) +unsigned long R_AliasCheckFrameBBox( maliasframe_t *frame, float worldxf[3][4] ) { unsigned long aggregate_and_clipcode = ~0U, aggregate_or_clipcode = 0; @@ -199,14 +201,96 @@ qboolean R_AliasCheckBBox (void) /* ================ -R_AliasTransformVector +R_AliasProjectAndClipTestFinalVert ================ */ -void R_AliasTransformVector(vec3_t in, vec3_t out, float xf[3][4] ) +void R_AliasProjectAndClipTestFinalVert( finalvert_t *fv ) { - out[0] = DotProduct(in, xf[0]) + xf[0][3]; - out[1] = DotProduct(in, xf[1]) + xf[1][3]; - out[2] = DotProduct(in, xf[2]) + xf[2][3]; + float zi; + float x, y, z; + + // project points + x = fv->xyz[0]; + y = fv->xyz[1]; + z = fv->xyz[2]; + zi = 1.0 / z; + + fv->zi = zi * s_ziscale; + + fv->u = (x * aliasxscale * zi) + aliasxcenter; + fv->v = (y * aliasyscale * zi) + aliasycenter; + + if (fv->u < r_refdef.aliasvrect.x) + fv->flags |= ALIAS_LEFT_CLIP; + if (fv->v < r_refdef.aliasvrect.y) + fv->flags |= ALIAS_TOP_CLIP; + if (fv->u > r_refdef.aliasvrectright) + fv->flags |= ALIAS_RIGHT_CLIP; + if (fv->v > r_refdef.aliasvrectbottom) + fv->flags |= ALIAS_BOTTOM_CLIP; +} + +/* +================ +R_AliasTransformFinalVerts +================ +*/ +static void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, maliasvert_t *oldv, maliasvert_t *newv ) +{ + int i; + + for ( i = 0; i < numpoints; i++, fv++, oldv++, newv++ ) + { + int temp; + float lightcos; + const vec_t *plightnormal; + vec3_t lerped_vert; + + lerped_vert[0] = r_lerp_move[0] + oldv->v[0]*r_lerp_backv[0] + newv->v[0]*r_lerp_frontv[0]; + lerped_vert[1] = r_lerp_move[1] + oldv->v[1]*r_lerp_backv[1] + newv->v[1]*r_lerp_frontv[1]; + lerped_vert[2] = r_lerp_move[2] + oldv->v[2]*r_lerp_backv[2] + newv->v[2]*r_lerp_frontv[2]; + + plightnormal = bytedirs[newv->lightnormalindex]; + + // PMM - added double damage shell + if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) + { + lerped_vert[0] += plightnormal[0] * POWERSUIT_SCALE; + lerped_vert[1] += plightnormal[1] * POWERSUIT_SCALE; + lerped_vert[2] += plightnormal[2] * POWERSUIT_SCALE; + } + + fv->xyz[0] = DotProduct(lerped_vert, aliastransform[0]) + aliastransform[0][3]; + fv->xyz[1] = DotProduct(lerped_vert, aliastransform[1]) + aliastransform[1][3]; + fv->xyz[2] = DotProduct(lerped_vert, aliastransform[2]) + aliastransform[2][3]; + + fv->flags = 0; + + // lighting + lightcos = DotProduct (plightnormal, r_plightvec); + temp = r_ambientlight; + + if (lightcos < 0) + { + temp += (int)(r_shadelight * lightcos); + + // clamp; because we limited the minimum ambient and shading light, we + // don't have to clamp low light, just bright + if (temp < 0) + temp = 0; + } + + fv->l = temp; + + if ( fv->xyz[2] < ALIAS_Z_CLIP_PLANE ) + { + fv->flags |= ALIAS_Z_CLIP; + } + else + { + R_AliasProjectAndClipTestFinalVert( fv ); + } + } } @@ -217,21 +301,10 @@ R_AliasPreparePoints General clipped case ================ */ -typedef struct -{ - int num_points; - dtrivertx_t *last_verts; // verts from the last frame - dtrivertx_t *this_verts; // verts from this frame - finalvert_t *dest_verts; // destination for transformed verts -} aliasbatchedtransformdata_t; - -aliasbatchedtransformdata_t aliasbatchedtransformdata; - -void R_AliasPreparePoints (void) -{ +static void R_AliasPreparePoints (void) { int i; - dstvert_t *pstverts; - dtriangle_t *ptri; + maliasst_t *pstverts; + maliastri_t *ptri; finalvert_t *pfv[3]; finalvert_t finalverts[MAXALIASVERTS + ((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 3]; @@ -248,24 +321,17 @@ void R_AliasPreparePoints (void) pfinalverts = (finalvert_t *) (((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); - aliasbatchedtransformdata.num_points = s_pmdl->num_xyz; - aliasbatchedtransformdata.last_verts = r_lastframe->verts; - aliasbatchedtransformdata.this_verts = r_thisframe->verts; - aliasbatchedtransformdata.dest_verts = pfinalverts; - - R_AliasTransformFinalVerts( aliasbatchedtransformdata.num_points, - aliasbatchedtransformdata.dest_verts, - aliasbatchedtransformdata.last_verts, - aliasbatchedtransformdata.this_verts ); + R_AliasTransformFinalVerts( currentmodel->numverts, pfinalverts, + r_lastframe->verts, r_thisframe->verts ); // clip and draw all triangles // - pstverts = (dstvert_t *)((byte *)s_pmdl + s_pmdl->ofs_st); - ptri = (dtriangle_t *)((byte *)s_pmdl + s_pmdl->ofs_tris); + pstverts = currentmodel->sts; + ptri = currentmodel->tris; if ( ( currententity->flags & (RF_WEAPONMODEL|RF_LEFTHAND) ) == (RF_WEAPONMODEL|RF_LEFTHAND) ) { - for (i=0 ; i<s_pmdl->num_tris ; i++, ptri++) + for (i=0 ; i<currentmodel->numtris ; i++, ptri++) { pfv[0] = &pfinalverts[ptri->index_xyz[0]]; pfv[1] = &pfinalverts[ptri->index_xyz[1]]; @@ -300,7 +366,7 @@ void R_AliasPreparePoints (void) } else { - for (i=0 ; i<s_pmdl->num_tris ; i++, ptri++) + for (i=0 ; i<currentmodel->numtris ; i++, ptri++) { pfv[0] = &pfinalverts[ptri->index_xyz[0]]; pfv[1] = &pfinalverts[ptri->index_xyz[1]]; @@ -341,7 +407,7 @@ void R_AliasPreparePoints (void) R_AliasSetUpTransform ================ */ -void R_AliasSetUpTransform (void) +static void R_AliasSetUpTransform (void) { int i; static float viewmatrix[3][4]; @@ -404,101 +470,6 @@ void R_AliasSetUpTransform (void) aliasoldworldtransform[2][3] = currententity->oldorigin[2]; } - -/* -================ -R_AliasTransformFinalVerts -================ -*/ -void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv ) -{ - int i; - - for ( i = 0; i < numpoints; i++, fv++, oldv++, newv++ ) - { - int temp; - float lightcos; - const float *plightnormal; - vec3_t lerped_vert; - - lerped_vert[0] = r_lerp_move[0] + oldv->v[0]*r_lerp_backv[0] + newv->v[0]*r_lerp_frontv[0]; - lerped_vert[1] = r_lerp_move[1] + oldv->v[1]*r_lerp_backv[1] + newv->v[1]*r_lerp_frontv[1]; - lerped_vert[2] = r_lerp_move[2] + oldv->v[2]*r_lerp_backv[2] + newv->v[2]*r_lerp_frontv[2]; - - plightnormal = bytedirs[newv->lightnormalindex]; - - // PMM - added double damage shell - if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) - { - lerped_vert[0] += plightnormal[0] * POWERSUIT_SCALE; - lerped_vert[1] += plightnormal[1] * POWERSUIT_SCALE; - lerped_vert[2] += plightnormal[2] * POWERSUIT_SCALE; - } - - fv->xyz[0] = DotProduct(lerped_vert, aliastransform[0]) + aliastransform[0][3]; - fv->xyz[1] = DotProduct(lerped_vert, aliastransform[1]) + aliastransform[1][3]; - fv->xyz[2] = DotProduct(lerped_vert, aliastransform[2]) + aliastransform[2][3]; - - fv->flags = 0; - - // lighting - lightcos = DotProduct (plightnormal, r_plightvec); - temp = r_ambientlight; - - if (lightcos < 0) - { - temp += (int)(r_shadelight * lightcos); - - // clamp; because we limited the minimum ambient and shading light, we - // don't have to clamp low light, just bright - if (temp < 0) - temp = 0; - } - - fv->l = temp; - - if ( fv->xyz[2] < ALIAS_Z_CLIP_PLANE ) - { - fv->flags |= ALIAS_Z_CLIP; - } - else - { - R_AliasProjectAndClipTestFinalVert( fv ); - } - } -} - -/* -================ -R_AliasProjectAndClipTestFinalVert -================ -*/ -void R_AliasProjectAndClipTestFinalVert( finalvert_t *fv ) -{ - float zi; - float x, y, z; - - // project points - x = fv->xyz[0]; - y = fv->xyz[1]; - z = fv->xyz[2]; - zi = 1.0 / z; - - fv->zi = zi * s_ziscale; - - fv->u = (x * aliasxscale * zi) + aliasxcenter; - fv->v = (y * aliasyscale * zi) + aliasycenter; - - if (fv->u < r_refdef.aliasvrect.x) - fv->flags |= ALIAS_LEFT_CLIP; - if (fv->v < r_refdef.aliasvrect.y) - fv->flags |= ALIAS_TOP_CLIP; - if (fv->u > r_refdef.aliasvrectright) - fv->flags |= ALIAS_RIGHT_CLIP; - if (fv->v > r_refdef.aliasvrectbottom) - fv->flags |= ALIAS_BOTTOM_CLIP; -} - /* =============== R_AliasSetupSkin @@ -510,13 +481,13 @@ static qboolean R_AliasSetupSkin (void) image_t *pskindesc; if (currententity->skin) - pskindesc = R_ImageForHandle( currententity->skin ); + pskindesc = IMG_ForHandle( currententity->skin ); else { skinnum = currententity->skinnum; - if ((skinnum >= s_pmdl->num_skins) || (skinnum < 0)) + if ((skinnum >= currentmodel->numskins) || (skinnum < 0)) { - Com_Printf( "R_AliasSetupSkin %s: no such skin # %d\n", + Com_DPrintf( "R_AliasSetupSkin %s: no such skin # %d\n", currentmodel->name, skinnum); skinnum = 0; } @@ -544,7 +515,7 @@ R_AliasSetupLighting FIXME: put lighting into tables ================ */ -void R_AliasSetupLighting (void) +static void R_AliasSetupLighting (void) { alight_t lighting; float lightvec[3] = {-1, 0, 0}; @@ -630,29 +601,23 @@ R_AliasSetupFrames ================= */ -void R_AliasSetupFrames( dmdl_t *pmdl ) -{ +static void R_AliasSetupFrames( void ) { int thisframe = currententity->frame; int lastframe = currententity->oldframe; - if ( ( thisframe >= pmdl->num_frames ) || ( thisframe < 0 ) ) - { - Com_DPrintf( "R_AliasSetupFrames %s: no such thisframe %d\n", - currentmodel->name, thisframe); + if( thisframe >= currentmodel->numframes || thisframe < 0 ) { + Com_DPrintf( "%s: %s: no such thisframe %d\n", + __func__, currentmodel->name, thisframe); thisframe = 0; } - if ( ( lastframe >= pmdl->num_frames ) || ( lastframe < 0 ) ) - { - Com_DPrintf( "R_AliasSetupFrames %s: no such lastframe %d\n", - currentmodel->name, lastframe); + if( lastframe >= currentmodel->numframes || lastframe < 0 ) { + Com_DPrintf( "%s: %s: no such lastframe %d\n", + __func__, currentmodel->name, lastframe); lastframe = 0; } - r_thisframe = (daliasframe_t *)((byte *)pmdl + pmdl->ofs_frames - + thisframe * pmdl->framesize); - - r_lastframe = (daliasframe_t *)((byte *)pmdl + pmdl->ofs_frames - + lastframe * pmdl->framesize); + r_thisframe = ¤tmodel->frames[thisframe]; + r_lastframe = ¤tmodel->frames[lastframe]; } /* @@ -660,7 +625,7 @@ void R_AliasSetupFrames( dmdl_t *pmdl ) ** ** Precomputes lerp coefficients used for the whole frame. */ -void R_AliasSetUpLerpData( dmdl_t *pmdl, float backlerp ) +static void R_AliasSetUpLerpData( float backlerp ) { float frontlerp; vec3_t translation, vectors[3]; @@ -701,52 +666,6 @@ void R_AliasSetUpLerpData( dmdl_t *pmdl, float backlerp ) static void R_AliasSetupBlend( void ) { extern void (*d_pdrawspans)( void * ); - -#ifdef TRUECOLOR_RENDERER - extern void R_PolysetDrawSpansOpaque( void * ); - extern void R_PolysetDrawSpansTranslucent( void * ); - extern void R_PolysetDrawSpansBlend( void * ); - extern void R_PolysetDrawSpansConstantBlend( void * ); - - vec3_t color; - - byte alphabyte; - - /*if( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) ) { - VectorClear (color); - if (currententity->flags & RF_SHELL_HALF_DAM) { - color[0] = 0.56f; - color[1] = 0.59f; - color[2] = 0.45f; - } - if ( currententity->flags & RF_SHELL_DOUBLE ) { - color[0] = 0.9f; - color[1] = 0.7f; - } - if ( currententity->flags & RF_SHELL_RED ) - color[0] = 1.0f; - if ( currententity->flags & RF_SHELL_GREEN ) - color[1] = 1.0f; - if ( currententity->flags & RF_SHELL_BLUE ) - color[2] = 1.0f; - - VectorScale( color, 255 * currententity->alpha, r_aliasblendcolor ); - r_aliasblendoneminusalpha = 1.0f - currententity->alpha; - d_pdrawspans = R_PolysetDrawSpansConstantBlend; - } else*/ if ( currententity->flags & RF_TRANSLUCENT ) { - - alphabyte = 255 * currententity->alpha; - r_aliasAlphaTable = r_alphaTables[alphabyte]; - r_aliasOneMinusAlphaTable = r_alphaTables[255 - alphabyte]; - d_pdrawspans = R_PolysetDrawSpansTranslucent; - - } else { - d_pdrawspans = R_PolysetDrawSpansOpaque; - - } - -#else - extern void R_PolysetDrawSpans8_Opaque( void * ); extern void R_PolysetDrawSpans8_33( void * ); extern void R_PolysetDrawSpans8_66( void * ); @@ -806,7 +725,6 @@ static void R_AliasSetupBlend( void ) { { d_pdrawspans = R_PolysetDrawSpans8_Opaque; } -#endif /* !32BIT_RENDERER */ } /* @@ -816,8 +734,6 @@ R_AliasDrawModel */ void R_AliasDrawModel (void) { - s_pmdl = (dmdl_t *)currentmodel->pool.base; - if ( r_lerpmodels->value == 0 ) currententity->backlerp = 0; @@ -830,7 +746,7 @@ void R_AliasDrawModel (void) ** we have to set our frame pointers and transformations before ** doing any real work */ - R_AliasSetupFrames( s_pmdl ); + R_AliasSetupFrames(); R_AliasSetUpTransform(); // see if the bounding box lets us trivially reject, also sets @@ -860,7 +776,7 @@ void R_AliasDrawModel (void) /* ** compute this_frame and old_frame addresses */ - R_AliasSetUpLerpData( s_pmdl, currententity->backlerp ); + R_AliasSetUpLerpData( currententity->backlerp ); if (currententity->flags & RF_DEPTHHACK) s_ziscale = (float)0x8000 * (float)0x10000 * 3.0; diff --git a/source/sw_bsp.c b/source/sw_bsp.c index 36f784e..df0222b 100644 --- a/source/sw_bsp.c +++ b/source/sw_bsp.c @@ -153,12 +153,12 @@ R_RecursiveClipBPoly Clip a bmodel poly down the world bsp tree ================ */ -void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) +void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, mface_t *psurf) { bedge_t *psideedges[2], *pnextedge, *ptedge; int i, side, lastside; float dist, frac, lastdist; - mplane_t *splitplane, tplane; + cplane_t *splitplane, tplane; mvertex_t *pvert, *plastvert, *ptvert; mnode_t *pn; int area; @@ -183,7 +183,7 @@ void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) // set the status for the last point as the previous point // FIXME: cache this stuff somehow? plastvert = pedges->v[0]; - lastdist = PlaneDiff (plastvert->position, &tplane); + lastdist = PlaneDiff (plastvert->point, &tplane); if (lastdist > 0) lastside = 0; @@ -191,7 +191,7 @@ void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) lastside = 1; pvert = pedges->v[1]; - dist = PlaneDiff (pvert->position, &tplane); + dist = PlaneDiff (pvert->point, &tplane); if (dist > 0) side = 0; @@ -207,15 +207,15 @@ void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) // generate the clipped vertex frac = lastdist / (lastdist - dist); ptvert = &pbverts[numbverts++]; - ptvert->position[0] = plastvert->position[0] + - frac * (pvert->position[0] - - plastvert->position[0]); - ptvert->position[1] = plastvert->position[1] + - frac * (pvert->position[1] - - plastvert->position[1]); - ptvert->position[2] = plastvert->position[2] + - frac * (pvert->position[2] - - plastvert->position[2]); + ptvert->point[0] = plastvert->point[0] + + frac * (pvert->point[0] - + plastvert->point[0]); + ptvert->point[1] = plastvert->point[1] + + frac * (pvert->point[1] - + plastvert->point[1]); + ptvert->point[2] = plastvert->point[2] + + frac * (pvert->point[2] - + plastvert->point[2]); // split into two edges, one on each side, and remember entering // and exiting points @@ -296,18 +296,19 @@ void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) // we're done with this branch if the node or leaf isn't in the PVS if (pn->visframe == r_visframecount) { - if (pn->contents != CONTENTS_NODE) + if (!pn->plane) { - if (pn->contents != CONTENTS_SOLID) + mleaf_t *pl = ( mleaf_t * )pn; + if (pl->contents != CONTENTS_SOLID) { if (r_newrefdef.areabits) { - area = ((mleaf_t *)pn)->area; - if (! (r_newrefdef.areabits[area>>3] & (1<<(area&7)) ) ) + area = pl->area; + if (!Q_IsBitSet(r_newrefdef.areabits, area) ) continue; // not visible } - r_currentbkey = ((mleaf_t *)pn)->key; + r_currentbkey = pl->key; R_RenderBmodelFace (psideedges[i], psurf); } } @@ -329,22 +330,21 @@ R_DrawSolidClippedSubmodelPolygons Bmodel crosses multiple leafs ================ */ -void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode) +void R_DrawSolidClippedSubmodelPolygons (mmodel_t *pmodel, mnode_t *topnode) { - int i, j, lindex; + int i, j; vec_t dot; - msurface_t *psurf; + mface_t *psurf; int numsurfaces; - mplane_t *pplane; + cplane_t *pplane; mvertex_t bverts[MAX_BMODEL_VERTS]; bedge_t bedges[MAX_BMODEL_EDGES], *pbedge; - medge_t *pedge, *pedges; + msurfedge_t *surfedge; // FIXME: use bounding-box-based frustum clipping info? - psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; - numsurfaces = pmodel->nummodelsurfaces; - pedges = pmodel->edges; + psurf = pmodel->firstface; + numsurfaces = pmodel->numfaces; for (i=0 ; i<numsurfaces ; i++, psurf++) { @@ -354,8 +354,8 @@ void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode) dot = PlaneDiff (modelorg, pplane); // draw the polygon - if (( !(psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || - ((psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + if (( !(psurf->drawflags & DSURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || + ((psurf->drawflags & DSURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) continue; // FIXME: use bounding-box-based frustum clipping info? @@ -368,32 +368,19 @@ void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode) pbedges = bedges; numbverts = numbedges = 0; pbedge = &bedges[numbedges]; - numbedges += psurf->numedges; + numbedges += psurf->numsurfedges; - for (j=0 ; j<psurf->numedges ; j++) + surfedge = psurf->firstsurfedge; + for (j=0 ; j<psurf->numsurfedges ; j++, surfedge++) { - lindex = pmodel->surfedges[psurf->firstedge+j]; - - if (lindex > 0) - { - pedge = &pedges[lindex]; - pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]]; - pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]]; - } - else - { - lindex = -lindex; - pedge = &pedges[lindex]; - pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]]; - pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]]; - } - + pbedge[j].v[0] = surfedge->edge->v[surfedge->vert ]; + pbedge[j].v[1] = surfedge->edge->v[surfedge->vert ^ 1]; pbedge[j].pnext = &pbedge[j+1]; } pbedge[j-1].pnext = NULL; // mark end of edges - if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) ) ) + if ( !( psurf->texinfo->c.flags & ( SURF_TRANS66 | SURF_TRANS33 ) ) ) R_RecursiveClipBPoly (pbedge, topnode, psurf); else R_RenderBmodelFace( pbedge, psurf ); @@ -408,18 +395,18 @@ R_DrawSubmodelPolygons All in one leaf ================ */ -void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags, mnode_t *topnode) +void R_DrawSubmodelPolygons (mmodel_t *pmodel, int clipflags, mnode_t *topnode) { int i; vec_t dot; - msurface_t *psurf; + mface_t *psurf; int numsurfaces; - mplane_t *pplane; + cplane_t *pplane; // FIXME: use bounding-box-based frustum clipping info? - psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; - numsurfaces = pmodel->nummodelsurfaces; + psurf = pmodel->firstface; + numsurfaces = pmodel->numfaces; for (i=0 ; i<numsurfaces ; i++, psurf++) { @@ -429,8 +416,8 @@ void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags, mnode_t *topnode) dot = PlaneDiff (modelorg, pplane); // draw the polygon - if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || - (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + if (((psurf->drawflags & DSURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || + (!(psurf->drawflags & DSURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) { r_currentkey = ((mleaf_t *)topnode)->key; @@ -448,86 +435,76 @@ int c_drawnode; R_RecursiveWorldNode ================ */ -void R_RecursiveWorldNode (mnode_t *node, int clipflags) -{ +void R_RecursiveWorldNode (mnode_t *node, int clipflags) { int i, c, side, *pindex; vec3_t acceptpt, rejectpt; - mplane_t *plane; - msurface_t *surf, **mark; + cplane_t *plane; + mface_t *surf, **mark; float d, dot; mleaf_t *pleaf; - if (node->contents == CONTENTS_SOLID) - return; // solid - - if (node->visframe != r_visframecount) - return; - -// cull the clipping planes if not trivial accept -// FIXME: the compiler is doing a lousy job of optimizing here; it could be -// twice as fast in ASM - if (clipflags) - { - for (i=0 ; i<4 ; i++) - { - if (! (clipflags & (1<<i)) ) - continue; // don't need to clip against it - - // generate accept and reject points - // FIXME: do with fast look-ups or integer tests based on the sign bit - // of the floating point values - - pindex = pfrustum_indexes[i]; - - rejectpt[0] = (float)node->minmaxs[pindex[0]]; - rejectpt[1] = (float)node->minmaxs[pindex[1]]; - rejectpt[2] = (float)node->minmaxs[pindex[2]]; - - d = PlaneDiff(rejectpt, &view_clipplanes[i]); - if (d <= 0) - return; - - acceptpt[0] = (float)node->minmaxs[pindex[3+0]]; - acceptpt[1] = (float)node->minmaxs[pindex[3+1]]; - acceptpt[2] = (float)node->minmaxs[pindex[3+2]]; - - d = PlaneDiff (acceptpt, &view_clipplanes[i]); - if (d >= 0) - clipflags &= ~(1<<i); // node is entirely on screen - } - } - -c_drawnode++; - -// if a leaf node, draw stuff - if (node->contents != -1) - { - pleaf = (mleaf_t *)node; - - // check for door connected areas - if (r_newrefdef.areabits) - { - if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) - return; // not visible - } - - mark = pleaf->firstmarksurface; - c = pleaf->nummarksurfaces; - - if (c) - { - do - { - (*mark)->visframe = r_framecount; - mark++; - } while (--c); - } - - pleaf->key = r_currentkey; - r_currentkey++; // all bmodels in a leaf share the same key - } - else - { + while( node->visframe == r_visframecount) { + // cull the clipping planes if not trivial accept + // FIXME: the compiler is doing a lousy job of optimizing here; it could be + // twice as fast in ASM + if (clipflags) { + for (i=0 ; i<4 ; i++) { + if (! (clipflags & (1<<i)) ) + continue; // don't need to clip against it + + // generate accept and reject points + // FIXME: do with fast look-ups or integer tests based on the sign bit + // of the floating point values + + pindex = pfrustum_indexes[i]; + + rejectpt[0] = (float)node->minmaxs[pindex[0]]; + rejectpt[1] = (float)node->minmaxs[pindex[1]]; + rejectpt[2] = (float)node->minmaxs[pindex[2]]; + + d = PlaneDiff(rejectpt, &view_clipplanes[i]); + if (d <= 0) + return; + + acceptpt[0] = (float)node->minmaxs[pindex[3+0]]; + acceptpt[1] = (float)node->minmaxs[pindex[3+1]]; + acceptpt[2] = (float)node->minmaxs[pindex[3+2]]; + + d = PlaneDiff (acceptpt, &view_clipplanes[i]); + if (d >= 0) + clipflags &= ~(1<<i); // node is entirely on screen + } + } + + c_drawnode++; + + // if a leaf node, draw stuff + if (!node->plane) { + pleaf = (mleaf_t *)node; + + if (pleaf->contents == CONTENTS_SOLID) + return; // solid + + // check for door connected areas + if (r_newrefdef.areabits) { + if (! Q_IsBitSet(r_newrefdef.areabits, pleaf->area ) ) + return; // not visible + } + + mark = pleaf->firstleafface; + c = pleaf->numleaffaces; + if (c) { + do + { + (*mark)->drawframe = r_framecount; + mark++; + } while (--c); + } + + pleaf->key = r_currentkey; + r_currentkey++; // all bmodels in a leaf share the same key + return; + } // node is just a decision point, so go down the apropriate sides // find which side of the node we are on @@ -544,35 +521,25 @@ c_drawnode++; R_RecursiveWorldNode (node->children[side], clipflags); // draw stuff - c = node->numsurfaces; - - if (c) - { - surf = r_worldmodel->surfaces + node->firstsurface; - - if (dot < -BACKFACE_EPSILON) - { - do - { - if ((surf->flags & SURF_PLANEBACK) && - (surf->visframe == r_framecount)) + c = node->numfaces; + if (c) { + surf = node->firstface; + if (dot < -BACKFACE_EPSILON) { + do { + if ((surf->drawflags & DSURF_PLANEBACK) && + (surf->drawframe == r_framecount)) { R_RenderFace (surf, clipflags); } - surf++; } while (--c); - } - else if (dot > BACKFACE_EPSILON) - { - do - { - if (!(surf->flags & SURF_PLANEBACK) && - (surf->visframe == r_framecount)) + } else if (dot > BACKFACE_EPSILON) { + do { + if (!(surf->drawflags & DSURF_PLANEBACK) && + (surf->drawframe == r_framecount)) { R_RenderFace (surf, clipflags); } - surf++; } while (--c); } @@ -582,8 +549,8 @@ c_drawnode++; } // recurse down the back side - R_RecursiveWorldNode (node->children[!side], clipflags); - } + node = node->children[side^1]; + } } @@ -608,10 +575,8 @@ void R_RenderWorld (void) currententity = &r_worldentity; VectorCopy (r_origin, modelorg); - currentmodel = r_worldmodel; - r_pcurrentvertbase = currentmodel->vertexes; - R_RecursiveWorldNode (currentmodel->nodes, 15); + R_RecursiveWorldNode (r_worldmodel->nodes, 15); } diff --git a/source/sw_draw.c b/source/sw_draw.c index c45c28e..4307b79 100644 --- a/source/sw_draw.c +++ b/source/sw_draw.c @@ -124,7 +124,13 @@ static drawStatic_t draw; static int colorIndices[8]; -void Draw_Init( void ) { +void R_SetScale( float *scale ) { + if( scale ) { + *scale = 1; + } +} + +void R_InitDraw( void ) { int i; memset( &draw, 0, sizeof( draw ) ); @@ -135,7 +141,7 @@ void Draw_Init( void ) { } } -void Draw_SetColor( int flags, const color_t color ) { +void R_SetColor( int flags, const color_t color ) { draw.flags &= ~DRAW_COLOR_MASK; if( flags == DRAW_COLOR_CLEAR ) { @@ -161,7 +167,7 @@ void Draw_SetColor( int flags, const color_t color ) { draw.flags |= flags; } -void Draw_SetClipRect( int flags, const clipRect_t *clip ) { +void R_SetClipRect( int flags, const clipRect_t *clip ) { draw.flags &= ~DRAW_CLIP_MASK; if( flags == DRAW_CLIP_DISABLED ) { @@ -173,34 +179,27 @@ void Draw_SetClipRect( int flags, const clipRect_t *clip ) { /* ============= -Draw_GetPicSize +R_GetPicSize ============= */ -qboolean Draw_GetPicSize( int *w, int *h, qhandle_t hPic ) { - image_t *gl; +qboolean R_GetPicSize( int *w, int *h, qhandle_t pic ) { + image_t *image = IMG_ForHandle( pic ); - gl = R_ImageForHandle( hPic ); if( w ) { - *w = gl->width; + *w = image->width; } if( h ) { - *h = gl->height; + *h = image->height; } - return gl->flags & if_transparent; -} - -qhandle_t R_RegisterFont( const char *name ) { - qhandle_t R_RegisterPic( const char *name ); - - return R_RegisterPic( name ); + return image->flags & if_transparent; } /* ============= -Draw_StretchData +R_DrawStretchData ============= */ -static void Draw_StretchData( int x, int y, int w, int h, int xx, int yy, +static void R_DrawStretchData( int x, int y, int w, int h, int xx, int yy, int ww, int hh, int pitch, byte *data ) { byte *srcpixels, *dstpixels, *dst, *src; @@ -309,10 +308,10 @@ static void Draw_StretchData( int x, int y, int w, int h, int xx, int yy, /* ============= -Draw_FixedData +R_DrawFixedData ============= */ -static void Draw_FixedData( int x, int y, int w, int h, +static void R_DrawFixedData( int x, int y, int w, int h, int pitch, byte *data ) { byte *srcpixels, *dstpixels; @@ -398,7 +397,7 @@ static void Draw_FixedData( int x, int y, int w, int h, } -static void Draw_FixedDataAsMask( int x, int y, int w, int h, +static void R_DrawFixedDataAsMask( int x, int y, int w, int h, int pitch, byte *data, byte tbyte ) { byte *srcpixels, *dstpixels; @@ -485,84 +484,63 @@ static void Draw_FixedDataAsMask( int x, int y, int w, int h, /* ============= -Draw_StretchPic +R_DrawStretcpic ============= */ -void Draw_StretchPicST( int x, int y, int w, int h, float s1, float t1, - float s2, float t2, qhandle_t hPic ) +void R_DrawStretcPicST( int x, int y, int w, int h, float s1, float t1, + float s2, float t2, qhandle_t pic ) { - image_t *image; + image_t *image = IMG_ForHandle( pic ); int xx, yy, ww, hh; - image = R_ImageForHandle( hPic ); - xx = image->width * s1; yy = image->height * t1; ww = image->width * ( s2 - s1 ); hh = image->height * ( t2 - t1 ); - //draw_current->drawStretchPic - Draw_StretchData( x, y, w, h, xx, yy, ww, hh, image->width, - image->pixels[0] ); + R_DrawStretchData( x, y, w, h, xx, yy, ww, hh, + image->width, image->pixels[0] ); } /* ============= -Draw_StretchPic +R_DrawStretchPic ============= */ -void Draw_StretchPic( int x, int y, int w, int h, qhandle_t hPic ) { - image_t *image; - - image = R_ImageForHandle( hPic ); +void R_DrawStretchPic( int x, int y, int w, int h, qhandle_t pic ) { + image_t *image = IMG_ForHandle( pic ); if( w == image->width && h == image->height ) { - Draw_FixedData( x, y, image->width, image->height, - image->width, image->pixels[0] ); + R_DrawFixedData( x, y, image->width, image->height, + image->width, image->pixels[0] ); return; } - //draw_current->drawStretchPic - Draw_StretchData( x, y, w, h, 0, 0, image->width, image->height, - image->width, image->pixels[0] ); + R_DrawStretchData( x, y, w, h, 0, 0, image->width, image->height, + image->width, image->pixels[0] ); } /* ============= -Draw_StretchPic +R_DrawStretcpic ============= */ -void Draw_Pic( int x, int y, qhandle_t hPic ) { - image_t *image; - - image = R_ImageForHandle( hPic ); - - //draw_current->drawFixedPic - Draw_FixedData( x, y, image->width, image->height, - image->width, image->pixels[0] ); +void R_DrawPic( int x, int y, qhandle_t pic ) { + image_t *image = IMG_ForHandle( pic ); + R_DrawFixedData( x, y, image->width, image->height, + image->width, image->pixels[0] ); } -/* -============= -Draw_StretchRaw -============= -*/ -void Draw_StretchRaw( int x, int y, int w, int h, int cols, - int rows, const byte *data ) -{ - Draw_StretchData( x, y, w, h, 0, 0, cols, rows, cols, ( byte * )data ); -} - -void Draw_Char( int x, int y, int flags, int ch, qhandle_t hFont ) { +void R_DrawChar( int x, int y, int flags, int ch, qhandle_t font ) { image_t *image; int xx, yy; byte *data; - if( !hFont ) { + if( !font ) { return; } - image = R_ImageForHandle( hFont ); + image = IMG_ForHandle( font ); if( image->width != 128 || image->height != 128 ) { return; } @@ -571,29 +549,29 @@ void Draw_Char( int x, int y, int flags, int ch, qhandle_t hFont ) { yy = ( ( ch >> 4 ) & 15 ) << 3; data = image->pixels[0] + yy * image->width + xx; if( draw.colorIndex != -1 && !( ch & 128 ) ) { - Draw_FixedDataAsMask( x, y, 8, 8, image->width, data, draw.colorIndex ); + R_DrawFixedDataAsMask( x, y, 8, 8, image->width, data, draw.colorIndex ); } else { - Draw_FixedData( x, y, 8, 8, image->width, data ); + R_DrawFixedData( x, y, 8, 8, image->width, data ); } } /* =============== -Draw_String +R_DrawString =============== */ -int Draw_String( int x, int y, int flags, size_t maxChars, - const char *string, qhandle_t hFont ) +int R_DrawString( int x, int y, int flags, size_t maxChars, + const char *string, qhandle_t font ) { image_t *image; byte c, *data; int xx, yy; int color, mask; - if( !hFont ) { + if( !font ) { return x; } - image = R_ImageForHandle( hFont ); + image = IMG_ForHandle( font ); if( image->width != 128 || image->height != 128 ) { return x; } @@ -642,9 +620,9 @@ int Draw_String( int x, int y, int flags, size_t maxChars, yy = ( c >> 4 ) << 3; data = image->pixels[0] + yy * image->width + xx; if( color != -1 && !( c & 128 ) ) { - Draw_FixedDataAsMask( x, y, 8, 8, image->width, data, color ); + R_DrawFixedDataAsMask( x, y, 8, 8, image->width, data, color ); } else { - Draw_FixedData( x, y, 8, 8, image->width, data ); + R_DrawFixedData( x, y, 8, 8, image->width, data ); } x += 8; @@ -654,30 +632,28 @@ int Draw_String( int x, int y, int flags, size_t maxChars, /* ============= -Draw_TileClear +R_TileClear This repeats a 64*64 tile graphic to fill the screen around a sized down refresh window. ============= */ -void Draw_TileClear( int x, int y, int w, int h, qhandle_t hPic ) { +void R_TileClear( int x, int y, int w, int h, qhandle_t pic ) { int i, j; byte *psrc; byte *pdest; - image_t *pic; + image_t *image; int x2; - if( !hPic ) { + if( !pic ) { return; } - if (x < 0) - { + if (x < 0) { w += x; x = 0; } - if (y < 0) - { + if (y < 0) { h += y; y = 0; } @@ -688,15 +664,14 @@ void Draw_TileClear( int x, int y, int w, int h, qhandle_t hPic ) { if (w <= 0 || h <= 0) return; - pic = R_ImageForHandle( hPic ); - if( pic->width != 64 || pic->height != 64 ) { + image = IMG_ForHandle( pic ); + if( image->width != 64 || image->height != 64 ) { return; } x2 = x + w; pdest = vid.buffer + y*vid.rowbytes; - for (i=0 ; i<h ; i++, pdest += vid.rowbytes) - { - psrc = pic->pixels[0] + pic->width * ((i+y)&63); + for (i=0 ; i<h ; i++, pdest += vid.rowbytes) { + psrc = image->pixels[0] + image->width * ((i+y)&63); for (j=x ; j<x2 ; j++) pdest[j] = psrc[j&63]; } @@ -705,80 +680,80 @@ void Draw_TileClear( int x, int y, int w, int h, qhandle_t hPic ) { /* ============= -Draw_Fill +R_DrawFill Fills a box of pixels with a single color ============= */ -void Draw_Fill (int x, int y, int w, int h, int c) -{ +void R_DrawFill( int x, int y, int w, int h, int c ) { byte *dest; int u, v; - if (x+w > vid.width) + if( x + w > vid.width ) w = vid.width - x; - if (y+h > vid.height) + if( y + h > vid.height ) h = vid.height - y; - if (x < 0) - { + if( x < 0 ) { w += x; x = 0; } - if (y < 0) - { + if( y < 0 ) { h += y; y = 0; } - if (w < 0 || h < 0) + if( w < 0 || h < 0 ) return; - dest = vid.buffer + y*vid.rowbytes + x; - for (v=0 ; v<h ; v++, dest += vid.rowbytes) - for (u=0 ; u<w ; u++) - dest[u] = c; -} -static byte Blend33( int pcolor, int dstcolor ) { - return vid.alphamap[pcolor + dstcolor*256]; -} - -static byte Blend66( int pcolor, int dstcolor ) { - return vid.alphamap[pcolor*256+dstcolor]; + dest = vid.buffer + y * vid.rowbytes + x; + for( v = 0; v < h; v++, dest += vid.rowbytes ) + for( u = 0; u < w; u++ ) + dest[u] = c; } -void Draw_FillEx( int x, int y, int w, int h, const color_t color ) { - int colorIndex; +void R_DrawFillEx( int x, int y, int w, int h, const color_t color ) { + int c; byte *dest; int u, v; - byte (*blendfunc)( int, int ); - colorIndex = color ? R_IndexForColor( color ) : 0xD7; - - blendfunc = NULL; - if( color[3] < 172 ) { - blendfunc = color[3] > 84 ? Blend66 : Blend33; - } - - if (x+w > vid.width) + if( x + w > vid.width ) w = vid.width - x; - if (y+h > vid.height) + if( y + h > vid.height ) h = vid.height - y; - if (x < 0) - { + if( x < 0 ) { w += x; x = 0; } - if (y < 0) - { + if( y < 0 ) { h += y; y = 0; } - if (w < 0 || h < 0) + if( w < 0 || h < 0 ) return; - dest = vid.buffer + y*vid.rowbytes + x; - for (v=0 ; v<h ; v++, dest += vid.rowbytes) - for (u=0 ; u<w ; u++) - dest[u] = blendfunc ? blendfunc( colorIndex, dest[u] ) : colorIndex; - + + c = color ? R_IndexForColor( color ) : 0xD7; + + dest = vid.buffer + y * vid.rowbytes + x; + if( color[3] < 172 ) { + if( color[3] > 84 ) { + for( v = 0; v < h; v++, dest += vid.rowbytes ) { + for( u = 0 ; u < w; u++ ) { + dest[u] = vid.alphamap[c * 256 + dest[u]]; + } + } + } else { + for( v = 0; v < h; v++, dest += vid.rowbytes ) { + for( u = 0 ; u < w; u++ ) { + dest[u] = vid.alphamap[c + dest[u] * 256]; + } + } + } + } else { + for( v = 0; v < h; v++, dest += vid.rowbytes ) { + for( u = 0 ; u < w; u++ ) { + dest[u] = c; + } + } + } } @@ -786,11 +761,11 @@ void Draw_FillEx( int x, int y, int w, int h, const color_t color ) { /* ================ -Draw_FadeScreen +R_DrawFadeScreen ================ */ -void Draw_FadeScreen (void) +void R_DrawFadeScreen (void) { int x,y; byte *pbuf; diff --git a/source/sw_edge.c b/source/sw_edge.c index cdb31b7..df18c95 100644 --- a/source/sw_edge.c +++ b/source/sw_edge.c @@ -116,7 +116,7 @@ void R_BeginEdgeFrame (void) surface_p = &surfaces[2]; // background is surface 1, // surface 0 is a dummy surfaces[1].spans = NULL; // no background spans yet - surfaces[1].flags = SURF_DRAWBACKGROUND; + surfaces[1].flags = DSURF_BACKGROUND; // put the background behind everything in the world if (sw_draworder->value) @@ -128,7 +128,7 @@ void R_BeginEdgeFrame (void) else { pdrawfunc = R_GenerateSpans; - surfaces[1].key = 0x7FFfFFFF; + surfaces[1].key = 0x7FFFFFFF; r_currentkey = 0; } @@ -728,7 +728,7 @@ SURFACE FILLING ========================================================================= */ -msurface_t *pface; +mface_t *pface; surfcache_t *pcurrentcache; vec3_t transformed_modelorg; vec3_t world_transformed_modelorg; @@ -773,15 +773,10 @@ void D_FlatFillSurface( surf_t *surf, uint32_t color ) { for( span = surf->spans; span; span = span->pnext ) { pdest = ( byte * )d_viewbuffer + - r_screenwidth * span->v + ( span->u << VID_SHIFT ); + r_screenwidth * span->v + span->u; count = span->count; do { -#ifdef TRUECOLOR_RENDERER - *( uint32_t * )pdest = color; -#else - *pdest = color & 0xff; -#endif - pdest += VID_BYTES; + *pdest++ = color & 0xff; } while( --count ); } } @@ -792,9 +787,9 @@ void D_FlatFillSurface( surf_t *surf, uint32_t color ) { D_CalcGradients ============== */ -void D_CalcGradients (msurface_t *pface) +void D_CalcGradients (mface_t *pface) { - mplane_t *pplane; + cplane_t *pplane; float mipscale; vec3_t p_temp1; vec3_t p_saxis, p_taxis; @@ -804,8 +799,8 @@ void D_CalcGradients (msurface_t *pface) mipscale = 1.0 / (float)(1 << miplevel); - TransformVector (pface->texinfo->vecs[0], p_saxis); - TransformVector (pface->texinfo->vecs[1], p_taxis); + TransformVector (pface->texinfo->axis[0], p_saxis); + TransformVector (pface->texinfo->axis[1], p_taxis); t = xscaleinv * mipscale; d_sdivzstepu = p_saxis[0] * t; @@ -825,15 +820,15 @@ void D_CalcGradients (msurface_t *pface) 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; + + pface->texinfo->offset[0]*t; tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) - ((pface->texturemins[1] << 16) >> miplevel) - + pface->texinfo->vecs[1][3]*t; + + pface->texinfo->offset[1]*t; // PGM - changing flow speed for non-warping textures. - if (pface->texinfo->flags & SURF_FLOWING) + if (pface->texinfo->c.flags & SURF_FLOWING) { - if(pface->texinfo->flags & SURF_WARP) + if(pface->texinfo->c.flags & SURF_WARP) sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.25) - (int)(r_newrefdef.time * 0.25) )); else sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.77) - (int)(r_newrefdef.time * 0.77) )); @@ -881,7 +876,7 @@ void D_TurbulentSurf (surf_t *s) pface = s->msurf; miplevel = 0; cacheblock = pface->texinfo->image->pixels[0]; - cachewidth = 64 << VID_SHIFT; + cachewidth = 64; if (s->insubmodel) { @@ -902,7 +897,7 @@ void D_TurbulentSurf (surf_t *s) //============ //PGM // textures that aren't warping are just flowing. Use NonTurbulent8 instead - if(!(pface->texinfo->flags & SURF_WARP)) + if(!(pface->texinfo->c.flags & SURF_WARP)) NonTurbulent8 (s->spans); else Turbulent8 (s->spans); @@ -946,7 +941,7 @@ void D_SkySurf (surf_t *s) D_FlatFillSurface (s, 0); } else { cacheblock = pface->texinfo->image->pixels[0]; - cachewidth = 256 << VID_SHIFT; + cachewidth = 256; D_CalcGradients (pface); @@ -1103,14 +1098,14 @@ void D_DrawSurfaces (void) r_drawnpolycount++; - if (! (s->flags & (SURF_DRAWSKYBOX|SURF_DRAWBACKGROUND|SURF_DRAWTURB) ) ) - D_SolidSurf (s); - else if (s->flags & SURF_DRAWSKYBOX) + if (s->flags & DSURF_SKY) D_SkySurf (s); - else if (s->flags & SURF_DRAWBACKGROUND) + else if (s->flags & DSURF_BACKGROUND) D_BackgroundSurf (s); - else if (s->flags & SURF_DRAWTURB) + else if (s->flags & DSURF_TURB) D_TurbulentSurf (s); + else + D_SolidSurf (s); } } diff --git a/source/sw_image.c b/source/sw_image.c index 5e03868..5e6a6cf 100644 --- a/source/sw_image.c +++ b/source/sw_image.c @@ -19,163 +19,31 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sw_local.h" +#include "d_wal.h" +image_t *r_notexture; byte d_16to8table[65536]; -int R_IndexForColor( const color_t color ) { - unsigned int r, g, b, c; - - r = ( color[0] >> 3 ) & 31; - g = ( color[1] >> 2 ) & 63; - b = ( color[2] >> 3 ) & 31; - - c = r | ( g << 5 ) | ( b << 11 ); - - return d_16to8table[c]; -} - - -image_t *R_ImageForHandle( qhandle_t hPic ) { - if( !hPic ) { - return r_notexture_mip; - } - - if( hPic < 1 || hPic >= r_numImages + 1 ) { - Com_Error( ERR_DROP, "R_ImageForHandle: out of range hPic: %i\n", hPic ); - } - - return &r_images[hPic - 1]; -} - -#ifdef TRUECOLOR_RENDERER - -static void R_MipMap( byte *in, byte *out, int width, int height ) { - int i, j; - - width <<= 2; - height >>= 1; - for( i = 0; i < height; i++, in += width ) { - for( j = 0; j < width; j += 8, out += 4, in += 8 ) { - out[0] = ( in[0] + in[4] + in[width+0] + in[width+4] ) >> 2; - out[1] = ( in[1] + in[5] + in[width+1] + in[width+5] ) >> 2; - out[2] = ( in[2] + in[6] + in[width+2] + in[width+6] ) >> 2; - out[3] = ( in[3] + in[7] + in[width+3] + in[width+7] ) >> 2; - } - } -} - -qboolean R_ConvertTo32( const byte *data, int width, int height, byte *buffer ) { - byte *dest; - byte p; - int i, size; - qboolean transparent; - - transparent = qfalse; - size = width * height; - - dest = buffer; - for( i = 0; i < size; i++ ) { - p = data[i]; - *( uint32_t * )dest = d_8to24table[p]; - - if( p == 255 ) { - // transparent, so scan around for another color - // to avoid alpha fringes - // FIXME: do a full flood fill so mips work... - if (i > width && data[i-width] != 255) - p = data[i-width]; - else if (i < size-width && data[i+width] != 255) - p = data[i+width]; - else if (i > 0 && data[i-1] != 255) - p = data[i-1]; - else if (i < size-1 && data[i+1] != 255) - p = data[i+1]; - else - p = 0; - // copy rgb components - dest[0] = d_8to24table[p] & 255; - dest[1] = ( d_8to24table[p] >> 8 ) & 255; - dest[2] = ( d_8to24table[p] >> 16 ) & 255; - - transparent = qtrue; - } - - dest += 4; - } - - return transparent; - -} - /* ================ -R_LoadWal +IMG_Unload ================ */ -image_t *R_LoadWal( const char *name ) { - miptex_t *mt; - image_t *image; - size_t size, length, ofs, endpos, w, h; - byte *source[4]; - - length = fs.LoadFile( name, ( void ** )&mt ); - if( !mt ) { - Com_DPrintf( "R_LoadWal: can't load %s\n", name ); - return r_notexture_mip; - } - - w = LittleLong( mt->width ); - h = LittleLong( mt->height ); - - size = w * h * ( 256 + 64 + 16 + 4 ) / 256; - ofs = LittleLong( mt->offsets[0] ); - endpos = ofs + size; - if( endpos < ofs || endpos > length ) { - Com_DPrintf( "R_LoadWal: %s is malformed\n", name ); - fs.FreeFile( ( void * )mt ); - return r_notexture_mip; - } - - image = R_AllocImage( name ); - image->width = image->upload_width = w; - image->height = image->upload_height = h; - image->type = it_wall; - - image->pixels[0] = R_Malloc( size * 4 ); - image->pixels[1] = image->pixels[0] + ( w * h ) * 4; - image->pixels[2] = image->pixels[1] + ( w * h / 4 ) * 4; - image->pixels[3] = image->pixels[2] + ( w * h / 16 ) * 4; - - source[0] = ( byte * )mt + ofs; - source[1] = source[0] + w * h; - source[2] = source[1] + w * h / 4; - source[3] = source[2] + w * h / 16; - - image->transparent = R_ConvertTo32( source[0], w, h, image->pixels[0] ); - R_ConvertTo32( source[1], w >> 1, h >> 1, image->pixels[1] ); - R_ConvertTo32( source[2], w >> 2, h >> 2, image->pixels[2] ); - R_ConvertTo32( source[3], w >> 3, h >> 3, image->pixels[3] ); - - return image; -} - -#endif /* TRUECOLOR_RENDERER */ - -//======================================================= - -void R_FreeImage( image_t *image ) { - com.Free( image->pixels[0] ); +void IMG_Unload( image_t *image ) { + if( image->flags & if_auto ) { + return; + } + Z_Free( image->pixels[0] ); + image->pixels[0] = NULL; } - /* ================ -R_LoadPic - +IMG_Load ================ */ -void R_LoadImage( image_t *image, byte *pic, int width, int height, imagetype_t type, imageflags_t flags ) { +void IMG_Load( image_t *image, byte *pic, int width, int height, imagetype_t type, imageflags_t flags ) { int i, c, b; image->registration_sequence = registration_sequence; @@ -199,133 +67,156 @@ void R_LoadImage( image_t *image, byte *pic, int width, int height, imagetype_t /* ================ -R_LoadWal +IMG_LoadWAL ================ */ -image_t *R_LoadWal( const char *name ) { +image_t *IMG_LoadWAL( const char *name ) { miptex_t *mt; - int ofs; image_t *image; - int size; + size_t width, height, offset, endpos, filelen, size; - fs.LoadFile( name, ( void ** )&mt ); + filelen = FS_LoadFile( name, ( void ** )&mt ); if( !mt ) { - //Com_Printf( "R_LoadWal: can't load %s\n", name ); - return r_notexture_mip; + return NULL; + } + + image = NULL; + + width = LittleLong( mt->width ); + height = LittleLong( mt->height ); + offset = LittleLong( mt->offsets[0] ); + + if( width < 1 || height < 1 || width > MAX_TEXTURE_SIZE || height > MAX_TEXTURE_SIZE ) { + Com_WPrintf( "LoadWAL: %s: bad dimensions\n", name ); + goto fail; + } + + size = width * height * ( 256 + 64 + 16 + 4 ) / 256; + endpos = offset + size; + if( endpos < offset || endpos > filelen ) { + Com_WPrintf( "LoadWAL: %s: bad offset\n", name ); + goto fail; } - image = R_AllocImage( name ); - image->width = image->upload_width = LittleLong( mt->width ); - image->height = image->upload_height = LittleLong( mt->height ); + image = IMG_Alloc( name ); + image->width = image->upload_width = width; + image->height = image->upload_height = height; image->type = it_wall; image->flags = if_paletted; image->registration_sequence = registration_sequence; - size = image->width * image->height * ( 256 + 64 + 16 + 4 ) / 256; image->pixels[0] = R_Malloc( size ); - image->pixels[1] = image->pixels[0] + image->width * image->height; - image->pixels[2] = image->pixels[1] + image->width * image->height / 4; - image->pixels[3] = image->pixels[2] + image->width * image->height / 16; + image->pixels[1] = image->pixels[0] + width * height; + image->pixels[2] = image->pixels[1] + width * height / 4; + image->pixels[3] = image->pixels[2] + width * height / 16; - ofs = LittleLong( mt->offsets[0] ); - memcpy( image->pixels[0], ( byte * )mt + ofs, size ); + memcpy( image->pixels[0], ( byte * )mt + offset, size ); - fs.FreeFile( ( void * )mt ); +fail: + FS_FreeFile( mt ); return image; } -/* -=============== -R_RegisterSkin -=============== -*/ -qhandle_t R_RegisterSkin( const char *name ) { - image_t *image; - - image = R_FindImage( name, it_skin ); - - return image ? ( image - r_images ) + 1 : 0; -} - -/* -================ -R_RegisterPic -================ -*/ -qhandle_t R_RegisterPic( const char *name ) { - image_t *image; - char fullname[MAX_QPATH]; - - if( name[0] == '*' ) { - image = R_FindImage( name + 1, it_tmp ); - } else if( name[0] == '/' || name[0] == '\\' ) { - image = R_FindImage( name + 1, it_pic ); - } else { - Q_concat( fullname, sizeof( fullname ), "pics/", name, NULL ); - COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) ); - image = R_FindImage( fullname, it_pic ); - } - - return image ? ( image - r_images ) + 1 : 0; -} - -/* -================ -R_BuildGammaTable -================ -*/ -void R_BuildGammaTable( void ) { +static void R_BuildGammaTable( void ) { int i, inf; - float g; - - g = vid_gamma->value; + float g = vid_gamma->value; if( g == 1.0 ) { for ( i = 0; i < 256; i++) sw_state.gammatable[i] = i; return; } - + for( i = 0; i < 256; i++ ) { inf = 255 * pow ( ( i + 0.5 ) / 255.5 , g ) + 0.5; - clamp( inf, 0, 255 ); - sw_state.gammatable[i] = inf; + sw_state.gammatable[i] = clamp( inf, 0, 255 ); } } -/* -=============== -R_InitImages -=============== -*/ -void R_InitImages( void ) { - byte *data; - size_t length; +#define NTX 16 - registration_sequence = 1; +static void R_CreateNotexture( void ) { + static byte buffer[NTX * NTX * ( 256 + 64 + 16 + 4 ) / 256]; + int x, y, m; + byte *p; + +// create a simple checkerboard texture for the default + r_notexture = IMG_Alloc( "*notexture" ); + r_notexture->type = it_wall; + r_notexture->flags = if_auto; + r_notexture->width = r_notexture->height = NTX; + r_notexture->upload_width = r_notexture->upload_height = NTX; + r_notexture->pixels[0] = buffer; + r_notexture->pixels[1] = r_notexture->pixels[0] + NTX * NTX; + r_notexture->pixels[2] = r_notexture->pixels[1] + NTX * NTX / 4; + r_notexture->pixels[3] = r_notexture->pixels[2] + NTX * NTX / 16; + + for( m = 0; m < 4; m++ ) { + p = r_notexture->pixels[m]; + for ( y = 0; y < ( 16 >> m ); y++ ) { + for( x = 0; x < ( 16 >> m ); x++ ) { + if( ( y < ( 8 >> m ) ) ^ ( x < ( 8 >> m ) ) ) + *p++ = 0; + else + *p++ = 1; + } + } + } +} + +int R_IndexForColor( const color_t color ) { + unsigned int r, g, b, c; + + r = ( color[0] >> 3 ) & 31; + g = ( color[1] >> 2 ) & 63; + b = ( color[2] >> 3 ) & 31; + + c = r | ( g << 5 ) | ( b << 11 ); + + return d_16to8table[c]; +} - length = fs.LoadFile( "pics/16to8.dat", ( void ** )&data ); - if( !data ) { +static void R_Get16to8( void ) { + fileHandle_t f; + size_t r; + + FS_FOpenFile( "pics/16to8.dat", &f, FS_MODE_READ ); + if( !f ) { Com_Error( ERR_FATAL, "Couldn't load pics/16to8.dat" ); } - if( length < 65536 ) { + r = FS_Read( d_16to8table, sizeof( d_16to8table ), f ); + if( r != sizeof( d_16to8table ) ) { Com_Error( ERR_FATAL, "Malformed pics/16to8.dat" ); } - memcpy( d_16to8table, data, 65536 ); - fs.FreeFile( data ); + FS_FCloseFile( f ); +} - R_GetPalette( &vid.colormap ); +/* +=============== +R_InitImages +=============== +*/ +void R_InitImages( void ) { + registration_sequence = 1; + + IMG_GetPalette( &vid.colormap ); vid.alphamap = vid.colormap + 64 * 256; -#ifdef USE_ASM +#if USE_ASM { /* variable needed by assembly code */ extern void *d_pcolormap; d_pcolormap = vid.colormap; } #endif + + R_Get16to8(); + + R_CreateNotexture(); + + R_BuildGammaTable(); } /* @@ -335,10 +226,10 @@ R_ShutdownImages */ void R_ShutdownImages( void ) { if( vid.colormap ) { - com.Free( vid.colormap ); + Z_Free( vid.colormap ); vid.colormap = NULL; } - R_FreeAllImages(); + IMG_FreeAll(); } diff --git a/source/sw_light.c b/source/sw_light.c index 3c1ea77..5071c21 100644 --- a/source/sw_light.c +++ b/source/sw_light.c @@ -39,12 +39,12 @@ R_MarkLights */ void R_MarkLights (dlight_t *light, int bit, mnode_t *node) { - mplane_t *splitplane; + cplane_t *splitplane; float dist; - msurface_t *surf; + mface_t *surf; int i; - if (node->contents != -1) + if (!node->plane) return; splitplane = node->plane; @@ -70,8 +70,8 @@ void R_MarkLights (dlight_t *light, int bit, mnode_t *node) } // mark the polygons - surf = r_worldmodel->surfaces + node->firstsurface; - for (i=0 ; i<node->numsurfaces ; i++, surf++) + surf = node->firstface; + for (i=0 ; i<node->numfaces ; i++, surf++) { if (surf->dlightframe != r_dlightframecount) { @@ -91,7 +91,7 @@ void R_MarkLights (dlight_t *light, int bit, mnode_t *node) R_PushDlights ============= */ -void R_PushDlights (model_t *model) +void R_PushDlights (mnode_t *headnode) { int i; dlight_t *l; @@ -99,8 +99,7 @@ void R_PushDlights (model_t *model) r_dlightframecount = r_framecount; for (i=0, l = r_newrefdef.dlights ; i<r_newrefdef.num_dlights ; i++, l++) { - R_MarkLights ( l, 1<<i, - model->nodes + model->firstnode); + R_MarkLights ( l, 1 << i, headnode); } } @@ -113,105 +112,38 @@ LIGHT SAMPLING ============================================================================= */ -vec3_t pointcolor; -mplane_t *lightplane; // used as shadow plane -vec3_t lightspot; - -int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) -{ - 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; +static qboolean RecursiveLightPoint (vec3_t p, vec3_t color) { + mface_t *surf; + int ds, dt; byte *lightmap; float *scales; int maps; float samp; - int r; - - if (node->contents != -1) - 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; - if (plane->type < 3) // axial planes - mid[plane->type] = plane->dist; - -// 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 = r_worldmodel->surfaces + node->firstsurface; - for (i=0 ; i<node->numsurfaces ; i++, surf++) - { - if (surf->flags&(SURF_DRAWTURB|SURF_DRAWSKY)) - 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; + vec3_t end; - ds >>= 4; - dt >>= 4; - - lightmap = surf->samples; - VectorCopy (vec3_origin, pointcolor); - if (lightmap) - { - lightmap += dt * ((surf->extents[0]>>4)+1) + ds; - - for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; maps++) - { - samp = *lightmap * (1.0/255); // adjust for gl scale - scales = r_newrefdef.lightstyles[surf->styles[maps]].rgb; - VectorMA (pointcolor, samp, scales, pointcolor); - lightmap += ((surf->extents[0]>>4)+1) * ((surf->extents[1]>>4)+1); - } - } - - return 1; - } + end[0] = p[0]; + end[1] = p[1]; + end[2] = p[2] - 2048; -// go down back side - return RecursiveLightPoint (node->children[!side], mid, end); + surf = BSP_LightPoint( r_worldmodel->nodes, p, end, &ds, &dt ); + if( !surf ) { + return qfalse; + } + + ds >>= 4; + dt >>= 4; + + lightmap = surf->lightmap; + lightmap += dt * ((surf->extents[0]>>4)+1) + ds; + + for (maps = 0 ; maps < MAX_LIGHTMAPS && surf->styles[maps] != 255 ; maps++) + { + samp = *lightmap * (1.0/255); // adjust for gl scale + scales = r_newrefdef.lightstyles[surf->styles[maps]].rgb; + VectorMA (color, samp, scales, color); + lightmap += ((surf->extents[0]>>4)+1) * ((surf->extents[1]>>4)+1); + } + return qtrue; } /* @@ -221,34 +153,21 @@ R_LightPoint */ void R_LightPoint (vec3_t p, vec3_t color) { - vec3_t end; - float r; int lnum; dlight_t *dl; float light; vec3_t dist; float add; - if (!r_worldmodel || !r_worldmodel->lightdata || !r_newrefdef.lightstyles) + if (!r_worldmodel || !r_worldmodel->lightmap || !r_newrefdef.lightstyles) { color[0] = color[1] = color[2] = 1.0; return; } - end[0] = p[0]; - end[1] = p[1]; - end[2] = p[2] - 2048; - - r = RecursiveLightPoint (r_worldmodel->nodes, p, end); - - if (r == -1) - { - VectorCopy (vec3_origin, color); - } - else - { - VectorCopy (pointcolor, color); - } + VectorClear( color ); + + RecursiveLightPoint (p, color); // // add dynamic lights @@ -279,7 +198,7 @@ R_AddDynamicLights =============== */ static void R_AddDynamicLights( void ) { - msurface_t *surf; + mface_t *surf; int lnum; int sd, td; float dist, rad, minlight; @@ -309,8 +228,7 @@ static void R_AddDynamicLights( void ) { rad = -rad; } - dist = DotProduct (dl->origin, surf->plane->normal) - - surf->plane->dist; + dist = PlaneDiffFast (dl->origin, surf->plane); rad -= fabs(dist); minlight = 32; // dl->minlight; if (rad < minlight) @@ -321,8 +239,8 @@ static void R_AddDynamicLights( void ) { impact[i] = dl->origin[i] - surf->plane->normal[i]*dist; } - local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; - local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; + local[0] = DotProduct (impact, tex->axis[0]) + tex->offset[0]; + local[1] = DotProduct (impact, tex->axis[1]) + tex->offset[1]; local[0] -= surf->texturemins[0]; local[1] -= surf->texturemins[1]; @@ -340,26 +258,6 @@ static void R_AddDynamicLights( void ) { else dist = td + (sd>>1);*/ dist = sqrt( sd * sd + td * td ); -#ifdef TRUECOLOR_RENDERER - { - uint16 *dest = &blocklights[(t*smax + s)*3]; - if( !negativeLight ) { - if( dist < minlight ) { - dest[0] += dl->color[0] * (rad - dist)*255; - dest[1] += dl->color[1] * (rad - dist)*255; - dest[2] += dl->color[2] * (rad - dist)*255; - } - } else { - if( dist < minlight ) { - dest[0] -= dl->color[0] * (rad - dist)*255; - dest[1] -= dl->color[1] * (rad - dist)*255; - dest[2] -= dl->color[2] * (rad - dist)*255; - } - //if(blocklights[t*smax + s] < minlight) - // blocklights[t*smax + s] = minlight; - } - } -#else if(!negativeLight) { if (dist < minlight) blocklights[t*smax + s] += (rad - dist)*256; @@ -369,7 +267,6 @@ static void R_AddDynamicLights( void ) { if(blocklights[t*smax + s] < minlight) blocklights[t*smax + s] = minlight; } -#endif } } } @@ -383,66 +280,6 @@ R_BuildLightMap Combine and scale multiple lightmaps into the 8.8 format in blocklights =============== */ -#ifdef TRUECOLOR_RENDERER - -void R_BuildLightMap( void ) { - int smax, tmax; - int t; - int i, size; - byte *lightmap; - int maps; - msurface_t *surf; - uint16 *dst; - - surf = r_drawsurf.surf; - - smax = ( surf->extents[0] >> 4 ) + 1; - tmax = ( surf->extents[1] >> 4 ) + 1; - size = smax * tmax; - if( size*3 > MAX_BLOCKLIGHTS ) { - Com_Error( ERR_DROP, "R_BuildLightMap: surface blocklights size %i > %i", size, MAX_BLOCKLIGHTS ); - } - -// clear to no light - dst = blocklights; - for( i = 0; i < size; i++ ) { - dst[0] = 0; - dst[1] = 0; - dst[2] = 0; - dst += LIGHTMAP_BYTES; - } - - if( r_fullbright->integer || !r_worldmodel->lightdata ) { - return; - } - -// add all the lightmaps - lightmap = surf->samples; - if( lightmap ) { - for( maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++ ) { - - byte *scale; - - dst = blocklights; - scale = r_drawsurf.lightadj[maps]; - for( i = 0; i < size; i++ ) { - dst[0] += lightmap[0] * scale[0]; - dst[1] += lightmap[1] * scale[1]; - dst[2] += lightmap[2] * scale[2]; - - lightmap += LIGHTMAP_BYTES; - dst += LIGHTMAP_BYTES; - } - - } - } - -// add all the dynamic lights - if (surf->dlightframe == r_framecount) - R_AddDynamicLights (); -} - -#else void R_BuildLightMap( void ) { int smax, tmax; @@ -450,7 +287,7 @@ void R_BuildLightMap( void ) { int i, size; byte *lightmap; int maps; - msurface_t *surf; + mface_t *surf; blocklight_t *dst; surf = r_drawsurf.surf; @@ -468,14 +305,14 @@ void R_BuildLightMap( void ) { *dst++ = 0; } - if( r_fullbright->integer || !r_worldmodel->lightdata ) { + if( r_fullbright->integer || !r_worldmodel->lightmap ) { return; } // add all the lightmaps - lightmap = surf->samples; + lightmap = surf->lightmap; if( lightmap ) { - for( maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++ ) { + for( maps = 0; maps < MAX_LIGHTMAPS && surf->styles[maps] != 255; maps++ ) { fixed8_t scale; dst = blocklights; @@ -507,4 +344,3 @@ void R_BuildLightMap( void ) { } -#endif diff --git a/source/sw_local.h b/source/sw_local.h index b906b6f..8ef587a 100644 --- a/source/sw_local.h +++ b/source/sw_local.h @@ -18,15 +18,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "config.h" -#include "q_shared.h" -#include "q_files.h" -#include "com_public.h" +#include "com_local.h" +#include "files.h" #include "ref_public.h" #include "in_public.h" #include "vid_public.h" +#include "sys_public.h" #include "q_list.h" +#include "bsp.h" #include "r_shared.h" +#include "d_md2.h" +#include "r_models.h" #define REF_VERSION "SOFT 0.01" @@ -81,8 +83,6 @@ typedef struct { extern oldrefdef_t r_refdef; -#include "sw_model.h" - /* ==================================================== @@ -185,6 +185,10 @@ TYPES ==================================================== */ +#define DSURF_SKY 2 +#define DSURF_TURB 4 +#define DSURF_BACKGROUND 8 + typedef struct { float u, v; float s, t; @@ -220,7 +224,8 @@ typedef struct { int pskindesc; int skinwidth; int skinheight; - dtriangle_t *ptriangles; +// dtriangle_t *ptriangles; + void *unused; finalvert_t *pfinalverts; int numtriangles; int drawtype; @@ -232,8 +237,8 @@ typedef struct { typedef struct drawsurf_s { byte *surfdat; // destination for generated surface int rowbytes; // destination logical width in bytes - msurface_t *surf; // description for surface to generate - fixed8_t lightadj[MAXLIGHTMAPS]; + mface_t *surf; // description for surface to generate + fixed8_t lightadj[MAX_LIGHTMAPS]; // adjust for lightmap levels for dynamic lighting image_t *image; int surfmip; // mipmapped ratio of surface texels / world pixels @@ -265,20 +270,15 @@ typedef struct clipplane_s { byte reserved[2]; } clipplane_t; -#ifdef TRUECOLOR_RENDERER -#define MAX_BLOCKLIGHTS 4096 -#define LIGHTMAP_BYTES 3 -#define blocklight_t short -#else #define MAX_BLOCKLIGHTS 1024 #define LIGHTMAP_BYTES 1 -#define blocklight_t int -#endif + +typedef int blocklight_t; 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 lightadj[MAX_LIGHTMAPS]; // checked for strobe flush int dlight; int size; // including header unsigned width; @@ -322,7 +322,7 @@ typedef struct surf_s { // -1 = in inverted span (end before // start) int flags; // currentface flags - msurface_t *msurf; + mface_t *msurf; entity_t *entity; float nearzi; // nearest 1/z on surface, for mipmapping qboolean insubmodel; @@ -342,6 +342,29 @@ typedef struct edge_s { medge_t *owner; } edge_t; +typedef struct maliasst_s { + signed short s; + signed short t; +} maliasst_t; + +typedef struct maliastri_s { + unsigned short index_xyz[3]; + unsigned short index_st[3]; +} maliastri_t; + +typedef struct maliasvert_s { + uint8_t v[3]; + uint8_t lightnormalindex; +} maliasvert_t; + +typedef struct maliasframe_s { + vec3_t scale; + vec3_t translate; + vec3_t bounds[2]; + vec_t radius; + maliasvert_t *verts; +} maliasframe_t; + /* ==================================================== @@ -398,7 +421,7 @@ void D_DrawZSpans (espan_t *pspans); void Turbulent8 (espan_t *pspan); void NonTurbulent8 (espan_t *pspan); //PGM -surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel); +surfcache_t *D_CacheSurface (mface_t *surface, int miplevel); extern int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle; @@ -493,7 +516,7 @@ void R_RenderWorld (void); //============================================================================= -extern mplane_t screenedge[4]; +extern cplane_t screenedge[4]; extern vec3_t r_origin; @@ -508,7 +531,7 @@ extern float xOrigin, yOrigin; extern int r_visframecount; -extern msurface_t *r_alpha_surfaces; +extern mface_t *r_alpha_surfaces; //============================================================================= @@ -525,19 +548,17 @@ void R_DrawAlphaSurfaces( void ); void R_DrawSprite (void); void R_DrawBeam( entity_t *e ); -void R_RenderFace (msurface_t *fa, int clipflags); -void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf); -void R_TransformPlane (mplane_t *p, float *normal, float *dist); +void R_RenderFace (mface_t *fa, int clipflags); +void R_RenderBmodelFace (bedge_t *pedges, mface_t *psurf); +void R_TransformPlane (cplane_t *p, float *normal, float *dist); void R_TransformFrustum (void); void R_DrawSurfaceBlock16 (void); void R_DrawSurfaceBlock8 (void); -void R_GenSkyTile (void *pdest); -void R_GenSkyTile16 (void *pdest); void R_Surf8Patch (void); void R_Surf16Patch (void); -void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags, mnode_t *topnode); -void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode); +void R_DrawSubmodelPolygons (mmodel_t *pmodel, int clipflags, mnode_t *topnode); +void R_DrawSolidClippedSubmodelPolygons (mmodel_t *pmodel, mnode_t *topnode); void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel); surf_t *R_GetSurf (void); @@ -548,7 +569,7 @@ void D_DrawSurfaces (void); void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist); void R_StepActiveU (edge_t *pedge); void R_RemoveEdges (edge_t *pedge); -void R_PushDlights (model_t *model); +void R_PushDlights (mnode_t *headnode); extern void R_Surf8Start (void); extern void R_Surf8End (void); @@ -580,8 +601,6 @@ void R_InitTurb (void); void R_DrawParticles (void); void R_SurfacePatch (void); -void R_BuildGammaTable( void ); - extern int r_amodels_drawn; extern edge_t *auxedges; extern int r_numallocatededges; @@ -595,19 +614,13 @@ extern edge_t edge_head; extern edge_t edge_tail; extern edge_t edge_aftertail; -#ifdef TRUECOLOR_RENDERER -color_t r_aliasblendcolor; -byte *r_aliasAlphaTable, *r_aliasOneMinusAlphaTable; -#else extern int r_aliasblendcolor; -#endif extern float aliasxscale, aliasyscale, aliasxcenter, aliasycenter; extern int r_outofsurfaces; extern int r_outofedges; -extern mvertex_t *r_pcurrentvertbase; extern int r_maxvalidedgeoffset; typedef struct { @@ -633,10 +646,9 @@ extern int r_viewcluster, r_oldviewcluster; extern int r_clipflags; extern int r_dlightframecount; -extern qboolean r_fov_greater_than_90; -extern image_t *r_notexture_mip; -extern model_t *r_worldmodel; +extern image_t *r_notexture; +extern bsp_t *r_worldmodel; void R_PrintAliasStats (void); void R_PrintTimes (void); @@ -644,10 +656,8 @@ void R_PrintDSpeeds (void); void R_AnimateLight (void); void R_LightPoint (vec3_t p, vec3_t color); void R_SetupFrame (void); -void R_cshift_f (void); void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1); void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip); -void R_SplitEntityOnNode2 (mnode_t *node); extern refdef_t r_newrefdef; @@ -684,9 +694,8 @@ void R_ShutdownImages (void); void R_GammaCorrectAndSetPalette( const byte *pal ); -extern mtexinfo_t *sky_texinfo[6]; - -void R_InitSkyBox (void); +void R_InitSkyBox( void ); +void R_EmitSkyBox( void ); void R_ApplySIRDAlgorithum( void ); @@ -701,9 +710,8 @@ typedef struct swstate_s { void R_IMFlatShadedQuad( vec3_t a, vec3_t b, vec3_t c, vec3_t d, int color, float alpha ); int R_IndexForColor( const color_t color ); -image_t *R_ImageForHandle( qhandle_t hPic ); -void Draw_Fill (int x, int y, int w, int h, int c); +void R_InitDraw( void ); extern swstate_t sw_state; diff --git a/source/sw_main.c b/source/sw_main.c index 085c7cc..fe8cbe3 100644 --- a/source/sw_main.c +++ b/source/sw_main.c @@ -21,34 +21,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sw_local.h" -#ifndef REF_HARD_LINKED -/* declare imports for this module */ -cmdAPI_t cmd; -cvarAPI_t cvar; -fsAPI_t fs; -commonAPI_t com; -sysAPI_t sys; -videoAPI_t vidsw; -#else -videoAPI_t video; -#define vidsw video -#endif - viddef_t vid; unsigned d_8to24table[256]; entity_t r_worldentity; -char skyname[MAX_QPATH]; -float skyrotate; -vec3_t skyaxis; -image_t *sky_images[6]; - refdef_t r_newrefdef; model_t *currentmodel; -model_t *r_worldmodel; +bsp_t *r_worldmodel; byte r_warpbuffer[WARP_WIDTH * WARP_HEIGHT]; @@ -64,8 +46,6 @@ int r_outofedges; qboolean r_dowarp; -mvertex_t *r_pcurrentvertbase; - int c_surf; int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs; qboolean r_surfsonstack; @@ -94,7 +74,7 @@ int r_screenwidth; float verticalFieldOfView; float xOrigin, yOrigin; -mplane_t screenedge[4]; +cplane_t screenedge[4]; // // refresh flags @@ -112,8 +92,6 @@ int r_frustum_indexes[4*6]; mleaf_t *r_viewleaf; int r_viewcluster, r_oldviewcluster; -image_t *r_notexture_mip; - float da_time1, da_time2, dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2; float se_time1, se_time2, de_time1, de_time2; @@ -153,7 +131,11 @@ cvar_t *vid_gamma; cvar_t *sw_lockpvs; //PGM -#ifndef USE_ASM +#if USE_ASM + +void *d_pcolormap; + +#else // USE_ASM // all global and static refresh variables are collected in a contiguous block // to avoid cache conflicts. @@ -178,46 +160,11 @@ short *d_pzbuffer; unsigned int d_zrowbytes; unsigned int d_zwidth; -#else - -void *d_pcolormap; - -#endif // USE_ASM - -byte r_notexture_buffer[512]; - -/* -================== -R_InitTextures -================== -*/ -void R_InitTextures (void) -{ - int x,y, m; - byte *dest; - -// create a simple checkerboard texture for the default - r_notexture_mip = (image_t *)&r_notexture_buffer; - - r_notexture_mip->width = r_notexture_mip->height = 16; - r_notexture_mip->upload_width = r_notexture_mip->upload_height = 16; - r_notexture_mip->pixels[0] = &r_notexture_buffer[sizeof(image_t)]; - r_notexture_mip->pixels[1] = r_notexture_mip->pixels[0] + 16*16; - r_notexture_mip->pixels[2] = r_notexture_mip->pixels[1] + 8*8; - r_notexture_mip->pixels[3] = r_notexture_mip->pixels[2] + 4*4; - - for( m = 0; m < 4; m++ ) { - dest = r_notexture_mip->pixels[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++ = 1; - } - } -} +#endif // !USE_ASM +int sintable[CYCLE*2]; +int intsintable[CYCLE*2]; +int blanktable[CYCLE*2]; // PGM /* ================ @@ -236,83 +183,77 @@ void R_InitTurb (void) } } -void R_ImageList_f( void ); void D_SCDump_f (void); void R_Register (void) { - sw_aliasstats = cvar.Get ("sw_polymodelstats", "0", 0); - sw_allow_modex = cvar.Get( "sw_allow_modex", "1", CVAR_ARCHIVE ); - sw_clearcolor = cvar.Get ("sw_clearcolor", "2", 0); - sw_drawflat = cvar.Get ("sw_drawflat", "0", CVAR_CHEAT); - sw_draworder = cvar.Get ("sw_draworder", "0", CVAR_CHEAT); - sw_maxedges = cvar.Get ("sw_maxedges", va( "%i", NUMSTACKEDGES ), 0); - sw_maxsurfs = cvar.Get ("sw_maxsurfs", va( "%i", NUMSTACKSURFACES ), 0); - sw_mipcap = cvar.Get ("sw_mipcap", "0", 0); - sw_mipscale = cvar.Get ("sw_mipscale", "1", 0); - sw_reportedgeout = cvar.Get ("sw_reportedgeout", "0", 0); - sw_reportsurfout = cvar.Get ("sw_reportsurfout", "0", 0); - sw_stipplealpha = cvar.Get( "sw_stipplealpha", "0", CVAR_ARCHIVE ); - sw_waterwarp = cvar.Get ("sw_waterwarp", "1", 0); + sw_aliasstats = Cvar_Get ("sw_polymodelstats", "0", 0); + sw_allow_modex = Cvar_Get( "sw_allow_modex", "1", CVAR_ARCHIVE ); + sw_clearcolor = Cvar_Get ("sw_clearcolor", "2", 0); + sw_drawflat = Cvar_Get ("sw_drawflat", "0", CVAR_CHEAT); + sw_draworder = Cvar_Get ("sw_draworder", "0", CVAR_CHEAT); + sw_maxedges = Cvar_Get ("sw_maxedges", va( "%i", NUMSTACKEDGES ), 0); + sw_maxsurfs = Cvar_Get ("sw_maxsurfs", va( "%i", NUMSTACKSURFACES ), 0); + sw_mipcap = Cvar_Get ("sw_mipcap", "0", 0); + sw_mipscale = Cvar_Get ("sw_mipscale", "1", 0); + sw_reportedgeout = Cvar_Get ("sw_reportedgeout", "0", 0); + sw_reportsurfout = Cvar_Get ("sw_reportsurfout", "0", 0); + sw_stipplealpha = Cvar_Get( "sw_stipplealpha", "0", CVAR_ARCHIVE ); + sw_waterwarp = Cvar_Get ("sw_waterwarp", "1", 0); //Start Added by Lewey - sw_drawsird = cvar.Get ("sw_drawsird", "0", 0); + sw_drawsird = Cvar_Get ("sw_drawsird", "0", 0); //End Added by Lewey - r_speeds = cvar.Get ("r_speeds", "0", 0); - r_fullbright = cvar.Get ("r_fullbright", "0", CVAR_CHEAT); - r_drawentities = cvar.Get ("r_drawentities", "1", 0); - r_drawworld = cvar.Get ("r_drawworld", "1", CVAR_CHEAT); - r_dspeeds = cvar.Get ("r_dspeeds", "0", 0); - r_lerpmodels = cvar.Get( "r_lerpmodels", "1", 0 ); - r_novis = cvar.Get( "r_novis", "0", 0 ); + r_speeds = Cvar_Get ("r_speeds", "0", 0); + r_fullbright = Cvar_Get ("r_fullbright", "0", CVAR_CHEAT); + r_drawentities = Cvar_Get ("r_drawentities", "1", 0); + r_drawworld = Cvar_Get ("r_drawworld", "1", CVAR_CHEAT); + r_dspeeds = Cvar_Get ("r_dspeeds", "0", 0); + r_lerpmodels = Cvar_Get( "r_lerpmodels", "1", 0 ); + r_novis = Cvar_Get( "r_novis", "0", 0 ); - vid_gamma = cvar.Get( "vid_gamma", "1.0", CVAR_ARCHIVE|CVAR_FILES ); + vid_gamma = Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE|CVAR_FILES ); - cmd.AddCommand ("modellist", Mod_Modellist_f); - cmd.AddCommand( "screenshot", R_ScreenShot_f ); - cmd.AddCommand( "scdump", D_SCDump_f ); + Cmd_AddCommand( "screenshot", R_ScreenShot_f ); + Cmd_AddCommand( "scdump", D_SCDump_f ); vid_gamma->modified = qtrue; // force us to rebuild the gamma table later //PGM - sw_lockpvs = cvar.Get ("sw_lockpvs", "0", 0); + sw_lockpvs = Cvar_Get ("sw_lockpvs", "0", 0); //PGM } void R_UnRegister (void) { - cmd.RemoveCommand( "screenshot" ); - cmd.RemoveCommand ("modellist"); - cmd.RemoveCommand( "scdump" ); + Cmd_RemoveCommand( "screenshot" ); + Cmd_RemoveCommand( "scdump" ); } -static void R_ModeChanged( int width, int height, int flags, - int rowbytes, void *pixels ) -{ +void R_ModeChanged( int width, int height, int flags, int rowbytes, void *pixels ) { vid.width = width; vid.height = height; vid.buffer = pixels; vid.rowbytes = rowbytes; - sw_surfcacheoverride = cvar.Get ("sw_surfcacheoverride", "0", 0); + sw_surfcacheoverride = Cvar_Get ("sw_surfcacheoverride", "0", 0); D_FlushCaches(); if( d_pzbuffer ) { - com.Free( d_pzbuffer ); + Z_Free( d_pzbuffer ); d_pzbuffer = NULL; } // free surface cache if( sc_base ) { - com.Free( sc_base ); + Z_Free( sc_base ); sc_base = NULL; } - d_pzbuffer = R_Malloc( vid.width * vid.height * 2 ); - memset( d_pzbuffer, 0, vid.width * vid.height * 2 ); + d_pzbuffer = R_Mallocz( vid.width * vid.height * 2 ); R_InitCaches(); @@ -329,8 +270,8 @@ qboolean R_Init( qboolean total ) { if( !total ) { R_InitImages(); - Draw_Init(); - Mod_Init(); + R_InitDraw(); + MOD_Init(); return qtrue; } @@ -345,17 +286,20 @@ qboolean R_Init( qboolean total ) { r_aliasuvscale = 1.0; // create the window - if( !vidsw.Init() ) { + if( !VID_Init() ) { return qfalse; } R_Register(); - R_InitImageManager(); + IMG_Init(); + MOD_Init(); /* get the palette before we create the window */ R_InitImages(); + R_InitSkyBox(); + view_clipplanes[0].leftedge = qtrue; view_clipplanes[1].rightedge = qtrue; view_clipplanes[1].leftedge = @@ -368,13 +312,8 @@ qboolean R_Init( qboolean total ) { r_refdef.xOrigin = XCENTERING; r_refdef.yOrigin = YCENTERING; - R_InitTextures(); R_InitTurb(); - Draw_Init(); - Mod_Init(); - - R_BuildGammaTable(); R_GammaCorrectAndSetPalette( ( const byte * ) d_8to24table ); return qtrue; @@ -390,37 +329,44 @@ void R_Shutdown( qboolean total ) { D_FlushCaches(); - Mod_FreeAll(); + MOD_FreeAll(); R_ShutdownImages(); + // free world model + if( r_worldmodel ) { + BSP_Free( r_worldmodel ); + r_worldmodel = NULL; + } + if( !total ) { return; } // free z buffer if( d_pzbuffer ) { - com.Free( d_pzbuffer ); + Z_Free( d_pzbuffer ); d_pzbuffer = NULL; } // free surface cache if( sc_base ) { - com.Free( sc_base ); + Z_Free( sc_base ); sc_base = NULL; } // free colormap if( vid.colormap ) { - com.Free( vid.colormap ); + Z_Free( vid.colormap ); vid.colormap = NULL; } R_UnRegister(); - R_ShutdownImageManager(); + IMG_Shutdown(); + MOD_Shutdown(); - vidsw.Shutdown(); + VID_Shutdown(); } /* @@ -439,8 +385,7 @@ void R_NewMap (void) if (r_cnumsurfs > NUMSTACKSURFACES) { - surfaces = R_Malloc (r_cnumsurfs * sizeof(surf_t)); - memset( surfaces, 0, r_cnumsurfs * sizeof(surf_t) ); + surfaces = R_Mallocz (r_cnumsurfs * sizeof(surf_t)); surface_p = surfaces; surf_max = &surfaces[r_cnumsurfs]; r_surfsonstack = qfalse; @@ -468,8 +413,7 @@ void R_NewMap (void) } else { - auxedges = R_Malloc (r_numallocatededges * sizeof(edge_t)); - memset( auxedges, 0, r_numallocatededges * sizeof(edge_t) ); + auxedges = R_Mallocz (r_numallocatededges * sizeof(edge_t)); } } @@ -484,7 +428,7 @@ cluster */ void R_MarkLeaves (void) { - byte *vis; + byte vis[MAX_MAP_VIS]; mnode_t *node; int i; mleaf_t *leaf; @@ -514,7 +458,7 @@ void R_MarkLeaves (void) return; } - vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel); + BSP_ClusterVis (r_worldmodel, vis, r_viewcluster, DVIS_PVS); for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++) { @@ -541,113 +485,67 @@ void R_MarkLeaves (void) ** ** IMPLEMENT THIS! */ -void R_DrawNullModel( void ) -{ +static void R_DrawNullModel( void ) { } -/* -============= -R_DrawEntitiesOnList -============= -*/ -void R_DrawEntitiesOnList (void) -{ +static int R_DrawEntities( int translucent ) { int i; - qboolean translucent_entities = qfalse; - - if (!r_drawentities->value) - return; + qboolean translucent_entities = 0; // all bmodels have already been drawn by the edge list - for (i=0 ; i<r_newrefdef.num_entities ; i++) - { + for( i = 0; i < r_newrefdef.num_entities; i++ ){ currententity = &r_newrefdef.entities[i]; - if ( currententity->flags & RF_TRANSLUCENT ) - { - translucent_entities = qtrue; + if( ( currententity->flags & RF_TRANSLUCENT ) == translucent ) { + translucent_entities++; continue; } - if ( currententity->flags & RF_BEAM ) - { + if( currententity->flags & RF_BEAM ) { modelorg[0] = -r_origin[0]; modelorg[1] = -r_origin[1]; modelorg[2] = -r_origin[2]; VectorCopy( vec3_origin, r_entorigin ); R_DrawBeam( currententity ); - } - else - { - currentmodel = R_ModelForHandle( currententity->model ); - if (!currentmodel) - { + } else { + if( currententity->model & 0x80000000 ) { + continue; + } + currentmodel = MOD_ForHandle( currententity->model ); + if( !currentmodel ) { R_DrawNullModel(); continue; } VectorCopy (currententity->origin, r_entorigin); VectorSubtract (r_origin, r_entorigin, modelorg); - switch (currentmodel->type) - { - case mod_sprite: - R_DrawSprite (); - break; - - case mod_alias: - R_AliasDrawModel (); - break; - - default: - break; - } + if( currentmodel->frames ) { + R_AliasDrawModel(); + } else if( currentmodel->spriteframes ) { + R_DrawSprite(); + } else { + Com_Error( ERR_FATAL, "%s: bad model type", __func__ ); + } } } + return translucent_entities; +} - if ( !translucent_entities ) - return; - - for (i=0 ; i<r_newrefdef.num_entities ; i++) - { - currententity = &r_newrefdef.entities[i]; - - if ( !( currententity->flags & RF_TRANSLUCENT ) ) - continue; - - if ( currententity->flags & RF_BEAM ) - { - modelorg[0] = -r_origin[0]; - modelorg[1] = -r_origin[1]; - modelorg[2] = -r_origin[2]; - VectorCopy( vec3_origin, r_entorigin ); - R_DrawBeam( currententity ); - } - else - { - currentmodel = R_ModelForHandle( currententity->model ); - if (!currentmodel) - { - R_DrawNullModel(); - continue; - } - VectorCopy (currententity->origin, r_entorigin); - VectorSubtract (r_origin, r_entorigin, modelorg); - - switch (currentmodel->type) - { - case mod_sprite: - R_DrawSprite (); - break; +/* +============= +R_DrawEntitiesOnList +============= +*/ +static void R_DrawEntitiesOnList( void ) { + int translucent_entities; - case mod_alias: - R_AliasDrawModel (); - break; + if( !r_drawentities->integer ) + return; - default: - break; - } - } - } + translucent_entities = R_DrawEntities( RF_TRANSLUCENT ); + if( translucent_entities ) { + R_DrawEntities( 0 ); + } } @@ -706,27 +604,20 @@ Find the first node that splits the given box */ mnode_t *R_FindTopnode (vec3_t mins, vec3_t maxs) { - mplane_t *splitplane; int sides; mnode_t *node; node = r_worldmodel->nodes; - while (1) - { - if (node->visframe != r_visframecount) - return NULL; // not visible at all - - if (node->contents != CONTENTS_NODE) - { - if (node->contents != CONTENTS_SOLID) - return node; // we've reached a non-solid leaf, so it's + while (node->visframe == r_visframecount) { + if (!node->plane) { + if (((mleaf_t * )node)->contents != CONTENTS_SOLID) + return node; // we've reached a non-solid leaf, so it's // visible and not BSP clipped return NULL; // in solid, so not visible } - splitplane = node->plane; - sides = BoxOnPlaneSideFast(mins, maxs, (cplane_t *)splitplane); + sides = BoxOnPlaneSideFast(mins, maxs, node->plane); if (sides == 3) return node; // this is the splitter @@ -737,6 +628,8 @@ mnode_t *R_FindTopnode (vec3_t mins, vec3_t maxs) else node = node->children[1]; } + + return NULL; // not visible at all } @@ -808,11 +701,12 @@ R_DrawBEntitiesOnList */ void R_DrawBEntitiesOnList (void) { - int i, clipflags; + int i, index, clipflags; vec3_t oldorigin; vec3_t mins, maxs; float minmaxs[6]; mnode_t *topnode; + mmodel_t *model; if (!r_drawentities->value) return; @@ -824,18 +718,23 @@ void R_DrawBEntitiesOnList (void) for (i=0 ; i<r_newrefdef.num_entities ; i++) { currententity = &r_newrefdef.entities[i]; - currentmodel = R_ModelForHandle( currententity->model ); - if (!currentmodel) - continue; - if (currentmodel->nummodelsurfaces == 0) + index = currententity->model; + if( !( index & 0x80000000 ) ) { + continue; + } + index = ~index; + if( index < 1 || index >= r_worldmodel->nummodels ) { + Com_Error( ERR_DROP, "%s: inline model %d out of range", + __func__, index ); + } + model = &r_worldmodel->models[index]; + if (model->numfaces == 0) continue; // clip brush only if ( currententity->flags & RF_BEAM ) continue; - if (currentmodel->type != mod_brush) - continue; // see if the bounding box lets us trivially reject, also sets // trivial accept status - RotatedBBox (currentmodel->mins, currentmodel->maxs, + RotatedBBox (model->mins, model->maxs, currententity->angles, mins, maxs); VectorAdd (mins, currententity->origin, minmaxs); VectorAdd (maxs, currententity->origin, (minmaxs+3)); @@ -851,26 +750,24 @@ void R_DrawBEntitiesOnList (void) VectorCopy (currententity->origin, r_entorigin); VectorSubtract (r_origin, r_entorigin, modelorg); - r_pcurrentvertbase = currentmodel->vertexes; - // FIXME: stop transforming twice R_RotateBmodel (); // calculate dynamic lighting for bmodel - R_PushDlights (currentmodel); + R_PushDlights (model->headnode); - if (topnode->contents == CONTENTS_NODE) + if (topnode->plane) { // not a leaf; has to be clipped to the world BSP r_clipflags = clipflags; - R_DrawSolidClippedSubmodelPolygons (currentmodel, topnode); + R_DrawSolidClippedSubmodelPolygons (model, topnode); } else { // falls entirely in one leaf, so we just put all the // edges in the edge list and let 1/z sorting handle // drawing order - R_DrawSubmodelPolygons (currentmodel, clipflags, topnode); + R_DrawSubmodelPolygons (model, clipflags, topnode); } // put back world rotation and frustum clipping @@ -926,14 +823,14 @@ void R_EdgeDrawing (void) if (r_dspeeds->integer) { - rw_time1 = sys.Milliseconds (); + rw_time1 = Sys_Milliseconds (); } R_RenderWorld (); if (r_dspeeds->integer) { - rw_time2 = sys.Milliseconds (); + rw_time2 = Sys_Milliseconds (); db_time1 = rw_time2; } @@ -941,7 +838,7 @@ void R_EdgeDrawing (void) if (r_dspeeds->integer) { - db_time2 = sys.Milliseconds (); + db_time2 = Sys_Milliseconds (); se_time1 = db_time2; } @@ -1023,19 +920,19 @@ void R_RenderFrame (refdef_t *fd) VectorCopy (fd->viewangles, r_refdef.viewangles); if (r_speeds->integer || r_dspeeds->integer) - r_time1 = sys.Milliseconds (); + r_time1 = Sys_Milliseconds (); R_SetupFrame (); R_MarkLeaves (); // done here so we know if we're in water - R_PushDlights (r_worldmodel); + R_PushDlights (r_worldmodel->nodes); R_EdgeDrawing (); if (r_dspeeds->integer) { - se_time2 = sys.Milliseconds (); + se_time2 = Sys_Milliseconds (); de_time1 = se_time2; } @@ -1043,14 +940,14 @@ void R_RenderFrame (refdef_t *fd) if (r_dspeeds->integer) { - de_time2 = sys.Milliseconds (); - dp_time1 = sys.Milliseconds (); + de_time2 = Sys_Milliseconds (); + dp_time1 = Sys_Milliseconds (); } R_DrawParticles (); if (r_dspeeds->integer) - dp_time2 = sys.Milliseconds (); + dp_time2 = Sys_Milliseconds (); R_DrawAlphaSurfaces(); @@ -1069,10 +966,10 @@ void R_RenderFrame (refdef_t *fd) //End Replaced by Lewey if (r_dspeeds->integer) - da_time1 = sys.Milliseconds (); + da_time1 = Sys_Milliseconds (); if (r_dspeeds->integer) - da_time2 = sys.Milliseconds (); + da_time2 = Sys_Milliseconds (); R_CalcPalette (); @@ -1096,11 +993,11 @@ void R_RenderFrame (refdef_t *fd) ** R_BeginFrame */ void R_BeginFrame( void ) { - vidsw.BeginFrame(); + VID_BeginFrame(); } void R_EndFrame( void ) { - vidsw.EndFrame(); + VID_EndFrame(); } /* @@ -1118,7 +1015,7 @@ void R_GammaCorrectAndSetPalette( const byte *palette ) { palette += 4; dest += 4; } - vidsw.UpdatePalette( sw_state.currentpalette ); + VID_UpdatePalette( sw_state.currentpalette ); } /* @@ -1215,56 +1112,6 @@ void R_DrawBeam( entity_t *e ) //=================================================================== -/* -============ -R_SetSky -============ -*/ -extern mtexinfo_t r_skytexinfo[6]; - -void R_SetSky( const char *name, float rotate, vec3_t axis ) { - // 3dstudio environment map names - static const char suf[6][3] = {"rt", "bk", "lf", "ft", "up", "dn"}; - static const int r_skysideimage[6] = {5, 2, 4, 1, 0, 3}; - int i; - char pathname[MAX_QPATH]; - - strncpy (skyname, name, sizeof(skyname)-1); - skyrotate = rotate; - VectorCopy (axis, skyaxis); - - for (i=0 ; i<6 ; i++) - { - Q_concat( pathname, sizeof( pathname ), - "env/", skyname, suf[r_skysideimage[i]], ".pcx", NULL ); - r_skytexinfo[i].image = R_FindImage (pathname, it_sky); - } -} - - - - -/* -================= -R_GetModelSize -================= -*/ -void R_GetModelSize( qhandle_t hModel, vec3_t mins, vec3_t maxs ) { - model_t *mod; - - mod = R_ModelForHandle( hModel ); - if( !mod ) { - return; - } - - if( mins ) { - VectorCopy( mod->mins, mins ); - } - if( maxs ) { - VectorCopy( mod->maxs, maxs ); - } -} - void R_GetConfig( glconfig_t *dest ) { memset( dest, 0, sizeof( *dest ) ); @@ -1273,202 +1120,3 @@ void R_GetConfig( glconfig_t *dest ) { dest->vidHeight = vid.height; } -#ifndef REF_HARD_LINKED - -// this is only here so the functions in q_shared.c can link - -void Com_Printf( const char *fmt, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, fmt ); - Q_vsnprintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - com.Print( PRINT_ALL, text ); -} - -void Com_DPrintf( const char *fmt, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, fmt ); - Q_vsnprintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - com.Print( PRINT_DEVELOPER, text ); -} - -void Com_WPrintf( const char *fmt, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, fmt ); - Q_vsnprintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - com.Print( PRINT_WARNING, text ); -} - -void Com_EPrintf( const char *fmt, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, fmt ); - Q_vsnprintf( text, sizeof( text ), fmt, argptr ); - va_end( argptr ); - - com.Print( PRINT_ERROR, text ); -} - -void Com_Error( comErrorType_t type, const char *error, ... ) { - va_list argptr; - char text[MAXPRINTMSG]; - - va_start( argptr, error ); - Q_vsnprintf( text, sizeof( text ), error, argptr ); - va_end( argptr ); - - com.Error( type, text ); -} - -#endif - -void R_BeginRegistration( const char *model ); -qhandle_t R_RegisterSkin( const char *name ); -qhandle_t R_RegisterModel( const char *name ); -qhandle_t R_RegisterPic( const char *name ); -qhandle_t R_RegisterFont( const char *name ); -void R_EndRegistration( void ); - -void Draw_SetScale( float *scale ) { - if( scale ) { - *scale = 1; - } -} - -void Draw_SetColor( int flags, const color_t color ); -void Draw_SetClipRect( int flags, const clipRect_t *clip ); -qboolean Draw_GetPicSize( int *w, int *h, qhandle_t hPic ); -void Draw_Pic( int x, int y, qhandle_t hPic ); -void Draw_StretchPic( int x, int y, int w, int h, qhandle_t hPic ); -void Draw_StretchPicST( int x, int y, int w, int h, float s1, float t1, - float s2, float t2, qhandle_t hPic ); -void Draw_TileClear( int x, int y, int w, int h, qhandle_t hPic ); -void Draw_Fill( int x, int y, int w, int h, int c ); -void Draw_FillEx( int x, int y, int w, int h, const color_t color ); -void Draw_StretchRaw( int x, int y, int w, int h, int cols, - int rows, const byte *data ); -void Draw_Char( int x, int y, int flags, int ch, qhandle_t hFont ); -int Draw_String( int x, int y, int flags, size_t maxChars, - const char *string, qhandle_t hFont ); - -/* -================= -Ref_FillAPI -================= -*/ -static void Ref_FillAPI( refAPI_t *api ) { - api->BeginRegistration = R_BeginRegistration; - api->RegisterModel = R_RegisterModel; - api->RegisterSkin = R_RegisterSkin; - api->RegisterPic = R_RegisterPic; - api->RegisterFont = R_RegisterFont; - api->SetSky = R_SetSky; - api->EndRegistration = R_EndRegistration; - api->GetModelSize = R_GetModelSize; - - api->RenderFrame = R_RenderFrame; - api->LightPoint = R_LightPoint; - - api->SetColor = Draw_SetColor; - api->SetClipRect = Draw_SetClipRect; - api->SetScale = Draw_SetScale; - api->DrawGetPicSize = Draw_GetPicSize; - api->DrawPic = Draw_Pic; - api->DrawStretchPic = Draw_StretchPic; - api->DrawStretchPicST = Draw_StretchPicST; - api->DrawTileClear = Draw_TileClear; - api->DrawFill = Draw_Fill; - api->DrawStretchRaw = Draw_StretchRaw; - api->DrawChar = Draw_Char; - api->DrawString = Draw_String; - - api->DrawFillEx = Draw_FillEx; - - api->Init = R_Init; - api->Shutdown = R_Shutdown; - - api->CinematicSetPalette = R_CinematicSetPalette; - api->BeginFrame = R_BeginFrame; - api->EndFrame = R_EndFrame; - api->ModeChanged = R_ModeChanged; - - api->GetConfig = R_GetConfig; - -} - -/* -================= -Ref_APISetupCallback -================= -*/ -qboolean Ref_APISetupCallback( api_type_t type, void *api ) { - switch( type ) { - case API_REFRESH: - Ref_FillAPI( ( refAPI_t * )api ); - break; - default: - /* not supported API type */ - return qfalse; - } - - return qtrue; -} - -#ifndef REF_HARD_LINKED - -/* -@@@@@@@@@@@@@@@@@@@@@ -moduleEntry - -@@@@@@@@@@@@@@@@@@@@@ -*/ -EXPORTED void *moduleEntry( int query, void *data ) { - moduleInfo_t *info; - moduleCapability_t caps; - APISetupCallback_t callback; - - switch( query ) { - case MQ_GETINFO: - info = ( moduleInfo_t * )data; - info->api_version = MODULES_APIVERSION; - Q_strncpyz( info->fullname, "Software Refresh Driver", - sizeof( info->fullname ) ); - Q_strncpyz( info->author, "ID Software, Inc", sizeof( info->author ) ); - return ( void * )qtrue; - - case MQ_GETCAPS: - caps = MCP_REFRESH; - return ( void * )caps; - - case MQ_SETUPAPI: - if( ( callback = ( APISetupCallback_t )data ) == NULL ) { - return NULL; - } - callback( API_CMD, &cmd ); - callback( API_CVAR, &cvar ); - callback( API_FS, &fs ); - callback( API_COMMON, &com ); - callback( API_SYSTEM, &sys ); - callback( API_VIDEO_SOFTWARE, &vidsw ); - - return ( void * )Ref_APISetupCallback; - - } - - /* quiet compiler warning */ - return NULL; -} - -#endif diff --git a/source/sw_misc.c b/source/sw_misc.c index c23db4a..d16891b 100644 --- a/source/sw_misc.c +++ b/source/sw_misc.c @@ -110,7 +110,7 @@ void D_ViewChanged (void) if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) { memset( d_pzbuffer, 0xff, vid.width * vid.height * sizeof( d_pzbuffer[0] ) ); - Draw_Fill( r_newrefdef.x, r_newrefdef.y, r_newrefdef.width, r_newrefdef.height, /*( int ) sw_clearcolor->value & 0xff*/0 ); + R_DrawFill( r_newrefdef.x, r_newrefdef.y, r_newrefdef.width, r_newrefdef.height, /*( int ) sw_clearcolor->value & 0xff*/0 ); } D_Patch (); @@ -128,7 +128,7 @@ void R_PrintTimes (void) int r_time2; int ms; - r_time2 = sys.Milliseconds (); + r_time2 = Sys_Milliseconds (); ms = r_time2 - r_time1; @@ -147,7 +147,7 @@ void R_PrintDSpeeds (void) { int ms, dp_time, r_time2, rw_time, db_time, se_time, de_time, da_time; - r_time2 = sys.Milliseconds (); + r_time2 = Sys_Milliseconds (); da_time = (da_time2 - da_time1); dp_time = (dp_time2 - dp_time1); @@ -218,7 +218,7 @@ void TransformVector (vec3_t in, vec3_t out) R_TransformPlane ================ */ -void R_TransformPlane (mplane_t *p, float *normal, float *dist) +void R_TransformPlane (cplane_t *p, float *normal, float *dist) { float d; @@ -388,11 +388,11 @@ void R_SetupFrame (void) // current viewleaf if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) ) { - r_viewleaf = Mod_PointInLeaf (r_origin, r_worldmodel); + r_viewleaf = BSP_PointLeaf (r_worldmodel->nodes, r_origin); r_viewcluster = r_viewleaf->cluster; } - if (sw_waterwarp->value && (r_newrefdef.rdflags & RDF_UNDERWATER) ) + if (sw_waterwarp->integer && (r_newrefdef.rdflags & RDF_UNDERWATER) ) r_dowarp = qtrue; else r_dowarp = qfalse; diff --git a/source/sw_model.c b/source/sw_model.c index 28678b5..1bebf9d 100644 --- a/source/sw_model.c +++ b/source/sw_model.c @@ -24,507 +24,40 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sw_local.h" -model_t *loadmodel; - -void Mod_LoadSpriteModel (model_t *mod, void *buffer); -void Mod_LoadBrushModel (model_t *mod, void *buffer); -void Mod_LoadAliasModel (model_t *mod, void *buffer); -model_t *Mod_LoadModel (model_t *mod, qboolean crash); - -byte mod_novis[MAX_MAP_LEAFS/8]; - -#define MAX_MOD_KNOWN 256 -model_t mod_known[MAX_MOD_KNOWN]; -int mod_numknown; - -// the inline * models from the current map are kept seperate -model_t mod_inline[MAX_MOD_KNOWN]; - int registration_sequence; -int modfilelen; - -/* -================ -R_ModelForHandle -================ -*/ -model_t *R_ModelForHandle( qhandle_t hModel ) { - if( !hModel ) { - return NULL; - } - - if( hModel < 0 ) { - // inline model - if( !r_worldmodel ) { - return NULL; - } - hModel = -hModel; - if( hModel >= r_worldmodel->numsubmodels ) { - Com_Error( ERR_DROP, "R_ModelForHandle: out of range inline hModel: %i", hModel ); - } - return &mod_inline[hModel]; - } - - if( hModel >= mod_numknown + 1 ) { - Com_Error( ERR_DROP, "R_ModelForHandle: out of range hModel: %i", hModel ); - } - return &mod_known[hModel - 1]; -} - -//=============================================================================== - - -/* -================ -Mod_Modellist_f -================ -*/ -void Mod_Modellist_f (void) -{ - int i; - model_t *mod; - int total; - - total = 0; - Com_Printf("Loaded models:\n"); - for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++) - { - if (!mod->name[0]) - continue; - Com_Printf( "%8"PRIz" : %s\n",mod->pool.cursize, mod->name); - total += mod->pool.cursize; - } - Com_Printf( "Total resident: %i\n", total); -} - -/* -=============== -Mod_Init -=============== -*/ -void Mod_Init (void) -{ - memset (mod_novis, 0xff, sizeof(mod_novis)); -} - -/* -================== -Mod_ForName - -Loads in a model for the given name -================== -*/ -qhandle_t Mod_ForName (const char *name, qboolean crash) -{ - model_t *mod; - byte *buf; - int i; - - if (!name || !name[0]) - Com_Error (ERR_DROP,"Mod_ForName: NULL name"); - - // - // inline models are grabbed only from worldmodel - // - if (name[0] == '*') - { - i = atoi(name+1); - if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels) - Com_Error (ERR_DROP, "bad inline model number"); - return -i; - } - - // - // search the currently loaded models - // - for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) - if (!strcmp (mod->name, name) ) - return i + 1; - - // - // find a free model slot spot - // - for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) - { - if (!mod->name[0]) - break; // free spot - } - if (i == mod_numknown) - { - if (mod_numknown == MAX_MOD_KNOWN) - Com_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN"); - mod_numknown++; - } - Q_strncpyz( mod->name, name, sizeof( mod->name ) ); - - // - // load the file - // - modfilelen = fs.LoadFile (mod->name, (void **)&buf); - if (!buf) - { - if (crash) - Com_Error (ERR_DROP,"Mod_NumForName: %s not found", mod->name); - memset (mod->name, 0, sizeof(mod->name)); - return 0; - } - - loadmodel = mod; - - // - // fill it in - // - - // call the apropriate loader - switch (LittleLong(*(unsigned *)buf)) - { - case IDALIASHEADER: - sys.HunkBegin (&loadmodel->pool, 0x200000); - Mod_LoadAliasModel (mod, buf); - break; - - case IDSPRITEHEADER: - sys.HunkBegin (&loadmodel->pool, 0x10000); - Mod_LoadSpriteModel (mod, buf); - break; - - case IDBSPHEADER: - sys.HunkBegin (&loadmodel->pool, 0x1000000); - Mod_LoadBrushModel (mod, buf); - break; - - default: - Com_Error (ERR_DROP,"Mod_NumForName: unknown fileid for %s", mod->name); - break; - } - - - - fs.FreeFile (buf); - - return ( mod - mod_known ) + 1; -} - - -/* -=============== -Mod_PointInLeaf -=============== -*/ -mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) -{ - mnode_t *node; - float d; - mplane_t *plane; - - if (!model || !model->nodes) - Com_Error (ERR_DROP, "Mod_PointInLeaf: bad model"); - - node = model->nodes; - while (1) - { - if (node->contents != -1) - return (mleaf_t *)node; - plane = node->plane; - d = DotProduct (p,plane->normal) - plane->dist; - if (d > 0) - node = node->children[0]; - else - node = node->children[1]; - } - - return NULL; // never reached -} - - -/* -=================== -Mod_DecompressVis -=================== -*/ -byte *Mod_DecompressVis (byte *in, model_t *model) -{ - static byte decompressed[MAX_MAP_LEAFS/8]; - int c; - byte *out; - int row; - - row = (model->vis->numclusters+7)>>3; - out = decompressed; - -#if 0 - memcpy (out, in, row); -#else - if (!in) - { // no vis info, so make all visible - while (row) - { - *out++ = 0xff; - row--; - } - return decompressed; - } - - do - { - if (*in) - { - *out++ = *in++; - continue; - } - - c = in[1]; - in += 2; - while (c) - { - *out++ = 0; - c--; - } - } while (out - decompressed < row); -#endif - - return decompressed; -} - -/* -============== -Mod_ClusterPVS -============== -*/ -byte *Mod_ClusterPVS (int cluster, model_t *model) -{ - if (cluster == -1 || !model->vis) - return mod_novis; - return Mod_DecompressVis ( (byte *)model->vis + model->vis->bitofs[cluster][DVIS_PVS], - model); -} - -/* -=============================================================================== - - BRUSHMODEL LOADING - -=============================================================================== -*/ - -byte *mod_base; - - -/* -================= -Mod_LoadLighting - -Converts the 24 bit lighting down to 8 bit -by taking the brightest component -================= -*/ -void Mod_LoadLighting (lump_t *l) -{ - int i, size; - byte *in; - - if (!l->filelen) - { - loadmodel->lightdata = NULL; - return; - } - size = l->filelen/3; - loadmodel->lightdata = sys.HunkAlloc (&loadmodel->pool, size); - in = (void *)(mod_base + l->fileofs); - for (i=0 ; i<size ; i++, in+=3) - { - if (in[0] > in[1] && in[0] > in[2]) - loadmodel->lightdata[i] = in[0]; - else if (in[1] > in[0] && in[1] > in[2]) - loadmodel->lightdata[i] = in[1]; - else - loadmodel->lightdata[i] = in[2]; - } -} - -/* -================= -Mod_LoadVisibility -================= -*/ -void Mod_LoadVisibility (lump_t *l) -{ - int i; - - if (!l->filelen) - { - loadmodel->vis = NULL; - return; - } - loadmodel->vis = sys.HunkAlloc (&loadmodel->pool, l->filelen); - memcpy (loadmodel->vis, mod_base + l->fileofs, l->filelen); - - loadmodel->vis->numclusters = LittleLong (loadmodel->vis->numclusters); - for (i=0 ; i<loadmodel->vis->numclusters ; i++) - { - loadmodel->vis->bitofs[i][0] = LittleLong (loadmodel->vis->bitofs[i][0]); - loadmodel->vis->bitofs[i][1] = LittleLong (loadmodel->vis->bitofs[i][1]); - } -} - - -/* -================= -Mod_LoadVertexes -================= -*/ -void Mod_LoadVertexes (lump_t *l) -{ - dvertex_t *in; - mvertex_t *out; - int i, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = sys.HunkAlloc (&loadmodel->pool, (count+8)*sizeof(*out)); // extra for skybox - - loadmodel->vertexes = out; - loadmodel->numvertexes = count; - - for ( i=0 ; i<count ; i++, in++, out++) - { - out->position[0] = LittleFloat (in->point[0]); - out->position[1] = LittleFloat (in->point[1]); - out->position[2] = LittleFloat (in->point[2]); - } -} /* ================= -Mod_LoadSubmodels +ProcessTexinfo ================= */ -void Mod_LoadSubmodels (lump_t *l) -{ - dmodel_t *in; - dmodel_t *out; - int i, j, count; +static void ProcessTexinfo( bsp_t *bsp ) { + mtexinfo_t *tex; + int i; + vec_t len1, len2; + char name[MAX_QPATH]; - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = sys.HunkAlloc (&loadmodel->pool, count*sizeof(*out)); - - loadmodel->submodels = out; - loadmodel->numsubmodels = count; - - for ( i=0 ; i<count ; i++, in++, out++) - { - for (j=0 ; j<3 ; j++) - { // spread the mins / maxs by a pixel - out->mins[j] = LittleFloat (in->mins[j]) - 1; - out->maxs[j] = LittleFloat (in->maxs[j]) + 1; - out->origin[j] = LittleFloat (in->origin[j]); - } - out->headnode = LittleLong (in->headnode); - out->firstface = LittleLong (in->firstface); - out->numfaces = LittleLong (in->numfaces); - } -} - -/* -================= -Mod_LoadEdges -================= -*/ -void Mod_LoadEdges (lump_t *l) -{ - dedge_t *in; - medge_t *out; - int i, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = sys.HunkAlloc (&loadmodel->pool, (count + 13) * sizeof(*out)); // extra for skybox - - loadmodel->edges = out; - loadmodel->numedges = count; - - for ( i=0 ; i<count ; i++, in++, out++) - { - out->v[0] = (unsigned short)LittleShort(in->v[0]); - out->v[1] = (unsigned short)LittleShort(in->v[1]); - } -} - -/* -================= -Mod_LoadTexinfo -================= -*/ -void Mod_LoadTexinfo (lump_t *l) -{ - texinfo_t *in; - mtexinfo_t *out, *step; - int i, j, count; - float len1, len2; - char name[MAX_QPATH]; - int next; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = sys.HunkAlloc (&loadmodel->pool, (count+6)*sizeof(*out)); // extra for skybox - - loadmodel->texinfo = out; - loadmodel->numtexinfo = count; - - for ( i=0 ; i<count ; i++, in++, out++) - { - for (j=0 ; j<8 ; j++) - out->vecs[0][j] = LittleFloat (in->vecs[0][j]); - len1 = VectorLength (out->vecs[0]); - len2 = VectorLength (out->vecs[1]); - len1 = (len1 + len2)/2; - if (len1 < 0.32) - out->mipadjust = 4; - else if (len1 < 0.49) - out->mipadjust = 3; - else if (len1 < 0.99) - out->mipadjust = 2; + tex = bsp->texinfo; + for( i = 0; i < bsp->numtexinfo; i++, tex++ ) { + len1 = VectorLength( tex->axis[0] ); + len2 = VectorLength( tex->axis[1] ); + len1 = ( len1 + len2 ) / 2; + if( len1 < 0.32 ) + tex->mipadjust = 4; + else if( len1 < 0.49 ) + tex->mipadjust = 3; + else if( len1 < 0.99 ) + tex->mipadjust = 2; else - out->mipadjust = 1; -#if 0 - if (len1 + len2 < 0.001) - out->mipadjust = 1; // don't crash - else - out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 ); -#endif - - out->flags = LittleLong (in->flags); + tex->mipadjust = 1; - next = LittleLong (in->nexttexinfo); - if (next > 0) - out->next = loadmodel->texinfo + next; - - Q_concat( name, sizeof( name ), "textures/", in->texture, ".wal", NULL ); - out->image = R_FindImage (name, it_wall); - if (!out->image) - { - out->image = r_notexture_mip; // texture not found - out->flags = 0; + Q_concat( name, sizeof( name ), "textures/", tex->name, ".wal", NULL ); + tex->image = IMG_Find( name, it_wall ); + if( !tex->image ) { + tex->image = r_notexture; // texture not found + //tex->flags = 0; } } - - // count animation frames - for (i=0 ; i<count ; i++) - { - out = &loadmodel->texinfo[i]; - out->numframes = 1; - for (step = out->next ; step && step != out ; step=step->next) - out->numframes++; - } } /* @@ -534,406 +67,74 @@ CalcSurfaceExtents Fills in s->texturemins[] and s->extents[] ================ */ -void CalcSurfaceExtents (msurface_t *s) -{ - float mins[2], maxs[2], val; - int i,j, e; +static void CalcSurfaceExtents( mface_t *s ) { + vec_t mins[2], maxs[2], val; + int i, j; + msurfedge_t *e; mvertex_t *v; mtexinfo_t *tex; int bmins[2], bmaxs[2]; mins[0] = mins[1] = 999999; - maxs[0] = maxs[1] = -99999; + maxs[0] = maxs[1] = -999999; tex = s->texinfo; - - for (i=0 ; i<s->numedges ; i++) - { - e = loadmodel->surfedges[s->firstedge+i]; - if (e >= 0) - v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; - else - v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; - - for (j=0 ; j<2 ; j++) - { - val = v->position[0] * tex->vecs[j][0] + - v->position[1] * tex->vecs[j][1] + - v->position[2] * tex->vecs[j][2] + - tex->vecs[j][3]; - if (val < mins[j]) + e = s->firstsurfedge; + for( i = 0; i < s->numsurfedges; i++, e++ ) { + v = e->edge->v[e->vert]; + for( j = 0; j < 2; j++ ) { + val = DotProduct( v->point, tex->axis[j] ) + tex->offset[j]; + if( val < mins[j] ) mins[j] = val; - if (val > maxs[j]) + if( val > maxs[j] ) maxs[j] = val; } } - for (i=0 ; i<2 ; i++) - { - bmins[i] = floor(mins[i]/16); - bmaxs[i] = ceil(maxs[i]/16); + for( i = 0; i < 2; i++ ) { + bmins[i] = floor( mins[i] / 16 ); + bmaxs[i] = ceil( maxs[i] / 16 ); - s->texturemins[i] = bmins[i] * 16; - s->extents[i] = (bmaxs[i] - bmins[i]) * 16; - if (s->extents[i] < 16) + s->texturemins[i] = bmins[i] << 4; + s->extents[i] = ( bmaxs[i] - bmins[i] ) << 4; + if( s->extents[i] < 16 ) { s->extents[i] = 16; // take at least one cache block - if ( !(tex->flags & (SURF_WARP|SURF_SKY)) && s->extents[i] > 256) - Com_Error (ERR_DROP,"Bad surface extents"); + } else if( s->extents[i] > 256 ) { + Com_Error( ERR_DROP, "Bad surface extents" ); + } } } /* ================= -Mod_LoadFaces +ProcessFaces ================= */ -void Mod_LoadFaces (lump_t *l) -{ - dface_t *in; - msurface_t *out; - int i, count, surfnum; - int planenum, side; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = sys.HunkAlloc (&loadmodel->pool, (count+6)*sizeof(*out)); // extra for skybox - - loadmodel->surfaces = out; - loadmodel->numsurfaces = count; - - for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++) - { - out->firstedge = LittleLong(in->firstedge); - out->numedges = LittleShort(in->numedges); - if (out->numedges < 3) - Com_Error (ERR_DROP,"Surface with %d edges", out->numedges); - out->flags = 0; - - planenum = LittleShort(in->planenum); - side = LittleShort(in->side); - if (side) - out->flags |= SURF_PLANEBACK; - - out->plane = loadmodel->planes + planenum; - - out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); - - CalcSurfaceExtents (out); - - // lighting info is converted from 24 bit on disk to 8 bit +static void ProcessFaces( bsp_t *bsp ) { + mface_t *s; + int i, j; - for (i=0 ; i<MAXLIGHTMAPS ; i++) - out->styles[i] = in->styles[i]; - i = LittleLong(in->lightofs); - if (i == -1) - out->samples = NULL; - else - out->samples = loadmodel->lightdata + i/3; - - // set the drawing flags flag - - if (!out->texinfo->image) - continue; - if (out->texinfo->flags & SURF_SKY) - { - out->flags |= SURF_DRAWSKY; + s = bsp->faces; + for( i = 0; i < bsp->numfaces; i++, s++ ) { + // set the drawing flags + if( s->texinfo->c.flags & SURF_SKY ) { continue; } - - if (out->texinfo->flags & SURF_WARP) - { - out->flags |= SURF_DRAWTURB; - for (i=0 ; i<2 ; i++) - { - out->extents[i] = 16384; - out->texturemins[i] = -8192; + if( s->texinfo->c.flags & (SURF_WARP|SURF_FLOWING) ) { + s->drawflags |= DSURF_TURB; + for( j = 0; j < 2; j++ ) { + s->extents[j] = 16384; + s->texturemins[j] = -8192; } continue; } -//============== -//PGM - // this marks flowing surfaces as turbulent, but with the new - // SURF_FLOW flag. - if (out->texinfo->flags & SURF_FLOWING) - { - out->flags |= SURF_DRAWTURB | SURF_FLOW; - for (i=0 ; i<2 ; i++) - { - out->extents[i] = 16384; - out->texturemins[i] = -8192; - } - continue; - } -//PGM -//============== - } -} - - -/* -================= -Mod_SetParent -================= -*/ -void Mod_SetParent (mnode_t *node, mnode_t *parent) -{ - node->parent = parent; - if (node->contents != -1) - return; - Mod_SetParent (node->children[0], node); - Mod_SetParent (node->children[1], node); -} - -/* -================= -Mod_LoadNodes -================= -*/ -void Mod_LoadNodes (lump_t *l) -{ - int i, j, count, p; - dnode_t *in; - mnode_t *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = sys.HunkAlloc (&loadmodel->pool, count*sizeof(*out)); - - loadmodel->nodes = out; - loadmodel->numnodes = count; - - for ( i=0 ; i<count ; i++, in++, out++) - { - for (j=0 ; j<3 ; j++) - { - out->minmaxs[j] = ( signed short )LittleShort (in->mins[j]); - out->minmaxs[3+j] = ( signed short )LittleShort (in->maxs[j]); - } - - p = LittleLong(in->planenum); - out->plane = loadmodel->planes + p; - - out->firstsurface = LittleShort (in->firstface); - out->numsurfaces = LittleShort (in->numfaces); - out->contents = CONTENTS_NODE; // differentiate from leafs - - for (j=0 ; j<2 ; j++) - { - p = LittleLong (in->children[j]); - if (p >= 0) - out->children[j] = loadmodel->nodes + p; - else - out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); - } - } - - Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs -} - -/* -================= -Mod_LoadLeafs -================= -*/ -void Mod_LoadLeafs (lump_t *l) -{ - dleaf_t *in; - mleaf_t *out; - int i, j, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = sys.HunkAlloc (&loadmodel->pool, count*sizeof(*out)); - - loadmodel->leafs = out; - loadmodel->numleafs = count; - - for ( i=0 ; i<count ; i++, in++, out++) - { - for (j=0 ; j<3 ; j++) - { - out->minmaxs[j] = ( signed short )LittleShort (in->mins[j]); - out->minmaxs[3+j] = ( signed short )LittleShort (in->maxs[j]); - } - - out->contents = LittleLong(in->contents); - out->cluster = LittleShort(in->cluster); - out->area = LittleShort(in->area); - - out->firstmarksurface = loadmodel->marksurfaces + - LittleShort(in->firstleafface); - out->nummarksurfaces = LittleShort(in->numleaffaces); - } -} - - -/* -================= -Mod_LoadMarksurfaces -================= -*/ -void Mod_LoadMarksurfaces (lump_t *l) -{ - int i, j, count; - short *in; - msurface_t **out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = sys.HunkAlloc (&loadmodel->pool, count*sizeof(*out)); - - loadmodel->marksurfaces = out; - loadmodel->nummarksurfaces = count; - - for ( i=0 ; i<count ; i++) - { - j = LittleShort(in[i]); - if (j >= loadmodel->numsurfaces) - Com_Error (ERR_DROP,"Mod_ParseMarksurfaces: bad surface number"); - out[i] = loadmodel->surfaces + j; + CalcSurfaceExtents( s ); } } -/* -================= -Mod_LoadSurfedges -================= -*/ -void Mod_LoadSurfedges (lump_t *l) -{ - int i, count; - int *in, *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = sys.HunkAlloc (&loadmodel->pool, (count+24)*sizeof(*out)); // extra for skybox - loadmodel->surfedges = out; - loadmodel->numsurfedges = count; - for ( i=0 ; i<count ; i++) - out[i] = LittleLong (in[i]); -} - -/* -================= -Mod_LoadPlanes -================= -*/ -void Mod_LoadPlanes (lump_t *l) -{ - int i, j; - mplane_t *out; - dplane_t *in; - int count; - int bits; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = sys.HunkAlloc (&loadmodel->pool, (count+6)*sizeof(*out)); // extra for skybox - - loadmodel->planes = out; - loadmodel->numplanes = count; - - for ( i=0 ; i<count ; i++, in++, out++) - { - bits = 0; - for (j=0 ; j<3 ; j++) - { - out->normal[j] = LittleFloat (in->normal[j]); - if (out->normal[j] < 0) - bits |= 1<<j; - } - - out->dist = LittleFloat (in->dist); - out->type = LittleLong (in->type); - out->signbits = bits; - } -} - - -/* -================= -Mod_LoadBrushModel -================= -*/ -void Mod_LoadBrushModel (model_t *mod, void *buffer) -{ - int i; - dheader_t *header; - dmodel_t *bm; - - loadmodel->type = mod_brush; - if (loadmodel != mod_known) - Com_Error (ERR_DROP, "Loaded a brush model after the world"); - - header = (dheader_t *)buffer; - - i = LittleLong (header->version); - if (i != BSPVERSION) - Com_Error (ERR_DROP,"Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); - -// swap all the lumps - mod_base = (byte *)header; - - for (i=0 ; i<sizeof(dheader_t)/4 ; i++) - ((int *)header)[i] = LittleLong ( ((int *)header)[i]); - -// load into heap - - Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); - Mod_LoadEdges (&header->lumps[LUMP_EDGES]); - Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); - Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); - Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); - Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); - Mod_LoadFaces (&header->lumps[LUMP_FACES]); - Mod_LoadMarksurfaces (&header->lumps[LUMP_LEAFFACES]); - Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); - Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); - Mod_LoadNodes (&header->lumps[LUMP_NODES]); - Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); - -// -// set up the submodels -// - for (i=0 ; i<mod->numsubmodels ; i++) - { - model_t *starmod; - - bm = &mod->submodels[i]; - starmod = &mod_inline[i]; - - *starmod = *loadmodel; - - starmod->firstmodelsurface = bm->firstface; - starmod->nummodelsurfaces = bm->numfaces; - starmod->firstnode = bm->headnode; - if (starmod->firstnode >= loadmodel->numnodes) - Com_Error (ERR_DROP, "Inline model %i has bad firstnode", i); - - VectorCopy (bm->maxs, starmod->maxs); - VectorCopy (bm->mins, starmod->mins); - - if (i == 0) - *loadmodel = *starmod; - } - - R_InitSkyBox (); -} /* ============================================================================== @@ -948,166 +149,129 @@ ALIAS MODELS Mod_LoadAliasModel ================= */ -void Mod_LoadAliasModel (model_t *mod, void *buffer) -{ - int i, j; - dmdl_t *pinmodel, *pheader; - dstvert_t *pinst, *poutst; - dtriangle_t *pintri, *pouttri; - daliasframe_t *pinframe, *poutframe; - int *pincmd, *poutcmd; - int version; - - pinmodel = (dmdl_t *)buffer; - - version = LittleLong (pinmodel->version); - if (version != ALIAS_VERSION) - Com_Error (ERR_DROP, "%s has wrong version number (%i should be %i)", - mod->name, version, ALIAS_VERSION); - - pheader = sys.HunkAlloc (&mod->pool, LittleLong(pinmodel->ofs_end)); - - // byte swap the header fields and sanity check - for (i=0 ; i<sizeof(dmdl_t)/4 ; i++) - ((int *)pheader)[i] = LittleLong (((int *)buffer)[i]); - - if (pheader->skinheight > MAX_LBM_HEIGHT) - Com_Error (ERR_DROP, "model %s has a skin taller than %d", mod->name, - MAX_LBM_HEIGHT); - - if (pheader->num_xyz <= 0) - Com_Error (ERR_DROP, "model %s has no vertices", mod->name); - - if (pheader->num_xyz > MAX_VERTS) - Com_Error (ERR_DROP, "model %s has too many vertices", mod->name); - - if (pheader->num_st <= 0) - Com_Error (ERR_DROP, "model %s has no st vertices", mod->name); - - if (pheader->num_tris <= 0) - Com_Error (ERR_DROP, "model %s has no triangles", mod->name); - - if (pheader->num_frames <= 0) - Com_Error (ERR_DROP, "model %s has no frames", mod->name); - -// -// load base s and t vertices (not used in gl version) -// - pinst = (dstvert_t *) ((byte *)pinmodel + pheader->ofs_st); - poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st); - - for (i=0 ; i<pheader->num_st ; i++) - { - poutst[i].s = ( signed short )LittleShort (pinst[i].s); - poutst[i].t = ( signed short )LittleShort (pinst[i].t); - } - -// -// load triangle lists -// - pintri = (dtriangle_t *) ((byte *)pinmodel + pheader->ofs_tris); - pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris); - - for (i=0 ; i<pheader->num_tris ; i++) - { - for (j=0 ; j<3 ; j++) - { - pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]); - pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]); - } - } - -// -// load the frames -// - for (i=0 ; i<pheader->num_frames ; i++) - { - pinframe = (daliasframe_t *) ((byte *)pinmodel - + pheader->ofs_frames + i * pheader->framesize); - poutframe = (daliasframe_t *) ((byte *)pheader - + pheader->ofs_frames + i * pheader->framesize); - - memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name)); - for (j=0 ; j<3 ; j++) - { - poutframe->scale[j] = LittleFloat (pinframe->scale[j]); - poutframe->translate[j] = LittleFloat (pinframe->translate[j]); +qboolean MOD_LoadMD2( model_t *model, const void *rawdata, size_t length ) { + dmd2header_t header; + dmd2frame_t *src_frame; + //dmd2trivertx_t *src_vert; + dmd2triangle_t *src_tri; + dmd2stvert_t *src_st; + maliasframe_t *dst_frame; + //maliasvert_t *dst_vert; + maliastri_t *dst_tri; + maliasst_t *dst_st; + char skinname[MAX_QPATH]; + char *src_skin; + image_t *skin; + int i, j; + + if( length < sizeof( header ) ) { + Com_WPrintf( "%s is too short\n", model->name ); + return qfalse; + } + + /* byte swap the header */ + header = *( dmd2header_t * )rawdata; + for( i = 0; i < sizeof( header )/4; i++ ) { + (( uint32_t * )&header)[i] = LittleLong( (( uint32_t * )&header)[i] ); + } + + if( !MOD_ValidateMD2( model, &header, length ) ) { + return qfalse; + } + + Hunk_Begin( &model->pool, 0x400000 ); + + // load triangle indices + model->tris = Model_Malloc( header.num_tris * sizeof( maliastri_t ) ); + model->numtris = header.num_tris; + + src_tri = ( dmd2triangle_t * )( ( byte * )rawdata + header.ofs_tris ); + dst_tri = model->tris; + for( i = 0; i < header.num_tris; i++, src_tri++, dst_tri++ ) { + for( j = 0; j < 3; j++ ) { + unsigned idx_xyz = LittleShort( src_tri->index_xyz[j] ); + unsigned idx_st = LittleShort( src_tri->index_st[j] ); + + if( idx_xyz >= header.num_xyz || idx_st >= header.num_st ) { + Com_WPrintf( "%s has bad triangle indices\n", model->name ); + goto fail; + } + + dst_tri->index_xyz[j] = idx_xyz; + dst_tri->index_st[j] = idx_st; + } + } + + // load base s and t vertices + model->sts = Model_Malloc( header.num_st * sizeof( maliasst_t ) ); + model->numsts = header.num_st; + + src_st = ( dmd2stvert_t * )( ( byte * )rawdata + header.ofs_st ); + dst_st = model->sts; + for( i = 0; i < header.num_st; i++, src_st++, dst_st++ ) { + dst_st->s = ( signed short )LittleShort( src_st->s ); + dst_st->t = ( signed short )LittleShort( src_st->t ); + } + + // load the frames + model->frames = Model_Malloc( header.num_frames * sizeof( maliasframe_t ) ); + model->numframes = header.num_frames; + model->numverts = header.num_xyz; + + src_frame = ( dmd2frame_t * )( ( byte * )rawdata + header.ofs_frames ); + dst_frame = model->frames; + for( i = 0; i < header.num_frames; i++, dst_frame++ ) { + for( j = 0; j < 3; j++ ) { + dst_frame->scale[j] = LittleFloat( src_frame->scale[j] ); + dst_frame->translate[j] = LittleFloat( src_frame->translate[j] ); } // verts are all 8 bit, so no swapping needed - memcpy (poutframe->verts, pinframe->verts, - pheader->num_xyz*sizeof(dtrivertx_t)); + dst_frame->verts = Model_Malloc( header.num_xyz * sizeof( maliasvert_t ) ); + + // TODO: check normal indices + memcpy( dst_frame->verts, src_frame->verts, header.num_xyz * sizeof( maliasvert_t ) ); + src_frame = ( dmd2frame_t * )( ( byte * )src_frame + header.framesize ); } - mod->type = mod_alias; - - // - // load the glcmds - // - pincmd = (int *) ((byte *)pinmodel + pheader->ofs_glcmds); - poutcmd = (int *) ((byte *)pheader + pheader->ofs_glcmds); - for (i=0 ; i<pheader->num_glcmds ; i++) - poutcmd[i] = LittleLong (pincmd[i]); - - // register all skins - memcpy ((char *)pheader + pheader->ofs_skins, (char *)pinmodel + pheader->ofs_skins, - pheader->num_skins*MAX_SKINNAME); - for (i=0 ; i<pheader->num_skins ; i++) - { - mod->skins[i] = R_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin); + src_skin = ( char * )rawdata + header.ofs_skins; + for( i = 0; i < header.num_skins; i++ ) { + Q_strncpyz( skinname, src_skin, sizeof( skinname ) ); + skin = IMG_Find( skinname, it_skin ); + if( !skin ) { + skin = r_notexture; + } + model->skins[i] = skin; + src_skin += MD2_MAX_SKINNAME; } -} - -/* -============================================================================== + model->numskins = header.num_skins; -SPRITE MODELS + Hunk_End( &model->pool ); + return qtrue; -============================================================================== -*/ - -/* -================= -Mod_LoadSpriteModel -================= -*/ -void Mod_LoadSpriteModel (model_t *mod, void *buffer) -{ - dsprite_t *sprin, *sprout; - int i; - - sprin = (dsprite_t *)buffer; - sprout = sys.HunkAlloc(&mod->pool, modfilelen); - - sprout->ident = LittleLong (sprin->ident); - sprout->version = LittleLong (sprin->version); - sprout->numframes = LittleLong (sprin->numframes); - - if (sprout->version != SPRITE_VERSION) - Com_Error (ERR_DROP, "%s has wrong version number (%i should be %i)", - mod->name, sprout->version, SPRITE_VERSION); +fail: + Hunk_Free( &model->pool ); + return qfalse; +} - if (sprout->numframes > MAX_MD2SKINS) - Com_Error (ERR_DROP, "%s has too many frames (%i > %i)", - mod->name, sprout->numframes, MAX_MD2SKINS); +void MOD_Reference( model_t *model ) { + int i; - // byte swap everything - for (i=0 ; i<sprout->numframes ; i++) - { - sprout->frames[i].width = LittleLong (sprin->frames[i].width); - sprout->frames[i].height = LittleLong (sprin->frames[i].height); - sprout->frames[i].origin_x = LittleLong (sprin->frames[i].origin_x); - sprout->frames[i].origin_y = LittleLong (sprin->frames[i].origin_y); - memcpy (sprout->frames[i].name, sprin->frames[i].name, MAX_SKINNAME); - mod->skins[i] = R_FindImage (sprout->frames[i].name, it_sprite); - } + model->registration_sequence = registration_sequence; - mod->type = mod_sprite; + // register any images used by the models + if( model->frames ) { + for( i = 0; i < model->numskins; i++ ) { + model->skins[i]->registration_sequence = registration_sequence; + } + } else if( model->spriteframes ) { + for( i = 0; i < model->numframes; i++ ) { + model->spriteframes[i].image->registration_sequence = registration_sequence; + } + } } -//============================================================================= - /* @@@@@@@@@@@@@@@@@@@@@ R_BeginRegistration @@ -1117,121 +281,43 @@ Specifies the model that will be used as the world */ void R_BeginRegistration( const char *model ) { char fullname[MAX_QPATH]; - cvar_t *flushmap; + bsp_t *bsp; registration_sequence++; r_oldviewcluster = -1; // force markleafs Q_concat( fullname, sizeof( fullname ), "maps/", model, ".bsp", NULL ); D_FlushCaches (); - // explicitly free the old map if different - // this guarantees that mod_known[0] is the world map - flushmap = cvar.Get ("flushmap", "0", 0); - if ( mod_known[0].name[0] && ( strcmp(mod_known[0].name, fullname) || flushmap->integer )) - Mod_Free (&mod_known[0]); - r_worldmodel = R_ModelForHandle ( R_RegisterModel( fullname ) ); + bsp = BSP_Load( fullname ); + if( bsp == r_worldmodel ) { + mtexinfo_t *tex = bsp->texinfo; + int i; + + for( i = 0; i < bsp->numtexinfo; i++, tex++ ) { + tex->image->registration_sequence = registration_sequence; + } + bsp->refcount--; + return; + } + BSP_Free( r_worldmodel ); + r_worldmodel = bsp; + + ProcessTexinfo( bsp ); + ProcessFaces( bsp ); + + // TODO R_NewMap (); } - -/* -@@@@@@@@@@@@@@@@@@@@@ -R_RegisterModel - -@@@@@@@@@@@@@@@@@@@@@ -*/ -qhandle_t R_RegisterModel( const char *name ) { - model_t *mod; - qhandle_t hModel; - int i; - dsprite_t *sprout; - dmdl_t *pheader; - - hModel = Mod_ForName (name, qfalse); - if( ( mod = R_ModelForHandle( hModel ) ) != NULL ) - { - mod->registration_sequence = registration_sequence; - - // register any images used by the models - if (mod->type == mod_sprite) - { - sprout = (dsprite_t *)mod->pool.base; - for (i=0 ; i<sprout->numframes ; i++) - mod->skins[i] = R_FindImage (sprout->frames[i].name, it_sprite); - } - else if (mod->type == mod_alias) - { - pheader = (dmdl_t *)mod->pool.base; - for (i=0 ; i<pheader->num_skins ; i++) - mod->skins[i] = R_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin); -//PGM - mod->numframes = pheader->num_frames; -//PGM - } - else if (mod->type == mod_brush) - { - for (i=0 ; i<mod->numtexinfo ; i++) - mod->texinfo[i].image->registration_sequence = registration_sequence; - } - } - return hModel; -} - /* @@@@@@@@@@@@@@@@@@@@@ R_EndRegistration @@@@@@@@@@@@@@@@@@@@@ */ -void R_EndRegistration (void) -{ - int i; - model_t *mod; - - for (i=0, mod=mod_known ; i<mod_numknown ; i++, mod++) - { - if (!mod->name[0]) - continue; - if (mod->registration_sequence != registration_sequence) - { // don't need this model - Mod_Free( mod ); - } - else - { // make sure it is paged in - Com_PageInMemory (mod->pool.base, mod->pool.cursize); - } - } - - R_FreeUnusedImages (); +void R_EndRegistration (void) { + MOD_FreeUnused(); + IMG_FreeUnused(); } -//============================================================================= - -/* -================ -Mod_Free -================ -*/ -void Mod_Free (model_t *mod) -{ - sys.HunkFree (&mod->pool); - memset (mod, 0, sizeof(*mod)); -} - -/* -================ -Mod_FreeAll -================ -*/ -void Mod_FreeAll (void) -{ - int i; - model_t *mod; - - for (i=0, mod = mod_known ; i<mod_numknown ; i++, mod++) - { - if (mod->name[0]) - Mod_Free (mod); - } -} diff --git a/source/sw_model.h b/source/sw_model.h deleted file mode 100644 index 2256e36..0000000 --- a/source/sw_model.h +++ /dev/null @@ -1,250 +0,0 @@ -/* -Copyright (C) 1997-2001 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__ - -/* - -d*_t structures are on-disk representations -m*_t structures are in-memory - -*/ - - -/* -============================================================================== - -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 !!! -#if 0 -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; -#else -#define mplane_t cplane_t -#endif - - -// !!! 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 mtexinfo_s -{ - float vecs[2][4]; - float mipadjust; - image_t *image; - int flags; - int numframes; - struct mtexinfo_s *next; // animation chain -} mtexinfo_t; - -typedef struct msurface_s -{ - int visframe; // should be drawn when node is crossed - - int dlightframe; - int dlightbits; - - mplane_t *plane; - int flags; - - int firstedge; // look up in model->surfedges[], negative numbers - int numedges; // are backwards edges - -// surface generation data - struct surfcache_s *cachespots[MIPLEVELS]; - - short texturemins[2]; - short extents[2]; - - mtexinfo_t *texinfo; - -// lighting info - byte styles[MAXLIGHTMAPS]; - byte *samples; // [numstyles*surfsize] - - struct msurface_s *nextalphasurface; -} msurface_t; - - -#define CONTENTS_NODE -1 -typedef struct mnode_s -{ -// common with leaf - int contents; // CONTENTS_NODE, to differentiate from leafs - int visframe; // node needs to be traversed if current - - short minmaxs[6]; // for bounding box culling - - struct mnode_s *parent; - -// node specific - mplane_t *plane; - struct mnode_s *children[2]; - - unsigned short firstsurface; - unsigned short numsurfaces; -} mnode_t; - - - -typedef struct mleaf_s -{ -// common with node - int contents; // wil be something other than CONTENTS_NODE - int visframe; // node needs to be traversed if current - - short minmaxs[6]; // for bounding box culling - - struct mnode_s *parent; - -// leaf specific - int cluster; - int area; - - msurface_t **firstmarksurface; - int nummarksurfaces; - int key; // BSP sequence number for leaf's contents -} mleaf_t; - - -//=================================================================== - -// -// Whole model -// - -typedef enum {mod_bad, mod_brush, mod_sprite, mod_alias } modtype_t; - -typedef struct model_s -{ - char name[MAX_QPATH]; - - int registration_sequence; - - modtype_t type; - int numframes; - - int flags; - -// -// volume occupied by the model graphics -// - vec3_t mins, maxs; - -// -// solid volume for clipping (sent from server) -// - qboolean clipbox; - vec3_t clipmins, clipmaxs; - -// -// brush model -// - int firstmodelsurface, nummodelsurfaces; - - int numsubmodels; - dmodel_t *submodels; - - int numplanes; - mplane_t *planes; - - int numleafs; // number of visible leafs, not counting 0 - mleaf_t *leafs; - - int numvertexes; - mvertex_t *vertexes; - - int numedges; - medge_t *edges; - - int numnodes; - int firstnode; - mnode_t *nodes; - - int numtexinfo; - mtexinfo_t *texinfo; - - int numsurfaces; - msurface_t *surfaces; - - int numsurfedges; - int *surfedges; - - int nummarksurfaces; - msurface_t **marksurfaces; - - dvis_t *vis; - - byte *lightdata; - - // for alias models and sprites - image_t *skins[MAX_MD2SKINS]; - mempool_t pool; -} model_t; - -//============================================================================ -model_t *R_ModelForHandle( qhandle_t hModel ); - -void Mod_Init (void); -void Mod_ClearAll (void); -void *Mod_Extradata (model_t *mod); // handles caching -void Mod_TouchModel (char *name); - -mleaf_t *Mod_PointInLeaf (float *p, model_t *model); -byte *Mod_ClusterPVS (int cluster, model_t *model); - -void Mod_Modellist_f (void); -void Mod_FreeAll (void); -void Mod_Free (model_t *mod); - -extern int registration_sequence; - -#endif // __MODEL__ diff --git a/source/sw_poly.c b/source/sw_poly.c index e3f662b..ab988d4 100644 --- a/source/sw_poly.c +++ b/source/sw_poly.c @@ -41,7 +41,7 @@ static espan_t *s_polygon_spans; polydesc_t r_polydesc; -msurface_t *r_alpha_surfaces; +mface_t *r_alpha_surfaces; extern int *r_turb_turb; @@ -52,109 +52,6 @@ static int s_minindex, s_maxindex; static void R_DrawPoly( int iswater ); -#ifdef TRUECOLOR_RENDERER - -void R_DrawSpanletOpaque( void ) { - byte *btemp; - unsigned ts, tt; - - do { - ts = s_spanletvars.s >> 16; - tt = s_spanletvars.t >> 16; - - btemp = s_spanletvars.pbase + ( ts << VID_SHIFT ) + tt * cachewidth; - - if( *s_spanletvars.pz <= ( s_spanletvars.izi >> 16 ) ) { - byte *alphaTable, *oneMinusAlphaTable; - - alphaTable = r_alphaTable[btemp[3]]; - oneMinusAlphaTable = r_alphaTable[255 - btemp[3]]; - - *s_spanletvars.pz = s_spanletvars.izi >> 16; - s_spanletvars.pdest[0] = oneMinusAlphaTable[s_spanletvars.pdest[0]] + alphaTable[btemp[2]]; - s_spanletvars.pdest[1] = oneMinusAlphaTable[s_spanletvars.pdest[1]] + alphaTable[btemp[1]]; - s_spanletvars.pdest[2] = oneMinusAlphaTable[s_spanletvars.pdest[2]] + alphaTable[btemp[0]]; - } - - s_spanletvars.izi += s_spanletvars.izistep; - s_spanletvars.pdest += VID_BYTES; - s_spanletvars.pz++; - s_spanletvars.s += s_spanletvars.sstep; - s_spanletvars.t += s_spanletvars.tstep; - } while( --s_spanletvars.spancount > 0 ); -} - - - -void R_DrawSpanletBlended( void ) { - byte *btemp; - unsigned ts, tt; - - do { - ts = s_spanletvars.s >> 16; - tt = s_spanletvars.t >> 16; - - btemp = s_spanletvars.pbase + ( ts << VID_SHIFT ) + tt * cachewidth; - - if( *s_spanletvars.pz <= ( s_spanletvars.izi >> 16 ) ) { - s_spanletvars.pdest[0] = s_spanletvars.oneMinusAlphaTable[s_spanletvars.pdest[0]] + s_spanletvars.alphaTable[btemp[2]]; - s_spanletvars.pdest[1] = s_spanletvars.oneMinusAlphaTable[s_spanletvars.pdest[1]] + s_spanletvars.alphaTable[btemp[1]]; - s_spanletvars.pdest[2] = s_spanletvars.oneMinusAlphaTable[s_spanletvars.pdest[2]] + s_spanletvars.alphaTable[btemp[0]]; - } - - s_spanletvars.izi += s_spanletvars.izistep; - s_spanletvars.pdest += VID_BYTES; - s_spanletvars.pz++; - s_spanletvars.s += s_spanletvars.sstep; - s_spanletvars.t += s_spanletvars.tstep; - } while( --s_spanletvars.spancount > 0 ); - -} - - - -void R_DrawSpanletConstant( void ) { - do { - if( *s_spanletvars.pz <= ( s_spanletvars.izi >> 16 ) ) { - s_spanletvars.pdest[0] = s_spanletvars.oneMinusAlphaTable[s_spanletvars.pdest[0]] + r_polyblendcolor[2]; - s_spanletvars.pdest[1] = s_spanletvars.oneMinusAlphaTable[s_spanletvars.pdest[1]] + r_polyblendcolor[1]; - s_spanletvars.pdest[2] = s_spanletvars.oneMinusAlphaTable[s_spanletvars.pdest[2]] + r_polyblendcolor[0]; - } - - s_spanletvars.izi += s_spanletvars.izistep; - s_spanletvars.pdest += VID_BYTES; - s_spanletvars.pz++; - } while( --s_spanletvars.spancount > 0 ); -} - - - -void R_DrawSpanletTurbulentBlended( void ) { - byte *btemp; - int sturb, tturb; - - do { - sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63; - tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63; - - btemp = s_spanletvars.pbase + ( sturb << VID_SHIFT ) + ( tturb << ( 6 + VID_SHIFT ) ); - - if( *s_spanletvars.pz <= ( s_spanletvars.izi >> 16 ) ) { - s_spanletvars.pdest[0] = s_spanletvars.oneMinusAlphaTable[s_spanletvars.pdest[0]] + s_spanletvars.alphaTable[btemp[2]]; - s_spanletvars.pdest[1] = s_spanletvars.oneMinusAlphaTable[s_spanletvars.pdest[1]] + s_spanletvars.alphaTable[btemp[1]]; - s_spanletvars.pdest[2] = s_spanletvars.oneMinusAlphaTable[s_spanletvars.pdest[2]] + s_spanletvars.alphaTable[btemp[0]]; - } - - s_spanletvars.izi += s_spanletvars.izistep; - s_spanletvars.pdest += VID_BYTES; - s_spanletvars.pz++; - s_spanletvars.s += s_spanletvars.sstep; - s_spanletvars.t += s_spanletvars.tstep; - } while( --s_spanletvars.spancount > 0 ); -} - -#else /* TRUECOLOR_RENDERER */ - /* ** R_DrawSpanletOpaque */ @@ -604,8 +501,6 @@ void R_DrawSpanlet66Stipple( void ) } } -#endif /* !TRUECOLOR_RENDERER */ - /* ** R_ClipPolyFace ** @@ -1111,10 +1006,11 @@ void R_ClipAndDrawPoly ( float alpha, int isturbulent, qboolean textured ) /* ** R_BuildPolygonFromSurface */ -void R_BuildPolygonFromSurface(msurface_t *fa) +void R_BuildPolygonFromSurface(mface_t *fa) { - int i, lindex, lnumverts; - medge_t *pedges, *r_pedge; + int i, lnumverts; + medge_t *pedges; + msurfedge_t *surfedge; int vertpage; float *vec; vec5_t *pverts; @@ -1123,42 +1019,31 @@ void R_BuildPolygonFromSurface(msurface_t *fa) r_polydesc.nump = 0; // reconstruct the polygon - pedges = currentmodel->edges; - lnumverts = fa->numedges; + pedges = r_worldmodel->edges; + lnumverts = fa->numsurfedges; vertpage = 0; pverts = r_clip_verts[0]; - for (i=0 ; i<lnumverts ; i++) + surfedge = fa->firstsurfedge; + for (i=0 ; i<lnumverts ; i++, surfedge++) { - lindex = currentmodel->surfedges[fa->firstedge + i]; - - if (lindex > 0) - { - r_pedge = &pedges[lindex]; - vec = currentmodel->vertexes[r_pedge->v[0]].position; - } - else - { - r_pedge = &pedges[-lindex]; - vec = currentmodel->vertexes[r_pedge->v[1]].position; - } - + vec = surfedge->edge->v[surfedge->vert]->point; VectorCopy (vec, pverts[i] ); } - VectorCopy( fa->texinfo->vecs[0], r_polydesc.vright ); - VectorCopy( fa->texinfo->vecs[1], r_polydesc.vup ); + VectorCopy( fa->texinfo->axis[0], r_polydesc.vright ); + VectorCopy( fa->texinfo->axis[1], r_polydesc.vup ); VectorCopy( fa->plane->normal, r_polydesc.vpn ); VectorCopy( r_origin, r_polydesc.viewer_position ); - if ( fa->flags & SURF_PLANEBACK ) + if ( fa->drawflags & DSURF_PLANEBACK ) { - VectorSubtract( vec3_origin, r_polydesc.vpn, r_polydesc.vpn ); + VectorInverse( r_polydesc.vpn ); } // PGM 09/16/98 - if ( fa->texinfo->flags & (SURF_WARP|SURF_FLOWING) ) + if ( fa->texinfo->c.flags & (SURF_WARP|SURF_FLOWING) ) { r_polydesc.pixels = fa->texinfo->image->pixels[0]; r_polydesc.pixel_width = fa->texinfo->image->width; @@ -1181,11 +1066,11 @@ void R_BuildPolygonFromSurface(msurface_t *fa) r_polydesc.dist = DotProduct( r_polydesc.vpn, pverts[0] ); - r_polydesc.s_offset = fa->texinfo->vecs[0][3] - tmins[0]; - r_polydesc.t_offset = fa->texinfo->vecs[1][3] - tmins[1]; + r_polydesc.s_offset = fa->texinfo->offset[0] - tmins[0]; + r_polydesc.t_offset = fa->texinfo->offset[1] - tmins[1]; // scrolling texture addition - if (fa->texinfo->flags & SURF_FLOWING) + if (fa->texinfo->c.flags & SURF_FLOWING) { r_polydesc.s_offset += -128 * ( (r_newrefdef.time*0.25) - (int)(r_newrefdef.time*0.25) ); } @@ -1295,9 +1180,9 @@ static void R_DrawPoly( int iswater ) */ void R_DrawAlphaSurfaces( void ) { - msurface_t *s = r_alpha_surfaces; + mface_t *s = r_alpha_surfaces; - currentmodel = r_worldmodel; + //currentmodel = r_worldmodel; modelorg[0] = -r_origin[0]; modelorg[1] = -r_origin[1]; @@ -1315,14 +1200,14 @@ void R_DrawAlphaSurfaces( void ) // R_ClipAndDrawPoly( 0.30f, ( s->texinfo->flags & SURF_WARP) != 0, qtrue ); // PGM - pass down all the texinfo flags, not just SURF_WARP. - if (s->texinfo->flags & SURF_TRANS66) - R_ClipAndDrawPoly( 0.60f, (s->texinfo->flags & (SURF_WARP|SURF_FLOWING)), qtrue ); + if (s->texinfo->c.flags & SURF_TRANS66) + R_ClipAndDrawPoly( 0.60f, (s->texinfo->c.flags & (SURF_WARP|SURF_FLOWING)), qtrue ); else - R_ClipAndDrawPoly( 0.30f, (s->texinfo->flags & (SURF_WARP|SURF_FLOWING)), qtrue ); + R_ClipAndDrawPoly( 0.30f, (s->texinfo->c.flags & (SURF_WARP|SURF_FLOWING)), qtrue ); //PGM //======= - s = s->nextalphasurface; + s = s->next; } r_alpha_surfaces = NULL; diff --git a/source/sw_polyse.c b/source/sw_polyse.c index 560004c..03ca7da 100644 --- a/source/sw_polyse.c +++ b/source/sw_polyse.c @@ -287,7 +287,7 @@ void R_PolysetScanLeftEdge_C(int height) d_aspancount += d_countextrastep; d_ptex += d_ptexextrastep; d_sfrac += d_sfracextrastep; - d_ptex += ( d_sfrac >> 16 ) << VID_SHIFT; + d_ptex += d_sfrac >> 16; d_sfrac &= 0xFFFF; d_tfrac += d_tfracextrastep; @@ -307,7 +307,7 @@ void R_PolysetScanLeftEdge_C(int height) d_aspancount += ubasestep; d_ptex += d_ptexbasestep; d_sfrac += d_sfracbasestep; - d_ptex += ( d_sfrac >> 16 ) << VID_SHIFT; + d_ptex += d_sfrac >> 16; d_sfrac &= 0xFFFF; d_tfrac += d_tfracbasestep; if (d_tfrac & 0x10000) @@ -466,122 +466,9 @@ void R_PolysetCalcGradients (int skinwidth) a_tstepxfrac = r_tstepx & 0xFFFF; } - a_ststepxwhole = skinwidth * (r_tstepx >> 16) + VID_BYTES * (r_sstepx >> 16); + a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16); } -#ifdef TRUECOLOR_RENDERER - -void R_PolysetDrawSpansTranslucent( spanpackage_t *pspanpackage ) { - int lcount; - byte *lpdest; - byte *lptex; - int lsfrac, ltfrac; - int llight; - int lzi; - short *lpz; - - do { - lcount = d_aspancount - pspanpackage->count; - - errorterm += erroradjustup; - if (errorterm >= 0) { - d_aspancount += d_countextrastep; - errorterm -= erroradjustdown; - } else { - d_aspancount += ubasestep; - } - - if (lcount) { - lpdest = pspanpackage->pdest; - lptex = pspanpackage->ptex; - lpz = pspanpackage->pz; - lsfrac = pspanpackage->sfrac; - ltfrac = pspanpackage->tfrac; - llight = pspanpackage->light; - lzi = pspanpackage->zi; - - do { - if ((lzi >> 16) >= *lpz) { - lpdest[0] = r_aliasOneMinusAlphaTable[lpdest[0]] + r_aliasAlphaTable[lptex[0]]; - lpdest[1] = r_aliasOneMinusAlphaTable[lpdest[1]] + r_aliasAlphaTable[lptex[1]]; - lpdest[2] = r_aliasOneMinusAlphaTable[lpdest[2]] + r_aliasAlphaTable[lptex[2]]; - } - lpdest += VID_BYTES; - lzi += r_zistepx; - lpz++; - llight += r_lstepx; - lptex += a_ststepxwhole; - lsfrac += a_sstepxfrac; - lptex += ( lsfrac >> 16 ) << VID_SHIFT; - lsfrac &= 0xFFFF; - ltfrac += a_tstepxfrac; - if (ltfrac & 0x10000) { - lptex += r_affinetridesc.skinwidth; - ltfrac &= 0xFFFF; - } - } while (--lcount); - } - - pspanpackage++; - } while (pspanpackage->count != -999999); -} - -void R_PolysetDrawSpansOpaque( spanpackage_t *pspanpackage ) { - int lcount; - byte *lpdest; - byte *lptex; - int lsfrac, ltfrac; - int llight; - int lzi; - short *lpz; - - do { - lcount = d_aspancount - pspanpackage->count; - - errorterm += erroradjustup; - if (errorterm >= 0) { - d_aspancount += d_countextrastep; - errorterm -= erroradjustdown; - } else { - d_aspancount += ubasestep; - } - - if (lcount) { - lpdest = pspanpackage->pdest; - lptex = pspanpackage->ptex; - lpz = pspanpackage->pz; - lsfrac = pspanpackage->sfrac; - ltfrac = pspanpackage->tfrac; - llight = pspanpackage->light; - lzi = pspanpackage->zi; - - do { - if ((lzi >> 16) >= *lpz) { - *lpz = lzi >> 16; - *( uint32_t * )lpdest = *( uint32_t * )lptex; - } - lpdest += VID_BYTES; - lzi += r_zistepx; - lpz++; - llight += r_lstepx; - lptex += a_ststepxwhole; - lsfrac += a_sstepxfrac; - lptex += ( lsfrac >> 16 ) << VID_SHIFT; - lsfrac &= 0xFFFF; - ltfrac += a_tstepxfrac; - if (ltfrac & 0x10000) { - lptex += r_affinetridesc.skinwidth; - ltfrac &= 0xFFFF; - } - } while (--lcount); - } - - pspanpackage++; - } while (pspanpackage->count != -999999); -} - -#else /* TRUECOLOR_RENDERER */ - /* ================ R_PolysetDrawThreshSpans8 @@ -923,13 +810,13 @@ void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage) if ((lzi >> 16) >= *lpz) { //PGM - if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE) + if(iractive) *lpdest = ((byte *)vid.colormap)[irtable[*lptex]]; else - *lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)]; + *lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)]; //PGM *lpz = lzi >> 16; - } + } lpdest++; lzi += r_zistepx; lpz++; @@ -990,8 +877,6 @@ void R_PolysetFillSpans8 (spanpackage_t *pspanpackage) } } -#endif /* !TRUECOLOR_RENDERER */ - /* ================ R_RasterizeAliasPolySmooth @@ -1029,7 +914,7 @@ void R_RasterizeAliasPolySmooth (void) ystart = plefttop[1]; d_aspancount = plefttop[0] - prighttop[0]; - d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) * VID_BYTES + + d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + (plefttop[3] >> 16) * r_affinetridesc.skinwidth; #if USE_ASM if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) @@ -1047,7 +932,7 @@ void R_RasterizeAliasPolySmooth (void) d_zi = plefttop[5]; d_pdest = (byte *)d_viewbuffer + - ystart * r_screenwidth + plefttop[0] * VID_BYTES; + ystart * r_screenwidth + plefttop[0]; d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; if (initialleftheight == 1) @@ -1084,8 +969,8 @@ void R_RasterizeAliasPolySmooth (void) d_pzextrastep = d_pzbasestep + 1; } - d_pdestbasestep = r_screenwidth + ( ubasestep << VID_SHIFT ); - d_pdestextrastep = d_pdestbasestep + VID_BYTES; + d_pdestbasestep = r_screenwidth + ubasestep; + d_pdestextrastep = d_pdestbasestep + 1; // TODO: can reuse partial expressions here @@ -1098,7 +983,7 @@ void R_RasterizeAliasPolySmooth (void) working_lstepx = r_lstepx; d_countextrastep = ubasestep + 1; - d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) * VID_BYTES + + d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + ((r_tstepy + r_tstepx * ubasestep) >> 16) * r_affinetridesc.skinwidth; #if USE_ASM @@ -1116,7 +1001,7 @@ void R_RasterizeAliasPolySmooth (void) d_lightbasestep = r_lstepy + working_lstepx * ubasestep; d_zibasestep = r_zistepy + r_zistepx * ubasestep; - d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) * VID_BYTES + + d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * r_affinetridesc.skinwidth; #if USE_ASM @@ -1162,14 +1047,14 @@ void R_RasterizeAliasPolySmooth (void) ystart = plefttop[1]; d_aspancount = plefttop[0] - prighttop[0]; - d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) * VID_BYTES + + d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + (plefttop[3] >> 16) * r_affinetridesc.skinwidth; d_sfrac = 0; d_tfrac = 0; d_light = plefttop[4]; d_zi = plefttop[5]; - d_pdest = (byte *)d_viewbuffer + ystart * r_screenwidth + ( plefttop[0] << VID_SHIFT ); + d_pdest = (byte *)d_viewbuffer + ystart * r_screenwidth + plefttop[0]; d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; if (height == 1) @@ -1193,8 +1078,8 @@ void R_RasterizeAliasPolySmooth (void) R_PolysetSetUpForLineScan(plefttop[0], plefttop[1], pleftbottom[0], pleftbottom[1]); - d_pdestbasestep = r_screenwidth + ( ubasestep << VID_SHIFT ); - d_pdestextrastep = d_pdestbasestep + VID_BYTES; + d_pdestbasestep = r_screenwidth + ubasestep; + d_pdestextrastep = d_pdestbasestep + 1; #if USE_ASM if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) @@ -1215,7 +1100,7 @@ void R_RasterizeAliasPolySmooth (void) working_lstepx = r_lstepx; d_countextrastep = ubasestep + 1; - d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) * VID_BYTES + + d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + ((r_tstepy + r_tstepx * ubasestep) >> 16) * r_affinetridesc.skinwidth; #if USE_ASM @@ -1233,7 +1118,7 @@ void R_RasterizeAliasPolySmooth (void) d_lightbasestep = r_lstepy + working_lstepx * ubasestep; d_zibasestep = r_zistepy + r_zistepx * ubasestep; - d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) * VID_BYTES + + d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * r_affinetridesc.skinwidth; #if USE_ASM diff --git a/source/sw_rast.c b/source/sw_rast.c index f40ca5c..4f84d42 100644 --- a/source/sw_rast.c +++ b/source/sw_rast.c @@ -21,8 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sw_local.h" -#define MAXLEFTCLIPEDGES 100 - // !!! if these are changed, they must be changed in asm_draw.h too !!! #define FULLY_CLIPPED_CACHED 0x80000000 #define FRAMECOUNT_MASK 0x7FFFFFFF @@ -39,172 +37,17 @@ clipplane_t world_clipplanes[16]; medge_t *r_pedge; qboolean r_leftclipped, r_rightclipped; -static qboolean makeleftedge, makerightedge; qboolean r_nearzionly; -int sintable[CYCLE*2]; -int intsintable[CYCLE*2]; -int blanktable[CYCLE*2]; // PGM - mvertex_t r_leftenter, r_leftexit; mvertex_t r_rightenter, r_rightexit; -typedef struct -{ - float u,v; - int ceilv; -} evert_t; - int r_emitted; float r_nearzi; float r_u1, r_v1, r_lzi1; int r_ceilv1; qboolean r_lastvertvalid; -int r_skyframe; - -msurface_t *r_skyfaces; -mplane_t r_skyplanes[6]; -mtexinfo_t r_skytexinfo[6]; -mvertex_t *r_skyverts; -medge_t *r_skyedges; -int *r_skysurfedges; - -// I just copied this data from a box map... -int skybox_planes[12] = {2,-128, 0,-128, 2,128, 1,128, 0,128, 1,-128}; - -int box_surfedges[24] = { 1,2,3,4, -1,5,6,7, 8,9,-6,10, -2,-7,-9,11, - 12,-3,-11,-8, -12,-10,-5,-4}; -int box_edges[24] = { 1,2, 2,3, 3,4, 4,1, 1,5, 5,6, 6,2, 7,8, 8,6, 5,7, 8,3, 7,4}; - -int box_faces[6] = {0,0,2,2,2,0}; - -vec3_t box_vecs[6][2] = { - { {0,-1,0}, {-1,0,0} }, - { {0,1,0}, {0,0,-1} }, - { {0,-1,0}, {1,0,0} }, - { {1,0,0}, {0,0,-1} }, - { {0,-1,0}, {0,0,-1} }, - { {-1,0,0}, {0,0,-1} } -}; - -float box_verts[8][3] = { - {-1,-1,-1}, - {-1,1,-1}, - {1,1,-1}, - {1,-1,-1}, - {-1,-1,1}, - {-1,1,1}, - {1,-1,1}, - {1,1,1} -}; - -// down, west, up, north, east, south -// {"rt", "bk", "lf", "ft", "up", "dn"}; - -/* -================ -R_InitSkyBox - -================ -*/ -void R_InitSkyBox (void) -{ - int i; - extern model_t *loadmodel; - - r_skyfaces = loadmodel->surfaces + loadmodel->numsurfaces; - loadmodel->numsurfaces += 6; - r_skyverts = loadmodel->vertexes + loadmodel->numvertexes; - loadmodel->numvertexes += 8; - r_skyedges = loadmodel->edges + loadmodel->numedges; - loadmodel->numedges += 12; - r_skysurfedges = loadmodel->surfedges + loadmodel->numsurfedges; - loadmodel->numsurfedges += 24; - if (loadmodel->numsurfaces > MAX_MAP_FACES - || loadmodel->numvertexes > MAX_MAP_VERTS - || loadmodel->numedges > MAX_MAP_EDGES) - Com_Error (ERR_DROP, "InitSkyBox: map overflow"); - - memset (r_skyfaces, 0, 6*sizeof(*r_skyfaces)); - for (i=0 ; i<6 ; i++) - { - r_skyplanes[i].normal[skybox_planes[i*2]] = 1; - r_skyplanes[i].dist = skybox_planes[i*2+1]; - - VectorCopy (box_vecs[i][0], r_skytexinfo[i].vecs[0]); - VectorCopy (box_vecs[i][1], r_skytexinfo[i].vecs[1]); - - r_skyfaces[i].plane = &r_skyplanes[i]; - r_skyfaces[i].numedges = 4; - r_skyfaces[i].flags = box_faces[i] | SURF_DRAWSKYBOX; - r_skyfaces[i].firstedge = loadmodel->numsurfedges-24+i*4; - r_skyfaces[i].texinfo = &r_skytexinfo[i]; - r_skyfaces[i].texturemins[0] = -128; - r_skyfaces[i].texturemins[1] = -128; - r_skyfaces[i].extents[0] = 256; - r_skyfaces[i].extents[1] = 256; - } - - for (i=0 ; i<24 ; i++) - if (box_surfedges[i] > 0) - r_skysurfedges[i] = loadmodel->numedges-13 + box_surfedges[i]; - else - r_skysurfedges[i] = - (loadmodel->numedges-13 + -box_surfedges[i]); - - for(i=0 ; i<12 ; i++) - { - r_skyedges[i].v[0] = loadmodel->numvertexes-9+box_edges[i*2+0]; - r_skyedges[i].v[1] = loadmodel->numvertexes-9+box_edges[i*2+1]; - r_skyedges[i].cachededgeoffset = 0; - } -} - -/* -================ -R_EmitSkyBox -================ -*/ -void R_EmitSkyBox (void) -{ - int i, j; - int oldkey; - - if (insubmodel) - return; // submodels should never have skies - if (r_skyframe == r_framecount) - return; // already set this frame - - r_skyframe = r_framecount; - - // set the eight fake vertexes - for (i=0 ; i<8 ; i++) - for (j=0 ; j<3 ; j++) - r_skyverts[i].position[j] = r_origin[j] + box_verts[i][j]*128; - - // set the six fake planes - for (i=0 ; i<6 ; i++) - if (skybox_planes[i*2+1] > 0) - r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]+128; - else - r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]-128; - - // fix texture offseets - for (i=0 ; i<6 ; i++) - { - r_skytexinfo[i].vecs[0][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[0]); - r_skytexinfo[i].vecs[1][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[1]); - } - - // emit the six faces - oldkey = r_currentkey; - r_currentkey = 0x7ffffff0; - for (i=0 ; i<6 ; i++) - { - R_RenderFace (r_skyfaces + i, 15); - } - r_currentkey = oldkey; // bsp sorting order -} #if !USE_ASM @@ -234,7 +77,7 @@ void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1) } else { - world = &pv0->position[0]; + world = &pv0->point[0]; // transform and project VectorSubtract (world, modelorg, local); @@ -263,7 +106,7 @@ void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1) ceilv0 = (int) ceil(v0); } - world = &pv1->position[0]; + world = &pv1->point[0]; // transform and project VectorSubtract (world, modelorg, local); @@ -398,91 +241,87 @@ void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip) float d0, d1, f; mvertex_t clipvert; - if (clip) - { - do - { - d0 = DotProduct (pv0->position, clip->normal) - clip->dist; - d1 = DotProduct (pv1->position, clip->normal) - clip->dist; - - if (d0 >= 0) - { - // point 0 is unclipped - if (d1 >= 0) - { - // both points are unclipped - continue; - } - - // only point 1 is clipped - - // we don't cache clipped edges - cacheoffset = 0x7FFFFFFF; - - f = d0 / (d0 - d1); - clipvert.position[0] = pv0->position[0] + - f * (pv1->position[0] - pv0->position[0]); - clipvert.position[1] = pv0->position[1] + - f * (pv1->position[1] - pv0->position[1]); - clipvert.position[2] = pv0->position[2] + - f * (pv1->position[2] - pv0->position[2]); - - if (clip->leftedge) - { - r_leftclipped = qtrue; - r_leftexit = clipvert; - } - else if (clip->rightedge) - { - r_rightclipped = qtrue; - r_rightexit = clipvert; - } - - R_ClipEdge (pv0, &clipvert, clip->next); - return; - } - else - { - // point 0 is clipped - if (d1 < 0) - { - // both points are clipped - // we do cache fully clipped edges - if (!r_leftclipped) - cacheoffset = FULLY_CLIPPED_CACHED | - (r_framecount & FRAMECOUNT_MASK); - return; - } - - // only point 0 is clipped - r_lastvertvalid = qfalse; - - // we don't cache partially clipped edges - cacheoffset = 0x7FFFFFFF; - - f = d0 / (d0 - d1); - clipvert.position[0] = pv0->position[0] + - f * (pv1->position[0] - pv0->position[0]); - clipvert.position[1] = pv0->position[1] + - f * (pv1->position[1] - pv0->position[1]); - clipvert.position[2] = pv0->position[2] + - f * (pv1->position[2] - pv0->position[2]); - - if (clip->leftedge) - { - r_leftclipped = qtrue; - r_leftenter = clipvert; - } - else if (clip->rightedge) - { - r_rightclipped = qtrue; - r_rightenter = clipvert; - } - - R_ClipEdge (&clipvert, pv1, clip->next); - return; - } - } while ((clip = clip->next) != NULL); + for( ; clip; clip = clip->next ) { + d0 = DotProduct (pv0->point, clip->normal) - clip->dist; + d1 = DotProduct (pv1->point, clip->normal) - clip->dist; + + if (d0 >= 0) + { + // point 0 is unclipped + if (d1 >= 0) + { + // both points are unclipped + continue; + } + + // only point 1 is clipped + + // we don't cache clipped edges + cacheoffset = 0x7FFFFFFF; + + f = d0 / (d0 - d1); + clipvert.point[0] = pv0->point[0] + + f * (pv1->point[0] - pv0->point[0]); + clipvert.point[1] = pv0->point[1] + + f * (pv1->point[1] - pv0->point[1]); + clipvert.point[2] = pv0->point[2] + + f * (pv1->point[2] - pv0->point[2]); + + if (clip->leftedge) + { + r_leftclipped = qtrue; + r_leftexit = clipvert; + } + else if (clip->rightedge) + { + r_rightclipped = qtrue; + r_rightexit = clipvert; + } + + R_ClipEdge (pv0, &clipvert, clip->next); + return; + } + else + { + // point 0 is clipped + if (d1 < 0) + { + // both points are clipped + // we do cache fully clipped edges + if (!r_leftclipped) + cacheoffset = FULLY_CLIPPED_CACHED | + (r_framecount & FRAMECOUNT_MASK); + return; + } + + // only point 0 is clipped + r_lastvertvalid = qfalse; + + // we don't cache partially clipped edges + cacheoffset = 0x7FFFFFFF; + + f = d0 / (d0 - d1); + clipvert.point[0] = pv0->point[0] + + f * (pv1->point[0] - pv0->point[0]); + clipvert.point[1] = pv0->point[1] + + f * (pv1->point[1] - pv0->point[1]); + clipvert.point[2] = pv0->point[2] + + f * (pv1->point[2] - pv0->point[2]); + + if (clip->leftedge) + { + r_leftclipped = qtrue; + r_leftenter = clipvert; + } + else if (clip->rightedge) + { + r_rightclipped = qtrue; + r_rightenter = clipvert; + } + + R_ClipEdge (&clipvert, pv1, clip->next); + return; + } } // add the edge @@ -520,27 +359,29 @@ void R_EmitCachedEdge (void) R_RenderFace ================ */ -void R_RenderFace (msurface_t *fa, int clipflags) +void R_RenderFace (mface_t *fa, int clipflags) { - int i, lindex; + int i; unsigned mask; - mplane_t *pplane; + cplane_t *pplane; float distinv; vec3_t p_normal; - medge_t *pedges, tedge; + medge_t tedge; + msurfedge_t *surfedge; clipplane_t *pclip; + qboolean makeleftedge, makerightedge; // translucent surfaces are not drawn by the edge renderer - if (fa->texinfo->flags & (SURF_TRANS33|SURF_TRANS66)) + if (fa->texinfo->c.flags & (SURF_TRANS33|SURF_TRANS66)) { - fa->nextalphasurface = r_alpha_surfaces; + fa->next = r_alpha_surfaces; r_alpha_surfaces = fa; return; } // sky surfaces encountered in the world will cause the // environment box surfaces to be emited - if ( fa->texinfo->flags & SURF_SKY ) + if ( fa->texinfo->c.flags & SURF_SKY ) { R_EmitSkyBox (); return; @@ -554,9 +395,9 @@ void R_RenderFace (msurface_t *fa, int clipflags) } // ditto if not enough edges left, or switch to auxedges if possible - if ((edge_p + fa->numedges + 4) >= edge_max) + if ((edge_p + fa->numsurfedges + 4) >= edge_max) { - r_outofedges += fa->numedges; + r_outofedges += fa->numsurfedges; return; } @@ -579,103 +420,52 @@ void R_RenderFace (msurface_t *fa, int clipflags) r_nearzi = 0; r_nearzionly = qfalse; makeleftedge = makerightedge = qfalse; - pedges = currentmodel->edges; r_lastvertvalid = qfalse; - for (i=0 ; i<fa->numedges ; i++) + surfedge = fa->firstsurfedge; + for (i=0 ; i<fa->numsurfedges ; i++, surfedge++) { - lindex = currentmodel->surfedges[fa->firstedge + i]; - - if (lindex > 0) - { - r_pedge = &pedges[lindex]; - - // if the edge is cached, we can just reuse the edge - if (!insubmodel) - { - if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) - { - if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == - r_framecount) - { - r_lastvertvalid = qfalse; - continue; - } - } - else - { - if ((((unsigned long)edge_p - (unsigned long)r_edges) > - r_pedge->cachededgeoffset) && - (((edge_t *)((unsigned long)r_edges + - r_pedge->cachededgeoffset))->owner == r_pedge)) - { - R_EmitCachedEdge (); - r_lastvertvalid = qfalse; - continue; - } - } - } - - // assume it's cacheable - cacheoffset = (byte *)edge_p - (byte *)r_edges; - r_leftclipped = r_rightclipped = qfalse; - R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]], - &r_pcurrentvertbase[r_pedge->v[1]], - pclip); - r_pedge->cachededgeoffset = cacheoffset; - - if (r_leftclipped) - makeleftedge = qtrue; - if (r_rightclipped) - makerightedge = qtrue; - r_lastvertvalid = qtrue; - } - else - { - lindex = -lindex; - r_pedge = &pedges[lindex]; - // if the edge is cached, we can just reuse the edge - if (!insubmodel) - { - if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) - { - if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == - r_framecount) - { - r_lastvertvalid = qfalse; - continue; - } - } - else - { - // it's cached if the cached edge is valid and is owned - // by this medge_t - if ((((unsigned long)edge_p - (unsigned long)r_edges) > - r_pedge->cachededgeoffset) && - (((edge_t *)((unsigned long)r_edges + - r_pedge->cachededgeoffset))->owner == r_pedge)) - { - R_EmitCachedEdge (); - r_lastvertvalid = qfalse; - continue; - } - } - } - - // assume it's cacheable - cacheoffset = (byte *)edge_p - (byte *)r_edges; - r_leftclipped = r_rightclipped = qfalse; - R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]], - &r_pcurrentvertbase[r_pedge->v[0]], - pclip); - r_pedge->cachededgeoffset = cacheoffset; - - if (r_leftclipped) - makeleftedge = qtrue; - if (r_rightclipped) - makerightedge = qtrue; - r_lastvertvalid = qtrue; - } + r_pedge = surfedge->edge; + + // if the edge is cached, we can just reuse the edge + if (!insubmodel) + { + if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) + { + if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == + r_framecount) + { + r_lastvertvalid = qfalse; + continue; + } + } + else + { + if ((((unsigned long)edge_p - (unsigned long)r_edges) > + r_pedge->cachededgeoffset) && + (((edge_t *)((unsigned long)r_edges + + r_pedge->cachededgeoffset))->owner == r_pedge)) + { + R_EmitCachedEdge (); + r_lastvertvalid = qfalse; + continue; + } + } + } + + // assume it's cacheable + cacheoffset = (byte *)edge_p - (byte *)r_edges; + r_leftclipped = r_rightclipped = qfalse; + R_ClipEdge (r_pedge->v[surfedge->vert ], + r_pedge->v[surfedge->vert ^ 1], + pclip); + r_pedge->cachededgeoffset = cacheoffset; + + if (r_leftclipped) + makeleftedge = qtrue; + if (r_rightclipped) + makerightedge = qtrue; + r_lastvertvalid = qtrue; } // if there was a clip off the left edge, add that edge too @@ -705,7 +495,7 @@ void R_RenderFace (msurface_t *fa, int clipflags) surface_p->msurf = fa; surface_p->nearzi = r_nearzi; - surface_p->flags = fa->flags; + surface_p->flags = fa->drawflags; surface_p->insubmodel = insubmodel; surface_p->spanstate = 0; surface_p->entity = currententity; @@ -733,19 +523,20 @@ void R_RenderFace (msurface_t *fa, int clipflags) R_RenderBmodelFace ================ */ -void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf) +void R_RenderBmodelFace (bedge_t *pedges, mface_t *psurf) { int i; unsigned mask; - mplane_t *pplane; + cplane_t *pplane; float distinv; vec3_t p_normal; medge_t tedge; clipplane_t *pclip; + qboolean makeleftedge, makerightedge; - if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66)) + if (psurf->texinfo->c.flags & (SURF_TRANS33|SURF_TRANS66)) { - psurf->nextalphasurface = r_alpha_surfaces; + psurf->next = r_alpha_surfaces; r_alpha_surfaces = psurf; return; } @@ -758,9 +549,9 @@ void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf) } // ditto if not enough edges left, or switch to auxedges if possible - if ((edge_p + psurf->numedges + 4) >= edge_max) + if ((edge_p + psurf->numsurfedges + 4) >= edge_max) { - r_outofedges += psurf->numedges; + r_outofedges += psurf->numsurfedges; return; } @@ -826,7 +617,7 @@ void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf) surface_p->msurf = psurf; surface_p->nearzi = r_nearzi; - surface_p->flags = psurf->flags; + surface_p->flags = psurf->drawflags; surface_p->insubmodel = qtrue; surface_p->spanstate = 0; surface_p->entity = currententity; diff --git a/source/sw_sky.c b/source/sw_sky.c new file mode 100644 index 0000000..233bb10 --- /dev/null +++ b/source/sw_sky.c @@ -0,0 +1,178 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. +Copyright (C) 2008 Andrey Nazarov + +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 "sw_local.h" + +//static float sky_rotate; +//static vec3_t sky_axis; + +static int r_skyframe; +static mface_t r_skyfaces[6]; +static cplane_t r_skyplanes[6]; +static mtexinfo_t r_skytexinfo[6]; +static mvertex_t r_skyverts[8]; +static medge_t r_skyedges[12]; +static msurfedge_t r_skysurfedges[24]; + +// 3dstudio environment map names +static const char r_skysidenames[6][3] = { "rt", "bk", "lf", "ft", "up", "dn" }; +static const int r_skysideimage[6] = { 5, 2, 4, 1, 0, 3 }; + +// I just copied this data from a box map... +static const int box_planes[12] = { + 2,-128, 0,-128, 2,128, 1,128, 0,128, 1,-128 +}; +static const int box_surfedges[24] = { + 1,2,3,4, 1,5,6,7, 8,9,6,10, 2,7,9,11, 12,3,11,8, 12,10,5,4 +}; +static const int box_surfverts[24] = { + 0,0,0,0, 1,0,0,0, 0,0,1,0, 1,1,1,0, 0,1,1,1, 1,1,1,1 +}; +static const int box_edges[24] = { + 1,2, 2,3, 3,4, 4,1, 1,5, 5,6, 6,2, 7,8, 8,6, 5,7, 8,3, 7,4 +}; +static const int box_flags[6] = { + 0, 0, 1, 1, 1, 0 +}; +static const vec3_t box_axis[6][2] = { + { {0,-1,0}, {-1,0,0} }, + { {0,1,0}, {0,0,-1} }, + { {0,-1,0}, {1,0,0} }, + { {1,0,0}, {0,0,-1} }, + { {0,-1,0}, {0,0,-1} }, + { {-1,0,0}, {0,0,-1} } +}; +static const vec3_t box_verts[8] = { + {-1,-1,-1}, + {-1,1,-1}, + {1,1,-1}, + {1,-1,-1}, + {-1,-1,1}, + {-1,1,1}, + {1,-1,1}, + {1,1,1} +}; + +/* +================ +R_InitSkyBox +================ +*/ +void R_InitSkyBox( void ) { + int i; + + for( i = 0; i < 6; i++ ) { + r_skyplanes[i].normal[box_planes[i*2]] = 1; + r_skyplanes[i].dist = box_planes[i*2+1]; + + VectorCopy( box_axis[i][0], r_skytexinfo[i].axis[0] ); + VectorCopy( box_axis[i][1], r_skytexinfo[i].axis[1] ); + + r_skyfaces[i].plane = &r_skyplanes[i]; + r_skyfaces[i].drawflags = box_flags[i] | DSURF_SKY; + r_skyfaces[i].numsurfedges = 4; + r_skyfaces[i].firstsurfedge = &r_skysurfedges[i*4]; + r_skyfaces[i].texinfo = &r_skytexinfo[i]; + r_skyfaces[i].texturemins[0] = -128; + r_skyfaces[i].texturemins[1] = -128; + r_skyfaces[i].extents[0] = 256; + r_skyfaces[i].extents[1] = 256; + } + + for( i = 0; i < 24; i++ ) { + r_skysurfedges[i].edge = &r_skyedges[box_surfedges[i]-1]; + r_skysurfedges[i].vert = box_surfverts[i]; + } + + for( i = 0; i < 12; i++ ) { + r_skyedges[i].v[0] = &r_skyverts[box_edges[i*2+0]-1]; + r_skyedges[i].v[1] = &r_skyverts[box_edges[i*2+1]-1]; + r_skyedges[i].cachededgeoffset = 0; + } +} + +/* +================ +R_EmitSkyBox +================ +*/ +void R_EmitSkyBox( void ) { + int i, j; + int oldkey; + + if (insubmodel) + return; // submodels should never have skies + if (r_skyframe == r_framecount) + return; // already set this frame + + r_skyframe = r_framecount; + + // set the eight fake vertexes + for( i = 0; i < 8; i++ ) + for( j = 0; j < 3; j++ ) + r_skyverts[i].point[j] = r_origin[j] + box_verts[i][j]*128; + + // set the six fake planes + for( i = 0; i < 6; i++ ) + if (box_planes[i*2+1] > 0) + r_skyplanes[i].dist = r_origin[box_planes[i*2]]+128; + else + r_skyplanes[i].dist = r_origin[box_planes[i*2]]-128; + + // fix texture offsets + for( i = 0; i < 6; i++ ) { + r_skytexinfo[i].offset[0] = -DotProduct( r_origin, r_skytexinfo[i].axis[0] ); + r_skytexinfo[i].offset[1] = -DotProduct( r_origin, r_skytexinfo[i].axis[1] ); + } + + // emit the six faces + oldkey = r_currentkey; + r_currentkey = 0x7ffffff0; + for( i = 0; i < 6; i++ ) { + R_RenderFace( &r_skyfaces[i], 15 ); + } + r_currentkey = oldkey; // bsp sorting order +} + +/* +============ +R_SetSky +============ +*/ +void R_SetSky( const char *name, float rotate, vec3_t axis ) { + int i; + char path[MAX_QPATH]; + image_t *image; + +// sky_rotate = rotate; +// VectorCopy( axis, sky_axis ); + + for( i = 0; i < 6; i++ ) { + Q_concat( path, sizeof( path ), "env/", name, + r_skysidenames[r_skysideimage[i]], ".pcx", NULL ); + image = IMG_Find( path, it_sky ); + if( !image ) { + image = r_notexture; + } + r_skytexinfo[i].image = image; + } +} + diff --git a/source/sw_sprite.c b/source/sw_sprite.c index cac2e37..978381e 100644 --- a/source/sw_sprite.c +++ b/source/sw_sprite.c @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern polydesc_t r_polydesc; -void R_BuildPolygonFromSurface(msurface_t *fa); +void R_BuildPolygonFromSurface(mface_t *fa); void R_PolygonCalculateGradients (void); extern void R_PolyChooseSpanletRoutine( float alpha, qboolean isturbulent ); @@ -41,27 +41,14 @@ void R_DrawSprite (void) { vec5_t *pverts; vec3_t left, up, right, down; - dsprite_t *s_psprite; - dsprframe_t *s_psprframe; - - - s_psprite = (dsprite_t *)currentmodel->pool.base; -#if 0 - if (currententity->frame >= s_psprite->numframes - || currententity->frame < 0) - { - Com_Printf( "No such sprite frame %i\n", - currententity->frame); - currententity->frame = 0; - } -#endif - currententity->frame %= s_psprite->numframes; - - s_psprframe = &s_psprite->frames[currententity->frame]; - - r_polydesc.pixels = currentmodel->skins[currententity->frame]->pixels[0]; - r_polydesc.pixel_width = s_psprframe->width; - r_polydesc.pixel_height = s_psprframe->height; + mspriteframe_t *frame; + + frame = ¤tmodel->spriteframes[ + currententity->frame % currentmodel->numframes]; + + r_polydesc.pixels = frame->image->pixels[0]; + r_polydesc.pixel_width = frame->width; + r_polydesc.pixel_height = frame->height; r_polydesc.dist = 0; // generate the sprite's axes, completely parallel to the viewplane. @@ -71,13 +58,13 @@ void R_DrawSprite (void) // build the sprite poster in worldspace VectorScale (r_polydesc.vright, - s_psprframe->width - s_psprframe->origin_x, right); + frame->width - frame->origin_x, right); VectorScale (r_polydesc.vup, - s_psprframe->height - s_psprframe->origin_y, up); + frame->height - frame->origin_y, up); VectorScale (r_polydesc.vright, - -s_psprframe->origin_x, left); + -frame->origin_x, left); VectorScale (r_polydesc.vup, - -s_psprframe->origin_y, down); + -frame->origin_y, down); // invert UP vector for sprites VectorNegate( r_polydesc.vup, r_polydesc.vup ); @@ -93,20 +80,20 @@ void R_DrawSprite (void) pverts[1][0] = r_entorigin[0] + up[0] + right[0]; pverts[1][1] = r_entorigin[1] + up[1] + right[1]; pverts[1][2] = r_entorigin[2] + up[2] + right[2]; - pverts[1][3] = s_psprframe->width; + pverts[1][3] = frame->width; pverts[1][4] = 0; pverts[2][0] = r_entorigin[0] + down[0] + right[0]; pverts[2][1] = r_entorigin[1] + down[1] + right[1]; pverts[2][2] = r_entorigin[2] + down[2] + right[2]; - pverts[2][3] = s_psprframe->width; - pverts[2][4] = s_psprframe->height; + pverts[2][3] = frame->width; + pverts[2][4] = frame->height; pverts[3][0] = r_entorigin[0] + down[0] + left[0]; pverts[3][1] = r_entorigin[1] + down[1] + left[1]; pverts[3][2] = r_entorigin[2] + down[2] + left[2]; pverts[3][3] = 0; - pverts[3][4] = s_psprframe->height; + pverts[3][4] = frame->height; r_polydesc.nump = 4; r_polydesc.s_offset = ( r_polydesc.pixel_width >> 1); diff --git a/source/sw_surf.c b/source/sw_surf.c index d77e33c..dc7b596 100644 --- a/source/sw_surf.c +++ b/source/sw_surf.c @@ -106,7 +106,7 @@ void R_DrawSurface( void ) { // from a source range of 0 - 255 /* width in bytes */ - twidth = ( mt->upload_width >> r_drawsurf.surfmip ) * VID_BYTES; + twidth = mt->upload_width >> r_drawsurf.surfmip; blocksize = 16 >> r_drawsurf.surfmip; blockdivshift = 4 - r_drawsurf.surfmip; @@ -121,14 +121,14 @@ void R_DrawSurface( void ) { pblockdrawer = surfmiptable[r_drawsurf.surfmip]; // TODO: only needs to be set when there is a display settings change - horzblockstep = blocksize << VID_SHIFT; + horzblockstep = blocksize; smax = mt->upload_width >> r_drawsurf.surfmip; tmax = mt->upload_height >> r_drawsurf.surfmip; sourcetstep = twidth; r_stepback = tmax * twidth; - r_sourcemax = r_source + ( tmax * smax * VID_BYTES ); + r_sourcemax = r_source + tmax * smax; soffset = r_drawsurf.surf->texturemins[0]; toffset = r_drawsurf.surf->texturemins[1]; @@ -146,7 +146,7 @@ void R_DrawSurface( void ) { prowdestbase = pcolumndest; - pbasesource = basetptr + ( soffset << VID_SHIFT ); + pbasesource = basetptr + soffset; (*pblockdrawer)(); @@ -359,7 +359,7 @@ void D_SCDump_f (void) D_CacheSurface ================ */ -surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel) +surfcache_t *D_CacheSurface (mface_t *surface, int miplevel) { surfcache_t *cache; diff --git a/source/sys_public.h b/source/sys_public.h new file mode 100644 index 0000000..86f9451 --- /dev/null +++ b/source/sys_public.h @@ -0,0 +1,76 @@ +/* +Copyright (C) 1997-2001 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. + +*/ + +// if api_version is different, the dll cannot be used +#define MODULES_APIVERSION 318 + +typedef struct { + void *base; + size_t maxsize; + size_t cursize; + size_t mapped; +} mempool_t; + +// loads the dll and returns entry pointer +void *Sys_LoadLibrary( const char *path, const char *sym, void **handle ); +void Sys_FreeLibrary( void *handle ); +void *Sys_GetProcAddress( void *handle, const char *sym ); + +unsigned Sys_Milliseconds( void ); +void Sys_Sleep( int msec ); + +void Hunk_Begin( mempool_t *pool, size_t maxsize ); +void *Hunk_Alloc( mempool_t *pool, size_t size ); +void Hunk_End( mempool_t *pool ); +void Hunk_Free( mempool_t *pool ); + +void Sys_Init( void ); +void Sys_AddDefaultConfig( void ); + +void Sys_RunConsole( void ); +void Sys_ConsoleOutput( const char *string ); +void Sys_SetConsoleTitle( const char *title ); +void Sys_Printf( const char *fmt, ... ) q_printf( 1, 2 ); +void Sys_Error( const char *error, ... ) q_noreturn q_printf( 1, 2 ); +void Sys_Quit( void ); + +void **Sys_ListFiles( const char *path, const char *extension, int flags, size_t length, int *numFiles ); + +qboolean Sys_GetPathInfo( const char *path, fsFileInfo_t *info ); +qboolean Sys_GetFileInfo( FILE *fp, fsFileInfo_t *info ); + +char *Sys_GetCurrentDirectory( void ); + +void Sys_DebugBreak( void ); + +void Sys_FixFPCW( void ); + +#ifdef USE_ANTICHEAT +qboolean Sys_GetAntiCheatAPI( void ); +#endif + +extern cvar_t *sys_basedir; +extern cvar_t *sys_libdir; +extern cvar_t *sys_refdir; +extern cvar_t *sys_homedir; +#ifdef __unix__ +extern cvar_t *sys_stdio; +#endif + diff --git a/source/sys_unix.c b/source/sys_unix.c index bfcf87b..9f71eab 100644 --- a/source/sys_unix.c +++ b/source/sys_unix.c @@ -48,15 +48,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "q_list.h" #include "q_field.h" #include "prompt.h" +#include "files.h" +#if USE_REF +#include "vid_public.h" +#endif +#include "sys_public.h" cvar_t *sys_basedir; cvar_t *sys_libdir; -cvar_t *sys_refdir; cvar_t *sys_homedir; cvar_t *sys_stdio; -sysAPI_t sys; - static qboolean tty_enabled; static struct termios tty_orig; static commandPrompt_t tty_prompt; @@ -409,8 +411,8 @@ void Hunk_Begin( mempool_t *pool, size_t maxsize ) { buf = mmap( NULL, pool->maxsize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0 ); if( buf == NULL || buf == ( void * )-1 ) { - Com_Error( ERR_FATAL, "%s: unable to virtual allocate %"PRIz" bytes", - __func__, pool->maxsize ); + Com_Error( ERR_FATAL, "%s: unable to reserve %"PRIz" bytes: %s", + __func__, pool->maxsize, strerror( errno ) ); } pool->base = buf; pool->mapped = pool->maxsize; @@ -588,19 +590,6 @@ qboolean Sys_GetAntiCheatAPI( void ) { } #endif -/* -================ -Sys_FillAPI -================ -*/ -void Sys_FillAPI( sysAPI_t *api ) { - api->Milliseconds = Sys_Milliseconds; - api->HunkBegin = Hunk_Begin; - api->HunkAlloc = Hunk_Alloc; - api->HunkEnd = Hunk_End; - api->HunkFree = Hunk_Free; -} - void Sys_FixFPCW( void ) { #ifdef __i386__ uint16_t cw; @@ -644,7 +633,7 @@ Sys_Kill static void Sys_Kill( int signum ) { Sys_ShutdownTTY(); -#ifndef DEDICATED_ONLY +#if USE_CLIENT && USE_REF VID_FatalShutdown(); #endif @@ -691,9 +680,7 @@ void Sys_Init( void ) { homedir = HOMEDIR; } sys_homedir = Cvar_Get( "homedir", homedir, CVAR_NOSET ); - sys_libdir = Cvar_Get( "libdir", LIBDIR, CVAR_NOSET ); - sys_refdir = Cvar_Get( "refdir", REFDIR, CVAR_NOSET ); sys_stdio = Cvar_Get( "sys_stdio", "2", CVAR_NOSET ); @@ -717,8 +704,6 @@ void Sys_Init( void ) { } Sys_FixFPCW(); - - Sys_FillAPI( &sys ); } /* @@ -748,7 +733,7 @@ void Sys_Error( const char *error, ... ) { Sys_ShutdownTTY(); -#ifndef DEDICATED_ONLY +#if USE_CLIENT && USE_REF VID_FatalShutdown(); #endif diff --git a/source/sys_win.c b/source/sys_win.c index 2f12029..81903db 100644 --- a/source/sys_win.c +++ b/source/sys_win.c @@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "q_list.h" #include "prompt.h" #include <mmsystem.h> -#ifdef DEDICATED_ONLY +#if !USE_CLIENT #include <winsvc.h> #endif #ifdef USE_DBGHELP @@ -31,8 +31,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #include <float.h> -sysAPI_t sys; - #define MAX_CONSOLE_INPUT_EVENTS 16 static HANDLE hinput = INVALID_HANDLE_VALUE; @@ -46,7 +44,7 @@ static qboolean gotConsole; static volatile qboolean errorEntered; static volatile qboolean shouldExit; -#ifdef DEDICATED_ONLY +#if !USE_CLIENT static SERVICE_STATUS_HANDLE statusHandle; #endif @@ -56,7 +54,6 @@ qboolean iswinnt; cvar_t *sys_basedir; cvar_t *sys_libdir; -cvar_t *sys_refdir; cvar_t *sys_homedir; static char currentDirectory[MAX_OSPATH]; @@ -107,7 +104,7 @@ void Sys_Error( const char *error, ... ) { Sys_Printf( S_COLOR_RED "********************\n" "FATAL: %s\n" "********************\n", text ); -#ifdef DEDICATED_ONLY +#if !USE_CLIENT if( !statusHandle ) #endif { @@ -128,7 +125,7 @@ Sys_Quit void Sys_Quit( void ) { timeEndPeriod( 1 ); -#ifndef DEDICATED_ONLY +#if USE_CLIENT if( dedicated && dedicated->integer ) { FreeConsole(); } @@ -392,16 +389,16 @@ static BOOL WINAPI Sys_ConsoleCtrlHandler( DWORD dwCtrlType ) { static void Sys_ConsoleInit( void ) { DWORD mode; -#ifdef DEDICATED_ONLY - if( statusHandle ) { - return; - } -#else +#if USE_CLIENT if( !AllocConsole() ) { Com_EPrintf( "Couldn't create system console.\n" "Console IO disabled.\n" ); return; } +#else + if( statusHandle ) { + return; + } #endif hinput = GetStdHandle( STD_INPUT_HANDLE ); @@ -433,7 +430,7 @@ SERVICE CONTROL =============================================================================== */ -#ifdef DEDICATED_ONLY +#if !USE_CLIENT static void Sys_InstallService_f( void ) { char servicePath[256]; @@ -675,19 +672,6 @@ qboolean Sys_GetFileInfo( FILE *fp, fsFileInfo_t *info ) { return qtrue; } -/* -================ -Sys_FillAPI -================ -*/ -void Sys_FillAPI( sysAPI_t *api ) { - api->Milliseconds = Sys_Milliseconds; - api->HunkBegin = Hunk_Begin; - api->HunkAlloc = Hunk_Alloc; - api->HunkEnd = Hunk_End; - api->HunkFree = Hunk_Free; -} - void Sys_FixFPCW( void ) { _controlfp( _PC_24|_RC_NEAR, _MCW_PC|_MCW_RC ); } @@ -728,17 +712,15 @@ void Sys_Init( void ) { // basedir <path> // allows the game to run from outside the data tree sys_basedir = Cvar_Get( "basedir", currentDirectory, CVAR_NOSET ); + sys_libdir = Cvar_Get( "libdir", currentDirectory, CVAR_NOSET ); // homedir <path> // specifies per-user writable directory for demos, screenshots, etc sys_homedir = Cvar_Get( "homedir", "", CVAR_NOSET ); - sys_libdir = Cvar_Get( "libdir", currentDirectory, CVAR_NOSET ); - sys_refdir = Cvar_Get( "refdir", va( "%s\\baseq2pro", currentDirectory ), CVAR_NOSET ); - sys_viewlog = Cvar_Get( "sys_viewlog", "0", CVAR_NOSET ); -#ifdef DEDICATED_ONLY +#if !USE_CLIENT Cmd_AddCommand( "installservice", Sys_InstallService_f ); Cmd_AddCommand( "deleteservice", Sys_DeleteService_f ); #endif @@ -747,8 +729,6 @@ void Sys_Init( void ) { if( dedicated->integer || sys_viewlog->integer ) { Sys_ConsoleInit(); } - - Sys_FillAPI( &sys ); } /* @@ -979,7 +959,7 @@ char *Sys_GetCurrentDirectory( void ) { //======================================================================= -#if !( defined DEDICATED_ONLY ) && ( USE_ANTICHEAT & 1 ) +#if ( USE_CLIENT ) && ( USE_ANTICHEAT & 1 ) typedef PVOID (*FNINIT)( VOID ); @@ -1155,7 +1135,7 @@ PRIVATE DWORD Sys_ExceptionHandler( DWORD exceptionCode, LPEXCEPTION_POINTERS ex "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; OSVERSIONINFO vinfo; -#ifndef DEDICATED_ONLY +#if USE_CLIENT Win_Shutdown(); #endif @@ -1164,7 +1144,7 @@ PRIVATE DWORD Sys_ExceptionHandler( DWORD exceptionCode, LPEXCEPTION_POINTERS ex "Would you like to generate a crash report?", "Unhandled Exception", MB_ICONERROR | MB_YESNO -#ifdef DEDICATED_ONLY +#if !USE_CLIENT | MB_SERVICE_NOTIFICATION #endif ); @@ -1389,7 +1369,12 @@ static void msvcrt_sucks( const wchar_t *expr, const wchar_t *func, const wchar_ #endif static int Sys_Main( int argc, char **argv ) { -#ifdef DEDICATED_ONLY +#if USE_CLIENT + if( !GetCurrentDirectory( sizeof( currentDirectory ) - 1, currentDirectory ) ) { + return 1; + } + currentDirectory[sizeof( currentDirectory ) - 1] = 0; +#else if( !GetModuleFileName( NULL, currentDirectory, sizeof( currentDirectory ) - 1 ) ) { return 1; } @@ -1403,11 +1388,6 @@ static int Sys_Main( int argc, char **argv ) { return 1; } } -#else - if( !GetCurrentDirectory( sizeof( currentDirectory ) - 1, currentDirectory ) ) { - return 1; - } - currentDirectory[sizeof( currentDirectory ) - 1] = 0; #endif #if USE_DBGHELP @@ -1449,7 +1429,62 @@ static int Sys_Main( int argc, char **argv ) { -#ifdef DEDICATED_ONLY +#if USE_CLIENT + +#define MAX_LINE_TOKENS 128 + +static char *sys_argv[MAX_LINE_TOKENS]; +static int sys_argc; + +/* +=============== +Sys_ParseCommandLine + +=============== +*/ +static void Sys_ParseCommandLine( char *line ) { + sys_argc = 1; + sys_argv[0] = APPLICATION; + while( *line ) { + while( *line && *line <= 32 ) { + line++; + } + if( *line == 0 ) { + break; + } + sys_argv[sys_argc++] = line; + while( *line > 32 ) { + line++; + } + if( *line == 0 ) { + break; + } + *line = 0; + if( sys_argc == MAX_LINE_TOKENS ) { + break; + } + line++; + } +} + +/* +================== +WinMain + +================== +*/ +int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { + // previous instances do not exist in Win32 + if( hPrevInstance ) { + return 1; + } + + hGlobalInstance = hInstance; + Sys_ParseCommandLine( lpCmdLine ); + return Sys_Main( sys_argc, sys_argv ); +} + +#else // USE_CLIENT static char **sys_argv; static int sys_argc; @@ -1515,60 +1550,5 @@ int QDECL main( int argc, char **argv ) { return Sys_Main( argc, argv ); } -#else // DEDICATED_ONLY - -#define MAX_LINE_TOKENS 128 - -static char *sys_argv[MAX_LINE_TOKENS]; -static int sys_argc; - -/* -=============== -Sys_ParseCommandLine - -=============== -*/ -static void Sys_ParseCommandLine( char *line ) { - sys_argc = 1; - sys_argv[0] = APPLICATION; - while( *line ) { - while( *line && *line <= 32 ) { - line++; - } - if( *line == 0 ) { - break; - } - sys_argv[sys_argc++] = line; - while( *line > 32 ) { - line++; - } - if( *line == 0 ) { - break; - } - *line = 0; - if( sys_argc == MAX_LINE_TOKENS ) { - break; - } - line++; - } -} - -/* -================== -WinMain - -================== -*/ -int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { - // previous instances do not exist in Win32 - if( hPrevInstance ) { - return 1; - } - - hGlobalInstance = hInstance; - Sys_ParseCommandLine( lpCmdLine ); - return Sys_Main( sys_argc, sys_argv ); -} - -#endif // !DEDICATED_ONLY +#endif // !USE_CLIENT diff --git a/source/ui_atoms.c b/source/ui_atoms.c index bafee89..89a3b64 100644 --- a/source/ui_atoms.c +++ b/source/ui_atoms.c @@ -321,7 +321,7 @@ qboolean UI_CursorInRect( vrect_t *rect ) { void UI_DrawString( int x, int y, const color_t color, int flags, const char *string ) { if( color ) { - ref.SetColor( DRAW_COLOR_RGBA, color ); + R_SetColor( DRAW_COLOR_RGBA, color ); } if( ( flags & UI_CENTER ) == UI_CENTER ) { @@ -330,14 +330,14 @@ void UI_DrawString( int x, int y, const color_t color, int flags, const char *st x -= Q_DrawStrlen( string ) * 8; } - ref.DrawString( x, y, flags, MAX_STRING_CHARS, string, uis.fontHandle ); + R_DrawString( x, y, flags, MAX_STRING_CHARS, string, uis.fontHandle ); if( color ) { - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); } } void UI_DrawChar( int x, int y, int flags, int ch ) { - ref.DrawChar( x, y, flags, ch, uis.fontHandle ); + R_DrawChar( x, y, flags, ch, uis.fontHandle ); } void UI_StringDimensions( vrect_t *rc, int flags, const char *string ) { @@ -352,17 +352,17 @@ void UI_StringDimensions( vrect_t *rc, int flags, const char *string ) { } void UI_DrawRect( const vrect_t *rc, int border, int color ) { - ref.DrawFill( rc->x, rc->y, border, rc->height, color ); // left - ref.DrawFill( rc->x + rc->width - border, rc->y, border, rc->height, color ); // right - ref.DrawFill( rc->x + border, rc->y, rc->width - border * 2, border, color ); // top - ref.DrawFill( rc->x + border, rc->y + rc->height - border, rc->width - border * 2, border, color ); // bottom + R_DrawFill( rc->x, rc->y, border, rc->height, color ); // left + R_DrawFill( rc->x + rc->width - border, rc->y, border, rc->height, color ); // right + R_DrawFill( rc->x + border, rc->y, rc->width - border * 2, border, color ); // top + R_DrawFill( rc->x + border, rc->y + rc->height - border, rc->width - border * 2, border, color ); // bottom } void UI_DrawRectEx( const vrect_t *rc, int border, const color_t color ) { - ref.DrawFillEx( rc->x, rc->y, border, rc->height, color ); // left - ref.DrawFillEx( rc->x + rc->width - border, rc->y, border, rc->height, color ); // right - ref.DrawFillEx( rc->x + border, rc->y, rc->width - border * 2, border, color ); // top - ref.DrawFillEx( rc->x + border, rc->y + rc->height - border, rc->width - border * 2, border, color ); // bottom + R_DrawFillEx( rc->x, rc->y, border, rc->height, color ); // left + R_DrawFillEx( rc->x + rc->width - border, rc->y, border, rc->height, color ); // right + R_DrawFillEx( rc->x + border, rc->y, rc->width - border * 2, border, color ); // top + R_DrawFillEx( rc->x + border, rc->y + rc->height - border, rc->width - border * 2, border, color ); // bottom } @@ -432,11 +432,11 @@ void UI_Draw( int realtime ) { return; } - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); if( uis.glconfig.renderer == GL_RENDERER_SOFTWARE ) { - ref.SetClipRect( DRAW_CLIP_MASK, &uis.clipRect ); + R_SetClipRect( DRAW_CLIP_MASK, &uis.clipRect ); } else { - ref.SetScale( &uis.scale ); + R_SetScale( &uis.scale ); } if( !uis.transparent ) { @@ -459,7 +459,7 @@ void UI_Draw( int realtime ) { // draw custom cursor in fullscreen mode if( uis.glconfig.flags & QVF_FULLSCREEN ) { - ref.DrawPic( uis.mouseCoords[0] - uis.cursorWidth / 2, + R_DrawPic( uis.mouseCoords[0] - uis.cursorWidth / 2, uis.mouseCoords[1] - uis.cursorHeight / 2, uis.cursorHandle ); } @@ -477,11 +477,11 @@ void UI_Draw( int realtime ) { } if( uis.glconfig.renderer == GL_RENDERER_SOFTWARE ) { - ref.SetClipRect( DRAW_CLIP_DISABLED, NULL ); + R_SetClipRect( DRAW_CLIP_DISABLED, NULL ); } else { - ref.SetScale( NULL ); + R_SetScale( NULL ); } - ref.SetColor( DRAW_COLOR_CLEAR, NULL ); + R_SetColor( DRAW_COLOR_CLEAR, NULL ); } /* @@ -609,9 +609,9 @@ static void ui_scale_changed( cvar_t *self ) { } void UI_ModeChanged( void ) { - ui_scale = cvar.Get( "ui_scale", "1", 0 ); + ui_scale = Cvar_Get( "ui_scale", "1", 0 ); ui_scale->changed = ui_scale_changed; - ref.GetConfig( &uis.glconfig ); + R_GetConfig( &uis.glconfig ); UI_Resize(); } @@ -640,9 +640,9 @@ qboolean UI_Init( void ) { UI_ModeChanged(); - uis.fontHandle = ref.RegisterFont( "conchars" ); - uis.cursorHandle = ref.RegisterPic( "ch1" ); - ref.DrawGetPicSize( &uis.cursorWidth, &uis.cursorHeight, uis.cursorHandle ); + uis.fontHandle = R_RegisterFont( "conchars" ); + uis.cursorHandle = R_RegisterPic( "ch1" ); + R_GetPicSize( &uis.cursorWidth, &uis.cursorHeight, uis.cursorHandle ); Vector4Set( uis.color.background, 0, 0, 0, 255 ); Vector4Set( uis.color.normal, 15, 128, 235, 100 ); diff --git a/source/ui_demos.c b/source/ui_demos.c index daf8404..5bf7e89 100644 --- a/source/ui_demos.c +++ b/source/ui_demos.c @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ui_local.h" +#include "files.h" #include "mdfour.h" /* @@ -118,7 +119,7 @@ static char *LoadCache( void **list ) { uint8_t hash[16]; Q_concat( buffer, sizeof( buffer ), m_demos.browse, "/" COM_DEMOCACHE_NAME, NULL ); - len = fs.LoadFile( buffer, ( void ** )&cache ); + len = FS_LoadFile( buffer, ( void ** )&cache ); if( !cache ) { return NULL; } @@ -144,7 +145,7 @@ static char *LoadCache( void **list ) { return cache; fail: - fs.FreeFile( cache ); + FS_FreeFile( cache ); return NULL; } @@ -160,23 +161,23 @@ static void WriteCache( void ) { } Q_concat( buffer, sizeof( buffer ), m_demos.browse, "/" COM_DEMOCACHE_NAME, NULL ); - fs.FOpenFile( buffer, &f, FS_MODE_WRITE ); + FS_FOpenFile( buffer, &f, FS_MODE_WRITE ); if( !f ) { return; } for( i = 0; i < 16; i++ ) { - fs.FPrintf( f, "%02x", m_demos.hash[i] ); + FS_FPrintf( f, "%02x", m_demos.hash[i] ); } - fs.FPrintf( f, "\\" ); + FS_FPrintf( f, "\\" ); for( i = m_demos.numDirs; i < m_demos.list.numItems; i++ ) { e = m_demos.list.items[i]; map = UI_GetColumn( e->name, 2 ); pov = UI_GetColumn( e->name, 3 ); - fs.FPrintf( f, "%s\\%s\\", map, pov ); + FS_FPrintf( f, "%s\\%s\\", map, pov ); } - fs.FCloseFile( f ); + FS_FCloseFile( f ); } static void CalcHash( void **list ) { @@ -275,9 +276,9 @@ static void FreeList( void ) { if( m_demos.list.items ) { for( i = 0; i < m_demos.list.numItems; i++ ) { - com.Free( m_demos.list.items[i] ); + Z_Free( m_demos.list.items[i] ); } - com.Free( m_demos.list.items ); + Z_Free( m_demos.list.items ); m_demos.list.items = NULL; m_demos.list.numItems = 0; } diff --git a/source/ui_menu.c b/source/ui_menu.c index 014367e..c8ad285 100644 --- a/source/ui_menu.c +++ b/source/ui_menu.c @@ -330,13 +330,13 @@ static void Field_Draw( menuField_t *f ) { UI_DrawString( f->generic.x + LCOLUMN_OFFSET, f->generic.y, NULL, f->generic.uiFlags | UI_RIGHT | UI_ALTCOLOR, f->generic.name ); - ref.DrawFillEx( f->generic.x + RCOLUMN_OFFSET, f->generic.y - 1, + R_DrawFillEx( f->generic.x + RCOLUMN_OFFSET, f->generic.y - 1, f->field.visibleChars * CHAR_WIDTH, CHAR_HEIGHT + 2, color ); IF_Draw( &f->field, f->generic.x + RCOLUMN_OFFSET, f->generic.y, flags, uis.fontHandle ); } else { - ref.DrawFillEx( f->generic.rect.x, f->generic.rect.y - 1, + R_DrawFillEx( f->generic.rect.x, f->generic.rect.y - 1, f->generic.rect.width, CHAR_HEIGHT + 2, color ); IF_Draw( &f->field, f->generic.rect.x, f->generic.rect.y, @@ -963,12 +963,12 @@ static void MenuList_DrawString( int x, int y, int flags, x += MLIST_PRESTEP; } - ref.SetClipRect( DRAW_CLIP_RIGHT|DRAW_CLIP_LEFT, &rc ); + R_SetClipRect( DRAW_CLIP_RIGHT|DRAW_CLIP_LEFT, &rc ); UI_DrawString( x, y + 1, NULL, column->uiFlags | flags, string ); if( uis.glconfig.renderer == GL_RENDERER_SOFTWARE ) { - ref.SetClipRect( DRAW_CLIP_MASK, &uis.clipRect ); + R_SetClipRect( DRAW_CLIP_MASK, &uis.clipRect ); } else { - ref.SetClipRect( DRAW_CLIP_DISABLED, NULL ); + R_SetClipRect( DRAW_CLIP_DISABLED, NULL ); } } @@ -1005,7 +1005,7 @@ static void MenuList_Draw( menuList_t *l ) { color = uis.color.active; } } - ref.DrawFillEx( xx, y, l->columns[j].width - 1, + R_DrawFillEx( xx, y, l->columns[j].width - 1, MLIST_SPACING - 1, color ); if( l->columns[j].name ) { @@ -1026,7 +1026,7 @@ static void MenuList_Draw( menuList_t *l ) { // draw scrollbar background if( !( l->mlFlags & MLF_HIDE_BACKGROUND ) ) { - ref.DrawFillEx( x + width, yy, MLIST_SCROLLBAR_WIDTH - 1, + R_DrawFillEx( x + width, yy, MLIST_SCROLLBAR_WIDTH - 1, barHeight, uis.color.normal ); } @@ -1039,7 +1039,7 @@ static void MenuList_Draw( menuList_t *l ) { } // draw scrollbar thumb - ref.DrawFillEx( x + width, + R_DrawFillEx( x + width, yy + Q_rint( barHeight * prestepFrac ), MLIST_SCROLLBAR_WIDTH - 1, Q_rint( barHeight * pageFrac ), @@ -1055,7 +1055,7 @@ static void MenuList_Draw( menuList_t *l ) { color = uis.color.active; } } - ref.DrawFillEx( xx, y, l->columns[j].width - 1, + R_DrawFillEx( xx, y, l->columns[j].width - 1, height, color ); xx += l->columns[j].width; @@ -1068,7 +1068,7 @@ static void MenuList_Draw( menuList_t *l ) { if( !( l->generic.flags & QMF_DISABLED ) && i == l->curvalue ) { xx = x; for( j = 0; j < l->numcolumns; j++ ) { - ref.DrawFillEx( xx, yy, l->columns[j].width - 1, + R_DrawFillEx( xx, yy, l->columns[j].width - 1, MLIST_SPACING, uis.color.selection ); xx += l->columns[j].width; } @@ -1497,10 +1497,10 @@ void Menu_Draw( menuFrameWork_t *menu ) { // draw background // if( menu->image ) { - ref.DrawStretchPic( 0, menu->y1, uis.width, + R_DrawStretchPic( 0, menu->y1, uis.width, menu->y2 - menu->y1, menu->image ); } else { - ref.DrawFillEx( 0, menu->y1, uis.width, + R_DrawFillEx( 0, menu->y1, uis.width, menu->y2 - menu->y1, menu->color ); } @@ -1565,7 +1565,7 @@ void Menu_Draw( menuFrameWork_t *menu ) { // draw status bar // if( menu->status ) { - ref.DrawFill( 0, menu->y2 - 8, uis.width, 8, 4 ); + R_DrawFill( 0, menu->y2 - 8, uis.width, 8, 4 ); UI_DrawString( uis.width / 2, menu->y2 - 8, NULL, UI_CENTER, menu->status ); } diff --git a/source/ui_multiplayer.c b/source/ui_multiplayer.c index a059b41..e33d1db 100644 --- a/source/ui_multiplayer.c +++ b/source/ui_multiplayer.c @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ui_local.h" +#include "files.h" /* ============================================================================= @@ -92,11 +93,11 @@ static void ClearSlot( serverSlot_t *slot ) { int i; for( i = 0; i < slot->numRules; i++ ) { - com.Free( slot->rules[i] ); + Z_Free( slot->rules[i] ); slot->rules[i] = NULL; } for( i = 0; i < slot->numPlayers; i++ ) { - com.Free( slot->players[i] ); + Z_Free( slot->players[i] ); slot->players[i] = NULL; } slot->numRules = slot->numPlayers = 0; @@ -148,7 +149,7 @@ void UI_AddToServerList( const serverStatus_t *status ) { map = "???"; } else { Com_sprintf( value, sizeof( value ), "maps/%s.bsp", map ); - if( fs.LoadFile( value, NULL ) == INVALID_LENGTH ) { + if( FS_LoadFile( value, NULL ) == INVALID_LENGTH ) { Q_concat( value, sizeof( value ), S_COLOR_RED, map, NULL ); map = value; } @@ -161,7 +162,7 @@ void UI_AddToServerList( const serverStatus_t *status ) { status->numPlayers, j ); if( m_join.names[i] ) { - com.Free( m_join.names[i] ); + Z_Free( m_join.names[i] ); } m_join.names[i] = UI_FormatColumns( 0, host, map, key, NULL ); @@ -193,7 +194,7 @@ static void PingSelected( void ) { serverSlot_t *s = &m_join.servers[m_join.list.curvalue]; if( m_join.names[m_join.list.curvalue] ) { - com.Free( m_join.names[m_join.list.curvalue] ); + Z_Free( m_join.names[m_join.list.curvalue] ); } m_join.names[m_join.list.curvalue] = UI_FormatColumns( 0, s->address, "???", "?/?", NULL ); @@ -220,7 +221,7 @@ static void AddUnlistedServers( void ) { CL_SendStatusRequest( NULL, 0 ); for( i = 0; i < MAX_STATUS_SERVERS; i++ ) { - var = cvar.Find( va( "adr%i", i ) ); + var = Cvar_FindVar( va( "adr%i", i ) ); if( !var ) { break; } @@ -266,7 +267,7 @@ static void FreeListedServers( void ) { for( i = 0; i < m_join.list.numItems; i++ ) { if( m_join.names[i] ) { - com.Free( m_join.names[i] ); + Z_Free( m_join.names[i] ); m_join.names[i] = NULL; } } diff --git a/source/ui_playerconfig.c b/source/ui_playerconfig.c index 9a098a5..0fcea96 100644 --- a/source/ui_playerconfig.c +++ b/source/ui_playerconfig.c @@ -63,13 +63,13 @@ static void ReloadMedia( void ) { char *skin = uis.pmi[m_player.model.curvalue].skindisplaynames[m_player.skin.curvalue]; Q_concat( scratch, sizeof( scratch ), "players/", model, "/tris.md2", NULL ); - m_player.entities[0].model = ref.RegisterModel( scratch ); + m_player.entities[0].model = R_RegisterModel( scratch ); Q_concat( scratch, sizeof( scratch ), "players/", model, "/", skin, ".pcx", NULL ); - m_player.entities[0].skin = ref.RegisterSkin( scratch ); + m_player.entities[0].skin = R_RegisterSkin( scratch ); Q_concat( scratch, sizeof( scratch ), "players/", model, "/w_railgun.md2", NULL ); - m_player.entities[1].model = ref.RegisterModel( scratch ); + m_player.entities[1].model = R_RegisterModel( scratch ); } static void RunFrame( void ) { @@ -111,7 +111,7 @@ static void Draw( menuFrameWork_t *self ) { Menu_Draw( self ); - ref.RenderFrame( &m_player.refdef ); + R_RenderFrame( &m_player.refdef ); } static void Size( menuFrameWork_t *self ) { diff --git a/source/ui_playermodels.c b/source/ui_playermodels.c index 91250a7..c9c34bb 100644 --- a/source/ui_playermodels.c +++ b/source/ui_playermodels.c @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ui_local.h" +#include "files.h" /* ============================================================================= @@ -93,7 +94,7 @@ void PlayerModel_Load( void ) { /* ** get a list of directories */ - if( !( list = ( char ** )fs.ListFiles( NULL, "players/*/*", FS_SEARCH_BYFILTER|FS_SEARCH_SAVEPATH, &numFiles ) ) ) { + if( !( list = ( char ** )FS_ListFiles( NULL, "players/*/*", FS_SEARCH_BYFILTER|FS_SEARCH_SAVEPATH, &numFiles ) ) ) { return; } @@ -119,7 +120,7 @@ void PlayerModel_Load( void ) { } } - fs.FreeList( ( void ** )list ); + FS_FreeList( ( void ** )list ); if( !ndirs ) { return; @@ -140,13 +141,13 @@ void PlayerModel_Load( void ) { // verify the existence of tris.md2 Q_concat( scratch, sizeof( scratch ), "players/", dirnames[i], "/tris.md2", NULL ); - if( fs.LoadFile( scratch, NULL ) == INVALID_LENGTH ) { + if( FS_LoadFile( scratch, NULL ) == INVALID_LENGTH ) { continue; } // verify the existence of at least one pcx skin Q_concat( scratch, sizeof( scratch ), "players/", dirnames[i], NULL ); - pcxnames = ( char ** )fs.ListFiles( scratch, ".pcx", 0, &npcxfiles ); + pcxnames = ( char ** )FS_ListFiles( scratch, ".pcx", 0, &npcxfiles ); if( !pcxnames ) { continue; } @@ -161,7 +162,7 @@ void PlayerModel_Load( void ) { } if( !nskins ) { - fs.FreeList( ( void ** )pcxnames ); + FS_FreeList( ( void ** )pcxnames ); continue; } @@ -178,11 +179,11 @@ void PlayerModel_Load( void ) { } } - fs.FreeList( ( void ** )pcxnames ); + FS_FreeList( ( void ** )pcxnames ); // load vweap models Q_concat( scratch, sizeof( scratch ), "players/", dirnames[i], "/w_*.md2", NULL ); - weaponNames = ( char ** )fs.ListFiles( NULL, scratch, FS_SEARCH_BYFILTER, &numWeapons ); + weaponNames = ( char ** )FS_ListFiles( NULL, scratch, FS_SEARCH_BYFILTER, &numWeapons ); pmi = &uis.pmi[uis.numPlayerModels++]; pmi->numWeapons = 0; @@ -199,7 +200,7 @@ void PlayerModel_Load( void ) { } } - fs.FreeList( ( void ** )weaponNames ); + FS_FreeList( ( void ** )weaponNames ); } // at this point we have a valid player model @@ -211,7 +212,7 @@ void PlayerModel_Load( void ) { } for( i = 0; i < ndirs; i++ ) { - com.Free( dirnames[i] ); + Z_Free( dirnames[i] ); } qsort( uis.pmi, uis.numPlayerModels, sizeof( uis.pmi[0] ), pmicmpfnc ); @@ -226,15 +227,15 @@ void PlayerModel_Free( void ) { for( i = 0, pmi = uis.pmi; i < uis.numPlayerModels; i++, pmi++ ) { if( pmi->skindisplaynames ) { for( j = 0; j < pmi->nskins; j++ ) { - com.Free( pmi->skindisplaynames[j] ); + Z_Free( pmi->skindisplaynames[j] ); } - com.Free( pmi->skindisplaynames ); + Z_Free( pmi->skindisplaynames ); } if( pmi->weaponNames ) { for( j = 0; j < pmi->numWeapons; j++ ) { - com.Free( pmi->weaponNames[j] ); + Z_Free( pmi->weaponNames[j] ); } - com.Free( pmi->weaponNames ); + Z_Free( pmi->weaponNames ); } memset( pmi, 0, sizeof( *pmi ) ); } diff --git a/source/ui_script.c b/source/ui_script.c index 502e1a4..2cd4fb2 100644 --- a/source/ui_script.c +++ b/source/ui_script.c @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ui_local.h" +#include "files.h" static menuSound_t Activate( menuCommon_t *self ) { menuAction_t *action = ( menuAction_t * )self; @@ -263,8 +264,8 @@ static void Parse_Background( menuFrameWork_t *menu ) { menu->transparent = qtrue; } } else { - menu->image = ref.RegisterPic( s ); - menu->transparent = ref.DrawGetPicSize( NULL, NULL, menu->image ); + menu->image = R_RegisterPic( s ); + menu->transparent = R_GetPicSize( NULL, NULL, menu->image ); } } @@ -392,13 +393,13 @@ static qboolean Parse_File( const char *path, int depth ) { if( COM_ParseColor( s, uis.color.background ) ) { uis.backgroundHandle = 0; } else { - uis.backgroundHandle = ref.RegisterPic( s ); + uis.backgroundHandle = R_RegisterPic( s ); } } else if( !strcmp( cmd, "font" ) ) { - uis.fontHandle = ref.RegisterFont( Cmd_Argv( 1 ) ); + uis.fontHandle = R_RegisterFont( Cmd_Argv( 1 ) ); } else if( !strcmp( cmd, "cursor" ) ) { - uis.cursorHandle = ref.RegisterPic( Cmd_Argv( 1 ) ); - ref.DrawGetPicSize( &uis.cursorWidth, + uis.cursorHandle = R_RegisterPic( Cmd_Argv( 1 ) ); + R_GetPicSize( &uis.cursorWidth, &uis.cursorHeight, uis.cursorHandle ); } else { Com_WPrintf( "Unknown keyword '%s'\n", cmd ); diff --git a/source/vid_local.h b/source/vid_local.h index 780635d..0166514 100644 --- a/source/vid_local.h +++ b/source/vid_local.h @@ -28,10 +28,8 @@ extern cvar_t *_vid_fullscreen; // vid_*.c // void VID_PumpEvents( void ); -void VID_ModeChanged( void ); +void VID_SetMode( void ); void VID_FillInputAPI( inputAPI_t *api ); -void VID_FillGLAPI( videoAPI_t *api ); -void VID_FillSWAPI( videoAPI_t *api ); // // cl_ref.c diff --git a/source/vid_public.h b/source/vid_public.h index bd31116..f272b1b 100644 --- a/source/vid_public.h +++ b/source/vid_public.h @@ -1,5 +1,5 @@ /* -Copyright (C) 2003-2006 Andrey Nazarov +Copyright (C) 2003-2008 Andrey Nazarov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -18,17 +18,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -typedef struct { - qboolean (*Init)( void ); - void (*Shutdown)( void ); +// vid_public.h -- interface to the host window system - void (*UpdateGamma)( const byte *table ); - void (*UpdatePalette)( const byte *palette ); - void *(*GetProcAddr)( const char *symbol ); +qboolean VID_Init( void ); +void VID_Shutdown( void ); +void VID_FatalShutdown( void ); - void (*BeginFrame)( void ); - void (*EndFrame)( void ); -} videoAPI_t; +void VID_UpdateGamma( const byte *table ); +void VID_UpdatePalette( const byte *palette ); +void *VID_GetProcAddr( const char *symbol ); -extern videoAPI_t video; +void VID_BeginFrame( void ); +void VID_EndFrame( void ); +char *VID_GetClipboardData( void ); +void VID_SetClipboardData( const char *data ); diff --git a/source/vid_sdl.c b/source/vid_sdl.c index 74d5cb1..7615b82 100644 --- a/source/vid_sdl.c +++ b/source/vid_sdl.c @@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "vid_local.h" #include "ref_public.h" #include "key_public.h" +#include "cl_public.h" #include "q2pro.xbm" #include <SDL.h> #if USE_X11 @@ -48,7 +49,8 @@ typedef struct { grab_t grabbed; } mouse; #ifdef __unix__ - //PFNGLXGETVIDEOSYNCSGIPROC glXGetVideoSyncSGI; + PFNGLXGETVIDEOSYNCSGIPROC glXGetVideoSyncSGI; + PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI; #endif } sdl_state_t; @@ -200,17 +202,17 @@ static qboolean SetMode( int flags, int forcedepth ) { success: SetHints(); sdl.surface = surf; - ref.ModeChanged( rc.width, rc.height, sdl.flags, surf->pitch, surf->pixels ); + R_ModeChanged( rc.width, rc.height, sdl.flags, surf->pitch, surf->pixels ); SCR_ModeChanged(); return qtrue; } /* ============ -VID_ModeChanged +VID_SetMode ============ */ -void VID_ModeChanged( void ) { +void VID_SetMode( void ) { if( !SetMode( sdl.surface->flags, sdl.surface->format->BitsPerPixel ) ) { Com_Error( ERR_FATAL, "Couldn't change video mode: %s", SDL_GetError() ); } @@ -277,7 +279,7 @@ static qboolean InitVideo( void ) { return qtrue; } -static void ShutdownVideo( void ) { +void VID_Shutdown( void ) { if( sdl.flags & QVF_GAMMARAMP ) { SDL_SetGammaRamp( sdl.gamma[0], sdl.gamma[1], sdl.gamma[2] ); } @@ -293,7 +295,7 @@ static void ShutdownVideo( void ) { } } -static void UpdateGamma( const byte *table ) { +void VID_UpdateGamma( const byte *table ) { Uint16 ramp[256]; int i; @@ -449,7 +451,7 @@ void VID_PumpEvents( void ) { if( sdl.surface->flags & SDL_RESIZABLE ) { Cvar_Set( "vid_geometry", va( "%dx%d", event.resize.w, event.resize.h ) ); - VID_ModeChanged(); + VID_SetMode(); return; } break; @@ -479,12 +481,62 @@ void VID_PumpEvents( void ) { /* =============================================================================== -OPENGL SPECIFIC +RENDERER SPECIFIC =============================================================================== */ -static qboolean InitGL( void ) { +#if USE_REF == REF_SOFT + +qboolean VID_Init( void ) { + if( !InitVideo() ) { + return qfalse; + } + + if( !SetMode( SDL_SWSURFACE|SDL_HWPALETTE|SDL_RESIZABLE, 8 ) ) { + Com_EPrintf( "Couldn't set video mode: %s\n", SDL_GetError() ); + VID_Shutdown(); + return qfalse; + } + + Activate(); + return qtrue; +} + +void VID_UpdatePalette( const byte *palette ) { + SDL_Color colors[256]; + SDL_Color *c; + + for( c = colors; c < colors + 256; c++ ) { + c->r = palette[0]; + c->g = palette[1]; + c->b = palette[2]; + palette += 4; + } + + SDL_SetPalette( sdl.surface, SDL_LOGPAL, colors, 0, 256 ); +} + +void VID_BeginFrame( void ) { + SDL_LockSurface( sdl.surface ); +} + +void VID_EndFrame( void ) { + SDL_UnlockSurface( sdl.surface ); + SDL_Flip( sdl.surface ); +} + +#else // SOFTWARE_RENDERER + +static cvar_t *gl_swapinterval; + +static void gl_swapinterval_changed( cvar_t *self ) { + if( sdl.glXSwapIntervalSGI ) { + sdl.glXSwapIntervalSGI( self->integer ); + } +} + +qboolean VID_Init( void ) { cvar_t *gl_driver; if( !InitVideo() ) { @@ -492,6 +544,7 @@ static qboolean InitGL( void ) { } gl_driver = Cvar_Get( "gl_driver", DEFAULT_OPENGL_DRIVER, CVAR_LATCH ); + gl_swapinterval = Cvar_Get( "gl_swapinterval", "1", CVAR_ARCHIVE ); if( SDL_GL_LoadLibrary( gl_driver->string ) == -1 ) { Com_EPrintf( "Couldn't load OpenGL library: %s\n", SDL_GetError() ); @@ -510,13 +563,17 @@ static qboolean InitGL( void ) { Com_EPrintf( "Couldn't set video mode: %s\n", SDL_GetError() ); goto fail; } -// sdl.glXGetVideoSyncSGI = SDL_GL_GetProcAddress( "glXGetVideoSyncSGI" ); + sdl.glXGetVideoSyncSGI = SDL_GL_GetProcAddress( "glXGetVideoSyncSGI" ); + sdl.glXSwapIntervalSGI = SDL_GL_GetProcAddress( "glXSwapIntervalSGI" ); + + gl_swapinterval->changed = gl_swapinterval_changed; + gl_swapinterval_changed( gl_swapinterval ); Activate(); return qtrue; fail: - ShutdownVideo(); + VID_Shutdown(); return qfalse; } @@ -537,97 +594,24 @@ qboolean VideoSync( void ) { } #endif -static void BeginFrameGL( void ) { +void VID_BeginFrame( void ) { } -static void EndFrameGL( void ) { +void VID_EndFrame( void ) { SDL_GL_SwapBuffers(); } -/* -============ -VID_FillGLAPI -============ -*/ -void VID_FillGLAPI( videoAPI_t *api ) { - api->Init = InitGL; - api->Shutdown = ShutdownVideo; - api->UpdateGamma = UpdateGamma; - api->UpdatePalette = NULL; - api->GetProcAddr = SDL_GL_GetProcAddress; - api->BeginFrame = BeginFrameGL; - api->EndFrame = EndFrameGL; +void *VID_GetProcAddr( const char *sym ) { + return SDL_GL_GetProcAddress( sym ); } -/* -=============================================================================== - -SOFTWARE SPECIFIC - -=============================================================================== -*/ - -#ifndef REF_HARD_LINKED - -static qboolean InitSoft( void ) { - if( !InitVideo() ) { - return qfalse; - } - - if( !SetMode( SDL_SWSURFACE|SDL_HWPALETTE|SDL_RESIZABLE, 8 ) ) { - Com_EPrintf( "Couldn't set video mode: %s\n", SDL_GetError() ); - ShutdownVideo(); - return qfalse; - } - - Activate(); - return qtrue; -} - -static void UpdatePalette( const byte *palette ) { - SDL_Color colors[256]; - SDL_Color *c; - - for( c = colors; c < colors + 256; c++ ) { - c->r = palette[0]; - c->g = palette[1]; - c->b = palette[2]; - palette += 4; - } - - SDL_SetPalette( sdl.surface, SDL_LOGPAL, colors, 0, 256 ); -} - -static void BeginFrameSoft( void ) { - SDL_LockSurface( sdl.surface ); -} - -static void EndFrameSoft( void ) { - SDL_UnlockSurface( sdl.surface ); - SDL_Flip( sdl.surface ); -} - -/* -============ -VID_FillSWAPI -============ -*/ -void VID_FillSWAPI( videoAPI_t *api ) { - api->Init = InitSoft; - api->Shutdown = ShutdownVideo; - api->UpdateGamma = UpdateGamma; - api->UpdatePalette = UpdatePalette; - api->GetProcAddr = NULL; - api->BeginFrame = BeginFrameSoft; - api->EndFrame = EndFrameSoft; -} +#endif // !SOFTWARE_RENDERER -#endif // !REF_HARD_LINKED /* =============================================================================== -SDL MOUSE DRIVER +MOUSE DRIVER =============================================================================== */ diff --git a/source/vid_win.c b/source/vid_win.c index b5bb881..758129f 100644 --- a/source/vid_win.c +++ b/source/vid_win.c @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #include "win_local.h" +#include "cl_public.h" #define WINDOW_CLASS_NAME "Quake2" @@ -125,10 +126,10 @@ static void Win_Show( const vrect_t *rc, qboolean fullscreen ) { } void Win_ModeChanged( void ) { -#ifndef REF_HARD_LINKED +#if USE_REF == REF_SOFT SWimp_ModeChanged(); #endif - ref.ModeChanged( win.rc.width, win.rc.height, win.flags, + R_ModeChanged( win.rc.width, win.rc.height, win.flags, win.pitch, win.buffer ); SCR_ModeChanged(); } @@ -196,7 +197,7 @@ void Win_SetMode( void ) { win.flags &= ~QVF_FULLSCREEN; } -void Win_UpdateGamma( const byte *table ) { +void VID_UpdateGamma( const byte *table ) { WORD v; int i; @@ -494,7 +495,7 @@ Win_MainWndProc main window procedure ==================== */ -LONG WINAPI Win_MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { +PRIVATE LONG WINAPI Win_MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch( uMsg ) { case WM_MOUSEWHEEL: { extern keydest_t Key_GetDest( void ); @@ -704,7 +705,7 @@ LONG WINAPI Win_MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam return DefWindowProc( hWnd, uMsg, wParam, lParam ); } -void VID_ModeChanged( void ) { +void VID_SetMode( void ) { Win_SetMode(); Win_ModeChanged(); } diff --git a/source/win_glimp.c b/source/win_glimp.c index e5d8851..cb83876 100644 --- a/source/win_glimp.c +++ b/source/win_glimp.c @@ -49,7 +49,7 @@ subsystem. Under OpenGL this means NULLing out the current DC and HGLRC, deleting the rendering context, and releasing the DC acquired for the window. The state structure is also nulled out. */ -static void GLimp_Shutdown( void ) { +void VID_Shutdown( void ) { if( qwglMakeCurrent ) { qwglMakeCurrent( NULL, NULL ); } @@ -69,7 +69,7 @@ static void GLimp_Shutdown( void ) { memset( &glw, 0, sizeof( glw ) ); } -static qboolean GLimp_InitGL( void ) { +static qboolean InitGL( void ) { PIXELFORMATDESCRIPTOR pfd = { sizeof( PIXELFORMATDESCRIPTOR ), // size of this pfd 1, // version number @@ -183,7 +183,7 @@ This routine is responsible for initializing the OS specific portions of OpenGL. Under Win32 this means dealing with the pixelformats and doing the wgl interface stuff. */ -static qboolean GLimp_Init( void ) { +qboolean VID_Init( void ) { const char *extensions; gl_driver = Cvar_Get( "gl_driver", "opengl32", CVAR_ARCHIVE|CVAR_REFRESH ); @@ -194,13 +194,13 @@ static qboolean GLimp_Init( void ) { Win_Init(); // initialize OpenGL context - if( !GLimp_InitGL() ) { + if( !InitGL() ) { if( !glw.minidriver ) { goto fail; } Com_Printf( "...attempting to load opengl32\n" ); Cvar_Set( "gl_driver","opengl32" ); - if( !GLimp_InitGL() ) { + if( !InitGL() ) { goto fail; } } @@ -216,8 +216,7 @@ static qboolean GLimp_Init( void ) { Com_Printf( "WGL_EXT_swap_control not found\n" ); } - Win_SetMode(); - Win_ModeChanged(); + VID_SetMode(); return qtrue; @@ -227,7 +226,7 @@ fail: } -static void GLimp_BeginFrame( void ) { +void VID_BeginFrame( void ) { } /* @@ -237,27 +236,17 @@ Responsible for doing a swapbuffers and possibly for other stuff as yet to be determined. Probably better not to make this a GLimp function and instead do a call to GLimp_SwapBuffers. */ -static void GLimp_EndFrame( void ) { +void VID_EndFrame( void ) { if( !qwglSwapBuffers( win.dc ) ) { int error = GetLastError(); if( !IsIconic( win.wnd ) ) { - Com_Error( ERR_FATAL, "GLimp_EndFrame: wglSwapBuffers failed with error %#x", error ); + Com_Error( ERR_FATAL, "wglSwapBuffers failed with error %#x", error ); } } } -/* -@@@@@@@@@@@@ -VID_FillGLAPI -@@@@@@@@@@@@ -*/ -void VID_FillGLAPI( videoAPI_t *api ) { - api->Init = GLimp_Init; - api->Shutdown = GLimp_Shutdown; - api->UpdateGamma = Win_UpdateGamma; - api->GetProcAddr = WGL_GetProcAddress; - api->BeginFrame = GLimp_BeginFrame; - api->EndFrame = GLimp_EndFrame; +void *VID_GetProcAddr( const char *symbol ) { + return ( void * )GetProcAddress( glw.hinstOpenGL, symbol ); } diff --git a/source/win_local.h b/source/win_local.h index 251e23b..7ecbc01 100644 --- a/source/win_local.h +++ b/source/win_local.h @@ -28,6 +28,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "vid_public.h" #include "vid_local.h" #include "ref_public.h" +#include "files.h" +#include "sys_public.h" #define WIN32_LEAN_AND_MEAN #include <windows.h> diff --git a/source/win_wgl.c b/source/win_wgl.c index 26b2038..f88986e 100644 --- a/source/win_wgl.c +++ b/source/win_wgl.c @@ -131,9 +131,6 @@ qboolean WGL_Init( const char *dllname ) { return qtrue; } -void *WGL_GetProcAddress( const char *symbol ) { - return ( void * )GetProcAddress( glw.hinstOpenGL, symbol ); -} #undef GPA |