summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2008-08-16 10:19:42 +0000
committerAndrey Nazarov <skuller@skuller.net>2008-08-16 10:19:42 +0000
commit1526e22e4ff29153e9c127081e8ea8d9e2f33b8c (patch)
treeb361766433d4a7b4a111865afd52803e2bbf7754
parente826e5f176f21cd18b3bbc22887a266835ada57c (diff)
Split some monolithic include files into smaller ones.
Use single BSP models cache for refresh and collision subsystems. Refresh libraries may not longer be dynamically loaded. Made gi.TagMalloc use separate tag namespace to avoid conflicts with engine reserverd tags. Fixed listing order of MVD channels in chooser menu. A lot of misc changes... MSVC build is definitely broken now.
-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