summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/common.mk43
-rw-r--r--build/q2pro.mk117
-rw-r--r--build/q2proded.mk43
-rw-r--r--build/ref_gl.mk76
-rw-r--r--build/ref_soft.mk47
-rw-r--r--build/server.mk37
-rw-r--r--build/target.mk19
-rwxr-xr-xconfigure286
-rw-r--r--debian/control4
-rwxr-xr-xdebian/rules2
-rw-r--r--source/bsp.c1179
-rw-r--r--source/bsp.h274
-rw-r--r--source/cl_console.c52
-rw-r--r--source/cl_draw.c50
-rw-r--r--source/cl_ents.c44
-rw-r--r--source/cl_input.c2
-rw-r--r--source/cl_keys.c39
-rw-r--r--source/cl_local.h26
-rw-r--r--source/cl_locs.c8
-rw-r--r--source/cl_main.c117
-rw-r--r--source/cl_null.c4
-rw-r--r--source/cl_parse.c30
-rw-r--r--source/cl_pred.c10
-rw-r--r--source/cl_public.h50
-rw-r--r--source/cl_ref.c208
-rw-r--r--source/cl_scrn.c117
-rw-r--r--source/cl_tent.c54
-rw-r--r--source/cl_view.c20
-rw-r--r--source/cmd.c23
-rw-r--r--source/cmodel.c948
-rw-r--r--source/cmodel.h86
-rw-r--r--source/com_local.h825
-rw-r--r--source/com_public.h340
-rw-r--r--source/common.c118
-rw-r--r--source/cvar.c40
-rw-r--r--source/d_bsp.h212
-rw-r--r--source/d_md2.h97
-rw-r--r--source/d_md3.h110
-rw-r--r--source/d_pak.h43
-rw-r--r--source/d_pcx.h44
-rw-r--r--source/d_sp2.h47
-rw-r--r--source/d_wal.h40
-rw-r--r--source/files.c45
-rw-r--r--source/files.h138
-rw-r--r--source/g_public.h4
-rw-r--r--source/gl_draw.c291
-rw-r--r--source/gl_images.c381
-rw-r--r--source/gl_local.h130
-rw-r--r--source/gl_main.c514
-rw-r--r--source/gl_mesh.c54
-rw-r--r--source/gl_models.c832
-rw-r--r--source/gl_sky.c21
-rw-r--r--source/gl_surf.c331
-rw-r--r--source/gl_tess.c181
-rw-r--r--source/gl_world.c440
-rw-r--r--source/mvd_game.c36
-rw-r--r--source/mvd_parse.c79
-rw-r--r--source/net_chan.c5
-rw-r--r--source/net_chan.h56
-rw-r--r--source/net_common.c7
-rw-r--r--source/net_sock.h154
-rw-r--r--source/net_stream.h42
-rw-r--r--source/pmove.c4
-rw-r--r--source/pmove.h50
-rw-r--r--source/prompt.c3
-rw-r--r--source/q_field.c8
-rw-r--r--source/q_fifo.h114
-rw-r--r--source/q_files.h539
-rw-r--r--source/q_msg.c1
-rw-r--r--source/q_shared.c2
-rw-r--r--source/q_shared.h1
-rw-r--r--source/qgl_api.c12
-rw-r--r--source/r_bsp.c664
-rw-r--r--source/r_images.c2290
-rw-r--r--source/r_models.c418
-rw-r--r--source/r_models.h84
-rw-r--r--source/r_shared.h418
-rw-r--r--source/ref_public.h113
-rw-r--r--source/sv_ac.c2
-rw-r--r--source/sv_ccmds.c6
-rw-r--r--source/sv_ents.c15
-rw-r--r--source/sv_game.c119
-rw-r--r--source/sv_init.c10
-rw-r--r--source/sv_local.h13
-rw-r--r--source/sv_main.c38
-rw-r--r--source/sv_public.h39
-rw-r--r--source/sv_send.c46
-rw-r--r--source/sv_world.c23
-rw-r--r--source/sw_alias.c340
-rw-r--r--source/sw_bsp.c275
-rw-r--r--source/sw_draw.c235
-rw-r--r--source/sw_edge.c47
-rw-r--r--source/sw_image.c341
-rw-r--r--source/sw_light.c254
-rw-r--r--source/sw_local.h102
-rw-r--r--source/sw_main.c634
-rw-r--r--source/sw_misc.c12
-rw-r--r--source/sw_model.c1292
-rw-r--r--source/sw_model.h250
-rw-r--r--source/sw_poly.c163
-rw-r--r--source/sw_polyse.c151
-rw-r--r--source/sw_rast.c501
-rw-r--r--source/sw_sky.c178
-rw-r--r--source/sw_sprite.c47
-rw-r--r--source/sw_surf.c10
-rw-r--r--source/sys_public.h76
-rw-r--r--source/sys_unix.c33
-rw-r--r--source/sys_win.c176
-rw-r--r--source/ui_atoms.c48
-rw-r--r--source/ui_demos.c19
-rw-r--r--source/ui_menu.c26
-rw-r--r--source/ui_multiplayer.c15
-rw-r--r--source/ui_playerconfig.c8
-rw-r--r--source/ui_playermodels.c27
-rw-r--r--source/ui_script.c13
-rw-r--r--source/vid_local.h4
-rw-r--r--source/vid_public.h23
-rw-r--r--source/vid_sdl.c164
-rw-r--r--source/vid_win.c11
-rw-r--r--source/win_glimp.c33
-rw-r--r--source/win_local.h2
-rw-r--r--source/win_wgl.c3
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)
diff --git a/configure b/configure
index 2e44ba2..1a8f9cf 100755
--- a/configure
+++ b/configure
@@ -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 = &currentmodel->frames[thisframe];
+ r_lastframe = &currentmodel->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 = &currentmodel->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